【问题标题】:Verilog slight drops in signal caused by clock change?时钟变化引起的Verilog信号轻微下降?
【发布时间】:2018-02-26 02:07:41
【问题描述】:

我有一个设计用于消除开关抖动的电路。它每 1 ms 对信号进行一次采样,并在移位寄存器中计数 8 ms。当寄存器计数 8 个 1ms 的高信号滴答时,我们假设信号是干净的并且输出 sig_clean 变高。出于某种原因,1KHz 时钟(1 毫秒时钟)的每个滴答声,我的干净信号都会下降到 0,然后在板载时钟的下一个滴答声中恢复。知道为什么会这样吗?

`timescale 1ns / 1ps

module debounce(
    input Clk100MHz, reset_n, Clk1KHzEn, sig,
    output reg sig_clean);

    reg [7:0] sigconfirm;

    initial sigconfirm = 8'b0000_0000;
    initial sig_clean = 0;

always@(posedge Clk100MHz)
    begin
        if(~reset_n)
            sig_clean <= 0;
        else
            if(Clk1KHzEn == 1)
                begin
                    if(sig == 1)
                        begin
                            sigconfirm[7] <= 1;
                            sigconfirm = sigconfirm >> 1;
                        end
                    else
                        begin
                            sigconfirm[7] <= 0;
                            sigconfirm = sigconfirm >> 1;
                        end
                end
    end

always@(posedge Clk100MHz)
    begin
        if(sigconfirm == 8'b1111_1111)
            sig_clean <= 1;
        else
            sig_clean <= 0;
    end 
endmodule

测试台:

`timescale 1ns / 1ps

模块lab_7_top_tb();

reg Clk100MHz, BTNC, BTNU;
wire CA, CB, CC, CD, CE, CF, CG, DP;
wire [7:0] AN;

lab_7_top labtop(
    .Clk100MHz(Clk100MHz),
    .BTNC(BTNC),
    .BTNU(BTNU),
    .CA(CA),
    .CB(CB),
    .CC(CC),
    .CD(CD),
    .CE(CE),
    .CF(CF),
    .CG(CG),
    .DP(DP),
    .AN(AN)
);

initial Clk100MHz = 0;
always #5 Clk100MHz = ~Clk100MHz;

initial begin
    BTNC = 1'b1; BTNU = 1'b0;
    #100;
    BTNC = 1'b0;
    #1000;
    press_BTNU;
    #1000;
    press_BTNU;
    #1000;
    $finish;
end

task press_BTNU;
    begin
        $display("%d Start of press button task", $time);
        BTNU = 0;
        #1000;
        BTNU = 1;
        #1500;
        BTNU = 0;
        #1200;
        BTNU = 1;
        #1800;
        BTNU = 0;
        #1100;
        BTNU = 1;
        #15000;
        BTNU = 0;
        #1800;
        BTNU = 1;
        #1600;
        BTNU = 0;
        #1400;
        BTNU = 1;
        #1100;
        BTNU = 0;
        #15000;
        $display("%d End of press button task", $time);
    end
endtask

结束模块

【问题讨论】:

  • 如果您显示您的测试台代码会很有帮助。
  • 您在 sigconfirm 和时钟之间存在竞争。请在两种情况下分配时使用“非阻塞”分配sigconfirm &lt;= sigconfirm &gt;&gt; 1;

标签: signals verilog


【解决方案1】:

原来问题是 2 个修复:我按照 Serge 的建议修复了阻塞分配,我交换了 sigconfirm 移位和分配位的顺序,得到:

sigconfirm <= sigconfirm >> 1;
sigconfirm[7] <= 1'b1;

现在生活很好!

【讨论】:

    【解决方案2】:

    您将resetsig_clean 放入错误的always 块中。应该是

    always @(posedge Clk100MHz)
        if (!reset_n)
            sig_clean <= 0; 
        else if(sigconfirm == 8'b1111_1111)
                sig_clean <= 1;
             else
                sig_clean <= 0;
    endmodule
    

    【讨论】:

    • 我已修复,但不幸的是错误仍然存​​在。
    猜你喜欢
    • 2016-02-10
    • 2020-01-10
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 2023-03-18
    • 1970-01-01
    • 2021-11-29
    相关资源
    最近更新 更多