Skip to content

Commit 2431265

Browse files
committed
Combinational implementation of EdgeDetector with zero latency
1 parent 5e8c4c2 commit 2431265

File tree

6 files changed

+167
-29
lines changed

6 files changed

+167
-29
lines changed
File renamed without changes.

00_obsolete/EdgeDetect.sv

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//------------------------------------------------------------------------------
2+
// EdgeDetect.sv
3+
// Konstantin Pavlov, [email protected]
4+
//------------------------------------------------------------------------------
5+
6+
// INFO ------------------------------------------------------------------------
7+
// Variable width edge detector
8+
// Features one tick propagation time
9+
10+
11+
/* --- INSTANTIATION TEMPLATE BEGIN ---
12+
13+
EdgeDetect #(
14+
.WIDTH( 32 )
15+
) ED1 (
16+
.clk( clk ),
17+
.nrst( 1'b1 ),
18+
.in( ),
19+
.rising( ),
20+
.falling( ),
21+
.both( )
22+
);
23+
24+
--- INSTANTIATION TEMPLATE END ---*/
25+
26+
27+
module EdgeDetect #(
28+
WIDTH = 1
29+
)(
30+
input clk,
31+
input nrst,
32+
33+
input [(WIDTH-1):0] in,
34+
output logic [(WIDTH-1):0] rising = 0,
35+
output logic [(WIDTH-1):0] falling = 0,
36+
output [(WIDTH-1):0] both
37+
);
38+
39+
40+
logic [(WIDTH-1):0] in_prev = 0;
41+
42+
always_ff @(posedge clk) begin
43+
if ( ~nrst ) begin
44+
in_prev <= 0;
45+
rising <= 0;
46+
falling <= 0;
47+
end
48+
else begin
49+
in_prev <= in;
50+
rising[(WIDTH-1):0] <= in[(WIDTH-1):0] & ~in_prev[(WIDTH-1):0];
51+
falling[(WIDTH-1):0] <= ~in[(WIDTH-1):0] & in_prev[(WIDTH-1):0];
52+
end
53+
end
54+
55+
assign both[(WIDTH-1):0] = rising[(WIDTH-1):0] | falling[(WIDTH-1):0];
56+
57+
endmodule
File renamed without changes.

EdgeDetect.sv

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,51 @@
44
//------------------------------------------------------------------------------
55

66
// INFO ------------------------------------------------------------------------
7-
// Variable width edge detector
8-
// Features one tick propagation time
7+
// Edge detector, ver.2
8+
// Combinational implementation (zero ticks delay)
9+
//
10+
// In case when "in" port has toggle rate 100% (changes every clock period)
11+
// "rising" and "falling" outputs will completely replicate input
12+
// "both" output will be always active in this case
913

1014

1115
/* --- INSTANTIATION TEMPLATE BEGIN ---
1216
13-
EdgeDetect #(
14-
.WIDTH( 32 )
15-
) ED1 (
16-
.clk( clk ),
17-
.nrst( 1'b1 ),
18-
.in( ),
19-
.rising( ),
17+
EdgeDetect ED1[31:0] (
18+
.clk( {32{clk}} ),
19+
.nrst( {32{1'b1}} ),
20+
.in( in[31:0] ),
21+
.rising( out[31:0] ),
2022
.falling( ),
2123
.both( )
2224
);
2325
2426
--- INSTANTIATION TEMPLATE END ---*/
2527

2628

27-
module EdgeDetect #(
28-
WIDTH = 1
29-
)(
29+
module EdgeDetect(
3030
input clk,
3131
input nrst,
3232

33-
input [(WIDTH-1):0] in,
34-
output logic [(WIDTH-1):0] rising = 0,
35-
output logic [(WIDTH-1):0] falling = 0,
36-
output [(WIDTH-1):0] both
33+
input in,
34+
output logic rising,
35+
output logic falling,
36+
output logic both
3737
);
3838

39-
40-
logic [(WIDTH-1):0] in_prev = 0;
41-
39+
logic in_d = 0;
4240
always_ff @(posedge clk) begin
4341
if ( ~nrst ) begin
44-
in_prev <= 0;
45-
rising <= 0;
46-
falling <= 0;
47-
end
48-
else begin
49-
in_prev <= in;
50-
rising[(WIDTH-1):0] <= in[(WIDTH-1):0] & ~in_prev[(WIDTH-1):0];
51-
falling[(WIDTH-1):0] <= ~in[(WIDTH-1):0] & in_prev[(WIDTH-1):0];
42+
in_d <= 0;
43+
end else begin
44+
in_d <= in;
5245
end
5346
end
5447

55-
assign both[(WIDTH-1):0] = rising[(WIDTH-1):0] | falling[(WIDTH-1):0];
48+
always_comb begin
49+
rising = nrst && (in && ~in_d);
50+
falling = nrst && (~in && in_d);
51+
both = nrst && (rising || falling);
52+
end
5653

5754
endmodule

EdgeDetect_tb.sv

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//------------------------------------------------------------------------------
2+
// EdgeDetect_tb.sv
3+
// Konstantin Pavlov, [email protected]
4+
//------------------------------------------------------------------------------
5+
6+
// INFO ------------------------------------------------------------------------
7+
//
8+
9+
`timescale 1ns / 1ps
10+
11+
module EdgeDetect_tb();
12+
13+
logic clk200;
14+
initial begin
15+
#0 clk200 = 1;
16+
forever
17+
#2.5 clk200 = ~clk200;
18+
end
19+
20+
logic rst;
21+
initial begin
22+
#10.2 rst = 1;
23+
#5 rst = 0;
24+
//#10000;
25+
forever begin
26+
#9985 rst = ~rst;
27+
#5 rst = ~rst;
28+
end
29+
end
30+
31+
logic nrst;
32+
assign nrst = ~rst;
33+
34+
logic rst_once;
35+
initial begin // initializing non-X data before PLL starts
36+
#10.2 rst_once = 1;
37+
#5 rst_once = 0;
38+
end
39+
initial begin
40+
#510.2 rst_once = 1; // PLL starts at 500ns, clock appears, so doing the reset for modules
41+
#5 rst_once = 0;
42+
end
43+
44+
logic nrst_once;
45+
assign nrst_once = ~rst_once;
46+
47+
logic [31:0] DerivedClocks;
48+
ClkDivider #(
49+
.WIDTH( 32 )
50+
) CD1 (
51+
.clk( clk200 ),
52+
.nrst( nrst_once ),
53+
.out( DerivedClocks[31:0] )
54+
);
55+
56+
logic [15:0] RandomNumber1;
57+
c_rand RNG1 (
58+
.clk( clk200 ),
59+
.rst( rst_once ),
60+
.reseed( 1'b0 ),
61+
.seed_val( DerivedClocks[31:0] ),
62+
.out( RandomNumber1[15:0] )
63+
);
64+
65+
logic start;
66+
initial begin
67+
#0 start = 1'b0;
68+
#100.2 start = 1'b1;
69+
#5 start = 1'b0;
70+
end
71+
72+
// Module under test ==========================================================
73+
74+
EdgeDetect ED1[15:0] (
75+
.clk( {16{clk200}} ),
76+
.nrst( {16{nrst_once}} ),
77+
.in( RandomNumber1[15:0] ),
78+
.rising( ),
79+
.falling( ),
80+
.both( )
81+
);
82+
83+
84+
endmodule

main_tb.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ reg clk200;
1515
initial begin
1616
#0 clk200 = 1;
1717
forever
18-
18+
#2.5 clk200 = ~clk200;
1919
end
2020

2121
reg rst;

0 commit comments

Comments
 (0)