rac_near_model.v
27.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
// $Id: rac_near_model.v,v 1.1 2002/03/28 00:26:11 berndt Exp $
// Copyright 1994, Rambus Inc., All Rights Reserved
// CONFIDENTIAL INFORMATION - RAMBUS INC. PROPRIETARY
//
// Data contained herein is proprietary information of Rambus Inc.
// which shall be treated confidentially and shall not be furnished to
// third parties or made public without prior written permission by
// Rambus Inc. Rambus Inc. does not convey any license under its
// patent, copyright or maskwork rights or any rights of others.
//
// Data contained herein is preliminary. Rambus Inc. makes no warranties,
// expressed or implied, of functionality or suitability for any purpose.
// Rambus Inc. assumes no obligation to correct any errors contained
// herein or to advise any user of this text of any correction if such be
// made.
// NOTICE: THIS IS A "NEAR" MODEL OF A RAMBUS ASIC CELL (RAC). IT SHOULD
// NOT BE USED FOR TAPEOUT. USERS OF THIS MODEL SHOULD TAKE
// SPECIAL CARE TO UNDERSTAND WHAT IT DOES, AND WHAT VALUE IT
// MAY HAVE FOR ANY DESIGN ACTIVITY. IT IS DEFINITELY NOT AN
// ACCURATE MODEL.
// NOTE: When using this model with VCS, there is a workaround in place
// that is necessary to bypass a verilog construct not currently
// supported by Chronologic. The method for bypassing this problem
// is to appropriately define the TicksPerNS parameter and to
// specify "+define+RAC_VCS_bug_fix" on the command-line.
`define RAC_VCS_bug_fix
// NOTE: This model differs from the spec version B.1 in respect to
// StopT/StopR. This behavior is summarized below.
// StopT asserted w/o StopR- stops transmit Oshifters(except BC)
// StopR asserted w/o StopT- stops received Ishifters(except BC)
// StopR&StopT asserted - stops O/Ishifters (except BC) and all
// select shifters
// This behavior is indicated throughout the model with
// "REV B.1 Behavior".
// known deficiencies and/or plans for improvement
// . setup/hold violations on inputs
// . no modelling for BISTMode, SCAN, Clock ByPass
// . no checks for "static" SCANClk during reduced power modes. SCANClk
// only checked for non-X condition.
// . error checking stops the clocks when inputs are not set to appropriate
// values necessary for normal operation. This is not normal behavior.
// . gate-level RAC model drives X on SynClk when dll is not locked. This
// model does not clock SynClk.
// . model does not correctly handle X assertions on all inputs.
// . VCS does not support "repeat(n)" syntax for assignments. This is
// currently handled with #delays, non-blocking assignments, and some
// notion of time.
// Parameter Usage
// RAC_NUM:
// This parameter defines this "instances" designation number
// for input violation messages. Useful for multiple RAC systems.
// no_RAC_quickstart:
// Setting this to "1" forces the dll and current control to be
// uninitialized, setting this to "0" (or anything but "1") puts
// the model into an immediate state of readiness.
// do_error_check:
// Indicates whether error checking is to be performed on
// non-modelled inputs. Checking is performed such that these
// inputs should be in a state required for normal operation.
// If "do_error_check" is set to any non-zero value, then
// error-checking is enabled. Set "do_error_check" to "0" to
// disable error-checking.
// TData_center_delay:
// This parameter defines the delay in simulator ticks from the
// edge of BusClk for which to center the transmit data.
// If there are 10ps ticks and a clock of 250MHz is used, then
// setting "TData_center_delay" to "100" will center the transmit
// data between the edges of the clocks.
// current_control_calibration_delay:
// When CCtlEn is set to "1" to put the RAC into auto current
// control calibration mode, this parameter defines the number
// of BusClk edges until calibration is achieved. A tremendous
// quantity of annoying messages are printed out until this time
// has elapsed. This parameter may be redefined to any useful
// value for modelling purposes (like 256) as long as the users
// of the model understand that the RAC current control will not
// be fully calibrated.
// dll_turn_on_delay:
// This parameter defines the dll lock time. Currently defined
// as 20 BusClk periods, which is a little too fast. This may
// be changed, but there is little value in doing so.
// TicksPerNS:
// This parameter defines the number of simulator ticks per elapsed
// ns. This is necessary only to support correctly a problem
// encountered by a construct not currently supported by Chronologic.
// bc:
// This parameter defines a BusClk half-period. Most timing
// parameters in the RAC specification are specified using this
// base unit.
`timescale 1ns / 1ns
module rac_near_model (
RData7, RData6, RData5, RData4, RData3, RData2, RData1, RData0,
SynClk, SynClkFd,
BusEnable, BISTFlag, SCANOut,
BusCtrl, BusData,
BusClk, BDSel, BCSel, BESel, RDSel, RCSel,
Reset,
TData7, TData6, TData5, TData4, TData3, TData2, TData1, TData0,
Vref,
BISTMode, IOSTMode, SCANMode, SCANClk, SCANEn, SCANIn, SynClkIn,
CCtlEn, CCtlLd, CCtlI, CCtlPgm, PwrUp, ExtBE, StopR, StopT,
ByPass, ByPSel, rclkASIC, tclkASIC, PhStall);
// parameters in order of most likely to be adjusted
parameter RAC_NUM = 0;
parameter no_RAC_quickstart = 1;
parameter do_error_check = 1;
parameter current_control_calibration_delay = 32768; // t47
parameter dll_turn_on_delay = 20;
// These parameters are defined to bypass problems under VCS. These
// add time dependence back into the model, undesirable. Will be
// removed once Chronologic supports necessary verilog constructs.
parameter TicksPerNS = 1;
parameter bc = 2*TicksPerNS;
parameter bcp = 2*bc;
parameter TData_center_delay = 0.5*bc;
// IMPORTANT: DO NOT CHANGE THESE PARAMETERS BELOW
parameter CCtll_delay = 256; // t46
parameter start_clock_latency_max = 4; // t83
parameter stop_clock_latency_max = 0; // t82
parameter current_control_update_delay = 8; // t45
parameter ExtBE_to_BusEn_delay = 8; // t85
output [9:0] RData7, RData6, RData5, RData4, RData3, RData2, RData1, RData0;
output SynClk, SynClkFd;
output BusEnable;
output BISTFlag, SCANOut;
inout BusCtrl;
inout [8:0] BusData;
input BusClk;
input [3:0] BDSel, BCSel, BESel, RDSel, RCSel;
input Reset;
input [10:0] TData7, TData6, TData5, TData4, TData3, TData2, TData1, TData0;
input Vref;
input BISTMode, IOSTMode, SCANMode, SCANClk, SCANEn, SCANIn,SynClkIn;
input CCtlEn, CCtlLd;
input [5:0] CCtlI;
input CCtlPgm, PwrUp, ExtBE, StopR, StopT;
input ByPass, ByPSel, rclkASIC, tclkASIC, PhStall;
// Test Modes ( This is a temporary placeholder to get rid of "no fanin" warn )
wire BISTFlag;
assign BISTFlag = 1'b0;
wire SCANOut;
assign SCANOut = 1'b0;
// This code performs basic error checking and causes the rac to fail
// disastrously upon detection. It's just a reminder that it is only
// a very simple model. This can be turned off by redefining the parameter
// "do_error_check" to 0; If "do_error_check" is set to 0, then the clocks
// will not be stopped upon detection of errors nor will errors be warned.
// Input Checking
input_checker #(RAC_NUM, do_error_check)
ic(
// outputs
rac_error,
// inputs
IOSTMode, BISTMode, SCANMode, SCANEn, ByPass, PhStall,
Vref, SCANClk, SCANIn, ByPSel, rclkASIC, tclkASIC,
dll_enabled, Reset, PwrUp);
// Clock Generation
clk_gen #(dll_turn_on_delay, start_clock_latency_max,
stop_clock_latency_max, no_RAC_quickstart,
TicksPerNS, bc, bcp)
cg(
// outputs
SynClk, SynClkFd, StopT_active, StopR_active, ClkPhase0, ClkPhase1,
dll_enabled,
// inputs
BusClk, SynClkIn, StopT, StopR, PwrUp, rac_error);
// Current Control
cctl
#(current_control_update_delay, CCtll_delay, current_control_calibration_delay,
TicksPerNS, bc)
cctl ( CCtl_OK, CCtlI, CCtlLd, CCtlEn, CCtlPgm, BusClk, SynClk);
sample_gen sg(
// outputs
BESel_Load, BCSel_Load, BDSel_Load, RCSel_Load, RDSel_Load,
// inputs
BESel, BCSel, BDSel, RCSel, RDSel, BusClk, SynClk, ClkPhase1,
ClkPhase0, StopR_active, StopT_active, Reset);
// This code generates the BusEnable output.
// BusEnable is made from a combination of the shift circuitry and
// a combinatorial logic produced from Reset and ExtBE. This shifter is
// slightly different than the others for this reason.
reg ext_be_tpd_r;
`ifdef RAC_VCS_bug_fix
always @(ExtBE) @(BusClk) ext_be_tpd_r <= #(ExtBE_to_BusEn_delay*bc) ExtBE;
`else
always @(ExtBE) ext_be_tpd_r <= repeat(ExtBE_to_BusEn_delay) @(BusClk) ExtBE;
`endif
wire ext_be_tpd;
assign ext_be_tpd = ext_be_tpd_r;
wire BusEn;
assign BusEnable = (Reset & ext_be_tpd) ? (CCtl_OK ? 1'b0 : 1'bx) : BusEn;
// bit routing for internally bus structure
wire [7:0] BE_Bus;
assign BE_Bus = { TData7[10], TData6[10], TData5[10], TData4[10],
TData3[10], TData2[10], TData1[10], TData0[10] };
wire [7:0] BC_Bus;
assign BC_Bus = { TData7[9], TData6[9], TData5[9], TData4[9],
TData3[9], TData2[9], TData1[9], TData0[9] };
wire [7:0] BD_Bus8;
assign BD_Bus8 = { TData7[8], TData6[8], TData5[8], TData4[8],
TData3[8], TData2[8], TData1[8], TData0[8] };
wire [7:0] BD_Bus7;
assign BD_Bus7 = { TData7[7], TData6[7], TData5[7], TData4[7],
TData3[7], TData2[7], TData1[7], TData0[7] };
wire [7:0] BD_Bus6;
assign BD_Bus6 = { TData7[6], TData6[6], TData5[6], TData4[6],
TData3[6], TData2[6], TData1[6], TData0[6] };
wire [7:0] BD_Bus5;
assign BD_Bus5 = { TData7[5], TData6[5], TData5[5], TData4[5],
TData3[5], TData2[5], TData1[5], TData0[5] };
wire [7:0] BD_Bus4;
assign BD_Bus4 = { TData7[4], TData6[4], TData5[4], TData4[4],
TData3[4], TData2[4], TData1[4], TData0[4] };
wire [7:0] BD_Bus3;
assign BD_Bus3 = { TData7[3], TData6[3], TData5[3], TData4[3],
TData3[3], TData2[3], TData1[3], TData0[3] };
wire [7:0] BD_Bus2;
assign BD_Bus2 = { TData7[2], TData6[2], TData5[2], TData4[2],
TData3[2], TData2[2], TData1[2], TData0[2] };
wire [7:0] BD_Bus1;
assign BD_Bus1 = { TData7[1], TData6[1], TData5[1], TData4[1],
TData3[1], TData2[1], TData1[1], TData0[1] };
wire [7:0] BD_Bus0;
assign BD_Bus0 = { TData7[0], TData6[0], TData5[0], TData4[0],
TData3[0], TData2[0], TData1[0], TData0[0] };
wire [7:0] RD_Bus9;
assign { RData7[9], RData6[9], RData5[9], RData4[9],
RData3[9], RData2[9], RData1[9], RData0[9] } = RD_Bus9;
wire [7:0] RD_Bus0;
assign { RData7[0], RData6[0], RData5[0], RData4[0],
RData3[0], RData2[0], RData1[0], RData0[0] } = RD_Bus0;
wire [7:0] RD_Bus1;
assign { RData7[1], RData6[1], RData5[1], RData4[1],
RData3[1], RData2[1], RData1[1], RData0[1] } = RD_Bus1;
wire [7:0] RD_Bus2;
assign { RData7[2], RData6[2], RData5[2], RData4[2],
RData3[2], RData2[2], RData1[2], RData0[2] } = RD_Bus2;
wire [7:0] RD_Bus3;
assign { RData7[3], RData6[3], RData5[3], RData4[3],
RData3[3], RData2[3], RData1[3], RData0[3] } = RD_Bus3;
wire [7:0] RD_Bus4;
assign { RData7[4], RData6[4], RData5[4], RData4[4],
RData3[4], RData2[4], RData1[4], RData0[4] } = RD_Bus4;
wire [7:0] RD_Bus5;
assign { RData7[5], RData6[5], RData5[5], RData4[5],
RData3[5], RData2[5], RData1[5], RData0[5] } = RD_Bus5;
wire [7:0] RD_Bus6;
assign { RData7[6], RData6[6], RData5[6], RData4[6],
RData3[6], RData2[6], RData1[6], RData0[6] } = RD_Bus6;
wire [7:0] RD_Bus7;
assign { RData7[7], RData6[7], RData5[7], RData4[7],
RData3[7], RData2[7], RData1[7], RData0[7] } = RD_Bus7;
wire [7:0] RD_Bus8;
assign { RData7[8], RData6[8], RData5[8], RData4[8],
RData3[8], RData2[8], RData1[8], RData0[8] } = RD_Bus8;
// pin drivers
pin_driver #(TData_center_delay) BE_shifter
(BusEn, BE_Bus, BusClk, BESel_Load, CCtl_OK, StopT_active);
pin_driver #(TData_center_delay) BC_shifter
// REV B.1 Behavior
//(BusCtrl, BC_Bus, BusClk, BCSel_Load, CCtl_OK, StopT_active);
(BusCtrl, BC_Bus, BusClk, BCSel_Load, CCtl_OK, 1'b0); // Oshifter always runs
pin_driver #(TData_center_delay) BD_shifter8
(BusData[8], BD_Bus8, BusClk, BDSel_Load, CCtl_OK, StopT_active);
pin_driver #(TData_center_delay) BD_shifter7
(BusData[7], BD_Bus7, BusClk, BDSel_Load, CCtl_OK, StopT_active);
pin_driver #(TData_center_delay) BD_shifter6
(BusData[6], BD_Bus6, BusClk, BDSel_Load, CCtl_OK, StopT_active);
pin_driver #(TData_center_delay) BD_shifter5
(BusData[5], BD_Bus5, BusClk, BDSel_Load, CCtl_OK, StopT_active);
pin_driver #(TData_center_delay) BD_shifter4
(BusData[4], BD_Bus4, BusClk, BDSel_Load, CCtl_OK, StopT_active);
pin_driver #(TData_center_delay) BD_shifter3
(BusData[3], BD_Bus3, BusClk, BDSel_Load, CCtl_OK, StopT_active);
pin_driver #(TData_center_delay) BD_shifter2
(BusData[2], BD_Bus2, BusClk, BDSel_Load, CCtl_OK, StopT_active);
pin_driver #(TData_center_delay) BD_shifter1
(BusData[1], BD_Bus1, BusClk, BDSel_Load, CCtl_OK, StopT_active);
pin_driver #(TData_center_delay) BD_shifter0
(BusData[0], BD_Bus0, BusClk, BDSel_Load, CCtl_OK, StopT_active);
// pin receivers
pin_receiver RD_shifter9
// REV B.1 Behavior
// (RD_Bus9, BusCtrl, BusClk, RCSel_Load, StopR_active);
(RD_Bus9, BusCtrl, BusClk, RCSel_Load, 1'b0); // Ishifter always runs
pin_receiver RD_shifter8
(RD_Bus8, BusData[8], BusClk, RDSel_Load, StopR_active);
pin_receiver RD_shifter7
(RD_Bus7, BusData[7], BusClk, RDSel_Load, StopR_active);
pin_receiver RD_shifter6
(RD_Bus6, BusData[6], BusClk, RDSel_Load, StopR_active);
pin_receiver RD_shifter5
(RD_Bus5, BusData[5], BusClk, RDSel_Load, StopR_active);
pin_receiver RD_shifter4
(RD_Bus4, BusData[4], BusClk, RDSel_Load, StopR_active);
pin_receiver RD_shifter3
(RD_Bus3, BusData[3], BusClk, RDSel_Load, StopR_active);
pin_receiver RD_shifter2
(RD_Bus2, BusData[2], BusClk, RDSel_Load, StopR_active);
pin_receiver RD_shifter1
(RD_Bus1, BusData[1], BusClk, RDSel_Load, StopR_active);
pin_receiver RD_shifter0
(RD_Bus0, BusData[0], BusClk, RDSel_Load, StopR_active);
endmodule
module input_checker(
rac_error,
IOSTMode, BISTMode, SCANMode, SCANEn, ByPass, PhStall,
Vref, SCANClk, SCANIn, ByPSel, rclkASIC, tclkASIC,
dll_enabled, Reset, PwrUp);
output rac_error;
input IOSTMode;
input BISTMode;
input SCANMode;
input SCANEn;
input ByPass;
input PhStall;
input Vref;
input SCANClk;
input SCANIn;
input ByPSel;
input rclkASIC;
input tclkASIC;
input dll_enabled;
input Reset;
input PwrUp;
parameter RAC_NUM = 99;
parameter do_error_check = 1;
reg rac_error;
initial rac_error = 0;
always @(IOSTMode or BISTMode or SCANMode or SCANEn or ByPass or PhStall or
Vref or SCANClk or SCANIn or ByPSel or rclkASIC or tclkASIC or dll_enabled
or Reset or PwrUp) begin
if ((Reset===1) || (PwrUp === 0))
rac_error = 0;
else if (((IOSTMode!==0) || (BISTMode!==0) || (SCANMode!==0) ||
(SCANEn!==0)|| /*(ByPass!==0) ||*/ (PhStall!==0) ||(Vref!==1) ||
(SCANClk===1'bx) || (SCANIn===1'bx) || (ByPSel===1'bx) ||
(rclkASIC===1'bx) || (tclkASIC===1'bx)) &&
dll_enabled && (do_error_check!==0))
begin
$display("rac:ERROR:Unsupported mode attempted or incorrect input value for normal operation with RAC#%d at time %d", RAC_NUM, $stime);
rac_error = 1;
end
end
endmodule
module clk_gen(
// outputs
SynClk, SynClkFd, StopT_active, StopR_active, ClkPhase0, ClkPhase1,
dll_enabled,
// inputs
BusClk, SynClkIn, StopT, StopR, PwrUp, rac_error);
// number of busticks until dll stable, not to spec.
parameter dll_turn_on_delay = 20;
parameter start_clock_latency_max = 4; // t83
parameter stop_clock_latency_max = 4; // t82
parameter no_RAC_quickstart = 1;
parameter TicksPerNS = 1;
parameter bc = 2*TicksPerNS;
parameter bcp = 2*bc;
output SynClk;
output SynClkFd;
output StopT_active;
output StopR_active;
output ClkPhase0;
output ClkPhase1;
output dll_enabled;
input BusClk;
input SynClkIn;
input StopT;
input StopR;
input PwrUp;
input rac_error;
reg SynClk;
reg [2:0] SynClkIn_sample;
reg dll_enabled;
reg StopT_active;
reg StopR_active;
// SynClkFd is modelled as identical to SynClk for functional modelling
wire SynClkFd;
assign SynClkFd = SynClk;
// These define two of the four phases of SynClk for use by the receivers
// and samplers.
wire ClkPhase0;
assign ClkPhase0 = ~SynClk & SynClkIn_sample[1];
wire ClkPhase1;
assign ClkPhase1 = ~SynClk & ~SynClkIn_sample[1];
// quickstart for RAC model
initial
begin
dll_enabled = 0; // assume quickstart off or badly done
if (no_RAC_quickstart != 1) // trying to quickstart
// hold off til PwrUp init;
// abandon if init BusClk w/o PwrUp
wait ((PwrUp !== 'bx) || (BusClk !== 'bx))
if (PwrUp == 1) // quickstart if PwrUp was set
begin
dll_enabled = 1;
SynClk = 0;
SynClkIn_sample = 0;
end
else
$display("rac:WARNING:quickstart enabled, but failed due to PwrUp not asserted");
end
// This procedural block generates SynClk derived from SynClkIn. For
// quickstart simulation purposes, the dll is enabled immediately at
// powerup and the internal registers that generate SynClk are reset.
// This is done to prevent having to multiplex a known value on SynClkIn
// or apply a force to clear out the registers.
always @(BusClk)
begin
if (BusClk===0)
SynClkIn_sample[0] = SynClkIn;
else
begin
SynClkIn_sample[2:1] = SynClkIn_sample[1:0];
if ((dll_enabled==1) &(rac_error==0))
SynClk = ~SynClkIn_sample[2];
end
end
// This procedural section initializes and maintains the dll. When
// using the quickstart values, the dll is immediately initialized and
// the synclk clock registers are valid. If not quickstart, then the
// normal procedure for initializing the RAC must be performed.
always @(PwrUp)
if (PwrUp!==1)
begin
disable dll_turn_on;
dll_enabled = 0;
end
else
begin:dll_turn_on
`ifdef RAC_VCS_bug_fix
@(posedge BusClk) dll_enabled <= #(dll_turn_on_delay*bcp) 1;
`else
dll_enabled <= repeat(dll_turn_on_delay) @(posedge BusClk) 1;
`endif
end
// This procedural block handles StopT and StopR enable generation
// for the rest of the logic to use.
always @(posedge SynClk)
begin
// StopT_active
if (StopT===0)
`ifdef RAC_VCS_bug_fix
StopT_active <= #(start_clock_latency_max*bc) 0;
`else
StopT_active <= repeat (start_clock_latency_max) @(BusClk) 0;
`endif
else
`ifdef RAC_VCS_bug_fix
StopT_active <= #(stop_clock_latency_max*bc) 1;
`else
StopT_active <= repeat (stop_clock_latency_max) @(BusClk) 1;
`endif
// StopR_active
if (StopR===0)
`ifdef RAC_VCS_bug_fix
StopR_active <= #(start_clock_latency_max*bc) 0;
`else
StopR_active <= repeat (start_clock_latency_max) @(BusClk) 0;
`endif
else
`ifdef RAC_VCS_bug_fix
StopR_active <= #(stop_clock_latency_max*bc) 1;
`else
StopR_active <= repeat (stop_clock_latency_max) @(BusClk) 1;
`endif
end
endmodule
module cctl(CCtl_OK, CCtlI, CCtlLd, CCtlEn, CCtlPgm, BusClk, SynClk);
output CCtl_OK;
input [5:0] CCtlI;
input CCtlLd;
input CCtlEn;
input CCtlPgm;
input BusClk;
input SynClk;
parameter current_control_update_delay = 8; // t45
parameter CCtll_delay = 256; // t46
parameter current_control_calibration_delay = 32768; // t47
parameter TicksPerNS = 1;
parameter bc = 2*TicksPerNS;
reg CCtl_OK;
reg [5:0] cctl_i;
reg [5:0] cctl_reg;
reg auto_cctl;
reg cctl_load_ok;
reg cctlld_i;
reg warn_auto_calibration_delay;
always @(negedge SynClk)
if (CCtlLd===1)
begin
// do not transmit during this time, output will be x if drive
// attempted.
cctlld_i = 1;
CCtl_OK = 0;
cctl_reg = auto_cctl ?
// derive cctl_reg from CCtlI or CCtlPgm
// gate RAC model requires 1 on CCtlPgm
(CCtlPgm ? 6'b101010 : 6'bxxxxxx)
// jam x into cctl_reg if CCtl_delay spec
// not met
: (cctl_load_ok ? cctl_i : 6'bxxxxxx) ;
if ((auto_cctl===1) & ~warn_auto_calibration_delay)
$display("rac: WARNING- Current Control Autocalibration delay MAX not met");
end
else if (cctlld_i)
begin
cctlld_i = 0;
CCtl_OK =
((cctl_reg[5]!==1'bx)&(cctl_reg[4]!==1'bx)&(cctl_reg[3]!==1'bx)&
(cctl_reg[2]!==1'bx)&(cctl_reg[1]!==1'bx)&(cctl_reg[0]!==1'bx));
end
always @(posedge SynClk)
begin
cctl_i = CCtlI;
auto_cctl = CCtlEn;
end
always @(auto_cctl)
if (auto_cctl===1)
begin:auto_mode
disable manual_mode;
cctl_load_ok = 0;
warn_auto_calibration_delay = 0;
`ifdef RAC_VCS_bug_fix
@(BusClk) warn_auto_calibration_delay <=
#(current_control_calibration_delay*bc) 1;
`else
warn_auto_calibration_delay <=
repeat(current_control_calibration_delay) @(BusClk) 1;
`endif
end
else if (auto_cctl===0)
begin:manual_mode
disable auto_mode;
warn_auto_calibration_delay = 0;
cctl_load_ok = 0;
`ifdef RAC_VCS_bug_fix
@(BusClk) cctl_load_ok <= #(CCtll_delay*bc) 1;
`else
cctl_load_ok <= repeat(CCtll_delay) @(BusClk) 1;
`endif
end
endmodule
module sample_gen(
// outputs
BESel_Load, BCSel_Load, BDSel_Load, RCSel_Load, RDSel_Load,
// inputs
BESel, BCSel, BDSel, RCSel, RDSel, BusClk, SynClk, ClkPhase1,
ClkPhase0, StopR_active, StopT_active, Reset );
output BESel_Load;
output BCSel_Load;
output BDSel_Load;
output RCSel_Load;
output RDSel_Load;
input [3:0] BESel;
input [3:0] BCSel;
input [3:0] BDSel;
input [3:0] RCSel;
input [3:0] RDSel;
input BusClk;
input SynClk;
input ClkPhase1;
input ClkPhase0;
input StopR_active;
input StopT_active;
input Reset;
reg [3:0] BESel_Hold;
reg [3:0] BESel_Shift;
reg [3:0] BCSel_Hold;
reg [3:0] BCSel_Shift;
reg [3:0] BDSel_Hold;
reg [3:0] BDSel_Shift;
reg [3:0] RCSel_Hold;
reg [3:0] RCSel_Shift;
reg [3:0] RDSel_Hold;
reg [3:0] RDSel_Shift;
// wire outputs
wire BESel_Load;
assign BESel_Load = BESel_Shift[0];
wire BCSel_Load;
assign BCSel_Load = BCSel_Shift[0];
wire BDSel_Load;
assign BDSel_Load = BDSel_Shift[0];
wire RCSel_Load;
assign RCSel_Load = RCSel_Shift[0];
wire RDSel_Load;
assign RDSel_Load = RDSel_Shift[0];
// wire intra-procedural assignments
wire [3:0] BESel_Hold_w;
assign BESel_Hold_w = BESel_Hold;
wire [3:0] BCSel_Hold_w;
assign BCSel_Hold_w = BCSel_Hold;
wire [3:0] BDSel_Hold_w;
assign BDSel_Hold_w = BDSel_Hold;
wire [3:0] RCSel_Hold_w;
assign RCSel_Hold_w = RCSel_Hold;
wire [3:0] RDSel_Hold_w;
assign RDSel_Hold_w = RDSel_Hold;
always @(negedge SynClk)
// REV B.1 Behavior
// if (~StopR_active)
if (~(StopR_active & StopT_active))
begin
BESel_Hold = BESel;
BCSel_Hold = BCSel;
BDSel_Hold = BDSel;
RCSel_Hold = RCSel;
RDSel_Hold = RDSel;
end
always @(posedge BusClk)
begin
// Transmit side action
// REV B.1 Behavior
// if (ClkPhase1 & ~StopR_active & ~Reset)
if (ClkPhase1 & ~(StopR_active & StopT_active) & ~Reset)
begin
BESel_Shift = BESel_Hold_w;
BCSel_Shift = BCSel_Hold_w;
BDSel_Shift = BDSel_Hold_w;
end
else
begin
BESel_Shift = {1'b0, BESel_Shift[3:1]};
BCSel_Shift = {1'b0, BCSel_Shift[3:1]};
BDSel_Shift = {1'b0, BDSel_Shift[3:1]};
end
// Receive side action
// REV B.1 Behavior
// if (ClkPhase0 & ~StopR_active)
if (ClkPhase0 & ~(StopR_active & StopT_active))
begin
RCSel_Shift = RCSel_Hold_w;
RDSel_Shift = RDSel_Hold_w;
end
else
begin
RCSel_Shift = {1'b0, RCSel_Shift[3:1]};
RDSel_Shift = {1'b0, RDSel_Shift[3:1]};
end
end
endmodule
module pin_receiver(Rbits, pin_in, BusClk, Sample, StopR_active);
output [7:0] Rbits;
input pin_in;
input BusClk;
input Sample;
input StopR_active;
reg [9:0] shift_in;
reg [7:0] Rbits;
always @(BusClk)
begin
// load the receive shift register, ([9:8] is receive latency)
if (~StopR_active)
shift_in = {~pin_in, shift_in[9:1]};
// Drive Rbits if receive clocks enabled.
if (Sample & BusClk & ~StopR_active)
Rbits = shift_in[7:0];
end
endmodule
module pin_driver(pin_out, Tbits, BusClk, Load, CCtl_OK, StopT_active);
parameter TData_center_delay = 0;
output pin_out;
input [7:0] Tbits;
input BusClk;
input Load;
input CCtl_OK;
input StopT_active;
reg [7:0] shift_out;
reg pin_out;
always @(BusClk)
begin
// Load shift register if load asserted and conditions OK
if (Load & ~StopT_active & BusClk)
shift_out = Tbits;
// If clocks active, then shift to the next bit on each edge of clk
else if (~StopT_active)
shift_out = {1'b0, shift_out[7:1]};
// Stop clock condition. Shift register retains data not clocked
// and will start shifting when clocks re-enabled. This means that
// when entering StopT condition, this shift register must be dry.
else
;
// normal pin drive during active clocks
if (~StopT_active & CCtl_OK)
#TData_center_delay pin_out = shift_out[0] ? 1'b0:1'bz;
// drive x if attempt made to drive during StopT!
else
#TData_center_delay pin_out = shift_out[0] ? 1'bx:1'bz;
end
endmodule