OpenCores
URL https://opencores.org/ocsvn/sgmii/sgmii/trunk

Subversion Repositories sgmii

[/] [sgmii/] [trunk/] [sim/] [BFMs/] [SGMII_altera/] [triple_speed_ethernet-library/] [altera_tse_reset_ctrl_lego.sv] - Blame information for rev 20

Details | Compare with Previous | View Log

Line No. Rev Author Line
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 20 jefflieu
            rinit <= 1;
91 9 jefflieu
                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 20 jefflieu
                    zspulse <= 1;
180 9 jefflieu
                                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 20 jefflieu
                    zspulse <= {rhc_bits + 1 { 1'b1}};
188 9 jefflieu
                                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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.