三分频的Verilog实现

//很实用也是笔试面试时常考的,已经经过仿真

占空比要求50%和不要求占空比差别会很大,先看一个占空比50%的描述
module div3(CLKIN,CLKOUT,RESETn);
input CLKIN,RESETn;
output CLKOUT;
 
//internal counter signals
reg[1:0] count_a;
reg[1:0] count_b;
reg      CLKOUT;
 
always @(negedge RESETn or posedge CLKIN)
begin
    if (RESETn==1''b0)
        count_a<=2''b00;
    else
        if (count_a==2''b10)
            count_a<=2''b00;
        else
            count_a<=count_a+1;
end
 
always @(negedge RESETn or negedge CLKIN)
begin
    if (RESETn==1''b0)
        count_b<=2''b0;
    else
        if (count_b==2''b10)
            count_b<=2''b00;
        else
            count_b<=count_b+1;
end
 
always @(count_a or count_b or RESETn)
begin
 if (RESETn==1''b0)
   CLKOUT=1''b0;
 else if((count_a+count_b==4)||(count_a+ count_b==1))
   CLKOUT=~CLKOUT;
end
 
 
endmodule
 
0    1     2     0     1     2
\  /    /  \     \   /     /  \
  0     1     2     0     1     2
 
下面是一个非50%的描述,只用了上升沿
 
module div3(CLKIN,CLKOUT,RESETn);
input CLKIN,RESETn;
output CLKOUT;
 
 
wire d;
reg     q1,q2;
wire         CLKOUT;
 
always @(negedge RESETn or posedge CLKIN)
begin
    if (RESETn==1''b0)
        q1<=1''b0;
    else
        q1<=d;
end
 
always @(negedge RESETn or posedge CLKIN)
begin
    if (RESETn==1''b0)
        q2<=1''b0;
    else
        q2<=q1;
end
 
assign d=~q1 & ~q2;
 
assign CLKOUT=q2;
 
endmodule
 
 
占空比不是50%,只用了单沿触发器,寄存器输出。

至于其他奇数要求50%的或者不要求的占空比的,都可以参照上面两个例子做出。
占空比为50%的一个更好的实现。  
module div3(CLKIN,CLKOUT,RESETn);
input CLKIN,RESETn;
output CLKOUT;
//internal counter signals
reg[1:0] count_a;
reg            b,c;
//reg        CLKOUT;
wire CLKOUT;
always @(negedge RESETn or posedge CLKIN)
begin
    if (RESETn==1''b0)
        count_a<=2''b00;
    else
        if (count_a==2''b10)
            count_a<=2''b00;
        else
            count_a<=count_a+1;
end
always @(negedge RESETn or negedge CLKIN)
begin
    if (RESETn==1''b0)
        b<=1''b0;
    else
        if (count_a==2''b01)
            b<=2''b0;
        else
            b<=1''b1;
end
always @(negedge RESETn or posedge CLKIN)
begin
    if (RESETn==1''b0)
        c<=1''b0;
    else
        if (count_a==2''b10)
            c<=1''b1;
        else if (count_a==2''b01)
            c<=1''b0;
end
assign          CLKOUT=b & c;

endmodule

投 票

觉得本文不错,投一票   

评 论


验证码: 看不清?换一张