边沿检测
上升沿检测
原理图
Verilog代码如下:
module posedge_detect(
input clk,
input rst_n,
input in_a,
output p_det
);
reg reg_q;
always @(posedge clk or negedge rst_n) begin
if(~rst_n)
reg_q <= 0;
else begin
reg_q <= in_a;
end
end
assign p_det = in_a && (!reg_q);
endmodule
仿真代码如下:
module tb();
reg clk;
reg rst_n;
reg in_a;
wire p_det;
parameter CLOCK_CYCLE = 20;
posedge_detect DUT(
.clk (clk ),
.rst_n (rst_n),
.in_a (in_a),
.p_det (p_det)
);
initial begin
clk = 1'b0;
rst_n = 1;
in_a = 0;
end
always #(CLOCK_CYCLE/2) clk = ~clk;
initial begin
#(CLOCK_CYCLE*2);
rst_n = 1'b0;
#(CLOCK_CYCLE*2);
rst_n = 1'b1;
@(posedge clk);
#35 in_a = 1;
@(posedge clk);
#15 in_a = 0;
@(posedge clk);
#35 in_a = 1;
@(posedge clk);
#15 in_a = 0;
#(CLOCK_CYCLE*5);
$finish();
end
initial begin
$fsdbDumpfile();
$fsdbDumpvars;
end
endmodule
波形如下:
tb中若使in_a在clk的上升沿变为1,则reg_q会在同一个时钟上升变为1,同一个时钟上升沿p_det采样到in_a 和req_q 的值都为0。
打两拍
原理图
module posedge_detect2(
input clk,
input rst_n,
input in_a,
output p_det
);
reg reg_q1;
reg reg_q2;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
reg_q1 <= 0;
reg_q2 <= 0;
end
else begin
reg_q1 <= in_a;
reg_q2 <= reg_q1;
end
end
assign p_det = in_a && (!reg_q2);
endmodule
波形如下:
下升沿检测
原理图
Verilog代码如下:
module negedge_detect2(
input clk,
input rst_n,
input in_a,
output n_det
);
reg reg_q1;
reg reg_q2;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
reg_q1 <= 0;
reg_q2 <= 0;
end
else begin
reg_q1 <= in_a;
reg_q2 <= reg_q1;
end
end
assign n_det = (!in_a) && (reg_q2);
endmodule
**波形如下:
双边沿检测
原理图
Verilog代码如下:
module double_detect2(
input clk,
input rst_n,
input in_a,
output d_det
);
reg reg_q1;
reg reg_q2;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
reg_q1 <= 0;
reg_q2 <= 0;
end
else begin
reg_q1 <= in_a;
reg_q2 <= reg_q1;
end
end
assign d_det = (in_a) ^ (reg_q2);
endmodule
波形如下: