-
Notifications
You must be signed in to change notification settings - Fork 385
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
88 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,19 @@ | ||
//------------------------------------------------------------------------------ | ||
// delayed_event.sv | ||
// published as part of https://github.com/pConst/basic_verilog | ||
// Konstantin Pavlov, [email protected] | ||
//------------------------------------------------------------------------------ | ||
|
||
// INFO ------------------------------------------------------------------------ | ||
// Module generates delayed pulse one clock width | ||
// Could be useful for initialization or sequencing some tasks | ||
// Could be easily daisy-chained by connecting "after_event" outputs | ||
// to the subsequent "ena" inputs | ||
// | ||
// - Could be useful for initialization or sequencing some tasks | ||
// - Could be easily daisy-chained by connecting "after_event" outputs | ||
// to the subsequent "ena" inputs | ||
// - Only one event can be triggered after every reset | ||
// - Delay operation could be suspended by setting ena to 0 at any time | ||
|
||
|
||
// | | ||
// |___,___, ,___,___,___,___,___,___,___,___,___,___,___, | ||
// | , |___| , , , , , , , , , , , nrst | ||
|
@@ -43,8 +48,7 @@ delayed_event #( | |
--- INSTANTIATION TEMPLATE END ---*/ | ||
|
||
module delayed_event #( parameter | ||
DELAY = 32, | ||
CNTR_WIDTH = $clog2(DELAY) | ||
DELAY = 32 | ||
)( | ||
input clk, // system clock | ||
input nrst, // negative reset | ||
|
@@ -56,31 +60,87 @@ module delayed_event #( parameter | |
); | ||
|
||
|
||
logic [CNTR_WIDTH-1:0] seq_cntr = CNTR_WIDTH'(DELAY); | ||
|
||
logic seq_cntr_is_0; | ||
assign seq_cntr_is_0 = (seq_cntr[CNTR_WIDTH-1:0]=='0); | ||
localparam CNTR_W = $clog2(DELAY+1); | ||
|
||
generate | ||
//========================================================================== | ||
if ( DELAY == 0 ) begin | ||
|
||
logic ena_rise; | ||
edge_detect event_edge ( | ||
.clk( clk ), | ||
.anrst( nrst ), | ||
.in( ena ), | ||
.rising( ena_rise ) | ||
); | ||
|
||
assign on_event = ena_rise; | ||
assign before_event = 1'b0; | ||
assign after_event = 1'b1; | ||
|
||
//========================================================================== | ||
end else if ( DELAY == 1 ) begin | ||
|
||
logic ena_d1 = 1'b0; | ||
always_ff @(posedge clk) begin | ||
if( ~nrst ) begin | ||
ena_d1 <= 1'b0; | ||
end else begin | ||
ena_d1 <= ena; | ||
end | ||
end | ||
|
||
logic ena_rise; | ||
edge_detect event_edge ( | ||
.clk( clk ), | ||
.anrst( nrst ), | ||
.in( ena_d1 ), | ||
.rising( ena_rise ) | ||
); | ||
|
||
logic got_ena = 1'b0; | ||
always_ff @(posedge clk) begin | ||
if( ~nrst ) begin | ||
got_ena <= 1'b0; | ||
end if( on_event ) begin | ||
got_ena <= 1'b1; | ||
end | ||
end | ||
|
||
assign on_event = ena_rise; | ||
assign before_event = !got_ena && !ena_rise; | ||
assign after_event = got_ena || ena_rise; | ||
|
||
//========================================================================== | ||
end else begin | ||
|
||
logic [CNTR_W-1:0] seq_cntr = CNTR_W'(DELAY); | ||
|
||
logic seq_cntr_is_0; | ||
assign seq_cntr_is_0 = (seq_cntr[CNTR_W-1:0]=='0); | ||
|
||
always_ff @(posedge clk) begin | ||
if( ~nrst) begin | ||
seq_cntr[CNTR_W-1:0] <= CNTR_W'(DELAY); | ||
end else begin | ||
if( ena && ~seq_cntr_is_0 ) begin | ||
seq_cntr[CNTR_W-1:0] <= seq_cntr[CNTR_W-1:0] - 1'b1; | ||
end | ||
end // nrst | ||
end | ||
|
||
edge_detect event_edge ( | ||
.clk( clk ), | ||
.anrst( 1'b1 ), | ||
.in( seq_cntr_is_0 ), | ||
.rising( on_event ) | ||
); | ||
|
||
assign before_event = ~seq_cntr_is_0; | ||
assign after_event = seq_cntr_is_0; | ||
|
||
always_ff @(posedge clk) begin | ||
if( ~nrst) begin | ||
seq_cntr[CNTR_WIDTH-1:0] <= DELAY; | ||
end else begin | ||
if( ena && ~seq_cntr_is_0 ) begin | ||
seq_cntr[CNTR_WIDTH-1:0] <= seq_cntr[CNTR_WIDTH-1:0] - 1'b1; | ||
end | ||
end // nrst | ||
end | ||
|
||
edge_detect cntr_edge ( | ||
.clk( clk ), | ||
.nrst( 1'b1 ), | ||
.in( seq_cntr_is_0 ), | ||
.rising( on_event ) | ||
); | ||
|
||
assign before_event = ~seq_cntr_is_0; | ||
assign after_event = seq_cntr_is_0; | ||
|
||
endgenerate | ||
|
||
endmodule | ||
|