【发布时间】: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 <= sigconfirm >> 1;