我有一个用于去抖开关的电路。它每隔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
测试平台:
`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
答案 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