Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / ccu / rtl / ccu_csr.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: ccu_csr.v
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35`define PLL_REG 40'h8300000000
36`define RNGCTL_REG 40'h8300000020
37`define RNGDAT_REG 40'h8300000030
38
39
40// POLYNOMIAL DEFINITION
41// x64 + x61 + x57 + x56 + x52 + x51 + x50 + x48 + x47 +
42// x46 + x43 + x42 + x41 + x39 + x38 + x37 + x35 + x32 +
43// x28 + x25 + x22 + x21 + x17 + x15 + x13 + x12 + x11 +
44// x7 + x5 + x + 1
45
46// poly coeffecients starting with x^63 going down to x^0 (x^64 tap is always 1)
47`define RNGCRC_POLY 64'b00100011000111011_100111011101001_000100100110001010111_00010100011
48// default values - currently set to 62
49`define DEFAULT_RNG_WAIT_VAL 16'h003E
50
51// FIELD DEFINITION
52`define PLL_DIV1 5:0
53`define PLL_DIV2 11:6
54`define PLL_DIV3 17:12
55`define PLL_DIV4 24:18
56`define ST_PHASE_HI 25
57`define ST_DELAY_CMP 27:26
58`define SERDES_DTM1 28
59`define SERDES_DTM2 29
60`define ALIGN_SHIFT 31:30
61`define CHANGE 32
62`define PLL_CHAR_IN 33
63`define ST_DELAY_DR 35:34
64`define PLL_CLAMP_FLTR 36
65`define PLL_RES 63:37
66
67`define RNG_RES 63:25
68`define RNG_WAIT_CNT 24:9
69`define RNG_BYPASS 8
70`define RNG_VCOCTRL_SEL 7:6
71`define RNG_ANLG_SEL 5:4
72`define RNG_CTL4 3
73`define RNG_CTL3 2
74`define RNG_CTL2 1
75`define RNG_CTL1 0
76
77
78// STATE DEFINITION
79`define CCUCSR_IDLE 3'b000
80`define CCUCSR_WRITE 3'b001
81`define CCUCSR_READ 3'b010
82`define CCUCSR_READ_SUCCESS 3'b011
83`define CCUCSR_READ_PROB 3'b100
84
85`timescale 1 ns / 10 ps
86
87module ccu_csr (
88 // ucb connectivity side
89 io_clk,
90
91 wr_req_vld,
92 addr_in,
93 data_in,
94 req_accepted,
95
96 rd_req_vld,
97 thr_id_in,
98 buf_id_in,
99
100 rack_busy,
101
102 data_out,
103 thr_id_out,
104 buf_id_out,
105 rd_ack_vld,
106 rd_nack_vld,
107
108 int_busy,
109 dev_id,
110 int_vld,
111
112 // other block connectivity
113 rst_n,
114 wmr_protect,
115 rng_data_in,
116 // RNG outputs
117 rng_ctl1,
118 rng_ctl2,
119 rng_ctl3,
120 rng_bypass,
121 rng_vcoctrl_sel,
122 rng_anlg_sel,
123 // PLL outputs
124 pll_div1,
125 pll_div2,
126 pll_div3,
127 pll_div4,
128 st_phase_hi,
129 st_delay_cmp,
130 st_delay_dr,
131 serdes_dtm1,
132 serdes_dtm2,
133 change,
134 align_shift,
135 pll_clamp_fltr,
136 pll_char_in
137);
138
139// *****************************************
140// PORT DECLARATION
141// *****************************************
142
143// ucb connectivity side
144// ------------------------
145input io_clk;
146
147// CSR Write case:
148input wr_req_vld; // when signal is asserted, following are valid to Local Unit
149input [39:0] addr_in; // Based on addr_in Local Unit will update the CSR info accordingly
150input [63:0] data_in; // Write command to invalid address should be discarded silently
151output req_accepted; // CSR Reg Block will assert a 1 clock pulse to indicate acceptance
152
153
154// CSR read case:
155input rd_req_vld; // when signal is asserted, following are valid to Local Unit
156// input [39:0] addr_in; // Based on addr_in Local Unit will read the CSR info accordingly
157input [5:0] thr_id_in;
158input [1:0] buf_id_in;
159input rack_busy; // until deasserted, CSR reg Block should NOT assert rd_ack_vld/"rd_nack_vld
160
161// output req_accepted; // CSR Reg Block will assert a 1 clock pulse to indicate acceptance
162output [63:0] data_out;
163output [5:0] thr_id_out;
164output [1:0] buf_id_out;
165output rd_ack_vld; // CSR Reg Block asserts this to send return data to CSR Interface logic
166output rd_nack_vld; // if not valid, Reg Block asserts this along with thr_id_in and buf_id_in
167
168
169// Interrupts : // unused stuff for now
170output int_busy;
171output [5:0] dev_id; // When Local Unit needs to send intr to NCU, there should be set
172output int_vld; // asserted indicates a valid interrupt to NCU, and asserts only when int_busy is 0.
173
174
175// other block connectivity
176// ------------------------
177input rst_n;
178input wmr_protect;
179input rng_data_in;
180
181// PLL_REG fields
182output [5:0] pll_div1;
183output [5:0] pll_div2;
184output [5:0] pll_div3;
185output [6:0] pll_div4;
186
187output pll_char_in;
188output change;
189output [1:0] align_shift;
190output serdes_dtm2;
191output serdes_dtm1;
192output [1:0] st_delay_cmp;
193output [1:0] st_delay_dr;
194output st_phase_hi;
195output pll_clamp_fltr;
196
197
198// RNG_CTL fields
199output rng_ctl1;
200output rng_ctl2;
201output rng_ctl3;
202output rng_bypass;
203output [1:0] rng_vcoctrl_sel;
204output [1:0] rng_anlg_sel;
205
206
207// *****************************************
208// WIRE/REG DECLARATION
209// *****************************************
210
211// ucb connectivity side
212wire io_clk;
213
214wire wr_req_vld;
215wire [39:0] addr_in;
216wire [63:0] data_in;
217reg req_accepted;
218
219wire rd_req_vld;
220wire [5:0] thr_id_in;
221wire [1:0] buf_id_in;
222wire rack_busy;
223
224reg [63:0] data_out;
225// reg [5:0] thr_id_out;
226// reg [1:0] buf_id_out;
227wire [5:0] thr_id_out;
228wire [1:0] buf_id_out;
229reg rd_ack_vld;
230reg rd_nack_vld;
231
232wire int_busy;
233wire [5:0] dev_id;
234wire int_vld;
235
236
237wire rst_n;
238wire wmr_protect;
239wire rng_data_in;
240// PLL_REG fields
241wire [5:0] pll_div1;
242wire [5:0] pll_div2;
243wire [5:0] pll_div3;
244wire [6:0] pll_div4;
245
246wire pll_char_in;
247wire change;
248wire [1:0] align_shift;
249wire serdes_dtm2;
250wire serdes_dtm1;
251wire [1:0] st_delay_cmp;
252wire [1:0] st_delay_dr;
253wire st_phase_hi;
254wire pll_clamp_fltr;
255
256
257// RNG_CTL fields
258wire rng_ctl1;
259wire rng_ctl2;
260wire rng_ctl3;
261wire rng_bypass;
262wire [1:0] rng_vcoctrl_sel;
263wire [1:0] rng_anlg_sel;
264wire [15:0] rng_wait_cnt;
265
266// ---------------------------------
267// internal wire/reg stuff
268// ---------------------------------
269
270wire rng_data_in_gated;
271
272// for instantiated flops
273wire [63:0] pll_r;
274wire [63:0] rngctl_r;
275wire [63:0] rngdat_r;
276wire rng_ctl4;
277wire [2:0] state;
278
279wire rng_data_synced;
280
281wire pll_match ;
282wire rngctl_match ;
283wire rngdat_match ;
284wire pll_wr_en;
285wire rngctl_wr_en;
286// wire rngdat_wr_en;
287
288wire pll_rd_en;
289wire rngctl_rd_en;
290wire rngdat_rd_en;
291
292wire wr_ok;
293wire rd_ok;
294wire rd_nok;
295
296wire l1clk;
297
298wire rng_busy;
299wire rng_cnt_reached;
300reg [15:0] rng_cnt;
301
302wire [63:0] lfsr_in;
303reg [63:0] lfsr_data;
304wire [63:0] msb_sel; // pick out msb based on poly coeff
305wire [63:0] poly; // given in decreasing powers of x
306wire lfsr_fdbk;
307
308wire [63:0] lfsr_data_muxed;
309wire [15:0] max_cnt;
310
311wire rng_wait_done;
312reg rng_cnt_reached_q1;
313// ***********************************************************
314// Unused outputs
315// ***********************************************************
316
317assign int_vld = 1'b0;
318assign int_busy = 1'b0;
319assign dev_id = 6'b0_0000;
320
321// ***********************************************************
322// CSR Fields
323// ***********************************************************
324
325assign pll_div1 = pll_r[`PLL_DIV1];
326assign pll_div2 = pll_r[`PLL_DIV2];
327assign pll_div3 = pll_r[`PLL_DIV3];
328assign pll_div4 = pll_r[`PLL_DIV4];
329assign st_phase_hi = pll_r[`ST_PHASE_HI];
330assign st_delay_cmp = pll_r[`ST_DELAY_CMP];
331assign serdes_dtm1 = pll_r[`SERDES_DTM1];
332assign serdes_dtm2 = pll_r[`SERDES_DTM2];
333assign align_shift = pll_r[`ALIGN_SHIFT];
334assign change = pll_r[`CHANGE];
335assign pll_char_in = pll_r[`PLL_CHAR_IN];
336assign st_delay_dr = pll_r[`ST_DELAY_DR]; // late addition
337assign pll_clamp_fltr = pll_r[`PLL_CLAMP_FLTR]; // late addition
338
339assign rng_ctl1 = rngctl_r[`RNG_CTL1];
340assign rng_ctl2 = rngctl_r[`RNG_CTL2];
341assign rng_ctl3 = rngctl_r[`RNG_CTL3];
342assign rng_ctl4 = rngctl_r[`RNG_CTL4];
343assign rng_anlg_sel = rngctl_r[`RNG_ANLG_SEL];
344assign rng_vcoctrl_sel = rngctl_r[`RNG_VCOCTRL_SEL];
345assign rng_bypass = rngctl_r[`RNG_BYPASS];
346assign rng_wait_cnt = rngctl_r[`RNG_WAIT_CNT];
347
348// address decodes & read/write enables
349
350assign pll_match = (addr_in == `PLL_REG);
351assign rngctl_match = (addr_in == `RNGCTL_REG);
352assign rngdat_match = (addr_in == `RNGDAT_REG);
353
354assign pll_wr_en = wr_req_vld & pll_match;
355assign rngctl_wr_en = wr_req_vld & rngctl_match;
356// assign rngdat_wr_en = wr_req_vld & rngdat_match;
357
358assign pll_rd_en = rd_req_vld & pll_match;
359assign rngctl_rd_en = rd_req_vld & rngctl_match;
360assign rngdat_rd_en = rd_req_vld & rngdat_match;
361
362
363// write success -- has no effect on acknowledge
364assign wr_ok = (pll_wr_en | rngctl_wr_en | wr_req_vld);
365
366// read success
367assign rd_ok = (pll_rd_en | rngctl_rd_en | rngdat_rd_en );
368
369// read no success
370assign rd_nok = rd_req_vld & ~(pll_match | rngctl_match | rngdat_match);
371
372
373// ***********************************************************
374// CSR Write implementation:
375// ***********************************************************
376// reg updates
377
378wire rst_gated_n;
379assign rst_gated_n = rst_n | wmr_protect;
380
381
382// WARM RESET PROTECTED FLOPS
383/* commented out to replace with instantiated flops
384
385always @(posedge l1clk or negedge rst_gated_n) begin
386 if (!rst_gated_n) begin
387 // pll default values
388 `PLL_DIV1 <= 6'h01; // /2 of sysclk 00_0001
389 `PLL_DIV2 <= 6'h07; // x8 of sysclk/2 00_0111
390 `PLL_DIV3 <= 6'h00; // no post-division 00_0000
391 `PLL_DIV4 <= 7'h04; // divide by 2 00_0010_0
392 `ST_PHASE_HI <= 1'b0; 0
393 `ST_DELAY_A <= 2'b0; 00
394 `SERDES_DTM1 <= 1'b0; 0
395 `SERDES_DTM2 <= 1'b0; 0
396 `ALIGN_SHIFT <= 2'b0; 00
397 `CHANGE <= 1'b1; 1
398 `PLL_CHAR_IN <= 1'b0; 0
399 `PLL_RES <= 30'b0; 00_0000_0000_0000_0000
400 end else begin
401 pll_r <= (!wmr_protect && pll_wr_en)?data_in:pll_r;
402 end
403end
404*/
405
406wire rst_gated;
407assign rst_gated = ~rst_gated_n;
408
409wire [63:0] pll_r_tmp;
410wire [63:0] pll_r_in;
411wire [63:0] pll_r_pre_in;
412
413wire [5:0] mask_div1;
414wire [5:0] mask_div2;
415wire [5:0] mask_div3;
416wire [6:0] mask_div4;
417
418// mask bits help to set to 1 during reset where needed
419// (aka use default values)
420assign mask_div1 = 6'b00_0001;
421assign mask_div2 = 6'b00_0111;
422assign mask_div3 = 6'b00_0001;
423assign mask_div4 = 7'b00_0100_0;
424
425assign pll_r_pre_in = (!wmr_protect && pll_wr_en)?data_in:pll_r;
426
427// invert inputs where needed
428assign pll_r_in = pll_r_pre_in ^ {31'b0, 1'b1, 7'b0, mask_div4, mask_div3, mask_div2, mask_div1};
429
430ccu_msff_arst_4x_64 pll_r_bank64 (
431 .q (pll_r_tmp), .reset_n (rst_gated_n), .d (pll_r_in), .l1clk (l1clk),
432 .si (1'b0), .siclk (1'b0), .soclk (1'b0), .so ()
433);
434
435assign pll_r[`PLL_DIV1 ] = pll_r_tmp[`PLL_DIV1 ] ^ mask_div1;
436assign pll_r[`PLL_DIV2 ] = pll_r_tmp[`PLL_DIV2 ] ^ mask_div2;
437assign pll_r[`PLL_DIV3 ] = pll_r_tmp[`PLL_DIV3 ] ^ mask_div3;
438assign pll_r[`PLL_DIV4 ] = pll_r_tmp[`PLL_DIV4 ] ^ mask_div4;
439assign pll_r[`ST_PHASE_HI ] = pll_r_tmp[`ST_PHASE_HI ];
440assign pll_r[`ST_DELAY_CMP] = pll_r_tmp[`ST_DELAY_CMP]; // from `st_delay_a
441assign pll_r[`SERDES_DTM1 ] = pll_r_tmp[`SERDES_DTM1 ];
442assign pll_r[`SERDES_DTM2 ] = pll_r_tmp[`SERDES_DTM2 ];
443assign pll_r[`ALIGN_SHIFT ] = pll_r_tmp[`ALIGN_SHIFT ];
444assign pll_r[`CHANGE ] = ~pll_r_tmp[`CHANGE ]; // bit is 1 by default
445assign pll_r[`PLL_CHAR_IN ] = pll_r_tmp[`PLL_CHAR_IN ];
446assign pll_r[`ST_DELAY_DR ] = pll_r_tmp[`ST_DELAY_DR ]; // late addition
447assign pll_r[`PLL_CLAMP_FLTR] = pll_r_tmp[`PLL_CLAMP_FLTR]; // late addition
448assign pll_r[`PLL_RES ] = pll_r_tmp[`PLL_RES ];
449
450
451// NOT WARM RESET PROTECTED
452/* commented out to replace with instantiated flops
453
454always @(posedge l1clk or negedge rst_n) begin
455 if (!rst_n) begin
456 // rng default values
457 `RNG_RES <= 55'b0;
458 `RNG_BYPASS <= 1'b0;
459 `RNG_VCOCTRL_SEL <= 2'b0;
460 `RNG_ANLG_SEL <= 2'b0;
461 `RNG_CTL4 <= 1'b0;
462 `RNG_CTL3 <= 1'b1;
463 `RNG_CTL2 <= 1'b1;
464 `RNG_CTL1 <= 1'b1;
465 end else begin
466 rngctl_r <= (rngctl_wr_en)?data_in:rngctl_r;
467 end
468end
469*/
470
471wire [63:0] rngctl_r_in;
472wire [63:0] rngctl_r_tmp;
473wire [63:0] rngctl_r_pre_in;
474
475wire rst;
476assign rst = ~rst_n;
477
478assign rngctl_r_pre_in = (rngctl_wr_en)?data_in:rngctl_r;
479assign rngctl_r_in = rngctl_r_pre_in ^
480 {39'b0,`DEFAULT_RNG_WAIT_VAL,9'b0_0000_1111}; // invert mask bits
481
482ccu_msff_arst_4x_64 rngctl_r_bank64 (
483 .q (rngctl_r_tmp), .reset_n (rst_n), .d (rngctl_r_in), .l1clk (l1clk),
484 .si (1'b0), .siclk (1'b0), .soclk (1'b0), .so ()
485);
486
487// inversion needed when asynchronously resetting to 1 is desired
488assign rngctl_r[`RNG_RES] = rngctl_r_tmp[`RNG_RES];
489assign rngctl_r[`RNG_WAIT_CNT] = rngctl_r_tmp[`RNG_WAIT_CNT] ^ `DEFAULT_RNG_WAIT_VAL;
490assign rngctl_r[`RNG_BYPASS] = rngctl_r_tmp[`RNG_BYPASS];
491assign rngctl_r[`RNG_VCOCTRL_SEL] = rngctl_r_tmp[`RNG_VCOCTRL_SEL];
492assign rngctl_r[`RNG_ANLG_SEL] = rngctl_r_tmp[`RNG_ANLG_SEL];
493assign rngctl_r[`RNG_CTL4] = ~rngctl_r_tmp[`RNG_CTL4];
494assign rngctl_r[`RNG_CTL3] = ~rngctl_r_tmp[`RNG_CTL3];
495assign rngctl_r[`RNG_CTL2] = ~rngctl_r_tmp[`RNG_CTL2];
496assign rngctl_r[`RNG_CTL1] = ~rngctl_r_tmp[`RNG_CTL1];
497
498
499// ***********************************************************
500// CSR read implementation:
501// ***********************************************************
502// reg reads
503always @(posedge l1clk) begin
504 if (pll_rd_en) data_out <= pll_r;
505 else if (rngctl_rd_en) data_out <= rngctl_r;
506 else if (rngdat_rd_en && rng_wait_done) data_out <= rngdat_r;
507 else data_out <= data_out;
508end
509
510// thread and dev id reads
511
512
513assign thr_id_out[5:0] = thr_id_in[5:0];
514assign buf_id_out[1:0] = buf_id_in[1:0];
515
516
517// ***********************************************************
518// CSR read/write acknowledgement:
519// ***********************************************************
520// finally settled for a simpler moore machine design
521//
522// state outputs
523always @(state) begin
524 case (state)
525 `CCUCSR_IDLE: begin
526 req_accepted = 1'b0;
527 rd_ack_vld = 1'b0;
528 rd_nack_vld = 1'b0;
529 end
530 `CCUCSR_WRITE: begin
531 req_accepted = 1'b1;
532 rd_ack_vld = 1'b0;
533 rd_nack_vld = 1'b0;
534 end
535 `CCUCSR_READ: begin
536 req_accepted = 1'b0;
537 rd_ack_vld = 1'b0;
538 rd_nack_vld = 1'b0;
539 end
540 `CCUCSR_READ_PROB: begin
541 req_accepted = 1'b1;
542 rd_ack_vld = 1'b0;
543 rd_nack_vld = 1'b1;
544 end
545 `CCUCSR_READ_SUCCESS: begin
546 req_accepted = 1'b1;
547 rd_ack_vld = 1'b1;
548 rd_nack_vld = 1'b0;
549 end
550 default: begin
551 req_accepted = 1'b0;
552 rd_ack_vld = 1'b0;
553 rd_nack_vld = 1'b0;
554 end
555 endcase
556end
557
558
559reg [2:0] state_in;
560always @(wr_ok or rd_req_vld or rack_busy or rng_busy or rd_ok or rd_nok or state) begin
561 case (state)
562
563 `CCUCSR_IDLE: begin
564 if (wr_ok)
565 state_in = `CCUCSR_WRITE;
566 else if (rd_req_vld)
567 state_in = `CCUCSR_READ;
568 else
569 state_in = `CCUCSR_IDLE;
570 end
571
572 `CCUCSR_WRITE: state_in = `CCUCSR_IDLE; // always return to idle
573
574 `CCUCSR_READ: begin
575 if (rack_busy || rng_busy) // handles special rng read
576 state_in = `CCUCSR_READ;
577 else if (rd_ok)
578 state_in = `CCUCSR_READ_SUCCESS;
579 else if (rd_nok)
580 state_in = `CCUCSR_READ_PROB;
581 else
582 state_in = `CCUCSR_READ;
583 end
584
585 `CCUCSR_READ_PROB: state_in = `CCUCSR_IDLE; // always return to idle
586
587 `CCUCSR_READ_SUCCESS: state_in = `CCUCSR_IDLE; // always return to idle
588
589 default: state_in = `CCUCSR_IDLE;
590 endcase
591end
592
593
594ccu_msff_arst_4x_3 state_bank3 (
595 .q(state),
596 .so(),
597 .d(state_in),
598 .l1clk(l1clk),
599 .si(1'b0),
600 .siclk(1'b0),
601 .soclk(1'b0),
602 .reset_n (rst_n)
603);
604
605
606// ***********************************************************
607// rng read mode for diagnostics
608// ***********************************************************
609//
610
611assign rng_cnt_reached = (rng_cnt == max_cnt);
612// assign rng_busy = rngdat_rd_en & rng_ctl4 & ~rng_cnt_reached;
613assign rng_busy = rngdat_rd_en & ~rng_wait_done;
614assign max_cnt = (rng_ctl4) ? rng_wait_cnt : 16'd62; // + 2 cycles for states
615
616// convert rng_cnt_reached to a pulse
617assign rng_wait_done = ~rng_cnt_reached_q1 & rng_cnt_reached;
618
619always @(posedge l1clk) begin
620 if (!rst_n)
621 rng_cnt_reached_q1 <= 1'b0;
622 else
623 rng_cnt_reached_q1 <= rng_cnt_reached;
624end
625
626
627// count up to max_cnt and hold till "idle"
628always @(posedge l1clk) begin
629 if (!rst_n)
630 rng_cnt <= 16'h0000;
631 else begin
632 if (state == `CCUCSR_IDLE)
633 rng_cnt <= 16'h0000;
634 else begin
635 if (rng_cnt == max_cnt)
636 rng_cnt <= max_cnt;
637 else
638 rng_cnt <= rng_cnt + 16'h0001;
639 end
640 end
641end
642
643// ***********************************************
644// synchronizer flop (for rngdata)
645// ***********************************************
646
647assign rng_data_in_gated = (rng_ctl1 | rng_ctl2 | rng_ctl3) & rng_data_in;
648
649cl_a1_clksyncff_4x rng_data_syncff (
650 .l1clk (l1clk), .d (rng_data_in_gated), .q(rng_data_synced),
651 .si(1'b0), .siclk(1'b0), .soclk (1'b0), .so()
652);
653
654// ***********************************************************
655// LFSR implementation & update register
656// ***********************************************************
657
658// load serial shift reg/LFSR
659assign poly = `RNGCRC_POLY ; // [a63..a0] for a63.x^63 + ... a0.x^0, a64=1
660// added xor for quicker entropy building; (ctl4==0) -> shift reg, period.
661assign lfsr_fdbk = rng_ctl4 & (lfsr_data[63] ^ rng_data_synced);
662assign msb_sel = {64{lfsr_fdbk}} & `RNGCRC_POLY;
663
664// flush with one's when a read is successful & (ctl4==1)
665// need to break next statement into 2 pieces to fix shift-reg bug
666// assign lfsr_in[63:0] = ((state == `CCUCSR_READ_SUCCESS) && rng_ctl4) ?
667// 64'hFFFF_FFFF_FFFF_FFFF : {lfsr_data[62:0],1'b0} ^ msb_sel[63:0];
668assign lfsr_in[63:1] = ((state == `CCUCSR_READ_SUCCESS) && rng_ctl4) ?
669 63'h7FFF_FFFF_FFFF_FFFF : lfsr_data[62:0] ^ msb_sel[63:1];
670assign lfsr_in[0] = (rng_ctl4 == 1'b0) ? rng_data_synced :
671 ((state == `CCUCSR_READ_SUCCESS) && rng_ctl4) ? 1'b1 : msb_sel[0];
672
673// convert to sync reset for convenience
674always @(posedge l1clk) begin
675 if (!rst_n) begin
676 lfsr_data <= 64'hFFFF_FFFF_FFFF_FFFF;
677 end else begin
678 lfsr_data <= lfsr_in;
679 end
680end
681
682// update rngdat_r register when done waiting
683assign lfsr_data_muxed = (rng_wait_done) ? lfsr_data: rngdat_r;
684
685// always @(posedge l1clk) rngdat_r <= lfsr_data_muxed;
686// do not flop in this stage
687assign rngdat_r = lfsr_data_muxed;
688
689// ***********************************************************
690// L1 header - io clk
691// ***********************************************************
692//
693cl_a1_l1hdr_8x header_io (
694 .l2clk(io_clk),
695 .l1clk(l1clk),
696 .pce(1'b1),
697 .se(1'b0),
698 .pce_ov(1'b0),
699 .stop(1'b0)
700);
701
702
703
704endmodule
705
706