verilog二分频代码&verilog三分频代码

来源:互联网 发布:北京11选五遗漏数据 编辑:程序博客网 时间:2024/04/28 19:28

1.二分频

首先要明白,二分频分的是输入时钟的频率,即CLK的频率。

思路:在每次CLK的上升沿或者下降沿让输出Q翻转不就完成频率的二分了吗?

代码:

    module div_2 (q,clk,reset); //   输出q,输入时钟CLK,同步复位信号RESET.
    output q;
    input reset;
    input clk;
    reg q;
    always @ (posedge clk or posedge reset)
    if (reset)
      q<=1'b0; // 复位置零
      else
      q<=~q; // 否则q信号翻转
endmodule

测试代码:

module test;
    reg clk;
    reg reset;
    div_2 d2 (q,clk,reset);// 调用我们设计的功能模块div_2
    always #20 clk=~clk;// 产生周期为40个时间单位的时钟脉冲信号

// initial块只执行一次,此处让CLK的起始电平为低,RESET为高
    initial    
    begin
        clk=1'b0;
        reset=1'b1;
        #24 reset =1'b0;
    end
endmodule

下面我们来看一下MODELSIM的仿真波形,是不是输出Q的频率变成CLK的一半了呢?



2.三分频

此处给的不是50%占空比的三分频,稍后给出。

思路:设置一个计数器,让计数器计数到适当的值得时候输出q翻转就行了。

代码:

module div_3 (q,clk,reset);
    output q;
    input reset;
    input clk;
    reg q;
    reg [1:0] count;   // 设了一个2位的计数器可以从00计数到11;
    always @ (posedge clk or posedge reset)   // 同步复位,上升沿有效
    if (reset)                           // 复位
    begin
      q<=1'b0;
      count<=2'b00;
end
      else if(count==0)                // 第一个CLK上升沿来的时候q翻转一次计数器加一;
        begin
         q<=~q;
         count<=count+1'b1;
        end
        else if(count==2)              //第3个CLK上升沿来的时候输出q翻转一次计数器归零;
        begin
            q=~q;
            count<=2'b00;
        end
        else                                 //   第二个CLK上升沿来的时候q不动作,计数器加一。   
        begin
        count<=count+1'b1;
        end
      endmodule

测试代码:

// 和以上2分频的一样的测试代码,就是调用功能模块的名字不同,这很好理解,就是你给的任意的CLK的

//频率我都可以三分频才对的

module test;
    reg clk;
    reg reset;
    div_3 d3 (q,clk,reset);
    always #20 clk=~clk;
    initial
    begin
        clk=1'b0;
        reset=1'b1;
        #24 reset =1'b0;
    end
endmodule

看一下波形,是不是原来的三个周期变成一个周期啦??也就是频率三分了



3.三分频    (占空比1/2)

思路:

占空比为50%的三分频稍微麻烦一些,其实就是两个占空比都为1/3的q1和q2相或得到占空比为50%的三分频输出q,只是这两个q1和q2分别是在时钟的上升沿和下降沿翻转而已。

代码:

module div_3 (q,clk,reset);
    output q;
    input reset;
    input clk;
    
    reg q1,q2;                // 内部寄存器变量,分别是两个占空比为1/3的分频;
    reg [1:0] count1,count2;
    assign q=q1|q2;     //   两个相或才是我们要得到的输出q
    always @ (posedge clk or posedge reset) //上升沿生成的三分频q1;
    if (reset)
    begin
      q1<=1'b0;
      count1<=2'b00;
end
      else if(count1==0)
        begin
         q1<=~q1;
         count1<=count1+1'b1;
        end
        else if(count1==1)
        begin
            q1=~q1;
           count1<=count1+1'b1;
        end
            else 
            begin
                count1<=2'b00;
            end
       
       
        always @ (negedge clk or posedge reset)     //下降沿生成的三分频信号q2, 该代码原

//                    理和q1产生原理一致
    if (reset)
    begin
      q2<=1'b0;
      count2<=2'b00;
end
      else if(count2==0)
        begin
         q2<=~q2;
         count2<=count2+1'b1;
        end
        else if(count2==1'b1)
        begin
            q2=~q2;
            count2<=count2+1'b1;
        end
            else 
            begin
                count2<=2'b00;
            end
      
      endmodule

测试代码:

module test; // 与以上各测试代码一致
    reg clk;
    reg reset;
    div_3 d3 (q,clk,reset);
    always #20 clk=~clk;
    initial
    begin
        clk=1'b0;
        reset=1'b1;
        #24 reset =1'b0;
    end
endmodule

我们来看一下q的波形,是不是占空比为50%的三分频输出呢?



好了,知道了这两个分频,我想你应该可以推理出其它的奇偶分频代码了,当然,大于2的偶分频代码需要有一个count来计数,在适当的时候翻转就行,其实分频代码从某种程度上来说就是计数器的适当输出而已。




clk_sys为输入时钟,rst为复位信号,clk_out为输出分频时钟,div_num为分频数目。多少分频就把div_num赋多少值。
module clk_div(clk_sys, rst, clk_out,div_num);  
input clk_sys;
input rst;  
input [4:0] div_num;  
output clk_out;  
reg clk_out; 
reg [3:0] baud_count;  
always @(posedge clk_sys) begin  
if (rst) begin  
baud_count<=0; clk_out<=0;  
end  
else begin  
if (baud_count==(div_num/2)-1) begin  
baud_count<=0; clk_out<=~clk_out;  
end  
else begin  
baud_count<=baud_count+1; clk_uart<= clk_out;  
end  
end endendmodule


0 0
原创粉丝点击