/
GPU_DECA_DDR3_top.sv
1690 lines (1429 loc) · 112 KB
/
GPU_DECA_DDR3_top.sv
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
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// ***********************************************************************************************************************************************************
//
// GPU_DECA_DDR3_top.sv
//
// Implements a GPU v16 core with the BrianHG_DDR3_CONTROLLER_top DDR3 controller.
//
// Version 1.70, 7th March, 2022.
//
// 400MHz, Quarter rate build.
//
// NEW -> SD Card interface.
//
// Written by Brian Guralnick and Jonathan Nock.
//
// For public use.
//
// Leave questions related to: the DDR3 controller in https://www.eevblog.com/forum/fpga/brianhg_ddr3_controller-open-source-ddr3-controller/
// the general project in https://www.eevblog.com/forum/fpga/fpga-vga-controller-for-8-bit-computer/
//
//************************************************************************************************************************************************************
//************************************************************************************************************************************************************
//************************************************************************************************************************************************************
`timescale 1 ps/ 1 ps // 1 picosecond steps, 1 picosecond precision.
module GPU_DECA_DDR3_top #(
// ************************************************************************************************************************************
// **************** GPU controls.
// ************************************************************************************************************************************
parameter int GPU_MEM = 524288, // Defines total video RAM, including 1KB palette
parameter string ENDIAN = "Little", // Endian for 8bit addressing access.
parameter bit [3:0] PDI_LAYERS = 4, // Number of parallel window layers.
parameter bit [3:0] SDI_LAYERS = 4, // Number of sequential window layers.
parameter bit ENABLE_TILE_MODE [0:7] = '{1,0,0,0,0,0,0,0}, // Enable tile mode for each PDI_LAYER from 0 to 7.
// TILES are available to all SDI_LAYERS of an enabled PDI_LAYER.
// Each tile enabled PDI_LAYER will use it's own dedicated FPGA blockram.
parameter bit SKIP_TILE_DELAY = 0, // Skip horizontal compensation delay due to disabled tile mode features. Only necessary for multiple PDI_LAYERS with mixed tile enable options.
parameter bit ENABLE_PALETTE [0:7] = '{1,1,1,1,1,1,1,1}, // Enable a palette blockram for each PDI_LAYER from 0 to 7.
// Each palette enabled PDI_LAYER will use it's own dedicated FPGA blockram.
parameter bit SKIP_PALETTE_DELAY = 0, // Skip horizontal compensation delay due to disabled palette. Only necessary for multiple PDI_LAYERS with mixed palette enable options.
parameter int HWREG_BASE_ADDRESS = 32'h00000100, // The first address where the HW REG controls are located for window layer 0. The first 256 bytes are reserved for general purpose use.
// Each window uses 32 bytes for their controls, IE assuming 32 windows, we need 1024 bytes worth of address space.
parameter int HWREG_BASE_ADDR_LSWAP = 32'h000000F0, // The first address where the 16 byte control to swap the SDI & PDI layer order.
parameter int PAL_BASE_ADDR = 32'h00001000, // Assuming 32 layers where each palette is 1024 bytes, we will use 32768 bytes for the palette.
parameter int TILE_BYTES = 65536, // Number of bytes reserved for the TILE/FONT memory. We will use 64k, IE it is possible to make a 16x16x8bpp 256 character font.
parameter int TILE_BASE_ADDR = 32'h00004000, //
parameter int LINE_BUFFER_WORDS = 512, // 256 minimum, larger multiples of 2 like 512 or 1024 helps improve sequential bursts.
// Note that internally, this figure is divided between the SDI_LAYERS parameter and multiplied
// by the PDI_LAYERS parameter.
// ************************************************************************************************************************************
// **************** BrianHG_DDR3 setup.
// ************************************************************************************************************************************
parameter string FPGA_VENDOR = "Altera", // (Only Altera for now) Use ALTERA, INTEL, LATTICE or XILINX.
parameter FPGA_FAMILY = "MAX 10", // With Altera, use Cyclone III, Cyclone IV, Cyclone V, MAX 10,....
parameter bit BHG_OPTIMIZE_SPEED = 1, // Use '1' for better FMAX performance, this will increase logic cell usage in the BrianHG_DDR3_PHY_SEQ module.
// It is recommended that you use '1' when running slowest -8 Altera fabric FPGA above 300MHz or Altera -6 fabric above 350MHz.
parameter bit BHG_EXTRA_SPEED = 1, // Use '1' for even better FMAX performance or when overclocking the core. This will increase logic cell usage.
// ************************************************************************************************************************************
// **************** System clock generation and operation.
// ************************************************************************************************************************************
parameter int CLK_KHZ_IN = 50000, // PLL source input clock frequency in KHz.
parameter int CLK_IN_MULT = 32, // Multiply factor to generate the DDR MTPS speed divided by 2.
parameter int CLK_IN_DIV = 4, // Divide factor. When CLK_KHZ_IN is 25000,50000,75000,100000,125000,150000, use 2,4,6,8,10,12.
parameter int DDR_TRICK_MTPS_CAP = 600, // 0=off, Set a false PLL DDR data rate for the compiler to allow FPGA overclocking. ***DO NOT USE.
parameter string INTERFACE_SPEED = "Quarter", // Either "Full", "Half", or "Quarter" speed for the user interface clock.
// This will effect the controller's interface CMD_CLK output port frequency.
// ************************************************************************************************************************************
// **************** DDR3 ram chip configuration settings
// ************************************************************************************************************************************
parameter int DDR3_CK_MHZ = ((CLK_KHZ_IN*CLK_IN_MULT/CLK_IN_DIV)/1000), // DDR3 CK clock speed in MHz.
parameter string DDR3_SPEED_GRADE = "-15E", // Use 1066 / 187E, 1333 / -15E, 1600 / -125, 1866 / -107, or 2133 MHz / 093.
parameter int DDR3_SIZE_GB = 4, // Use 0,1,2,4 or 8. (0=512mb) Caution: Must be correct as ram chip size affects the tRFC REFRESH period.
parameter int DDR3_WIDTH_DQ = 16, // Use 8 or 16. The width of each DDR3 ram chip.
parameter int DDR3_NUM_CHIPS = 1, // 1, 2, or 4 for the number of DDR3 RAM chips.
parameter int DDR3_NUM_CK = 1, // Select the number of DDR3_CK & DDR3_CK# output pairs.
// Optionally use 2 for 4 ram chips, if not 1 for each ram chip for best timing..
// These are placed on a DDR DQ or DDR CK# IO output pins.
parameter int DDR3_WIDTH_ADDR = 15, // Use for the number of bits to address each row.
parameter int DDR3_WIDTH_BANK = 3, // Use for the number of bits to address each bank.
parameter int DDR3_WIDTH_CAS = 10, // Use for the number of bits to address each column.
parameter int DDR3_WIDTH_DM = (DDR3_WIDTH_DQ*DDR3_NUM_CHIPS/8), // The width of the write data mask. (***Double when using multiple 4 bit DDR3 ram chips.)
parameter int DDR3_WIDTH_DQS = (DDR3_WIDTH_DQ*DDR3_NUM_CHIPS/8), // The number of DQS pairs. (***Double when using multiple 4 bit DDR3 ram chips.)
parameter int DDR3_RWDQ_BITS = (DDR3_WIDTH_DQ*DDR3_NUM_CHIPS*8), // Must equal to total bus width across all DDR3 ram chips *8.
parameter int DDR3_ODT_RTT = 40, // use 120, 60, 40, 30, 20 Ohm. or 0 to disable ODT. (On Die Termination during write operation.)
parameter int DDR3_RZQ = 40, // use 34 or 40 Ohm. (Output Drive Strength during read operation.)
parameter int DDR3_TEMP = 85, // use 85,95,105. (Peak operating temperature in degrees Celsius.)
parameter int DDR3_WDQ_PHASE = 270, // 270, Select the write and write DQS output clock phase relative to the DDR3_CK/CK#
parameter int DDR3_RDQ_PHASE = 0, // 0, Select the read latch clock for the read data and DQS input relative to the DDR3_CK.
parameter bit [3:0] DDR3_MAX_REF_QUEUE = 8, // Defines the size of the refresh queue where refreshes will have a higher priority than incoming SEQ_CMD_ENA command requests.
// *** Do not go above 8, doing so may break the data sheet's maximum ACTIVATE-to-PRECHARGE command period.
parameter bit [6:0] IDLE_TIME_uSx10 = 10, // Defines the time in 1/10uS until the command IDLE counter will allow low priority REFRESH cycles.
// Use 10 for 1uS. 0=disable, 2 for a minimum effect, 127 maximum.
parameter bit SKIP_PUP_TIMER = 0, // Skip timer during and after reset. ***ONLY use 1 for quick simulations.
parameter string BANK_ROW_ORDER = "ROW_BANK_COL", // Only supports "ROW_BANK_COL" or "BANK_ROW_COL". Choose to optimize your memory access.
parameter int PORT_ADDR_SIZE = (DDR3_WIDTH_ADDR + DDR3_WIDTH_BANK + DDR3_WIDTH_CAS + (DDR3_WIDTH_DM-1)),
// ************************************************************************************************************************************
// **************** BrianHG_DDR3_COMMANDER_2x1 configuration parameter settings.
// ************************************************************************************************************************************
//
// Current port assignments:
// 0 - rs232_debugger
// 1 - BRIDGETTE
// 2 - GEOFF (R/W)
// 3 - GEOFF (R only)
// 4 - BrianHG_GFX_VGA_Window_System_DDR3_REGS
// 5 - SID
//
parameter int PORT_TOTAL = 6, // Set the total number of DDR3 controller write ports, 1 to 4 max.
parameter int PORT_MLAYER_WIDTH [0:3] = '{2,2,2,2}, // Use 2 through 16. This sets the width of each MUX join from the top PORT
// inputs down to the final SEQ output. 2 offers the greatest possible FMAX while
// making the first layer width = to PORT_TOTAL will minimize MUX layers to 1,
// but with a large number of ports, FMAX may take a beating.
// ************************************************************************************************************************************
// PORT_MLAYER_WIDTH illustration
// ************************************************************************************************************************************
// PORT_TOTAL = 16
// PORT_MLAYER_WIDTH [0:3] = {4,4,x,x}
//
// (PORT_MLAYER_WIDTH[0]=4) (PORT_MLAYER_WIDTH[1]=4) (PORT_MLAYER_WIDTH[2]=N/A) (not used) (PORT_MLAYER_WIDTH[3]=N/A) (not used)
// These layers are not used since we already
// PORT_xxxx[ 0] ----------\ reached one single port to drive the DDR3 SEQ.
// PORT_xxxx[ 1] -----------==== ML10_xxxx[0] --------\
// PORT_xxxx[ 2] ----------/ \
// PORT_xxxx[ 3] ---------/ \
// \
// PORT_xxxx[ 4] ----------\ \
// PORT_xxxx[ 5] -----------==== ML10_xxxx[1] -------------==== SEQ_xxxx wires to DDR3_PHY controller.
// PORT_xxxx[ 6] ----------/ /
// PORT_xxxx[ 7] ---------/ /
// /
// PORT_xxxx[ 8] ----------\ /
// PORT_xxxx[ 9] -----------==== ML10_xxxx[2] --------/
// PORT_xxxx[10] ----------/ /
// PORT_xxxx[11] ---------/ /
// /
// PORT_xxxx[12] ----------\ /
// PORT_xxxx[13] -----------==== ML10_xxxx[3] ---/
// PORT_xxxx[14] ----------/
// PORT_xxxx[15] ---------/
//
//
// PORT_TOTAL = 16
// PORT_MLAYER_WIDTH [0:3] = {3,3,3,x}
// This will offer a better FMAX compared to {4,4,x,x}, but the final DDR3 SEQ command has 1 additional clock cycle pipe delay.
//
// (PORT_MLAYER_WIDTH[0]=3) (PORT_MLAYER_WIDTH[1]=3) (PORT_MLAYER_WIDTH[2]=3) (PORT_MLAYER_WIDTH[3]=N/A)
// It would make no difference if (not used, we made it down to 1 port)
// this layer width was set to [2].
// PORT_xxxx[ 0] ----------\
// PORT_xxxx[ 1] -----------=== ML10_xxxx[0] -------\
// PORT_xxxx[ 2] ----------/ \
// \
// PORT_xxxx[ 3] ----------\ \
// PORT_xxxx[ 4] -----------=== ML10_xxxx[1] -----------==== ML20_xxxx[0] ---\
// PORT_xxxx[ 5] ----------/ / \
// / \
// PORT_xxxx[ 6] ----------\ / \
// PORT_xxxx[ 7] -----------=== ML10_xxxx[2] -------/ \
// PORT_xxxx[ 8] ----------/ \
// \
// PORT_xxxx[ 9] ----------\ \
// PORT_xxxx[10] -----------=== ML11_xxxx[0] -------\ \
// PORT_xxxx[11] ----------/ \ \
// \ \
// PORT_xxxx[12] ----------\ \ \
// PORT_xxxx[13] -----------=== ML11_xxxx[1] -----------==== ML20_xxxx[1] ---------------==== SEQ_xxxx wires to DDR3_PHY controller.
// PORT_xxxx[14] ----------/ / /
// / /
// PORT_xxxx[15] ----------\ / /
// 0=[16] -----------=== ML11_xxxx[2] -------/ /
// 0=[17] ----------/ /
// /
// /
// /
// 0 = ML20_xxxx[2] -------/
//
// ************************************************************************************************************************************
parameter int PORT_VECTOR_SIZE = 16, // Sets the width of each port's VECTOR input and output.
// ************************************************************************************************************************************
// ***** DO NOT CHANGE THE NEXT 4 PARAMETERS FOR THIS VERSION OF THE BrianHG_DDR3_COMMANDER.sv... *************************************
parameter int READ_ID_SIZE = 4, // The number of bits available for the read ID. This will limit the maximum possible read/write cache modules.
parameter int DDR3_VECTOR_SIZE = READ_ID_SIZE + 1, // Sets the width of the VECTOR for the DDR3_PHY_SEQ controller. 4 bits for 16 possible read ports.
parameter int PORT_CACHE_BITS = (8*DDR3_WIDTH_DM*8), // Note that this value must be a multiple of ' (8*DDR3_WIDTH_DQ*DDR3_NUM_CHIPS)* burst 8 '.
parameter int CACHE_ADDR_WIDTH = $clog2(PORT_CACHE_BITS/8), // This is the number of LSB address bits which address all the available 8 bit bytes inside the cache word.
parameter int BYTE_INDEX_BITS = (DDR3_WIDTH_CAS + (DDR3_WIDTH_DM-1)), // Sets the starting address bit where a new row & bank begins.
// ************************************************************************************************************************************
// PORT_'feature' = '{port# 0,1,2,3,4,5,,,} Sets the feature for each DDR3 ram controller interface port 0 to port 15.
parameter bit PORT_TOGGLE_INPUT [0:15] = '{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
// When enabled, the associated port's 'CMD_busy' and 'CMD_ena' ports will operate in
// toggle mode where each toggle of the 'CMD_ena' will represent a new command input
// and the port is busy whenever the 'CMD_busy' output is not equal to the 'CMD_ena' input.
// This is an advanced feature used to communicate with the input channel when your source
// control is operating at 2x this module's CMD_CLK frequency, or 1/2 CMD_CLK frequency
// if you have disabled the port's PORT_W_CACHE_TOUT.
parameter bit [8:0] PORT_R_DATA_WIDTH [0:15] = '{ 8, 8, 16, 16,128,128,128,128,128,128,128,128,128,128,128,128},
parameter bit [8:0] PORT_W_DATA_WIDTH [0:15] = '{ 8, 8, 16, 16,128,128,128,128,128,128,128,128,128,128,128,128},
// Use 8,16,32,64,128, or 256 bits, maximum = 'PORT_CACHE_BITS'
// As a precaution, this will prune/ignore unused data bits and write masks bits, however,
// all the data ports will still be 'PORT_CACHE_BITS' bits and the write masks will be 'PORT_CACHE_WMASK' bits.
// (a 'PORT_CACHE_BITS' bit wide data bus has 32 individual mask-able bytes (8 bit words))
// For ports sizes below 'PORT_CACHE_BITS', the data is stored and received in Big Endian.
parameter bit [1:0] PORT_PRIORITY [0:15] = '{ 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
// Use 0 to 3. If a port with a higher priority receives a request, even if another
// port's request matches the current page, the higher priority port will take
// precedence and force the RAM controller to leave the current page.
parameter int PORT_READ_STACK [0:15] = '{ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24},
// Sets the size of the intermediate read command request stack.
// 16 through 32, default = 20
// The size of the number of read commands built up in advance while the read channel waits
// for the DDR3_PHY_SEQ to return the read request data.
// Multiple reads must be accumulated to allow an efficient continuous read burst.
// IE: Use 16 level deep when running a small data port width like 16 or 32 so sequential read cache
// hits continue through the command input allowing cache miss read req later-on in the req stream to be
// immediately be sent to the DDR3_PHY_SEQ before the DDR3 even returns the first read req data.
parameter bit [8:0] PORT_W_CACHE_TOUT [0:15] = '{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256},
// A timeout for the write cache to dump it's contents to ram.
// 0 = immediate writes, or no write cache.
// 256 = Wait up to 256 CMD_CLK clock cycles since the previous write req.
// to the same 'PORT_CACHE_BITS' bit block before writing to ram. Write reqs outside
// the current 'PORT_CACHE_BITS' bit cache block clears the timer and forces an immediate write.
parameter bit PORT_R_CACHE_TOUT_ENA [0:15] = '{ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
// A 0 will direct the read cache to indefinitely keep its contents valid until a new read address is
// requested outside the the current cache contents. Recommended for very slow read cycles where you may
// manually read outside the current cached address if you wish to re-read from the DDR3.
// A 1 will use the automatic timeout setting below to automatically clear the read cache address.
parameter bit [8:0] PORT_R_CACHE_TOUT [0:15] = '{256,256,256,256, 0,256,256,256,256,256,256,256,256,256,256,256},
// A timeout for the read cache to consider its contents stale.
// 0 = Always read from DDR3, or no read caching.
// 256 = Wait up to 256 CMD_CLK clock cycles since the previous read req before considering the cached read stale.
parameter bit PORT_R_WDT_ENA [0:15] = '{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
// A 1 will automatically detect an impossible skipped/missing read command due to multiport cache collision
// between a read input CMD_ena and output CMD_read_ready, unfreezing this potential situation.
parameter bit PORT_CACHE_SMART [0:15] = '{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
// When enabled, if an existing read cache exists at the same write request address,
// that read's cache will immediately be updated with the new write data.
// This function may impact the FMAX for the system clock and increase LUT usage.
// *** Disable when designing a memory read/write testing algorithm.
parameter bit PORT_DREG_READ [0:15] = '{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
// When enabled, an additional register is placed at the read data out to help improve FMAX.
parameter bit [8:0] PORT_MAX_BURST [0:15] = '{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256},
// 1 through 256, 0=No sequential burst priority.
// Defines the maximum consecutive read or write burst commands from a single
// port if another read/write port requests exists with the same priority level,
// but their memory request exist in a different row. * Every 1 counts for a BL8 burst.
// This will prevent a single continuous stream port from hogging up all the ram access time.
// IE: If set to 0, commander will seek if other read/write requests are ready before
// continuing access to the same port DDR3 access.
parameter bit SMART_BANK = 0 // 1=ON, 0=OFF, With SMART_BANK enabled, the BrianHG_DDR3_COMMANDER will remember which
// ROW# has been activated in each DDR3 BANK# so that when prioritizing read and write
// ports of equal priority, multiple commands across multiple banks whose ROWs have
// matching existing activation will be prioritized/coalesced as if they were part of
// the sequential burst as PRECHARGE and ACTIVATE commands are not needed when bursting
// between active banks maintaining an unbroken read/write stream.
// (Of course the BrianHG_DDR3_PHY_SEQ is able to handle smart banking as well...)
// Note that enabling this feature uses additional logic cells and may impact FMAX.
// Disabling this feature will only coalesce commands in the current access ROW.
// Parameter 'BANK_ROW_ORDER' will define which address bits define the accessed BANK number.
)
(
// *****************************************************************************************************************
// ********** DECA Board's IOs.
// *****************************************************************************************************************
//////////// CLOCK //////////
input ADC_CLK_10,
input MAX10_CLK1_50,
input MAX10_CLK2_50,
//////////// KEY //////////
input [1:0] KEY,
//////////// LED //////////
output logic [7:0] LED,
//////////// CapSense Button //////////
inout CAP_SENSE_I2C_SCL,
inout CAP_SENSE_I2C_SDA,
//////////// Audio //////////
// VCC_AUD_IO -> 6 IOVDD -> 1.5v
// VCC_AUD -> 26 LDOIN -> 3.3v
// 29 DVDD -> Internal LDO + decoupling caps.
// 24 AVDD -> Internal LDO + decoupling caps.
//
// LOL pin 22 and LOR pin 23 drive the line out jack.
// IN2_L pin 15 and IN2_R pin 16 drive the line in jack.
//
output AUDIO_MCLK, // *** 1 MCLK
output AUDIO_BCLK, // *** 2 BCLK
output AUDIO_WCLK, // *** 3 WCLK
output AUDIO_DIN_MFP1, // *** 4 DIN /MFP1
input AUDIO_DOUT_MFP2, // *** 5 DOUT/MFP2
output AUDIO_SCLK_MFP3, // *** 8 SCLK/MFP3
inout AUDIO_SCL_SS_n, // *** 9 SCL/SS_n 2k-pullup
inout AUDIO_SDA_MOSI, // *** 10 SDA/MOSI 2k-pullup
input AUDIO_MISO_MFP4, // *** 11 MISO/MFP4
output AUDIO_SPI_SELECT, // *** 12 SPI_SELECT -> make low for I2C.
output AUDIO_RESET_n, // *** 31 RESET_n
inout AUDIO_GPIO_MFP5, // *** 32 GPIO_MFP5
//////////// Flash //////////
inout [3:0] FLASH_DATA,
output FLASH_DCLK,
output FLASH_NCSO,
output FLASH_RESET_n,
//////////// G-Sensor //////////
output G_SENSOR_CS_n,
input G_SENSOR_INT1,
input G_SENSOR_INT2,
inout G_SENSOR_SCLK,
inout G_SENSOR_SDI,
inout G_SENSOR_SDO,
//////////// HDMI-TX //////////
inout HDMI_I2C_SCL,
inout HDMI_I2C_SDA,
inout [3:0] HDMI_I2S,
inout HDMI_LRCLK,
inout HDMI_MCLK,
inout HDMI_SCLK,
output HDMI_TX_CLK,
output [23:0] HDMI_TX_D,
output HDMI_TX_DE,
output HDMI_TX_HS,
input HDMI_TX_INT,
output HDMI_TX_VS,
//////////// Light Sensor //////////
output LIGHT_I2C_SCL,
inout LIGHT_I2C_SDA,
inout LIGHT_INT,
//////////// MIPI //////////
output MIPI_CORE_EN,
output MIPI_I2C_SCL,
inout MIPI_I2C_SDA,
input MIPI_LP_MC_n,
input MIPI_LP_MC_p,
input [3:0] MIPI_LP_MD_n,
input [3:0] MIPI_LP_MD_p,
input MIPI_MC_p,
output MIPI_MCLK,
input [3:0] MIPI_MD_p,
output MIPI_RESET_n,
output MIPI_WP,
//////////// Ethernet //////////
input NET_COL,
input NET_CRS,
output NET_MDC,
inout NET_MDIO,
output NET_PCF_EN,
output NET_RESET_n,
input NET_RX_CLK,
input NET_RX_DV,
input NET_RX_ER,
input [3:0] NET_RXD,
input NET_TX_CLK,
output NET_TX_EN,
output [3:0] NET_TXD,
//////////// Power Monitor //////////
input PMONITOR_ALERT,
output PMONITOR_I2C_SCL,
inout PMONITOR_I2C_SDA,
//////////// Humidity and Temperature Sensor //////////
input RH_TEMP_DRDY_n,
output RH_TEMP_I2C_SCL,
inout RH_TEMP_I2C_SDA,
//////////// MicroSD Card //////////
output SD_CLK,
inout SD_CMD,
output SD_CMD_DIR,
output SD_D0_DIR,
output SD_D123_DIR,
inout [3:0] SD_DAT,
input SD_FB_CLK,
output SD_SEL,
//////////// SW //////////
input [1:0] SW,
//////////// Board Temperature Sensor //////////
output TEMP_CS_n,
output TEMP_SC,
inout TEMP_SIO,
//////////// USB //////////
input USB_CLKIN,
output USB_CS,
inout [7:0] USB_DATA,
input USB_DIR,
input USB_FAULT_n,
input USB_NXT,
output USB_RESET_n,
output USB_STP,
//////////// BBB Conector //////////
input BBB_PWR_BUT,
input BBB_SYS_RESET_n,
inout [43:0] GPIO0_D,
inout [22:0] GPIO1_D,
// *****************************************************************************************************************
// ********** Results from DDR3_PHY_SEQ, IO Names happen to match DECA Board's IO assignment pin names.
// *****************************************************************************************************************
output DDR3_RESET_n, // DDR3 RESET# input pin.
output [DDR3_NUM_CK-1:0] DDR3_CK_p, // DDR3_CK ****************** YOU MUST SET THIS IO TO A DIFFERENTIAL LVDS or LVDS_E_3R
output [DDR3_NUM_CK-1:0] DDR3_CK_n, // DDR3_CK ****************** YOU MUST SET THIS IO TO A DIFFERENTIAL LVDS or LVDS_E_3R
// ************************** port to generate the negative DDR3_CK# output.
// ************************** Generate an additional DDR_CK_p pair for every DDR3 ram chip.
output DDR3_CKE, // DDR3 CKE
output DDR3_CS_n, // DDR3 CS#
output DDR3_RAS_n, // DDR3 RAS#
output DDR3_CAS_n, // DDR3 CAS#
output DDR3_WE_n, // DDR3 WE#
output DDR3_ODT, // DDR3 ODT
output [DDR3_WIDTH_ADDR-1:0] DDR3_A, // DDR3 multiplexed address input bus
output [DDR3_WIDTH_BANK-1:0] DDR3_BA, // DDR3 Bank select
output [DDR3_WIDTH_DM-1:0] DDR3_DM, // DDR3 Write data mask. DDR3_DM[0] drives write DQ[7:0], DDR3_DM[1] drives write DQ[15:8]...
inout [DDR3_WIDTH_DQ-1:0] DDR3_DQ, // DDR3 DQ data IO bus.
inout [DDR3_WIDTH_DQS-1:0] DDR3_DQS_p, // DDR3 DQS ********* IOs. DQS[0] drives DQ[7:0], DQS[1] drives DQ[15:8], DQS[2] drives DQ[23:16]...
inout [DDR3_WIDTH_DQS-1:0] DDR3_DQS_n // DDR3 DQS ********* IOs. DQS[0] drives DQ[7:0], DQS[1] drives DQ[15:8], DQS[2] drives DQ[23:16]...
// ****************** YOU MUST SET THIS IO TO A DIFFERENTIAL LVDS or LVDS_E_3R
// ****************** port to generate the negative DDR3_DQS# IO.
);
// *****************************************************
// ********* BrianHG_DDR3_PHY_SEQ logic / wires.
// *****************************************************
logic RST_IN,CLK_IN,RST_OUT,PLL_LOCKED,DDR3_CLK,CMD_CLK,DDR3_CLK_50,DDR3_CLK_25;
logic SEQ_CAL_PASS, DDR3_READY;
logic [7:0] RDCAL_data ;
// ****************************************
// DDR3 controller interface.
// ****************************************
logic CMD_busy [0:PORT_TOTAL-1]; // For each port, when high, the DDR3 controller will not accept an incoming command on that port.
logic CMD_ena [0:PORT_TOTAL-1]; // Send a command.
logic CMD_write_ena [0:PORT_TOTAL-1]; // Set high when you want to write data, low when you want to read data.
logic [PORT_ADDR_SIZE-1:0] CMD_addr [0:PORT_TOTAL-1]; // Command Address pointer.
logic [PORT_CACHE_BITS-1:0] CMD_wdata [0:PORT_TOTAL-1]; // During a 'CMD_write_req', this data will be written into the DDR3 at address 'CMD_addr'.
// Each port's 'PORT_DATA_WIDTH' setting will prune the unused write data bits.
// *** All channels of the 'CMD_wdata' will always be PORT_CACHE_BITS wide, however,
// only the bottom 'PORT_W_DATA_WIDTH' bits will be active.
logic [PORT_CACHE_BITS/8-1:0] CMD_wmask [0:PORT_TOTAL-1]; // Write enable byte mask for the individual bytes within the 256 bit data bus.
// When low, the associated byte will not be written.
// Each port's 'PORT_DATA_WIDTH' setting will prune the unused mask bits.
// *** All channels of the 'CMD_wmask' will always be 'PORT_CACHE_BITS/8' wide, however,
// only the bottom 'PORT_W_DATA_WIDTH/8' bits will be active.
logic [PORT_VECTOR_SIZE-1:0] CMD_read_vector_in [0:PORT_TOTAL-1]; // The contents of the 'CMD_read_vector_in' during a read req will be sent to the
// 'CMD_read_vector_out' in parallel with the 'CMD_read_data' during the 'CMD_read_ready' pulse.
// *** All channels of the 'CMD_read_vector_in' will always be 'PORT_VECTOR_SIZE' wide,
// it is up to the user to '0' the unused input bits on each individual channel.
logic CMD_read_ready [0:PORT_TOTAL-1]; // Goes high for 1 clock when the read command data is valid.
logic [PORT_CACHE_BITS-1:0] CMD_read_data [0:PORT_TOTAL-1]; // Valid read data when 'CMD_read_ready' is high.
// *** All channels of the 'CMD_read_data will' always be 'PORT_CACHE_BITS' wide, however,
// only the bottom 'PORT_R_DATA_WIDTH' bits will be active.
logic [PORT_VECTOR_SIZE-1:0] CMD_read_vector_out [0:PORT_TOTAL-1]; // Returns the 'CMD_read_vector_in' which was sampled during the 'CMD_read_req' in parallel
// with the 'CMD_read_data'. This allows for multiple post reads where the output
// has a destination pointer.
logic CMD_priority_boost [0:PORT_TOTAL-1]; // Boosts the port's 'PORT_PRIORITY' parameter by a weight of 4 when set.
// **************************************************************************************
// This Write Data TAP port passes a copy of all the writes going to the DDR3 memory.
// This will allow to 'shadow' selected write addresses to other peripherals
// which may be accessed by all the multiple write ports.
// This port is synchronous to the CMD_CLK.
// **************************************************************************************
logic TAP_WRITE_ENA, rTAP_WRITE_ENA = 0 ;
logic [PORT_ADDR_SIZE-1:0] TAP_ADDR , rTAP_ADDR = 0 ;
logic [PORT_CACHE_BITS-1:0] TAP_WDATA , rTAP_WDATA = 0 ;
logic [PORT_CACHE_BITS/8-1:0] TAP_WMASK , rTAP_WMASK = 0 ;
// ***********************************************************************************************************************************************************
// ***********************************************************************************************************************************************************
// ***********************************************************************************************************************************************************
// This module is the complete BrianHG_DDR3_CONTROLLER_v15 system assembled initiating:
//
// - BrianHG_DDR3_CONTROLLER_v15_top.sv -> v1.5 TOP entry to the complete project which wires the DDR3_COMMANDER_v15 to the DDR3_PHY_SEQ giving you access to all the read/write ports + access to the DDR3 IO pins.
// - BrianHG_DDR3_COMMANDER_v15.sv -> v1.5 High FMAX speed multi-port read and write requests and cache, commands the BrianHG_DDR3_PHY_SEQ.sv sequencer.
// - BrianHG_DDR3_CMD_SEQUENCER.sv -> Takes in the read and write requests, generates a stream of DDR3 commands to execute the read and writes.
// - BrianHG_DDR3_PHY_SEQ.sv -> DDR3 PHY sequencer. (If you want just a compact DDR3 controller, skip the DDR3_CONTROLLER_top & DDR3_COMMANDER and just use this module alone.)
// - BrianHG_DDR3_PLL.sv -> Generates the system clocks. (*** Currently Altera/Intel only ***)
// - BrianHG_DDR3_GEN_tCK.sv -> Generates all the tCK count clock cycles for the DDR3_PHY_SEQ so that the DDR3 clock cycle requirements are met.
// - BrianHG_DDR3_FIFOs.sv -> Serial shifting logic FIFOs.
//
// ***********************************************************************************************************************************************************
// ***********************************************************************************************************************************************************
// ***********************************************************************************************************************************************************
BrianHG_DDR3_CONTROLLER_v16_top #(
.FPGA_VENDOR (FPGA_VENDOR ), .FPGA_FAMILY (FPGA_FAMILY ), .INTERFACE_SPEED (INTERFACE_SPEED ),
.BHG_OPTIMIZE_SPEED (BHG_OPTIMIZE_SPEED), .BHG_EXTRA_SPEED (BHG_EXTRA_SPEED ),
.CLK_KHZ_IN (CLK_KHZ_IN ), .CLK_IN_MULT (CLK_IN_MULT ), .CLK_IN_DIV (CLK_IN_DIV ),
.DDR3_CK_MHZ (DDR3_CK_MHZ ), .DDR3_SPEED_GRADE (DDR3_SPEED_GRADE ), .DDR3_SIZE_GB (DDR3_SIZE_GB ),
.DDR3_WIDTH_DQ (DDR3_WIDTH_DQ ), .DDR3_NUM_CHIPS (DDR3_NUM_CHIPS ), .DDR3_NUM_CK (DDR3_NUM_CK ),
.DDR3_WIDTH_ADDR (DDR3_WIDTH_ADDR ), .DDR3_WIDTH_BANK (DDR3_WIDTH_BANK ), .DDR3_WIDTH_CAS (DDR3_WIDTH_CAS ),
.DDR3_WIDTH_DM (DDR3_WIDTH_DM ), .DDR3_WIDTH_DQS (DDR3_WIDTH_DQS ), .DDR3_ODT_RTT (DDR3_ODT_RTT ),
.DDR3_RZQ (DDR3_RZQ ), .DDR3_TEMP (DDR3_TEMP ), .DDR3_WDQ_PHASE (DDR3_WDQ_PHASE ),
.DDR3_RDQ_PHASE (DDR3_RDQ_PHASE ), .DDR3_MAX_REF_QUEUE (DDR3_MAX_REF_QUEUE), .IDLE_TIME_uSx10 (IDLE_TIME_uSx10 ),
.SKIP_PUP_TIMER (SKIP_PUP_TIMER ), .BANK_ROW_ORDER (BANK_ROW_ORDER ), .DDR_TRICK_MTPS_CAP (DDR_TRICK_MTPS_CAP),
.PORT_ADDR_SIZE (PORT_ADDR_SIZE ),
.PORT_MLAYER_WIDTH (PORT_MLAYER_WIDTH ),
.PORT_TOTAL (PORT_TOTAL ), .PORT_VECTOR_SIZE (PORT_VECTOR_SIZE ), .PORT_TOGGLE_INPUT (PORT_TOGGLE_INPUT),
.PORT_R_DATA_WIDTH (PORT_R_DATA_WIDTH ), .PORT_W_DATA_WIDTH (PORT_W_DATA_WIDTH ),
.PORT_PRIORITY (PORT_PRIORITY ), .PORT_READ_STACK (PORT_READ_STACK ),
.PORT_CACHE_SMART (PORT_CACHE_SMART ), .PORT_W_CACHE_TOUT (PORT_W_CACHE_TOUT ),
.PORT_R_CACHE_TOUT (PORT_R_CACHE_TOUT ), .PORT_R_WDT_ENA (PORT_R_WDT_ENA ), .PORT_R_CACHE_TOUT_ENA (PORT_R_CACHE_TOUT_ENA),
.PORT_MAX_BURST (PORT_MAX_BURST ), .PORT_DREG_READ (PORT_DREG_READ ), .SMART_BANK (SMART_BANK )
) DDR3 (
// *** Interface Reset, Clocks & Status. ***
.RST_IN (RST_IN ), .RST_OUT (RST_OUT ),
.CLK_IN (CLK_IN ), .CMD_CLK (CMD_CLK ),
.DDR3_READY (DDR3_READY ), .SEQ_CAL_PASS (SEQ_CAL_PASS ),
.PLL_LOCKED (PLL_LOCKED ), .DDR3_CLK (DDR3_CLK ),
.DDR3_CLK_50 (DDR3_CLK_50 ), .DDR3_CLK_25 (DDR3_CLK_25 ),
// *** DDR3 Commander functions ***
.CMD_busy (CMD_busy ), .CMD_ena (CMD_ena ),
.CMD_write_ena (CMD_write_ena ), .CMD_addr (CMD_addr ),
.CMD_wdata (CMD_wdata ), .CMD_wmask (CMD_wmask ),
.CMD_read_vector_in (CMD_read_vector_in ), .CMD_priority_boost (CMD_priority_boost ),
.CMD_read_ready (CMD_read_ready ), .CMD_read_data (CMD_read_data ),
.CMD_read_vector_out (CMD_read_vector_out ),
// *** DDR3 Ram Chip IO Pins ***
.DDR3_CK_p (DDR3_CK_p ), .DDR3_CK_n (DDR3_CK_n ), .DDR3_CKE (DDR3_CKE ), .DDR3_CS_n (DDR3_CS_n ),
.DDR3_RAS_n (DDR3_RAS_n ), .DDR3_CAS_n (DDR3_CAS_n ), .DDR3_WE_n (DDR3_WE_n ), .DDR3_ODT (DDR3_ODT ),
.DDR3_A (DDR3_A ), .DDR3_BA (DDR3_BA ), .DDR3_DM (DDR3_DM ), .DDR3_DQ (DDR3_DQ ),
.DDR3_DQS_p (DDR3_DQS_p ), .DDR3_DQS_n (DDR3_DQS_n ), .DDR3_RESET_n (DDR3_RESET_n ),
// debug IO
.RDCAL_data (RDCAL_data ), .reset_phy (DB232_rx3[7]), .reset_cmd (DB232_rx3[6]),
// Write data TAP port.
.TAP_WRITE_ENA (TAP_WRITE_ENA ), .TAP_ADDR (TAP_ADDR ),
.TAP_WDATA (TAP_WDATA ), .TAP_WMASK (TAP_WMASK )
);
// ***********************************************************************************************************************************************************
// ***********************************************************************************************************************************************************
// ***********************************************************************************************************************************************************
wire rd_px_ctr_rs ;
wire wr_px_ctr_rs ;
wire [15:0] geo_cmd ;
wire [7:0] geo_stat_rd ;
wire [7:0] collision_rd ;
wire [7:0] collision_wr ;
// ***************************************************************************************************************
// *** Set default address buffer values for those not normally controlled by the GPU ****************************
// ***************************************************************************************************************
assign GPIO0_D[32] = 0 ; // HI_OE - LOW to enable
assign GPIO0_D[33] = 1 ; // HI_DIR - HIGH for A>B direction (to FPGA)
assign GPIO0_D[42] = 0 ; // LO_OE - LOW to enable
assign GPIO0_D[43] = 1 ; // LO_DIR - HIGH for A>B direction (to FPGA)
// Set default values for unused Control Bus Outputs
assign GPIO0_D[9] = 0 ; // WR output
assign GPIO0_D[10] = 0 ; // M_REQ output
assign GPIO0_D[11] = 0 ; // RD output
assign GPIO0_D[12] = 0 ; // BUS_REQ output
assign GPIO0_D[13] = 0 ; // IO_REQ output
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// *** RESET CIRCUIT *********************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
logic reset ;
logic DFF_inst8 ;
logic DFF_inst26 ;
logic DFF_inst41 ;
wire geo_reset ;
wire reset_line ;
wire RESET_Z80 ;
wire INV_RESET_DFF ;
exp b2v_inst4(
.in ( DFF_inst8 ),
.out ( INV_RESET_DFF )
);
exp b2v_inst23(
.in ( DFF_inst41 ),
.out ( RESET_Z80 )
);
assign geo_reset = DFF_inst26 ;
assign reset_line = RESET_Z80 | INV_RESET_DFF ;
always@(posedge DDR3_CLK_25) begin
DFF_inst26 <= reset ;
reset <= reset_line ;
DFF_inst41 <= GPIO1_D[10] ;
DFF_inst8 <= KEY[0] ;
end
// Set default DDR3 bus signals for Bridgette
assign CMD_read_vector_in [1] = 0 ;
assign CMD_priority_boost [1] = 0 ;
// Wires from Z80 to PSG.
wire [ 7:0] psg_addr ;
wire [ 7:0] psg_data_i ;
wire [ 7:0] psg_data_o ;
wire psg_wr_en ;
// ***************************************************************************************************************
// ************************* IO buses to/from the Z80 bridge and peripheral modules ******************************
// ***************************************************************************************************************
// These look like they'll take up a lot of interconnect resources, but the compiler will prune them down to only
// the signals that are actually used, although I'm not sure this applies to IO_RD_DATA if it has a default value
// applied to each line.
wire [255:0] IO_WR_STROBE /* synthesis keep */;
wire [ 7:0] IO_WR_DATA [0:255] /* synthesis keep */;
wire [255:0] IO_RD_STROBE ;
logic [ 7:0] IO_RD_DATA [0:255] = '{ default: 8'hFF } ;
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// *** BRIDGETTE *************************************************************************************************
// *** Z80 Bridge ************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
Z80_Bus_Interface #(
// ************** Z80 bus timing settings. **************
.READ_PORT_CLK_sPOS ( 0 ), // Number of Z80_CLK cycles before the bus interface responds to a Read Port command.
.READ_PORT_CLK_aPOS ( 2 ), // Number of Z80_CLK cycles before the bus must have valid data in response to a Read Port command.
.WRITE_PORT_CLK_POS ( 2 ), // Number of Z80_CLK cycles before the bus interface samples the Write Port command's data.
// 0 to 7, Number of CMD_CLK cycles to wait for DDR3 read before asserting the WAIT during a Read Memory cycle.
// Use 0 for an instant guaranteed 'WAIT' every read. (Safest for Read Instruction Opcode cycle.)
// Use 2 for compatibility with waiting for a BrianHG_DDR3 read cache hit before asserting the 'WAIT'.
.Z80_DELAY_WAIT_RI ( 3 ), // 0 to 7, Number of CMD_CLK cycles to wait for DDR3 read_ready before asserting the WAIT during a Read Instruction Opcode cycle.
.Z80_DELAY_WAIT_RM ( 3 ), // 0 to 7, Number of CMD_CLK cycles to wait for DDR3 read_ready before asserting the WAIT during a Read Memory cycle.
.Z80_WAIT_QUICK_OFF ( 1 ), // 0 (Default) = WAIT is turned off only during a low Z80_CLK. 1 = WAIT is turned off as soon as a read_ready is received.
// ************** Direction control for DATA BUS level converter **************
.data_in ( 1'b0 ), // Direction controls for 74LVC245 buffers - hardware dependent!
.data_out ( 1'b1 ), // Direction controls for 74LVC245 buffers - hardware dependent!
// ************** Parameters specific to the uCOM host **************
.BANK_ID ( '{9,3,71,80,85,32,77,65,88,49,48,0,255,255,255,255} ), // The BANK_ID data to return ('GPU MAX10')
.BANK_ID_ADDR ( GPU_MEM-16 ), // Address to return BANK_ID data from
.BANK_RESPONSE ( 1 ), // 1 - respond to reads at BANK_ID_ADDR with BANK_ID data, 0 - ignore reads to that address
.MEM_SIZE_BYTES ( GPU_MEM ), // Specifies size of GPU RAM available to host (anything above this returns $FF or $7E)
.MEMORY_RANGE ( 3'b010 ), // Z80_addr[21:19] == 3'b010 targets the 512KB 'window' at 0x100000-0x17FFFF (Socket 3 on the uCom)
// ************** Interrupts are not currently used **************
.INT_TYP ( 0 ), // 0 = polled (IO), 1 = interrupt.
.INT_VEC ( 48 ), // INTerrupt VECtor to be passed to host in event of an interrupt acknowledge.
// ************** Read IO port addresses range. **************
// READ_PORT_BEGIN is set so low to catch MMU IO calls (38h-3Ch)
.READ_PORT_BEGIN ( 56 ), // Sets the beginning port number which can be read.
.READ_PORT_END ( 251 ), // Sets the ending port number which can be read.
.GPU_ML ( GPU_ML ),
.GPU_MH ( GPU_MH )
) BRIDGETTE (
// ***********************************
// *** Core System Clock and Reset ***
// ***********************************
.CMD_CLK ( CMD_CLK ), // System clock (75-200 MHz)
.reset ( reset ), // System reset signal
// ***********************************
// *** Z80 bus control connections ***
// ***********************************
.Z80_CLK ( GPIO1_D[3] ), // Z80 host's clock signal (8 MHz default).
// Z80 address bus (22-bit)
.Z80_ADDR ({ GPIO0_D[14], GPIO0_D[15], GPIO0_D[16], GPIO0_D[17], GPIO0_D[18], GPIO0_D[19], GPIO0_D[20], GPIO0_D[21],
GPIO0_D[26], GPIO0_D[27], GPIO0_D[28], GPIO0_D[29], GPIO0_D[30], GPIO0_D[31], GPIO0_D[34], GPIO0_D[35],
GPIO0_D[36], GPIO0_D[37], GPIO0_D[38], GPIO0_D[39], GPIO0_D[40], GPIO0_D[41]
}),
// Control bus
.Z80_M1n ( GPIO1_D[8] ), // Z80 M1 goes LOW with MREQ to signal Z80 Machine Cycle 1 (opcode fetch).
// Z80 M1 goes LOW with IORQ to signal an interrupt acknowledge (INTACK).
.Z80_IORQn ( GPIO1_D[7] ), // Z80 IORQ goes LOW when Z80 is performing an IO operation.
.Z80_MREQn ( GPIO1_D[6] ), // Z80 MREQ goes LOW when Z80 is performing a memory operation.
.Z80_WAIT ( GPIO0_D[8] ), // Active HIGH, signals to Z80 to WAIT.
.Z80_RDn ( GPIO1_D[4] ), // Z80 RD goes LOW to signal a Z80 ReaD operation.
.Z80_WRn ( GPIO1_D[5] ), // Z80 WR goes LOW when Z80 is performing a WRite operation.
// Data bus (8-bit)
.Z80_DATA ({ GPIO1_D[11], GPIO1_D[12], GPIO1_D[13], GPIO1_D[14], GPIO1_D[15], GPIO1_D[16], GPIO1_D[17], GPIO1_D[18] }),
// Interrupts
.Z80_IEI ( ), // NOT USED, Z80 INTerrupt daisy chain input - active LOW, prevents Z80_bridge from raising an INTerrupt request.
.Z80_INT_REQ ( ), // NOT USED, Active HIGH (signal is inverted in the FPGA interface), signals to Z80 an INTerrupt request.
.Z80_IEO ( ), // NOT USED, Active LOW, prevents devices further down the daisy chain from requesting INTerrupts.
// *** Z80 bidir data bus and bus steering connections. ***
.Z80_245data_dir ( GPIO1_D[20] ), // Controls direction of the Z80 data bus buffer.
.Z80_245_oe ( GPIO1_D[19] ), // Enable/disable signal for Z80 data bus buffer.
// *** Extended Address (EA) bus steering connections ***
.EA_DIR ( GPIO0_D[23] ), // Controls direction of the EA bus buffer.
.EA_OE ( GPIO0_D[22] ), // Enable/disable signal for EA bus buffer.
// The EA bus direction control should default to Z80 > FPGA direction.
// These controls are present for a future FPGA MMU to replace the hardware MMU on the memory card, or
// for EA bus control by an optional FPGA CPU core.
// *********************************
// *** Z80 <-> System RAM Access ***
// *********************************
.CMD_busy ( CMD_busy [1] ), // High when a DDR3 read/write req is not allowed to take place.
.CMD_ena ( CMD_ena [1] ), // Flag HIGH for at least 1 clock when reading/writing to DDR3 RAM
.CMD_addr ( (PORT_ADDR_SIZE)'( CMD_addr [1] ) ), // Z80 requested address.
.CMD_write_ena ( CMD_write_ena [1] ), // Flag HIGH for 1 CMD_CLK when writing to RAM
.CMD_write_data ( (PORT_CACHE_BITS)'( CMD_wdata [1] ) ), // Data from Z80 to be written into RAM.
.CMD_write_mask ( (PORT_CACHE_BITS/8)'( CMD_wmask [1] ) ), // Write data enable mask to RAM.
.CMD_read_ready ( CMD_read_ready [1] ), // One-shot signal from mux or DDR3_Controller that data is ready
.CMD_read_data ( (8)'( CMD_read_data [1] ) ), // Read Data from RAM to be sent to Z80.
// *******************************
// *** Z80 peripheral IO ports ***
// *******************************
.WRITE_PORT_STROBE ( IO_WR_STROBE ), // The bit [port_number] in this 256 bit bus will pulse when the Z80 writes to that port number.
.WRITE_PORT_DATA ( IO_WR_DATA ), // The array [port_number] will hold the last written data to that port number.
.READ_PORT_STROBE ( IO_RD_STROBE ), // The bit [port_number] in this 256 bit bus will pulse when the Z80 reads from that port number.
.READ_PORT_DATA ( IO_RD_DATA ), // The array [port_number] will be sent to the Z80 during a port read so long as the read port
// number is within parameter READ_PORT_BEGIN and READ_PORT_END.
// ***************************************************************************************************
// **** Wishbone Master Interface ********************************************************************
// ***************************************************************************************************
/*
.m_wb_adr_o ( h_wb_adr ), // 8-bit address
.m_wb_dat_o ( h_wb_dat_o ), // 32-bit data out
.m_wb_dat_i ( h_wb_dat_i ), // 32-bit data in
.m_wb_sel_o ( h_sel_o ), // WISHBONE byte select input [3:0] (indicates where valid data is expected on the dat_i or dat_o bus)
.m_wb_we_o ( h_we_o ), // WISHBONE write enable output
.m_wb_cyc_o ( h_cyc_o ), // WISHBONE cycle output
.m_wb_stb_o ( h_stb_o ), // WISHBONE strobe output
.m_wb_ack_i ( h_ack_i ), // WISHBONE acknowledge input
*/
// 2D accelerated Geometry unit IO access.
.RD_PX_CTR ( collision_rd ), // COPY READ PIXEL collision counter from pixel_writer.
.WR_PX_CTR ( collision_wr ), // WRITE PIXEL collision counter from pixel_writer.
.RD_PX_CTR_STROBE ( rd_px_ctr_rs ), // Active HIGH, signals GEOFF to reset READ PIXEL collision counter.
.WR_PX_CTR_STROBE ( wr_px_ctr_rs ) // Active HIGH, signals GEOFF to reset WRITE PIXEL collision counter.
);
// ***************************************************************************************************************
// ***************************************************************************************************************
// *** Host IO Addresses *****************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
parameter bit [7:0] MMU_A0 = 'h38 ; // IO address for Bank 0 setting
parameter bit [7:0] MMU_A1 = 'h39 ; // IO address for Bank 1 setting
parameter bit [7:0] MMU_A2 = 'h3A ; // IO address for Bank 2 setting
parameter bit [7:0] MMU_A3 = 'h3B ; // IO address for Bank 3 setting
parameter bit [7:0] MMU_EN = 'h3C ; // IO address for MMU enable
//
parameter bit [7:0] FPU_A = 'hDE ; // IO address for FPU interface - Input A, low-byte of 32-bit input.
parameter bit [7:0] FPU_B = 'hE3 ; // IO address for FPU interface - Input B, low-byte of 32-bit input.
parameter bit [7:0] FPU_Q = 'hE8 ; // IO address for FPU interface - Output Q, low-byte of 32-bit output.
parameter bit [7:0] FPU_F = 'hED ; // IO address for FPU interface - FP format switch.
//
parameter bit [7:0] PSG_LATCH = 'hEE ; // IO address for PSG LATCH register R/W - write latches register, read returns data
parameter bit [7:0] PSG_WRITE = 'hEF ; // IO address for PSG WRITE port W-only
parameter bit [7:0] SD_STATUS = 'hF0 ; // IO address for SD STATUS register R-only
parameter bit [7:0] SD_SECTOR = 'hF1 ; // IO address for SD SECTOR address pipe - R/W (indexed by ARG_PTR)
parameter bit [7:0] SD_MODE = 'hF2 ; // IO address for SD operation trigger - W-only
parameter bit [7:0] SD_ARG_PTR = 'hF3 ; // IO address for SD ARG_PTR - R/W
parameter bit [7:0] GPU_RNG = 'hF5 ; // IO address for GPU random number generator
parameter bit [7:0] GEO_LO = 'hF6 ; // IO address for GEOFF LOW byte.
parameter bit [7:0] GEO_HI = 'hF7 ; // IO address for GEOFF HIGH byte.
parameter bit [7:0] FIFO_STAT = 'hF8 ; // IO address for GPU FIFO status on bit 0 - remaining bits free for other data.
parameter bit [7:0] GPU_ML = 'hF9 ; // IO address for lower 8-bits of the upper 12-bits of the DDR3 address bus
parameter bit [7:0] GPU_MH = 'hFA ; // IO address for upper 4-bits of the upper 12-bits of the DDR3 address bus
// 0xFB-FC and 0xFE are available.
// 0xFD is the hardware port on the uCOM CPU card. 0xFF is CF_EN port, if CompactFlash card is installed in uCOM host.
// ***************************************************************************************************************
// ***************************************************************************************************************
// *** HIPI - Host IO Peripheral Interconnect ********************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
wire [ 1:0] arg_ptr ;
host_IO #(
.MMU_A0 ( MMU_A0 ),
.MMU_A1 ( MMU_A1 ),
.MMU_A2 ( MMU_A2 ),
.MMU_A3 ( MMU_A3 ),
.MMU_EN ( MMU_EN ),
.PSG_LATCH ( PSG_LATCH ),
.PSG_WRITE ( PSG_WRITE ),
.SD_STATUS ( SD_STATUS ),
.SD_SECTOR ( SD_SECTOR ),
.SD_MODE ( SD_MODE ),
.SD_ARG_PTR ( SD_ARG_PTR ),
.GPU_RNG ( GPU_RNG ),
.GPU_ML ( GPU_ML ),
.GPU_MH ( GPU_MH )
) HIPI (
.clk ( CMD_CLK ),
.reset ( reset ),
.WRITE_PORT_DATA ( IO_WR_DATA ),
.WRITE_PORT_STROBE ( IO_WR_STROBE ),
.MMU_AREA ( IO_RD_DATA[MMU_A0:MMU_A3] ),
.MMU_ENABLE ( IO_RD_DATA[MMU_EN] ),
.GPU_MMU_LO ( IO_RD_DATA[GPU_ML] ),
.GPU_MMU_HI ( IO_RD_DATA[GPU_MH] ),
.ARG_PTR ( arg_ptr ),
.SD_sector ( sd_sector ), // 32-bit sector address
.SD_op_ena ( sd_op_req ), // SD transaction request signal
.SD_wr_ena ( sd_wr_ena ), // read/write signal (LOW - read, HIGH - write)
.SD_busy ( sdi_busy ),
.RNG_OUT ( IO_RD_DATA[GPU_RNG] )
);
assign IO_RD_DATA[PSG_LATCH] = psg_data_o ;
always_comb begin
case ( arg_ptr )
2'b00 : IO_RD_DATA[SD_SECTOR] = sd_sector[ 7: 0] ;
2'b01 : IO_RD_DATA[SD_SECTOR] = sd_sector[15: 8] ;
2'b10 : IO_RD_DATA[SD_SECTOR] = sd_sector[23:16] ;
2'b11 : IO_RD_DATA[SD_SECTOR] = sd_sector[31:24] ;
endcase
end
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// *** SID *******************************************************************************************************
// *** SD Card Interface *****************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
wire sd_op_req ; // enable request from Bridgette
wire [1:0] sd_wr_ena ; // SD op mode from Bridgette
wire [31:0] sd_sector ;
wire sdi_busy ;
// Set default signals for SD <-> DDR3 bus
assign CMD_read_vector_in [5] = 0 ;
assign CMD_priority_boost [5] = 0 ;
SDInterface #(
.CLK_DIV ( 3 ),
.BUFFER_ADDR ( 'h5000 )
) SID (
.CLK ( CMD_CLK ), // 125MHz system clock
.RESET ( reset ), // reset active HIGH
// interface <-> Bridgette
// input from Bridgette
.ENABLE ( sd_op_req ), // HIGH to start RD/WR op
.MODE ( sd_wr_ena ), // HIGH for write request
.SECTOR ( sd_sector ), // sector number to read/write
// output to Bridgette
.BUSY ( sdi_busy ), // HIGH when interface is busy read/writing
.SD_STATUS ( IO_RD_DATA[SD_STATUS] ), // aggregated SD status byte
// SD phy connections
.SD_DATA ( SD_DAT ), // data to/from SD card
.SD_CMD ( SD_CMD ), // bidir CMD signal
.SD_CLK ( SD_CLK ), // clock signal to SD card
.SD_CMD_DIR ( SD_CMD_DIR ), // HIGH = TO SD card, LOW = FROM SD card
.SD_D0_DIR ( SD_D0_DIR ), // HIGH = TO SD card, LOW = FROM SD card
.SD_D123_DIR ( SD_D123_DIR ), // HIGH = TO SD card, LOW = FROM SD card
.SD_SEL ( SD_SEL ), // SD select
// DDR3 connections
// input (DDR3 -> SD WR ops)
.DDR3_busy ( CMD_busy [5] ), // HIGH when DDR3 is busy
.DDR3_rd_rdy ( CMD_read_ready [5] ), // data from DDR3 is ready
.DDR3_rd_data ( CMD_read_data [5] ), // read data from DDR3
// output (SD -> DDR3 RD ops)
.DDR3_addr_o ( CMD_addr [5] ),
.DDR3_ena ( CMD_ena [5] ), // Flag HIGH for 1 CMD_CLK when sending a DDR3 command
.DDR3_wr_ena ( CMD_write_ena [5] ), // HIGH signals write request to DDR3 Controller
.DDR3_wr_data ( CMD_wdata [5] ), // 128-bit data bus
.DDR3_wr_mask ( CMD_wmask [5] ) // Write data enable mask
);
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// *** ARYA ******************************************************************************************************
// *** YM2149 PSG Interface **************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
// ***************************************************************************************************************
localparam DDR3_CLK_HZ = (CLK_KHZ_IN*CLK_IN_MULT/CLK_IN_DIV*1000); // Calculate the DDR3 hz speed.
localparam CMD_CLK_HZ = INTERFACE_SPEED[0]=="Q" ? DDR3_CLK_HZ/4 :
INTERFACE_SPEED[0]=="q" ? DDR3_CLK_HZ/4 : DDR3_CLK_HZ/2 ; // Generate the correct CMD_CLK_HZ.
//
wire s0_bclk,s0_wclk,s0_data ;
logic [7:0] r_psg_addr,r_psg_data_i,r_psg_data_o ; // help FMAX routing.
logic r_psg_wr_en ; // help FMAX routing.
always_ff @(posedge CMD_CLK) {r_psg_wr_en,r_psg_addr,r_psg_data_i,psg_data_o}<={IO_WR_STROBE[PSG_WRITE],IO_WR_DATA[PSG_LATCH],IO_WR_DATA[PSG_WRITE],r_psg_data_o}; // help FMAX routing.
YM2149_PSG_system #(