1
1
// ------------------------------------------------------------------------------
2
2
// delayed_event.sv
3
+ // published as part of https://github.com/pConst/basic_verilog
3
4
// Konstantin Pavlov, [email protected]
4
5
// ------------------------------------------------------------------------------
5
6
6
7
// INFO ------------------------------------------------------------------------
7
8
// Module generates delayed pulse one clock width
8
- // Could be useful for initialization or sequencing some tasks
9
- // Could be easily daisy-chained by connecting "after_event" outputs
10
- // to the subsequent "ena" inputs
11
9
//
10
+ // - Could be useful for initialization or sequencing some tasks
11
+ // - Could be easily daisy-chained by connecting "after_event" outputs
12
+ // to the subsequent "ena" inputs
13
+ // - Only one event can be triggered after every reset
14
+ // - Delay operation could be suspended by setting ena to 0 at any time
15
+
16
+
12
17
// |
13
18
// |___,___, ,___,___,___,___,___,___,___,___,___,___,___,
14
19
// | , |___| , , , , , , , , , , , nrst
@@ -43,8 +48,7 @@ delayed_event #(
43
48
--- INSTANTIATION TEMPLATE END ---*/
44
49
45
50
module delayed_event # ( parameter
46
- DELAY = 32 ,
47
- CNTR_WIDTH = $clog2(DELAY )
51
+ DELAY = 32
48
52
)(
49
53
input clk, // system clock
50
54
input nrst, // negative reset
@@ -56,31 +60,87 @@ module delayed_event #( parameter
56
60
);
57
61
58
62
59
- logic [CNTR_WIDTH - 1 : 0 ] seq_cntr = CNTR_WIDTH ' (DELAY );
60
-
61
- logic seq_cntr_is_0;
62
- assign seq_cntr_is_0 = (seq_cntr[CNTR_WIDTH - 1 : 0 ]== '0 );
63
+ localparam CNTR_W = $clog2 (DELAY + 1 );
64
+
65
+ generate
66
+ // ==========================================================================
67
+ if ( DELAY == 0 ) begin
68
+
69
+ logic ena_rise;
70
+ edge_detect event_edge (
71
+ .clk ( clk ),
72
+ .anrst ( nrst ),
73
+ .in ( ena ),
74
+ .rising ( ena_rise )
75
+ );
76
+
77
+ assign on_event = ena_rise;
78
+ assign before_event = 1'b0 ;
79
+ assign after_event = 1'b1 ;
80
+
81
+ // ==========================================================================
82
+ end else if ( DELAY == 1 ) begin
83
+
84
+ logic ena_d1 = 1'b0 ;
85
+ always_ff @ (posedge clk) begin
86
+ if ( ~ nrst ) begin
87
+ ena_d1 <= 1'b0 ;
88
+ end else begin
89
+ ena_d1 <= ena;
90
+ end
91
+ end
92
+
93
+ logic ena_rise;
94
+ edge_detect event_edge (
95
+ .clk ( clk ),
96
+ .anrst ( nrst ),
97
+ .in ( ena_d1 ),
98
+ .rising ( ena_rise )
99
+ );
100
+
101
+ logic got_ena = 1'b0 ;
102
+ always_ff @ (posedge clk) begin
103
+ if ( ~ nrst ) begin
104
+ got_ena <= 1'b0 ;
105
+ end if ( on_event ) begin
106
+ got_ena <= 1'b1 ;
107
+ end
108
+ end
109
+
110
+ assign on_event = ena_rise;
111
+ assign before_event = ! got_ena && ! ena_rise;
112
+ assign after_event = got_ena || ena_rise;
113
+
114
+ // ==========================================================================
115
+ end else begin
116
+
117
+ logic [CNTR_W - 1 : 0 ] seq_cntr = CNTR_W ' (DELAY );
118
+
119
+ logic seq_cntr_is_0;
120
+ assign seq_cntr_is_0 = (seq_cntr[CNTR_W - 1 : 0 ]== '0 );
121
+
122
+ always_ff @ (posedge clk) begin
123
+ if ( ~ nrst) begin
124
+ seq_cntr[CNTR_W - 1 : 0 ] <= CNTR_W ' (DELAY );
125
+ end else begin
126
+ if ( ena && ~ seq_cntr_is_0 ) begin
127
+ seq_cntr[CNTR_W - 1 : 0 ] <= seq_cntr[CNTR_W - 1 : 0 ] - 1'b1 ;
128
+ end
129
+ end // nrst
130
+ end
131
+
132
+ edge_detect event_edge (
133
+ .clk ( clk ),
134
+ .anrst ( 1'b1 ),
135
+ .in ( seq_cntr_is_0 ),
136
+ .rising ( on_event )
137
+ );
138
+
139
+ assign before_event = ~ seq_cntr_is_0;
140
+ assign after_event = seq_cntr_is_0;
63
141
64
- always_ff @ (posedge clk) begin
65
- if ( ~ nrst) begin
66
- seq_cntr[CNTR_WIDTH - 1 : 0 ] <= DELAY ;
67
- end else begin
68
- if ( ena && ~ seq_cntr_is_0 ) begin
69
- seq_cntr[CNTR_WIDTH - 1 : 0 ] <= seq_cntr[CNTR_WIDTH - 1 : 0 ] - 1'b1 ;
70
142
end
71
- end // nrst
72
- end
73
-
74
- edge_detect cntr_edge (
75
- .clk ( clk ),
76
- .nrst ( 1'b1 ),
77
- .in ( seq_cntr_is_0 ),
78
- .rising ( on_event )
79
- );
80
-
81
- assign before_event = ~ seq_cntr_is_0;
82
- assign after_event = seq_cntr_is_0;
83
-
143
+ endgenerate
84
144
85
145
endmodule
86
146
0 commit comments