44// ------------------------------------------------------------------------------
55
66// INFO -------------------------------------------------------------------------
7- // Static Delay for arbitrary signal
7+ // Static Delay for arbitrary signal, v2
88// Another equivalent names for this module:
99// conveyor.sv
1010// synchronizer.sv
1414//
1515//
1616// CAUTION: delay module is widely used for synchronizing signals across clock
17- // domains. To automatically exclude input data paths from timing analisys
18- // set_false_path SDC constraint is integrated into this module. Applicable
19- // only to Intel/Altera Quartus IDE. Xilinx users still should write the
20- // constraints manually
17+ // domains. When synchronizing, please exclude input data paths from timing
18+ // analisys manually by writing appropriate set_false_path SDC constraint
2119//
20+ // Version 2 introduces "ALTERA_BLOCK_RAM" option to implement delays using
21+ // block RAM. Quartus can make shifters on block RAM aautomatically
22+ // using 'altshift_taps' internal module when "Auto Shift Register
23+ // Replacement" option is ON
2224
2325
2426/* --- INSTANTIATION TEMPLATE BEGIN ---
2527
2628delay #(
27- .LENGTH( 2 )
29+ .LENGTH( 2 ),
30+ .WIDTH( 1 ),
31+ .TYPE( "CELLS" )
2832) S1 (
2933 .clk( clk ),
3034 .nrst( 1'b1 ),
3135 .ena( 1'b1 ),
36+
3237 .in( ),
3338 .out( )
3439);
@@ -37,45 +42,110 @@ delay #(
3742
3843
3944module delay # ( parameter
40- LENGTH = 2 // delay/synchronizer chain length
41- // default length for synchronizer chain is 2
45+ LENGTH = 2 , // delay/synchronizer chain length
46+ WIDTH = 1 , // signal width
47+ TYPE = " CELLS" , // "ALTERA_BLOCK_RAM" infers block ram fifo
48+ // all other values infer registers
49+
50+ CNTR_W = $clog2(LENGTH )
4251)(
4352 input clk,
4453 input nrst,
4554 input ena,
46- input in,
47- output out
55+
56+ input [WIDTH - 1 : 0 ] in,
57+ output [WIDTH - 1 : 0 ] out
4858);
4959
5060generate
5161
5262 if ( LENGTH == 0 ) begin
53- assign out = in;
63+
64+ assign out[WIDTH - 1 : 0 ] = in[WIDTH - 1 : 0 ];
65+
5466 end else if ( LENGTH == 1 ) begin
5567
56- logic data = 0 ;
68+ logic [ WIDTH - 1 : 0 ] data = ' 0 ;
5769 always_ff @ (posedge clk) begin
58- if ( ~ nrst) begin
59- data <= 0 ;
60- end else if ( ena) begin
61- data <= in;
70+ if ( ~ nrst ) begin
71+ data[ WIDTH - 1 : 0 ] <= ' 0 ;
72+ end else if ( ena ) begin
73+ data[ WIDTH - 1 : 0 ] <= in[ WIDTH - 1 : 0 ] ;
6274 end
6375 end
64- assign out = data;
76+ assign out[ WIDTH - 1 : 0 ] = data[ WIDTH - 1 : 0 ] ;
6577
6678 end else begin
79+ if ( TYPE == " ALTERA_BLOCK_RAM" && LENGTH >= 4 ) begin
6780
68- logic [LENGTH : 1 ] data = 0 ;
69- always_ff @ (posedge clk) begin
70- if (~ nrst) begin
71- data[LENGTH : 1 ] <= 0 ;
72- end else if (ena) begin
73- data[LENGTH : 1 ] <= { data[LENGTH - 1 : 1 ],in} ;
81+ logic [CNTR_W - 1 : 0 ] delay_cntr = '0 ;
82+
83+ logic fifo_output_ena;
84+ assign fifo_output_ena = (delay_cntr[CNTR_W - 1 : 0 ] == LENGTH );
85+
86+ always_ff @ (posedge clk) begin
87+ if ( ~ nrst ) begin
88+ delay_cntr[CNTR_W - 1 : 0 ] <= '0 ;
89+ end else begin
90+ if ( ena && ~ fifo_output_ena) begin
91+ delay_cntr[CNTR_W - 1 : 0 ] <= delay_cntr[CNTR_W - 1 : 0 ] + 1'b1 ;
92+ end
93+ end
7494 end
75- end
76- assign out = data[LENGTH ];
7795
78- end // if
96+ logic [WIDTH - 1 : 0 ] fifo_out;
97+ scfifo # (
98+ .LPM_WIDTH ( WIDTH ),
99+ .LPM_NUMWORDS ( LENGTH ), // must be at least 4
100+ .LPM_WIDTHU ( CNTR_W ),
101+ .LPM_SHOWAHEAD ( " ON" ),
102+ .UNDERFLOW_CHECKING ( " ON" ),
103+ .OVERFLOW_CHECKING ( " ON" ),
104+ .ALMOST_FULL_VALUE ( 0 ),
105+ .ALMOST_EMPTY_VALUE ( 0 ),
106+ .ENABLE_ECC ( " FALSE" ),
107+ .ALLOW_RWCYCLE_WHEN_FULL ( " ON" ),
108+ .USE_EAB ( " ON" ),
109+ .MAXIMIZE_SPEED ( 5 ),
110+ .DEVICE_FAMILY ( " Cyclone V" )
111+ ) internal_fifo (
112+ .clock ( clk ),
113+ .aclr ( 1'b0 ),
114+ .sclr ( ~ nrst ),
115+
116+ .data ( in[WIDTH - 1 : 0 ] ),
117+ .wrreq ( ena ),
118+ .rdreq ( ena && fifo_output_ena ),
119+
120+ .q ( fifo_out[WIDTH - 1 : 0 ] ),
121+ .empty ( ),
122+ .full ( ),
123+ .almost_full ( ),
124+ .almost_empty ( ),
125+ .usedw ( ),
126+ .eccstatus ( )
127+ );
128+
129+ assign out[WIDTH - 1 : 0 ] = (fifo_output_ena)? (fifo_out[WIDTH - 1 : 0 ]): ('0 );
130+
131+ end else begin
132+
133+ logic [LENGTH : 1 ][WIDTH - 1 : 0 ] data = '0 ;
134+ always_ff @ (posedge clk) begin
135+ integer i;
136+ if ( ~ nrst ) begin
137+ data <= '0 ;
138+ end else if ( ena ) begin
139+ for (i= LENGTH - 1 ; i> 0 ; i-- ) begin
140+ data[i+ 1 ][WIDTH - 1 : 0 ] <= data[i][WIDTH - 1 : 0 ];
141+ end
142+ data[1 ][WIDTH - 1 : 0 ] <= in[WIDTH - 1 : 0 ];
143+ end
144+ end
145+ assign out[WIDTH - 1 : 0 ] = data[LENGTH ][WIDTH - 1 : 0 ];
146+
147+ end // if TYPE
148+ end // if LENGTH
79149
80150endgenerate
81151
0 commit comments