Verilog时钟变化导致信号轻微下降?

时间:2018-02-26 02:07:42

标签: signals verilog

我有一个用于去抖开关的电路。它每隔1 ms对信号进行采样,并在移位寄存器中计数8ms。当寄存器计数高信号的8个1ms滴答时,我们假设信号是干净的并且输出sig_clean变高。出于某种原因,1KHz时钟(1 ms时钟)的每个滴答,我的干净信号降至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

Waveform of error

测试平台:

`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

endmodule

2 个答案:

答案 0 :(得分:1)

原来问题是2个修复:我修正了像Serge建议的阻塞任务,并且我交换了sigconfirm移位并分配该位的命令,以获得:

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

现在生活很美好!

答案 1 :(得分:0)

您将reset sig_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