微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > Verilog 时钟双沿触发,有什么缺点

Verilog 时钟双沿触发,有什么缺点

时间:10-02 整理:3721RD 点击:
对于奇数分频,如3分频,Verilog代码如下:想问一下各位,这样类似双沿触发的,有什么不好的地方吗?
module clk3 (clk_in,rst,clk_out);
input clk_in;
input rst;
output clk_out;
reg clk_out;
wire clk_in_inv;  // invert clk_in
assign clk_in_inv = clk_in;
reg [1:0] cnt;
always @ (posedge clk_in or posedge clk_in_inv or posedge rst)
begin
    if(rst)
    begin
        clk_out <= 1'b0;
        cnt <= 2'd0;
    end
    else
    begin
        if(cnt==2'd2)
        begin
                clk_out <= ~clk_out;
                cnt <= 2'd0;
        end
        else
        begin
            cnt <= cnt+2'd1;
        end
    end
end
endmodule

这个你自己想想的吧,你自己仿真综合一下试试

一般的寄存器都是单沿的, 设置为双沿触发可能会综合为两个寄存器

很容易造成前仿和后防不一致。这里需要小心

stdcell中DFF都是只用一个时钟,你这样设计应该不可综合或者LEC无法通过。

最大的问题是stdcell/fpga里没有这样的器件。如果有这样的器件当然没问题,可以由两个Latch和一个Mux组成,KTH课件有介绍。

三分频代码完全可以不用双触发,双触发不要用。引用别人的代码,这个代码经过仿真测试过。
module div_3(clk,rst,count1,count2,clk_even);
    input clk;
    input rst;
    output [3:0] count1;
    output [3:0] count2;
    output clk_even;
   
    reg [3:0] count1,count2;
    reg clkA,clkB;
    reg clktet;
    wire clk_even,clk_re;
    parameter N = 3;
   
    assign clk_re = ~clk;
    assign clk_even = clkA | clkB;
   
   //count计数到2后归零
   always @(posedge clk or negedge rst)
        begin

       if(!rst)
           begin
               count1 <= 0;
           end
       else if(count1 < (N-1))
           begin
              count1 <= count1 + 1'b1;
           end
       else
           begin
              count1 <= 0;
           end
     end
    wire [3:0] NA;
    assign NA = (N-1) >> 1;//NA=2

    always @(posedge clk or negedge rst)
        begin
        if(!rst)
                begin
            clkA <= 1'b0;
        end
       else if(count1 < (N-1))
                    begin
                    if(count1 == NA)
                                            begin
                            clkA <= ~clkA;
                        end
                end
            else
                            begin
                    clkA <= ~clkA;
                end
    end
   
        always @(posedge clk_re or negedge rst) begin
        if(!rst)
                    begin
                count2 <= 0;
            end
        else if(count2 < (N-1))
                     begin
                count2 <= count1 + 1'b1;
             end
           else begin
                count2 <= 0;
                  end
end

wire [3:0] NB;
assign NB = (N-1) >> 1;
    always @(posedge clk_re or negedge rst) begin
        if(!rst) begin
          clkB <= 0;
          end
         else if(count2 < (N-1)) begin
                    if(count2 == NB) begin
                         clkB <= ~clkB;
                         end
                                end
         else begin
            clkB <= ~clkB;
          end
    end

reg [3:0] cnt10;
    always @(posedge clk or negedge rst) begin
        if(!rst) begin
            cnt10 <= 0;
          end
        else if(cnt10==4) begin
            cnt10 <= 0;
         end
        else begin
            cnt10 <= cnt10 + 1'b1;
         end
     end

    always @(posedge clk or negedge rst) begin
        if(!rst) begin
            clktet <= 0;
          end
        else if(cnt10 == 4) begin
            clktet <= ~clktet;
        end
     end
endmodule

上面的代码,是组合逻辑产生的时钟,会有毛刺,这是个老问题了。

现在ALM中包含两个寄存器,布局接近,所以组合逻辑产生的始终问题不会特别明显
如果改进,可以在输出时钟前用寄存器打一拍。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top