三分频的Verilog实现

上一篇 / 下一篇  2007-10-12 14:35:05 / 个人分类:FPGA嵌入式

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

占空比要求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


TAG:

kejie的个人空间 引用 删除 kejie   /   2007-10-23 18:48:51
写错了,不应该寄存器输出
//mkj
module div_odd(clk,rst,oclk);
input clk,rst;
output oclk;

reg [2:0] cnt_n;
reg out_n,out_p;
reg oclk;


always @(×)
oclk<=out_n | out_p;

always @(posedge clk or negedge rst)
begin
  if (~rst)
    begin
      cnt_p<=3'h0;  
    end
  else
    if (cnt_p==3'h6)
       cnt_p<=3'h0;
    else
       cnt_p<=cnt_p+1'h1;
end


always @(posedge clk or negedge rst)
begin  
  if (~rst)
    out_p<=1'h0;
  else
    if (cnt_p<3'h3)
      out_p<=1'h0;
    else
      out_p<=1'h1;
end

always @(negedge clk or negedge rst)
begin  
  if (~rst)
    out_n<=1'h0;
  else
    out_n<=out_p;
end

endmodule
kejie的个人空间 引用 删除 kejie   /   2007-10-23 18:40:14
cyberholic 你和baizy1980的差不多,不过都是直观写法,我当时也是这么写的,那日突然想到下面这样子,感觉不错,共享给你们。
参考一下下面我写的,虽没仿真过,但我有信心正确,感觉比你的少几个寄存器,1个比较器,并且是寄存器输出。
给提点意见吧

//mkj
module div_odd(clk,rst,oclk);
input clk,rst;
output oclk;

reg [2:0] cnt_n;
reg out_n,out_p;
reg oclk;


always @(posedge clk or negedge rst)
if (~rst)      oclk<=0;  
else           oclk<=out_n | out_p;

always @(posedge clk or negedge rst)
begin
  if (~rst)
    begin
      cnt_p<=3'h0;  
    end
  else
    if (cnt_p==3'h6)
       cnt_p<=3'h0;
    else
       cnt_p<=cnt_p+1'h1;
end


always @(posedge clk or negedge rst)
begin  
  if (~rst)
    out_p<=1'h0;
  else
    if (cnt_p<3'h3)
      out_p<=1'h0;
    else
      out_p<=1'h1;
end

always @(negedge clk or negedge rst)
begin  
  if (~rst)
    out_n<=1'h0;
  else
    out_n<=out_p;
end

endmodule
cyberholic的个人空间 引用 删除 cyberholic   /   2007-10-18 22:51:28
这是我的7分频的 ,仿真过的。。。。请指教
module div_odd(clk,rst,oclk);
input clk,rst;
output oclk;

reg [7:0] cnt_n,cnt_p;
reg out_n,out_p;

assign oclk=out_n & out_p;

always @(posedge clk or negedge rst)
begin
  if (~rst)
    begin
      cnt_p<=8'h0;  
    end
  else
    if (cnt_p==8'h6)
       cnt_p<=8'h0;
    else
       cnt_p<=cnt_p+1'h1;
end

always @(negedge clk or negedge rst)
begin
  if (~rst)
    begin
      cnt_n<=8'h0;  
    end
  else
    if (cnt_n==8'h6)
       cnt_n<=8'h0;
    else
       cnt_n<=cnt_n+1'h1;
end

always @(posedge clk or negedge rst)
begin  
  if (~rst)
    out_p<=1'h0;
  else
    if (cnt_p<8'h3)
      out_p<=1'h0;
    else
      out_p<=1'h1;
end

always @(negedge clk or negedge rst)
begin  
  if (~rst)
    out_n<=1'h0;
  else
    if (cnt_n<8'h3)
      out_n<=1'h0;
    else
      out_n<=1'h1;
end

endmodule
kejie的个人空间 引用 删除 kejie   /   2007-10-17 19:53:52
老兄,下面是我写的,感觉会省点东西。。。并且寄存器输出
我没做仿真验证,自己来吧,祝找到好工作!

////////////////////////////////////
//div3
//designed by mkj
////////////////////////////////////
module div3(CLKIN,CLKOUT,RESETn);
input CLKIN,RESETn;
output CLKOUT;
  
//internal counter signals
reg[1:0] count_a;
reg      count_b;
reg      CLKOUT;
  
always @(posedge CLKIN or negedge RESETn )
begin
    if (!RESETn)
        count_a<=2'b00;
    else
        if (count_a==2'b10)
            count_a<=2'b00;
        else
            count_a<=count_a+1;
end
  
always @(negedge CLKIN or negedge RESETn )
begin
    if ( !RESETn )
        count_b<=1'b0;
    else count_b<=count_a[0];
end
  
always @(posedge CLKIN or negedge RESETn )
if ( !RESETn )
   CLKOUT<=1'b0;
else CLKOUT<= count_b | count_a[0];  
  
endmodule
zouhuaqiao的个人空间 引用 删除 zouhuaqiao   /   2007-10-15 18:10:43
没脑子
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar