FPGA学习笔记. 二分频和三分频

二分频和三分频

二分频:将输入频率CLK分为原来的 1/2 。

实现:在每次CLK的上升沿或下降沿将输出翻转。

三分频

1/3占空比。

实现:可使用上升沿或下降沿计数生成输出。需要一个两位计数器。

  1. 第一个CLK,输出Q翻转,计数器加1;
  2. 第二个CLK,输出Q不变,计数器加1;
  3. 第三个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

仿真结果

原文地址:https://www.cnblogs.com/protogenoi/p/10036370.html