竞争:同一个信号,经过不同通路到达某一个门电路的输入端,时间上有先后(不是同时到达)的一种现象
冒险:由于竞争导致输入产生了干扰信号,也就是预期不该有的信号
如下图,输出F=A’ & A;由于反相器的存在,导致A’相比于A到达与门输入端的时间会滞后,导致出现干扰脉冲信号
但是竞争不一定会有冒险,比如在低速数字电路,输出并联加入小电容滤波,即使输入端有竞争,脉冲持续时间比较短,刚往上跳动时候,电容通电也不会有脉冲,也就不一定有冒险,有冒险肯定有竞争
下面举个产生毛刺和消除毛刺的例子
测试文件
`timescale 1ns/1ns
module test;
reg clk;
reg rstn;
reg en;
reg din_rvs;
reg flag;
initial begin
rstn = 1'b0;
clk = 1'b0;
#5 rstn = 1'b1;
forever begin
#5 clk = ~ clk;
end
end
initial begin
en = 1'b0;
din_rvs = 1'b1;
#19;
en = 1'b1;
#1;
din_rvs = 0;
#1000;
$finish();
end
comptt_hazard inst0(
.clk (clk),
.rstn (rstn),
.en (en),
.din_rvs (din_rvs),
.flag (flag)
);
initial begin
$fsdbDumpfile("comptt_hazard_fan");
$fsdbDumpvars;
$vcdpluson;
end
endmodule
assign语句
`timescale 1ns/1ns
module comptt_hazard(
input clk,
input rstn,
input en,
input din_rvs,
output reg flag
);
wire condition;
assign condition = din_rvs & en ;
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
flag <= 1'b0;
end
else begin
flag <= condition;
end
end
endmodule
输出信号使用专用寄存器直接输出结构,用触发器锁存稳定的值避免采样毛刺
`timescale 1ns/1ns;
module comptt_hazard(
input clk,
input rstn,
input en,
input din_rvs,
output reg flag
);
reg en_ff;
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
en_ff <= 1'b0;
end
else begin
en_ff <= en;
end
end
reg din_rvs_ff;
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
din_rvs_ff <= 1'b0;
end
else begin
din_rvs_ff <= din_rvs;
end
end
assign condition = din_rvs_ff & en_ff;
//D触发器寄存一拍
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
flag <= 1'b0;
end
else begin
flag <= condition;
end
end
endmodule
仿真波形图分别如下图
有毛刺产生
无毛刺产生