1 |
9 |
jefflieu |
// (C) 2001-2010 Altera Corporation. All rights reserved.
|
2 |
|
|
// Your use of Altera Corporation's design tools, logic functions and other
|
3 |
|
|
// software and tools, and its AMPP partner logic functions, and any output
|
4 |
|
|
// files any of the foregoing (including device programming or simulation
|
5 |
|
|
// files), and any associated documentation or information are expressly subject
|
6 |
|
|
// to the terms and conditions of the Altera Program License Subscription
|
7 |
|
|
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
8 |
|
|
// license agreement, including, without limitation, that your use is for the
|
9 |
|
|
// sole purpose of programming logic devices manufactured by Altera and sold by
|
10 |
|
|
// Altera or its authorized distributors. Please refer to the applicable
|
11 |
|
|
// agreement for further details.
|
12 |
|
|
//
|
13 |
|
|
// Reset controller building block.
|
14 |
|
|
//
|
15 |
|
|
// Handles a single reset stage. Can be daisy-chained with other blocks for purely sequential resets.
|
16 |
|
|
// Options include reset pulse length in clock cycles, and a counter for sdone stability checking.
|
17 |
|
|
//
|
18 |
|
|
// $Header$
|
19 |
|
|
//
|
20 |
|
|
|
21 |
|
|
`timescale 1 ns / 1 ns
|
22 |
|
|
|
23 |
|
|
module altera_tse_reset_ctrl_lego
|
24 |
|
|
#(
|
25 |
|
|
parameter reset_hold_til_rdone = 0, // 1 means reset stays high until rdone arrives
|
26 |
|
|
// 0 means fixed pulse length, defined by reset_hold_cycles
|
27 |
|
|
parameter reset_hold_cycles = 1, // reset pulse length in clock cycles
|
28 |
|
|
parameter sdone_delay_cycles = 0, // optional delay from rdone received til sdone sent to next block
|
29 |
|
|
parameter rdone_is_edge_sensitive = 0 // default is level sensitive rdone
|
30 |
|
|
)
|
31 |
|
|
(
|
32 |
|
|
// clocks and PLLs
|
33 |
|
|
input wire clock,
|
34 |
|
|
input wire start,
|
35 |
|
|
input tri0 aclr, // active-high asynchronous reset
|
36 |
|
|
output wire reset,
|
37 |
|
|
input tri1 rdone, // reset done signal
|
38 |
|
|
output reg sdone // sequence done for this lego
|
39 |
|
|
);
|
40 |
|
|
localparam max_precision = 32; // VCS requires this declaration outside the function
|
41 |
|
|
function integer ceil_log2;
|
42 |
|
|
input [max_precision-1:0] input_num;
|
43 |
|
|
integer i;
|
44 |
|
|
reg [max_precision-1:0] try_result;
|
45 |
|
|
begin
|
46 |
|
|
i = 0;
|
47 |
|
|
try_result = 1;
|
48 |
|
|
while ((try_result << i) < input_num && i < max_precision)
|
49 |
|
|
i = i + 1;
|
50 |
|
|
ceil_log2 = i;
|
51 |
|
|
end
|
52 |
|
|
endfunction
|
53 |
|
|
|
54 |
|
|
// How many bits are needed for 'reset_hold_cycles' counter?
|
55 |
|
|
localparam rhc_bits = ceil_log2(reset_hold_cycles);
|
56 |
|
|
localparam rhc_load_constant = (1 << rhc_bits) | (reset_hold_cycles-1);
|
57 |
|
|
// How many bits are needed for 'sdone_delay_cycles' counter?
|
58 |
|
|
localparam sdc_bits = ceil_log2(sdone_delay_cycles);
|
59 |
|
|
localparam sdc_load_constant = (1 << sdc_bits)
|
60 |
|
|
| ((rdone_is_edge_sensitive == 1 && sdone_delay_cycles > 1) ? sdone_delay_cycles-2 : sdone_delay_cycles-1);
|
61 |
|
|
localparam sdone_stable_cycles = (sdone_delay_cycles > 1 ? sdone_delay_cycles+1 : 0);
|
62 |
|
|
|
63 |
|
|
wire spulse; // synchronous detection of 'start' 0-to-1 transition
|
64 |
|
|
wire rhold;
|
65 |
|
|
wire timed_reset_in_progress;
|
66 |
|
|
wire rinit_next; // combinatorial input to rinit DFF
|
67 |
|
|
wire rdonei; // internal selector between rdone and rdsave (rdone_is_edge_sensitive==1)
|
68 |
|
|
wire rdpulse; // synchronous detection of 'rdone' 0-to-1 transition, when rdone_is_edge_sensitive==1
|
69 |
|
|
|
70 |
|
|
reg zstart = 0; // delayed value of 'start' input, used for detection of 0-to-1 transition
|
71 |
|
|
reg rinit = 0; // state bit that indicates sequence is in progress
|
72 |
|
|
|
73 |
|
|
initial begin
|
74 |
|
|
sdone = 0; // 1 indicates sequence is done
|
75 |
|
|
end
|
76 |
|
|
|
77 |
|
|
|
78 |
|
|
// 'start' input, detect 0-to-1 transition that triggers sequence
|
79 |
|
|
assign spulse = start & ~zstart;
|
80 |
|
|
always @(posedge clock or posedge aclr)
|
81 |
|
|
if (aclr == 1'b1)
|
82 |
|
|
zstart <= 0;
|
83 |
|
|
else
|
84 |
|
|
zstart <= start;
|
85 |
|
|
|
86 |
|
|
// rinit state bit, triggered by spulse, waits while rhold = 1
|
87 |
|
|
assign rinit_next = spulse | (rinit & (rhold | ~rdonei | rdpulse)) | timed_reset_in_progress;
|
88 |
|
|
always @(posedge clock or posedge aclr)
|
89 |
|
|
if (aclr == 1'b1)
|
90 |
|
|
rinit <= 0;
|
91 |
|
|
else
|
92 |
|
|
rinit <= rinit_next;
|
93 |
|
|
|
94 |
|
|
// optional internal 'rdone' generation logic, if rdone_is_edge_sensitive==1
|
95 |
|
|
generate
|
96 |
|
|
if (rdone_is_edge_sensitive == 0) begin
|
97 |
|
|
assign rdpulse = 0;
|
98 |
|
|
assign rdonei = rdone;
|
99 |
|
|
end
|
100 |
|
|
else begin
|
101 |
|
|
// instantiate synchronous edge-detection logic for rdone
|
102 |
|
|
reg zrdone = 0; // for edge-sensitive rdone, detect 0-to-1 transition synchronously
|
103 |
|
|
reg rdsave = 0; // for edge-sensitive rdone, use this as internal rdone
|
104 |
|
|
always @(posedge clock or posedge aclr) begin
|
105 |
|
|
if (aclr == 1'b1) begin
|
106 |
|
|
zrdone <= 0;
|
107 |
|
|
rdsave <= 0;
|
108 |
|
|
end
|
109 |
|
|
else begin
|
110 |
|
|
zrdone <= rdone; // previous value of rdone for synchronous edge detection
|
111 |
|
|
rdsave <= ~spulse & (rdpulse | rdsave);
|
112 |
|
|
end
|
113 |
|
|
end
|
114 |
|
|
assign rdpulse = rdone & ~zrdone;
|
115 |
|
|
assign rdonei = rdsave;
|
116 |
|
|
end
|
117 |
|
|
endgenerate
|
118 |
|
|
|
119 |
|
|
// rhold depends on sdone_delay_cycles and rdone_is_edge_sensitive
|
120 |
|
|
generate
|
121 |
|
|
if (sdone_delay_cycles == 0 || (sdone_delay_cycles == 1 && rdone_is_edge_sensitive == 1))
|
122 |
|
|
assign rhold = ~rdonei; // sdone_delay_cycles=0
|
123 |
|
|
else begin
|
124 |
|
|
// declare only when needed to avoid Quartus synthesis warnings
|
125 |
|
|
reg [sdc_bits:0] rhold_reg = 0; // for sdone_delay_cycles > 0
|
126 |
|
|
if (sdone_delay_cycles == 1) begin
|
127 |
|
|
always @(posedge clock or posedge aclr) begin
|
128 |
|
|
if (aclr == 1'b1)
|
129 |
|
|
rhold_reg <= 0;
|
130 |
|
|
else
|
131 |
|
|
rhold_reg <= ~(rinit & rdonei);
|
132 |
|
|
end
|
133 |
|
|
assign rhold = rhold_reg[0]; // sdone_delay_cycles=1
|
134 |
|
|
end
|
135 |
|
|
else begin
|
136 |
|
|
// need to count cycles to make sure rdone is stable
|
137 |
|
|
always @(posedge clock or posedge aclr)
|
138 |
|
|
begin
|
139 |
|
|
if (aclr == 1'b1)
|
140 |
|
|
rhold_reg <= 0;
|
141 |
|
|
else if ((rinit & rdonei & ~rdpulse) == 0)
|
142 |
|
|
// keep load value until rinit & rdone both high, and no new rdone pulses
|
143 |
|
|
rhold_reg <= sdc_load_constant[sdc_bits:0];
|
144 |
|
|
else
|
145 |
|
|
rhold_reg <= rhold_reg - 1'b1;
|
146 |
|
|
end
|
147 |
|
|
assign rhold = rhold_reg[sdc_bits]; // sdone_delay_cycles > 1
|
148 |
|
|
end
|
149 |
|
|
end
|
150 |
|
|
endgenerate
|
151 |
|
|
|
152 |
|
|
// sdone state bit indicates that reset sequence completed. Clear again on 'start'
|
153 |
|
|
always @(posedge clock or posedge aclr)
|
154 |
|
|
if (aclr == 1'b1)
|
155 |
|
|
sdone <= 0;
|
156 |
|
|
else
|
157 |
|
|
sdone <= ~spulse & (sdone | (rinit & ~rinit_next));
|
158 |
|
|
|
159 |
|
|
// reset pulse generation logic depends on 2 parameters
|
160 |
|
|
generate
|
161 |
|
|
if (reset_hold_til_rdone == 1) begin
|
162 |
|
|
assign reset = rinit;
|
163 |
|
|
assign timed_reset_in_progress = 0;
|
164 |
|
|
end
|
165 |
|
|
else if (reset_hold_cycles < 1) begin // 0 is legal, but catch negative (illegal) values too
|
166 |
|
|
assign reset = spulse;
|
167 |
|
|
assign timed_reset_in_progress = 0;
|
168 |
|
|
end
|
169 |
|
|
else begin
|
170 |
|
|
// declare only when needed to avoid Quartus synthesis warnings
|
171 |
|
|
reg [rhc_bits:0] zspulse = 0; // bits for reset pulse if fixed length
|
172 |
|
|
assign timed_reset_in_progress = zspulse[rhc_bits];
|
173 |
|
|
assign reset = zspulse[rhc_bits];
|
174 |
|
|
|
175 |
|
|
if (reset_hold_cycles == 1)
|
176 |
|
|
// a single-cycle reset pulse needs 1 register
|
177 |
|
|
always @(posedge clock or posedge aclr)
|
178 |
|
|
if (aclr == 1'b1)
|
179 |
|
|
zspulse <= 0;
|
180 |
|
|
else
|
181 |
|
|
zspulse <= spulse;
|
182 |
|
|
else begin
|
183 |
|
|
// multi-cycle reset pulse needs a counter
|
184 |
|
|
always @(posedge clock or posedge aclr)
|
185 |
|
|
begin
|
186 |
|
|
if (aclr == 1'b1)
|
187 |
|
|
zspulse <= 0;
|
188 |
|
|
else if (spulse == 1)
|
189 |
|
|
zspulse <= rhc_load_constant[rhc_bits:0];
|
190 |
|
|
else if (zspulse[rhc_bits] == 1)
|
191 |
|
|
zspulse <= zspulse - 1'b1;
|
192 |
|
|
end
|
193 |
|
|
end
|
194 |
|
|
end
|
195 |
|
|
endgenerate
|
196 |
|
|
|
197 |
|
|
// generate
|
198 |
|
|
// case (reset_hold_til_rdone)
|
199 |
|
|
// 0 : m1 U1 (a, b, c);
|
200 |
|
|
// 2 : m2 U1 (a, b, c);
|
201 |
|
|
// default : m3 U1 (a, b, c);
|
202 |
|
|
// endcase
|
203 |
|
|
// endgenerate
|
204 |
|
|
|
205 |
|
|
// general assertions
|
206 |
|
|
//synopsys translate_off
|
207 |
|
|
// vlog/vcs/ncverilog: +define+ALTERA_XCVR_ASSERTIONS
|
208 |
|
|
`ifdef ALTERA_XCVR_ASSERTIONS
|
209 |
|
|
// when rdone is edge sensitive, last rdone +ve edge triggers sdone +ve edge,
|
210 |
|
|
// 'sdone_delay_cycles' later. "##1 1" is an always-true cycle to match $rise(sdone)
|
211 |
|
|
sequence rdone_last_edge;
|
212 |
|
|
@(posedge clock) $rose(rdone) ##1 !$rose(rdone) [*sdone_delay_cycles] ##1 1;
|
213 |
|
|
endsequence
|
214 |
|
|
|
215 |
|
|
// when rdone is level sensitive, stable rdone for 'sdone_delay_cycles' consecutive cycles
|
216 |
|
|
// triggers sdone +ve edge. "##1 1" is an always-true cycle to match $rise(sdone)
|
217 |
|
|
sequence rdone_stable_level;
|
218 |
|
|
@(posedge clock) rdone [*(sdone_delay_cycles+1)] ##1 1;
|
219 |
|
|
endsequence
|
220 |
|
|
|
221 |
|
|
// Most assertions aren't valid when 'aclr' is active
|
222 |
|
|
//`define assert_awake(arg) assert property (disable iff (aclr) arg )
|
223 |
|
|
always @(aclr)
|
224 |
|
|
if (aclr) $assertkill;
|
225 |
|
|
else $asserton;
|
226 |
|
|
|
227 |
|
|
generate
|
228 |
|
|
always @(posedge clock) begin
|
229 |
|
|
// A rising edge on start will result in reset high within 1 clock cycle
|
230 |
|
|
assert property ($rose(start & ~aclr) |-> ##[0:1] reset);
|
231 |
|
|
// A rising edge on reset will result in sdone low within 1 clock cycle
|
232 |
|
|
assert property ($rose(reset) |-> ##[0:1] !sdone);
|
233 |
|
|
|
234 |
|
|
// assertions for optional behavior: reset pulse length options
|
235 |
|
|
if (reset_hold_til_rdone == 0 && reset_hold_cycles > 1)
|
236 |
|
|
// Verify fixed-length reset pulse option
|
237 |
|
|
assert property ($rose(reset) |-> reset [*reset_hold_cycles] ##1 !reset)
|
238 |
|
|
else $error("Reset pulse length should be %d", reset_hold_cycles);
|
239 |
|
|
if (reset_hold_til_rdone == 0 && reset_hold_cycles == 1)
|
240 |
|
|
// Verify fixed 1-length reset pulse option
|
241 |
|
|
assert property ($rose(reset) |=> !reset);
|
242 |
|
|
if (reset_hold_til_rdone == 0 && reset_hold_cycles == 0)
|
243 |
|
|
// Verify minimal-length reset pulse option, which mirrors 'start' edge detection
|
244 |
|
|
assert property ($rose(start & ~aclr) |-> reset ##1 !reset);
|
245 |
|
|
if (reset_hold_til_rdone == 1) begin
|
246 |
|
|
// with hold-til-rdone, reset should not deassert until after rdone asserts, then deassert immediately
|
247 |
|
|
assert property ($rose(reset) && !rdone |=> $stable(reset) [*0:$] ##1 (reset && rdone) ##1 !reset);
|
248 |
|
|
assert property ($rose(reset) && rdone ##1 rdone [*sdone_delay_cycles] |=> !reset); // rdone was already high
|
249 |
|
|
//assert property ($rose(reset) && !rdone |-> ##[0:$] rdone ##1 !reset);
|
250 |
|
|
end
|
251 |
|
|
|
252 |
|
|
// assertions for optional behavior: sdone delay options and rdone edge sensitive option
|
253 |
|
|
if (rdone_is_edge_sensitive == 1)
|
254 |
|
|
// rdone edge-sensitive option only has an effect when sdone_delay_cycles > 0
|
255 |
|
|
assert property ($rose(sdone) |-> rdone_last_edge.ended);
|
256 |
|
|
if (rdone_is_edge_sensitive == 0)
|
257 |
|
|
// rdone defaults to level-sensitive
|
258 |
|
|
assert property ($rose(sdone) |-> (rdone_stable_level.ended or $past($fell(reset),1)));
|
259 |
|
|
end
|
260 |
|
|
endgenerate
|
261 |
|
|
`endif // ALTERA_XCVR_ASSERTIONS
|
262 |
|
|
//synopsys translate_on
|
263 |
|
|
endmodule
|