FPGA学习笔记. 二分频和三分频
二分频和三分频
二分频:将输入频率CLK分为原来的 1/2 。
实现:在每次CLK的上升沿或下降沿将输出翻转。
三分频:
1/3占空比。
实现:可使用上升沿或下降沿计数生成输出。需要一个两位计数器。
- 第一个CLK,输出Q翻转,计数器加1;
- 第二个CLK,输出Q不变,计数器加1;
- 第三个CLK,输出Q翻转,计数器清零。
50%占空比。
实现:将上升沿生成的Q1和下降沿生成的Q2两个1/3占空比相或。
code:
module DividerMultiple( input clk_i, input rst_n_i, output div2_o, output div3_o, output [1:0]div3p_o, output [1:0]div3n_o // output [1:0]div3_r, // output div3_75 ); //*************** reg div2_o_r; //**************** reg [1:0] pos_cnt; reg [1:0] neg_cnt; reg div3_o_r0; reg div3_o_r1; //reg div3p_o; //reg div3n_o; //reg [1:0]div3_r; //reg div3_75; //******************* //always@(posedge clk_i or negedge rst_n_i) //begin // if(!rst_n_i)begin // div3_r <= 2'b00; // div3_75 <= 1'b0; // end // else begin // if(div3_r == 2'b00) begin // div3_75 <= ~div3_75; // div3_r <= div3_r + 1'b1; // end // else if(div3_r == 2'b10) begin // div3_75 <= ~div3_75; // div3_r <= 2'b00; // end // else // div3_r <= 2'b00; // end //end //two divided-frequency always@(posedge clk_i or negedge rst_n_i) begin if(!rst_n_i)begin div2_o_r <= 1'b0; end else begin div2_o_r <= ~div2_o_r; end end //three divided-frequency always@(posedge clk_i or negedge rst_n_i) //上升沿计数 begin if(!rst_n_i)begin pos_cnt<=2'b00; end else begin if(pos_cnt==2'd2) pos_cnt<=2'b00; else pos_cnt<=pos_cnt+1'b1; end end always@(negedge clk_i or negedge rst_n_i) //下降沿计数 begin if(!rst_n_i)begin neg_cnt<=2'b00; end else begin if(neg_cnt==2'd2) begin neg_cnt<=2'b00; end else neg_cnt<=neg_cnt+1'b1; end end always@(posedge clk_i or negedge rst_n_i) begin if(!rst_n_i) div3_o_r0<=1'b0; else if(pos_cnt<2'd1) div3_o_r0<=1'b1; else div3_o_r0<=1'b0; end always@(negedge clk_i or negedge rst_n_i) begin if(!rst_n_i) div3_o_r1<=1'b0; else if(neg_cnt<2'd1) div3_o_r1<=1'b1; else div3_o_r1<=1'b0; end assign div2_o = div2_o_r; assign div3_o = div3_o_r0 | div3_o_r1; //相或 assign div3p_o = div3_o_r0; assign div3n_o = div3_o_r1; endmodule
testbench
module Divider_Multiple_tb; // Inputs reg clk_i; reg rst_n_i; // Outputs wire div2_o; wire div3_o; wire [1:0]div3p_o; wire [1:0]div3n_o; // Instantiate the Unit Under Test (UUT) DividerMultiple uut ( .clk_i(clk_i), .rst_n_i(rst_n_i), .div2_o(div2_o), .div3_o(div3_o) , .div3p_o(div3p_o) , .div3n_o(div3n_o) ); initial begin // Initialize Inputs4 clk_i = 0; rst_n_i = 0; // Wait 100 ns for global reset to finish #96; rst_n_i=1; end always begin #5 clk_i=~clk_i; end endmodule
仿真结果: