mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-14 06:42:54 +08:00
Generalized delayed_event code
This commit is contained in:
parent
2e3551056b
commit
23709d8278
114
delayed_event.sv
114
delayed_event.sv
@ -1,14 +1,19 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// delayed_event.sv
|
// delayed_event.sv
|
||||||
|
// published as part of https://github.com/pConst/basic_verilog
|
||||||
// Konstantin Pavlov, pavlovconst@gmail.com
|
// Konstantin Pavlov, pavlovconst@gmail.com
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// INFO ------------------------------------------------------------------------
|
// INFO ------------------------------------------------------------------------
|
||||||
// Module generates delayed pulse one clock width
|
// 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
|
// | , |___| , , , , , , , , , , , nrst
|
||||||
@ -43,8 +48,7 @@ delayed_event #(
|
|||||||
--- INSTANTIATION TEMPLATE END ---*/
|
--- INSTANTIATION TEMPLATE END ---*/
|
||||||
|
|
||||||
module delayed_event #( parameter
|
module delayed_event #( parameter
|
||||||
DELAY = 32,
|
DELAY = 32
|
||||||
CNTR_WIDTH = $clog2(DELAY)
|
|
||||||
)(
|
)(
|
||||||
input clk, // system clock
|
input clk, // system clock
|
||||||
input nrst, // negative reset
|
input nrst, // negative reset
|
||||||
@ -56,31 +60,87 @@ module delayed_event #( parameter
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
logic [CNTR_WIDTH-1:0] seq_cntr = CNTR_WIDTH'(DELAY);
|
localparam CNTR_W = $clog2(DELAY+1);
|
||||||
|
|
||||||
logic seq_cntr_is_0;
|
generate
|
||||||
assign seq_cntr_is_0 = (seq_cntr[CNTR_WIDTH-1:0]=='0);
|
//==========================================================================
|
||||||
|
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
|
||||||
end // nrst
|
endgenerate
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user