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

 

 

仿真結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM