-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathzpu_soc.vhd
2314 lines (2054 loc) · 137 KB
/
zpu_soc.vhd
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
---------------------------------------------------------------------------------------------------------
--
-- Name: zpu_soc.vhd
-- Created: January 2019
-- Author(s): Philip Smart
-- Description: ZPU System On a Chip
-- This module contains the System on a Chip definition for the ZPU.
-- Itś purpose is to provide a functional eco-system around the ZPU to actually perform
-- real tasks. As a basic, boot and stack RAM, UART I/O and Timers are needed to at least
-- present a monitor via UART for interaction. Upon this can be added an SD card for
-- disk storage using the Fat FileSystem, SPI etc. Also, as the Wishbone interface is
-- used in the Evo CPU, any number of 3rd party device IP Cores can be added relatively
-- easily.
--
-- Credits:
-- Copyright: (c) 2018 Philip Smart <[email protected]>
--
-- History: January 2019 - Initial creation.
--
---------------------------------------------------------------------------------------------------------
-- This source file is free software: you can redistribute it and-or modify
-- it under the terms of the GNU General Public License as published
-- by the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This source file is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http:--www.gnu.org-licenses->.
---------------------------------------------------------------------------------------------------------
library ieee;
library pkgs;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.zpu_soc_pkg.all;
use work.zpu_pkg.all;
entity zpu_soc is
generic (
SYSCLK_FREQUENCY : integer := SYSTEM_FREQUENCY -- System clock frequency
);
port (
-- Global Control --
SYSCLK : in std_logic; -- System clock, running at frequency indicated in SYSCLK_FREQUENCY
MEMCLK : in std_logic; -- Memory clock, running at twice frequency indicated in SYSCLK_FREQUENCY
RESET_IN : in std_logic;
-- UART 0 & 1
UART_RX_0 : in std_logic;
UART_TX_0 : out std_logic;
UART_RX_1 : in std_logic;
UART_TX_1 : out std_logic;
-- SPI signals
-- SPI_MISO : in std_logic := '1'; -- Allow the SPI interface not to be plumbed in.
-- SPI_MOSI : out std_logic;
-- SPI_CLK : out std_logic;
-- SPI_CS : out std_logic;
-- SD Card (SPI) signals
SDCARD_MISO : in std_logic_vector(SOC_SD_DEVICES-1 downto 0) := (others => '1');
SDCARD_MOSI : out std_logic_vector(SOC_SD_DEVICES-1 downto 0);
SDCARD_CLK : out std_logic_vector(SOC_SD_DEVICES-1 downto 0);
SDCARD_CS : out std_logic_vector(SOC_SD_DEVICES-1 downto 0);
-- -- PS/2 signals
-- PS2K_CLK_IN : in std_logic := '1';
-- PS2K_DAT_IN : in std_logic := '1';
-- PS2K_CLK_OUT : out std_logic;
-- PS2K_DAT_OUT : out std_logic;
-- PS2M_CLK_IN : in std_logic := '1';
-- PS2M_DAT_IN : in std_logic := '1';
-- PS2M_CLK_OUT : out std_logic;
-- PS2M_DAT_OUT : out std_logic;
-- -- I²C signals
-- I2C_SCL_IO : inout std_logic;
-- I2C_SDA_IO : inout std_logic;
-- -- IOCTL Bus
-- IOCTL_DOWNLOAD : out std_logic; -- Downloading to FPGA.
-- IOCTL_UPLOAD : out std_logic; -- Uploading from FPGA.
-- IOCTL_CLK : out std_logic; -- I/O Clock.
-- IOCTL_WR : out std_logic; -- Write Enable to FPGA.
-- IOCTL_RD : out std_logic; -- Read Enable from FPGA.
-- IOCTL_SENSE : in std_logic; -- Sense to see if HPS accessing ioctl bus.
-- IOCTL_SELECT : out std_logic; -- Enable IOP control over ioctl bus.
-- IOCTL_ADDR : out std_logic_vector(24 downto 0); -- Address in FPGA to write into.
-- IOCTL_DOUT : out std_logic_vector(31 downto 0); -- Data to be written into FPGA.
-- IOCTL_DIN : in std_logic_vector(31 downto 0); -- Data to be read into HPS.
-- SDRAM signals
SDRAM_CLK : out std_logic; -- sdram is accessed at 100MHz
SDRAM_CKE : out std_logic; -- clock enable.
SDRAM_DQ : inout std_logic_vector(15 downto 0); -- 16 bit bidirectional data bus
SDRAM_ADDR : out std_logic_vector(11 downto 0); -- 12 bit multiplexed address bus
SDRAM_DQM : out std_logic_vector(1 downto 0); -- two byte masks
SDRAM_BA : out std_logic_vector(1 downto 0); -- two banks
SDRAM_CS_n : out std_logic; -- a single chip select
SDRAM_WE_n : out std_logic; -- write enable
SDRAM_RAS_n : out std_logic; -- row address select
SDRAM_CAS_n : out std_logic; -- columns address select
SDRAM_READY : out std_logic; -- sd ready.
-- TCPU signals.
TCPU_DATA : out std_logic_vector(15 downto 0); -- Data bus
TCPU_CTL_SET_n : out std_logic; -- Set the transceiver control signals.
TCPU_CLK_n : in std_logic; -- Z80 Main Clock
TCPU_NMI_n : in std_logic; -- Z80 NMI converted to 3.3v
TCPU_INT_n : in std_logic; -- Z80 INT converted to 3.,3v
TCPU_WAIT_I_n : in std_logic; -- Z80 Wait converted to 3.3v.
TCPU_BUSACK_I_n : in std_logic; -- Z80 Bus Ack converted to 3.3v.
TCPU_BUSACK_n : out std_logic; -- CYC sending BUS ACK
TCPU_BUSRQ_n : out std_logic; -- CYC requesting Z80 bus.
TCPU_BUSRQ_I_n : in std_logic -- System requesting Z80 bus.
);
end entity;
architecture rtl of zpu_soc is
-- FSM States for the SD card to interface with the controller.
type SDStateType is
(
SD_STATE_IDLE,
SD_STATE_RESET,
SD_STATE_RESET_1,
SD_STATE_WRITE,
SD_STATE_WRITE_1,
SD_STATE_WRITE_2,
SD_STATE_READ,
SD_STATE_READ_1,
SD_STATE_READ_2
);
-- Reset processing.
signal RESET_n : std_logic := '0';
signal RESET_COUNTER : unsigned(15 downto 0);
signal RESET_COUNTER_RX : unsigned(15 downto 0);
-- Millisecond counter
signal MICROSEC_DOWN_COUNTER : unsigned(23 downto 0); -- Allow for 16 seconds delay.
signal MILLISEC_DOWN_COUNTER : unsigned(17 downto 0); -- Allow for 262 seconds delay.
signal MILLISEC_UP_COUNTER : unsigned(31 downto 0); -- Up counter allowing for 49 days count in milliseconds.
signal SECOND_DOWN_COUNTER : unsigned(11 downto 0); -- Allow for 1 hour in seconds delay.
signal MICROSEC_DOWN_TICK : integer range 0 to 150; -- Independent tick register to ensure down counter is accurate.
signal MILLISEC_DOWN_TICK : integer range 0 to 150*1000; -- Independent tick register to ensure down counter is accurate.
signal SECOND_DOWN_TICK : integer range 0 to 150*1000000; -- Independent tick register to ensure down counter is accurate.
signal MILLISEC_UP_TICK : integer range 0 to 150*1000; -- Independent tick register to ensure up counter is accurate.
signal MICROSEC_DOWN_INTR : std_logic; -- Interrupt when counter reaches 0.
signal MICROSEC_DOWN_INTR_EN : std_logic; -- Interrupt enable for microsecond down counter.
signal MILLISEC_DOWN_INTR : std_logic; -- Interrupt when counter reaches 0.
signal MILLISEC_DOWN_INTR_EN : std_logic; -- Interrupt enable for millisecond down counter.
signal SECOND_DOWN_INTR : std_logic; -- Interrupt when counter reaches 0.
signal SECOND_DOWN_INTR_EN : std_logic; -- Interrupt enable for second down counter.
signal RTC_MICROSEC_TICK : integer range 0 to 150; -- Allow for frequencies upto 150MHz.
signal RTC_MICROSEC_COUNTER : integer range 0 to 1000; -- Real Time Clock counters.
signal RTC_MILLISEC_COUNTER : integer range 0 to 1000;
signal RTC_SECOND_COUNTER : integer range 0 to 60;
signal RTC_MINUTE_COUNTER : integer range 0 to 60;
signal RTC_HOUR_COUNTER : integer range 0 to 24;
signal RTC_DAY_COUNTER : integer range 1 to 32;
signal RTC_MONTH_COUNTER : integer range 1 to 13;
signal RTC_YEAR_COUNTER : integer range 0 to 4095;
signal RTC_TICK_HALT : std_logic;
-- Timer register block signals
signal TIMER_REG_REQ : std_logic;
signal TIMER1_TICK : std_logic;
-- -- SPI Clock counter
-- signal SPI_TICK : unsigned(8 downto 0);
-- signal SPICLK_IN : std_logic;
-- signal SPI_FAST : std_logic;
-- -- SPI signals
-- signal HOST_TO_SPI : std_logic_vector(7 downto 0);
-- signal SPI_TO_HOST : std_logic_vector(31 downto 0);
-- signal SPI_WIDE : std_logic;
-- signal SPI_TRIGGER : std_logic;
-- signal SPI_BUSY : std_logic;
-- signal SPI_ACTIVE : std_logic;
-- SD Card signals
type SDAddrArray is array(natural range 0 to SOC_SD_DEVICES-1) of std_logic_vector(WORD_32BIT_RANGE);
type SDDataArray is array(natural range 0 to SOC_SD_DEVICES-1) of std_logic_vector(7 downto 0);
type SDErrorArray is array(natural range 0 to SOC_SD_DEVICES-1) of std_logic_vector(15 downto 0);
--
signal SD_RESET : std_logic_vector(SOC_SD_DEVICES-1 downto 0); -- active-high, synchronous reset.
signal SD_RD : std_logic_vector(SOC_SD_DEVICES-1 downto 0); -- active-high read block request.
signal SD_WR : std_logic_vector(SOC_SD_DEVICES-1 downto 0); -- active-high write block request.
signal SD_CONTINUE : std_logic_vector(SOC_SD_DEVICES-1 downto 0); -- If true, inc address and continue R/W.
signal SD_CARD_TYPE : std_logic_vector(SOC_SD_DEVICES-1 downto 0); -- Type of card, 0 = SD, 1 = SDHC
signal SD_ADDR : SDAddrArray; -- Block address.
signal SD_DATA_READ : SDDataArray; -- Data read from block.
signal SD_DATA_WRITE : std_logic_vector(7 downto 0); -- Data byte to write to block.
signal SD_DATA_VALID : std_logic; -- Flag to indicate when data has been received (rx).
signal SD_DATA_REQ : std_logic; -- Flag to indicate when data is valid for tx.
signal SD_CHANNEL : integer range 0 to SOC_SD_DEVICES-1; -- Active channel in the state machine.
signal SD_BUSY : std_logic_vector(SOC_SD_DEVICES-1 downto 0); -- High when controller is busy performing some operation.
signal SD_HNDSHK_IN : std_logic_vector(SOC_SD_DEVICES-1 downto 0); -- High when host has data to give or has taken data.
signal SD_HNDSHK_OUT : std_logic_vector(SOC_SD_DEVICES-1 downto 0); -- High when controller has taken data or has data to give.
signal SD_ERROR : SDErrorArray; -- Card error occurred (1).
signal SD_OVERRUN : std_logic; -- Receive data overrun flag.
signal SD_STATE : SDStateType; -- State machine states.
signal SD_RESET_TIMER : integer range 0 to 100; -- 100ns reset timer, allows for SYSFREQ = 10 .. 100MHz.
-- UART signals
signal UART0_WR : std_logic;
signal UART0_ADDR : std_logic;
signal UART0_DATA_OUT : std_logic_vector(31 downto 0);
signal UART0_TX_INTR : std_logic;
signal UART0_RX_INTR : std_logic;
signal UART1_WR : std_logic;
signal UART1_ADDR : std_logic;
signal UART1_DATA_OUT : std_logic_vector(31 downto 0);
signal UART1_TX_INTR : std_logic;
signal UART1_RX_INTR : std_logic;
signal UART1_TX : std_logic;
signal UART2_TX : std_logic;
-- -- PS2 signals
-- signal PS2_INT : std_logic;
-- -- PS2 Keyboard Signals.
-- signal KBD_IDLE : std_logic;
-- signal KBD_RECV : std_logic;
-- signal KBD_RECV_REG : std_logic;
-- signal KBD_SEND_BUSY : std_logic;
-- signal KBD_SEND_TRIGGER : std_logic;
-- signal KBD_SEND_DONE : std_logic;
-- signal KBD_SEND_BYTE : std_logic_vector(7 downto 0);
-- signal KBD_RECV_BYTE : std_logic_vector(10 downto 0);
-- -- I²C Signals.
-- signal SCL_PAD_IN : std_logic; -- i2c clock line input
-- signal SCL_PAD_OUT : std_logic; -- i2c clock line output
-- signal SCL_PAD_OE : std_logic; -- i2c clock line output enable, active low
-- signal SDA_PAD_IN : std_logic; -- i2c data line input
-- signal SDA_PAD_OUT : std_logic; -- i2c data line output
-- signal SDA_PAD_OE : std_logic; -- i2c data line output enable, active low
-- signal WB_DATA_READ_I2C : std_logic_vector(WORD_32BIT_RANGE); -- i2c data as 32bit word for placing on WB bus.
-- signal WB_I2C_ACK : std_logic;
-- signal WB_I2C_HALT : std_logic;
-- signal WB_I2C_ERR : std_logic;
-- signal WB_I2C_CS : std_logic;
-- signal WB_I2C_IRQ : std_logic;
-- Wishbone control signals.
signal WB_SDRAM_ACK : std_logic;
signal WB_SDRAM_STB : std_logic;
signal WB_DATA_READ_SDRAM : std_logic_vector(WORD_32BIT_RANGE);
signal WB_SDRAM_SELECT : std_logic;
signal WB_SDRAM_WREN : std_logic;
signal SRD : std_logic;
signal SWR : std_logic;
signal dataMask : std_logic_vector(3 downto 0);
signal dataWord : std_logic_vector(31 downto 0);
-- ZPU signals
signal MEM_BUSY : std_logic;
signal IO_WAIT_SD : std_logic;
-- signal IO_WAIT_SPI : std_logic;
-- signal IO_WAIT_PS2 : std_logic;
signal IO_WAIT_INTR : std_logic;
signal IO_WAIT_TIMER1 : std_logic;
signal MEM_DATA_READ : std_logic_vector(WORD_32BIT_RANGE);
signal MEM_DATA_WRITE : std_logic_vector(WORD_32BIT_RANGE);
signal MEM_ADDR : std_logic_vector(ADDR_BIT_RANGE);
signal MEM_WRITE_ENABLE : std_logic;
signal MEM_WRITE_BYTE_ENABLE : std_logic;
signal MEM_WRITE_HWORD_ENABLE : std_logic;
signal MEM_READ_ENABLE : std_logic;
signal MEM_READ_ENABLE_LAST : std_logic;
signal MEM_DATA_READ_INSN : std_logic_vector(WORD_32BIT_RANGE);
signal MEM_ADDR_INSN : std_logic_vector(ADDR_BIT_RANGE);
signal MEM_READ_ENABLE_INSN : std_logic;
signal IO_DATA_READ : std_logic_vector(WORD_32BIT_RANGE);
-- signal IO_DATA_READ_SPI : std_logic_vector(WORD_32BIT_RANGE);
signal IO_DATA_READ_SD : std_logic_vector(WORD_32BIT_RANGE);
-- signal IO_DATA_READ_PS2 : std_logic_vector(WORD_32BIT_RANGE);
signal IO_DATA_READ_INTRCTL : std_logic_vector(WORD_32BIT_RANGE);
signal IO_DATA_READ_SOCCFG : std_logic_vector(WORD_32BIT_RANGE);
signal IO_DATA_READ_TCPU : std_logic_vector(WORD_32BIT_RANGE);
-- ZPU ROM/BRAM/RAM/Stack signals.
signal MEM_A_WRITE_ENABLE : std_logic;
signal MEM_A_ADDR : std_logic_vector(ADDR_32BIT_RANGE);
signal MEM_A_WRITE : std_logic_vector(WORD_32BIT_RANGE);
signal MEM_B_WRITE_ENABLE : std_logic;
signal MEM_B_ADDR : std_logic_vector(ADDR_32BIT_RANGE);
signal MEM_B_WRITE : std_logic_vector(WORD_32BIT_RANGE);
signal MEM_A_READ : std_logic_vector(WORD_32BIT_RANGE);
signal MEM_B_READ : std_logic_vector(WORD_32BIT_RANGE);
-- Master Wishbone Memory/IO bus interface.
signal WB_CLK_I : std_logic;
signal WB_RST_I : std_logic;
signal WB_ACK_I : std_logic;
signal WB_DAT_I : std_logic_vector(WORD_32BIT_RANGE);
signal WB_DAT_O : std_logic_vector(WORD_32BIT_RANGE);
signal WB_ADR_O : std_logic_vector(ADDR_BIT_RANGE);
signal WB_CYC_O : std_logic;
signal WB_STB_O : std_logic;
signal WB_CTI_O : std_logic_vector(2 downto 0);
signal WB_WE_O : std_logic;
signal WB_SEL_O : std_logic_vector(WORD_4BYTE_RANGE);
signal WB_HALT_I : std_logic;
signal WB_ERR_I : std_logic;
signal WB_INTA_I : std_logic;
-- Interrupt signals
signal INT_TRIGGERS : std_logic_vector(SOC_INTR_MAX downto 0);
signal INT_ENABLE : std_logic_vector(SOC_INTR_MAX downto 0);
signal INT_STATUS : std_logic_vector(SOC_INTR_MAX downto 0);
signal INT_REQ : std_logic;
signal INT_TRIGGER : std_logic;
signal INT_ACK : std_logic;
signal INT_DONE : std_logic;
-- ZPU ROM/BRAM/RAM
signal BRAM_SELECT : std_logic;
signal RAM_SELECT : std_logic;
signal SDRAM_SELECT : std_logic;
signal BRAM_WREN : std_logic;
signal RAM_WREN : std_logic;
signal SDRAM_WREN : std_logic;
signal SDRAM_RDEN : std_logic;
signal SDRAM_MEM_BUSY : std_logic;
signal BRAM_DATA_READ : std_logic_vector(WORD_32BIT_RANGE);
signal RAM_DATA_READ : std_logic_vector(WORD_32BIT_RANGE);
signal SDRAM_DATA_READ : std_logic_vector(WORD_32BIT_RANGE);
-- IO Chip selects
signal IO_SELECT : std_logic; -- IO Range 0x<msb=0>7FFFFxxx of devices connected to the ZPU system bus.
signal WB_IO_SELECT : std_logic; -- IO Range of the ZPU CPU 0x<msb=1>F00000 .. 0x<nsb=1>FFFFFF
signal WB_IO_SOC_SELECT : std_logic; -- IO Range used within the SoC for small devices, upto 256 locations per device. 0x<msb=1>1F000xx
signal IO_UART_SELECT : std_logic; -- Uart Range 0xFFFFFAxx
signal IO_INTR_SELECT : std_logic; -- Interrupt Range 0xFFFFFBxx
signal IO_TIMER_SELECT : std_logic; -- Timer Range 0xFFFFFCxx
-- signal IO_SPI_SELECT : std_logic; -- SPI Range 0xFFFFFDxx
-- signal IO_PS2_SELECT : std_logic; -- PS2 Range 0xFFFFFExx
signal TCPU_CS : std_logic; -- 0x700-80F
signal SD_CS : std_logic; -- 0x900-93F
signal UART0_CS : std_logic; -- 0xA00-C0F
signal UART1_CS : std_logic; -- 0xA10-A1F
signal INTR0_CS : std_logic; -- 0xB00-B0F
signal TIMER0_CS : std_logic; -- 0xC00-C0F Millisecond timer.
signal TIMER1_CS : std_logic; -- 0xC10-C1F
-- signal SPI0_CS : std_logic; -- 0xD00-D0F
-- signal PS2_CS : std_logic; -- 0xE00-E0F
signal SOCCFG_CS : std_logic; -- 0xF00-F0F
function to_std_logic(L: boolean) return std_logic is
begin
if L then
return('1');
else
return('0');
end if;
end function to_std_logic;
begin
--
-- Instantiation
--
-- Main CPU
ZPUFLEX: if ZPU_FLEX = 1 generate
ZPU0 : zpu_core_flex
generic map (
IMPL_MULTIPLY => true,
IMPL_COMPARISON_SUB => true,
IMPL_EQBRANCH => true,
IMPL_STOREBH => false,
IMPL_LOADBH => false,
IMPL_CALL => true,
IMPL_SHIFT => true,
IMPL_XOR => true,
CACHE => true,
-- IMPL_EMULATION => minimal,
-- REMAP_STACK => false --true, -- We need to remap the Boot ROM / Stack RAM so we can access SDRAM
CLK_FREQ => SYSCLK_FREQUENCY,
STACK_ADDR => SOC_STACK_ADDR -- Initial stack address on CPU start.
)
port map (
clk => SYSCLK,
reset => not RESET_n,
enable => '1',
in_mem_busy => MEM_BUSY,
mem_read => MEM_DATA_READ,
mem_write => MEM_DATA_WRITE,
out_mem_addr => MEM_ADDR,
out_mem_writeEnable => MEM_WRITE_ENABLE,
out_mem_hEnable => MEM_WRITE_HWORD_ENABLE,
out_mem_bEnable => MEM_WRITE_BYTE_ENABLE,
out_mem_readEnable => MEM_READ_ENABLE,
interrupt_request => INT_TRIGGER,
interrupt_ack => INT_ACK, -- Interrupt acknowledge, ZPU has entered Interrupt Service Routine.
interrupt_done => INT_DONE, -- Interrupt service routine completed/done.
break => open,
debug_txd => UART2_TX, -- Debug serial output.
--
MEM_A_WRITE_ENABLE => MEM_A_WRITE_ENABLE,
MEM_A_ADDR => MEM_A_ADDR,
MEM_A_WRITE => MEM_A_WRITE,
MEM_B_WRITE_ENABLE => MEM_B_WRITE_ENABLE,
MEM_B_ADDR => MEM_B_ADDR,
MEM_B_WRITE => MEM_B_WRITE,
MEM_A_READ => MEM_A_READ,
MEM_B_READ => MEM_B_READ
);
end generate;
ZPUSMALL: if ZPU_SMALL = 1 generate
ZPU0 : zpu_core_small
generic map (
CLK_FREQ => SYSCLK_FREQUENCY,
STACK_ADDR => SOC_STACK_ADDR -- Initial stack address on CPU start.
)
port map (
clk => SYSCLK,
areset => not RESET_n,
enable => '1',
in_mem_busy => MEM_BUSY,
mem_read => MEM_DATA_READ,
mem_write => MEM_DATA_WRITE,
out_mem_addr => MEM_ADDR,
out_mem_writeEnable => MEM_WRITE_ENABLE,
out_mem_hEnable => MEM_WRITE_HWORD_ENABLE,
out_mem_bEnable => MEM_WRITE_BYTE_ENABLE,
out_mem_readEnable => MEM_READ_ENABLE,
mem_writeMask => open,
interrupt_request => INT_TRIGGER,
interrupt_ack => INT_ACK, -- Interrupt acknowledge, ZPU has entered Interrupt Service Routine.
interrupt_done => INT_DONE, -- Interrupt service routine completed/done.
break => open,
debug_txd => UART2_TX, -- Debug serial output.
MEM_A_WRITE_ENABLE => MEM_A_WRITE_ENABLE,
MEM_A_ADDR => MEM_A_ADDR,
MEM_A_WRITE => MEM_A_WRITE,
MEM_B_WRITE_ENABLE => MEM_B_WRITE_ENABLE,
MEM_B_ADDR => MEM_B_ADDR,
MEM_B_WRITE => MEM_B_WRITE,
MEM_A_READ => MEM_A_READ,
MEM_B_READ => MEM_B_READ
);
end generate;
ZPUMEDIUM: if ZPU_MEDIUM = 1 generate
ZPU0 : zpu_core_medium
generic map (
CLK_FREQ => SYSCLK_FREQUENCY,
STACK_ADDR => SOC_STACK_ADDR -- Initial stack address on CPU start.
)
port map (
clk => SYSCLK,
areset => not RESET_n,
enable => '1',
in_mem_busy => MEM_BUSY,
mem_read => MEM_DATA_READ,
mem_write => MEM_DATA_WRITE,
out_mem_addr => MEM_ADDR,
out_mem_writeEnable => MEM_WRITE_ENABLE,
out_mem_hEnable => MEM_WRITE_HWORD_ENABLE,
out_mem_bEnable => MEM_WRITE_BYTE_ENABLE,
out_mem_readEnable => MEM_READ_ENABLE,
mem_writeMask => open,
interrupt_request => INT_TRIGGER,
interrupt_ack => INT_ACK, -- Interrupt acknowledge, ZPU has entered Interrupt Service Routine.
interrupt_done => INT_DONE, -- Interrupt service routine completed/done.
break => open,
debug_txd => UART2_TX -- Debug serial output.
);
end generate;
ZPUEVO: if ZPU_EVO = 1 generate
ZPU0 : zpu_core_evo
generic map (
-- Optional hardware features to be implemented.
IMPL_HW_BYTE_WRITE => EVO_USE_HW_BYTE_WRITE, -- Enable use of hardware direct byte write rather than read 33bits-modify 8 bits-write 32bits.
IMPL_HW_WORD_WRITE => EVO_USE_HW_WORD_WRITE, -- Enable use of hardware direct byte write rather than read 32bits-modify 16 bits-write 32bits.
IMPL_OPTIMIZE_IM => IMPL_EVO_OPTIMIZE_IM, -- If the instruction cache is enabled, optimise Im instructions to gain speed.
IMPL_USE_INSN_BUS => SOC_IMPL_INSN_BRAM, -- Use a seperate bus to read instruction memory, normally implemented in BRAM.
IMPL_USE_WB_BUS => EVO_USE_WB_BUS, -- Use the wishbone interface in addition to direct access bus.
-- Optional instructions to be implemented in hardware:
IMPL_ASHIFTLEFT => IMPL_EVO_ASHIFTLEFT, -- Arithmetic Shift Left (uses same logic so normally combined with ASHIFTRIGHT and LSHIFTRIGHT).
IMPL_ASHIFTRIGHT => IMPL_EVO_ASHIFTRIGHT, -- Arithmetic Shift Right.
IMPL_CALL => IMPL_EVO_CALL, -- Call to direct address.
IMPL_CALLPCREL => IMPL_EVO_CALLPCREL, -- Call to indirect address (add offset to program counter).
IMPL_DIV => IMPL_EVO_DIV, -- 32bit signed division.
IMPL_EQ => IMPL_EVO_EQ, -- Equality test.
IMPL_EXTENDED_INSN => IMPL_EVO_EXTENDED_INSN, -- Extended multibyte instruction set.
IMPL_FIADD32 => IMPL_EVO_FIADD32, -- Fixed point Q17.15 addition.
IMPL_FIDIV32 => IMPL_EVO_FIDIV32, -- Fixed point Q17.15 division.
IMPL_FIMULT32 => IMPL_EVO_FIMULT32, -- Fixed point Q17.15 multiplication.
IMPL_LOADB => IMPL_EVO_LOADB, -- Load single byte from memory.
IMPL_LOADH => IMPL_EVO_LOADH, -- Load half word (16bit) from memory.
IMPL_LSHIFTRIGHT => IMPL_EVO_LSHIFTRIGHT, -- Logical shift right.
IMPL_MOD => IMPL_EVO_MOD, -- 32bit modulo (remainder after division).
IMPL_MULT => IMPL_EVO_MULT, -- 32bit signed multiplication.
IMPL_NEG => IMPL_EVO_NEG, -- Negate value in TOS.
IMPL_NEQ => IMPL_EVO_NEQ, -- Not equal test.
IMPL_POPPCREL => IMPL_EVO_POPPCREL, -- Pop a value into the Program Counter from a location relative to the Stack Pointer.
IMPL_PUSHSPADD => IMPL_EVO_PUSHSPADD, -- Add a value to the Stack pointer and push it onto the stack.
IMPL_STOREB => IMPL_EVO_STOREB, -- Store/Write a single byte to memory/IO.
IMPL_STOREH => IMPL_EVO_STOREH, -- Store/Write a half word (16bit) to memory/IO.
IMPL_SUB => IMPL_EVO_SUB, -- 32bit signed subtract.
IMPL_XOR => IMPL_EVO_XOR, -- Exclusive or of value in TOS.
-- Size/Control parameters for the optional hardware.
MAX_INSNRAM_SIZE => (2**(SOC_MAX_ADDR_INSN_BRAM_BIT)), -- Maximum size of the optional instruction BRAM on the INSN Bus.
MAX_L1CACHE_BITS => MAX_EVO_L1CACHE_BITS, -- Maximum size in instructions of the Level 0 instruction cache governed by the number of bits, ie. 8 = 256 instruction cache.
MAX_L2CACHE_BITS => MAX_EVO_L2CACHE_BITS, -- Maximum bit size in bytes of the Level 2 instruction cache governed by the number of bits, ie. 8 = 256 byte cache.
MAX_MXCACHE_BITS => MAX_EVO_MXCACHE_BITS, -- Maximum size of the memory transaction cache governed by the number of bits.
RESET_ADDR_CPU => SOC_RESET_ADDR_CPU, -- Initial start address of the CPU.
START_ADDR_MEM => SOC_START_ADDR_MEM, -- Start address of program memory.
STACK_ADDR => SOC_STACK_ADDR, -- Initial stack address on CPU start.
CLK_FREQ => SYSCLK_FREQUENCY -- System clock frequency.
)
port map (
CLK => SYSCLK,
RESET => not RESET_n,
ENABLE => '1',
MEM_BUSY => MEM_BUSY,
MEM_DATA_IN => MEM_DATA_READ,
MEM_DATA_OUT => MEM_DATA_WRITE,
MEM_ADDR => MEM_ADDR,
MEM_WRITE_ENABLE => MEM_WRITE_ENABLE,
MEM_READ_ENABLE => MEM_READ_ENABLE,
MEM_WRITE_BYTE => MEM_WRITE_BYTE_ENABLE,
MEM_WRITE_HWORD => MEM_WRITE_HWORD_ENABLE,
-- Instruction memory path.
MEM_BUSY_INSN => '0',
MEM_DATA_IN_INSN => MEM_DATA_READ_INSN,
MEM_ADDR_INSN => MEM_ADDR_INSN,
MEM_READ_ENABLE_INSN => MEM_READ_ENABLE_INSN,
-- Master Wishbone Memory/IO bus interface.
WB_CLK_I => WB_CLK_I,
WB_RST_I => not RESET_n,
WB_ACK_I => WB_ACK_I,
WB_DAT_I => WB_DAT_I,
WB_DAT_O => WB_DAT_O,
WB_ADR_O => WB_ADR_O,
WB_CYC_O => WB_CYC_O,
WB_STB_O => WB_STB_O,
WB_CTI_O => WB_CTI_O,
WB_WE_O => WB_WE_O,
WB_SEL_O => WB_SEL_O,
WB_HALT_I => WB_HALT_I,
WB_ERR_I => WB_ERR_I,
WB_INTA_I => WB_INTA_I,
--
INT_REQ => INT_TRIGGER,
INT_ACK => INT_ACK, -- Interrupt acknowledge, ZPU has entered Interrupt Service Routine.
INT_DONE => INT_DONE, -- Interrupt service routine completed/done.
BREAK => open, -- A break instruction encountered.
CONTINUE => '1', -- When break activated, processing stops. Setting CONTINUE to logic 1 resumes processing with next instruction.
DEBUG_TXD => UART2_TX -- Debug serial output.
);
end generate;
ZPUEVOMIN: if ZPU_EVO_MINIMAL = 1 generate
ZPU0 : zpu_core_evo
generic map (
-- Optional hardware features to be implemented.
IMPL_HW_BYTE_WRITE => EVO_USE_HW_BYTE_WRITE, -- Enable use of hardware direct byte write rather than read 33bits-modify 8 bits-write 32bits.
IMPL_HW_WORD_WRITE => EVO_USE_HW_WORD_WRITE, -- Enable use of hardware direct byte write rather than read 32bits-modify 16 bits-write 32bits.
IMPL_OPTIMIZE_IM => IMPL_EVOM_OPTIMIZE_IM, -- If the instruction cache is enabled, optimise Im instructions to gain speed.
IMPL_USE_INSN_BUS => SOC_IMPL_INSN_BRAM, -- Use a seperate bus to read instruction memory, normally implemented in BRAM.
IMPL_USE_WB_BUS => EVO_USE_WB_BUS, -- Use the wishbone interface in addition to direct access bus.
-- Optional instructions to be implemented in hardware:
IMPL_ASHIFTLEFT => IMPL_EVOM_ASHIFTLEFT, -- Arithmetic Shift Left (uses same logic so normally combined with ASHIFTRIGHT and LSHIFTRIGHT).
IMPL_ASHIFTRIGHT => IMPL_EVOM_ASHIFTRIGHT, -- Arithmetic Shift Right.
IMPL_CALL => IMPL_EVOM_CALL, -- Call to direct address.
IMPL_CALLPCREL => IMPL_EVOM_CALLPCREL, -- Call to indirect address (add offset to program counter).
IMPL_DIV => IMPL_EVOM_DIV, -- 32bit signed division.
IMPL_EQ => IMPL_EVOM_EQ, -- Equality test.
IMPL_EXTENDED_INSN => IMPL_EVOM_EXTENDED_INSN, -- Extended multibyte instruction set.
IMPL_FIADD32 => IMPL_EVOM_FIADD32, -- Fixed point Q17.15 addition.
IMPL_FIDIV32 => IMPL_EVOM_FIDIV32, -- Fixed point Q17.15 division.
IMPL_FIMULT32 => IMPL_EVOM_FIMULT32, -- Fixed point Q17.15 multiplication.
IMPL_LOADB => IMPL_EVOM_LOADB, -- Load single byte from memory.
IMPL_LOADH => IMPL_EVOM_LOADH, -- Load half word (16bit) from memory.
IMPL_LSHIFTRIGHT => IMPL_EVOM_LSHIFTRIGHT, -- Logical shift right.
IMPL_MOD => IMPL_EVOM_MOD, -- 32bit modulo (remainder after division).
IMPL_MULT => IMPL_EVOM_MULT, -- 32bit signed multiplication.
IMPL_NEG => IMPL_EVOM_NEG, -- Negate value in TOS.
IMPL_NEQ => IMPL_EVOM_NEQ, -- Not equal test.
IMPL_POPPCREL => IMPL_EVOM_POPPCREL, -- Pop a value into the Program Counter from a location relative to the Stack Pointer.
IMPL_PUSHSPADD => IMPL_EVOM_PUSHSPADD, -- Add a value to the Stack pointer and push it onto the stack.
IMPL_STOREB => IMPL_EVOM_STOREB, -- Store/Write a single byte to memory/IO.
IMPL_STOREH => IMPL_EVOM_STOREH, -- Store/Write a half word (16bit) to memory/IO.
IMPL_SUB => IMPL_EVOM_SUB, -- 32bit signed subtract.
IMPL_XOR => IMPL_EVOM_XOR, -- Exclusive or of value in TOS.
-- Size/Control parameters for the optional hardware.
MAX_INSNRAM_SIZE => (2**(SOC_MAX_ADDR_INSN_BRAM_BIT)), -- Maximum size of the optional instruction BRAM on the INSN Bus.
MAX_L1CACHE_BITS => MAX_EVO_MIN_L1CACHE_BITS, -- Maximum size in instructions of the Level 0 instruction cache governed by the number of bits, ie. 8 = 256 instruction cache.
MAX_L2CACHE_BITS => MAX_EVO_MIN_L2CACHE_BITS, -- Maximum size in bytes of the Level 2 instruction cache governed by the number of bits, ie. 8 = 256 byte cache.
MAX_MXCACHE_BITS => MAX_EVO_MIN_MXCACHE_BITS, -- Maximum size of the memory transaction cache governed by the number of bits.
RESET_ADDR_CPU => SOC_RESET_ADDR_CPU, -- Initial start address of the CPU.
START_ADDR_MEM => SOC_START_ADDR_MEM, -- Start address of program memory.
STACK_ADDR => SOC_STACK_ADDR, -- Initial stack address on CPU start.
CLK_FREQ => SYSCLK_FREQUENCY -- System clock frequency.
)
port map (
CLK => SYSCLK,
RESET => not RESET_n,
ENABLE => '1',
MEM_BUSY => MEM_BUSY,
MEM_DATA_IN => MEM_DATA_READ,
MEM_DATA_OUT => MEM_DATA_WRITE,
MEM_ADDR => MEM_ADDR,
MEM_WRITE_ENABLE => MEM_WRITE_ENABLE,
MEM_READ_ENABLE => MEM_READ_ENABLE,
MEM_WRITE_BYTE => MEM_WRITE_BYTE_ENABLE,
MEM_WRITE_HWORD => MEM_WRITE_HWORD_ENABLE,
-- Instruction memory path.
MEM_BUSY_INSN => '0',
MEM_DATA_IN_INSN => MEM_DATA_READ_INSN,
MEM_ADDR_INSN => MEM_ADDR_INSN,
MEM_READ_ENABLE_INSN => MEM_READ_ENABLE_INSN,
-- Master Wishbone Memory/IO bus interface.
WB_CLK_I => WB_CLK_I,
WB_RST_I => not RESET_n,
WB_ACK_I => WB_ACK_I,
WB_DAT_I => WB_DAT_I,
WB_DAT_O => WB_DAT_O,
WB_ADR_O => WB_ADR_O,
WB_CYC_O => WB_CYC_O,
WB_STB_O => WB_STB_O,
WB_CTI_O => WB_CTI_O,
WB_WE_O => WB_WE_O,
WB_SEL_O => WB_SEL_O,
WB_HALT_I => WB_HALT_I,
WB_ERR_I => WB_ERR_I,
WB_INTA_I => WB_INTA_I,
--
INT_REQ => INT_TRIGGER,
INT_ACK => INT_ACK, -- Interrupt acknowledge, ZPU has entered Interrupt Service Routine.
INT_DONE => INT_DONE, -- Interrupt service routine completed/done.
BREAK => open, -- A break instruction encountered.
CONTINUE => '1', -- When break activated, processing stops. Setting CONTINUE to logic 1 resumes processing with next instruction.
DEBUG_TXD => UART2_TX -- Debug serial output.
);
end generate;
-- ROM
ZPUROMSMALL : if (ZPU_SMALL = 1 or ZPU_FLEX = 1) and SOC_IMPL_BRAM = true generate
ZPUROM : entity work.BootROM
port map (
clk => SYSCLK,
memAWriteEnable => MEM_A_WRITE_ENABLE,
memAAddr => MEM_A_ADDR(ADDR_32BIT_BRAM_RANGE),
memAWrite => MEM_A_WRITE,
memBWriteEnable => MEM_B_WRITE_ENABLE,
memBAddr => MEM_B_ADDR(ADDR_32BIT_BRAM_RANGE),
memBWrite => MEM_B_WRITE,
memARead => MEM_A_READ,
memBRead => MEM_B_READ
);
end generate;
-- This block should provide byte addressable dual port BRAM for the Flex but for some reason Quartus quarks when compiling when the B port is used for writes. Not sure why
-- but needs revisiting as it will gain some performance improvements for the flex core.
--ZPUROMFLEX : if ZPU_FLEX = 1 and SOC_IMPL_BRAM = true generate
-- ZPUROM : entity work.DualPortBootBRAM
-- generic map (
-- addrbits => SOC_MAX_ADDR_BRAM_BIT
-- )
-- port map (
-- clk => SYSCLK,
-- memAAddr => MEM_A_ADDR(17 downto 2),
-- memAWriteEnable => MEM_A_WRITE_ENABLE,
-- memAWriteByte => MEM_WRITE_BYTE_ENABLE,
-- memAWriteHalfWord => MEM_WRITE_HWORD_ENABLE,
-- memAWrite => MEM_A_WRITE,
-- memARead => MEM_A_READ,
-- memBAddr => MEM_B_ADDR(ADDR_32BIT_BRAM_RANGE),
-- memBWrite => MEM_B_WRITE,
-- memBWriteEnable => MEM_B_WRITE_ENABLE,
-- memBRead => MEM_B_READ
-- );
--end generate;
ZPUROMMEDIUM : if ZPU_MEDIUM = 1 and SOC_IMPL_BRAM = true generate
ZPUROM : entity work.BootROM
port map (
clk => SYSCLK,
memAWriteEnable => BRAM_WREN,
memAAddr => MEM_ADDR(ADDR_32BIT_BRAM_RANGE),
memAWrite => MEM_DATA_WRITE,
memBWriteEnable => '0',
memBAddr => MEM_ADDR(ADDR_32BIT_BRAM_RANGE),
memBWrite => (others => '0'),
memARead => open,
memBRead => BRAM_DATA_READ
);
end generate;
-- Evo system BRAM, dual port to allow for seperate instruction bus read.
ZPUDPBRAMEVO : if (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and SOC_IMPL_INSN_BRAM = true and SOC_IMPL_BRAM = true generate
ZPUBRAM : entity work.DualPortBootBRAM
generic map (
addrbits => SOC_MAX_ADDR_BRAM_BIT
)
port map (
clk => SYSCLK,
memAAddr => MEM_ADDR(ADDR_BIT_BRAM_RANGE),
memAWriteEnable => BRAM_WREN,
memAWriteByte => MEM_WRITE_BYTE_ENABLE,
memAWriteHalfWord => MEM_WRITE_HWORD_ENABLE,
memAWrite => MEM_DATA_WRITE,
memARead => BRAM_DATA_READ,
memBAddr => MEM_ADDR_INSN(ADDR_32BIT_BRAM_RANGE),
memBWrite => (others => '0'),
memBWriteEnable => '0',
memBRead => MEM_DATA_READ_INSN
);
end generate;
-- Evo system BRAM, single port as no seperate instruction bus configured.
ZPUBRAMEVO : if (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and SOC_IMPL_INSN_BRAM = false and SOC_IMPL_BRAM = true generate
ZPUBRAM : entity work.SinglePortBootBRAM
generic map (
addrbits => SOC_MAX_ADDR_BRAM_BIT
)
port map (
clk => SYSCLK,
memAAddr => MEM_ADDR(ADDR_BIT_BRAM_RANGE),
memAWriteEnable => BRAM_WREN,
memAWriteByte => MEM_WRITE_BYTE_ENABLE,
memAWriteHalfWord => MEM_WRITE_HWORD_ENABLE,
memAWrite => MEM_DATA_WRITE,
memARead => BRAM_DATA_READ
);
end generate;
-- Evo RAM, a seperate block of RAM created in BRAM in addition to the main system BRAM, generally used for applications and termed RAM in this module.
ZPURAMEVO : if (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and SOC_IMPL_RAM = true generate
ZPURAM : entity work.SinglePortBRAM
generic map (
addrbits => SOC_MAX_ADDR_RAM_BIT
)
port map (
clk => SYSCLK,
memAAddr => MEM_ADDR(ADDR_BIT_RAM_RANGE),
memAWriteEnable => RAM_WREN,
memAWriteByte => MEM_WRITE_BYTE_ENABLE,
memAWriteHalfWord => MEM_WRITE_HWORD_ENABLE,
memAWrite => MEM_DATA_WRITE,
memARead => RAM_DATA_READ
);
-- RAM Range SOC_ADDR_RAM_START) -> SOC_ADDR_RAM_END
RAM_SELECT <= '1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and (MEM_ADDR >= std_logic_vector(to_unsigned(SOC_ADDR_RAM_START, MEM_ADDR'LENGTH)) and MEM_ADDR < std_logic_vector(to_unsigned(SOC_ADDR_RAM_END, MEM_ADDR'LENGTH)))
else '0';
-- Enable write to RAM when selected and CPU in write state.
RAM_WREN <= '1' when RAM_SELECT = '1' and MEM_WRITE_ENABLE = '1'
else '0';
end generate;
-- SDRAM over System bus.
ZPUSDRAMEVO : if (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and SOC_IMPL_SDRAM = true and (BOARD_QMV = true or BOARD_CYC1000 = true) generate
ZPUSDRAM : entity work.SDRAM
generic map (
SDRAM_ROWS => SOC_SDRAM_ROWS, -- Number of Rows in the SDRAM.
SDRAM_COLUMNS => SOC_SDRAM_COLUMNS, -- Number of Columns in an SDRAM page (ie. 1 row).
SDRAM_BANKS => SOC_SDRAM_BANKS, -- Number of banks in the SDRAM.
SDRAM_DATAWIDTH => SOC_SDRAM_DATAWIDTH, -- Data width of SDRAM chip (ie. 16, 32).
SDRAM_CLK_FREQ => SOC_SDRAM_CLK_FREQ, -- Frequency of SDRAM clock in Hertz.
SDRAM_tRCD => SOC_SDRAM_tRCD, -- tRCD - RAS to CAS minimum period (in ns), ie. 20ns -> 2 cycles@100MHz
SDRAM_tRP => SOC_SDRAM_tRP, -- tRP - Precharge delay, min time for a precharge command to complete (in ns), ie. 15ns -> 2 cycles@100MHz
SDRAM_tRFC => SOC_SDRAM_tRFC, -- tRFC - Auto-refresh minimum time to complete (in ns), ie. 66ns
SDRAM_tREF => SOC_SDRAM_tREF -- tREF - period of time a complete refresh of all rows is made within (in ms).
)
port map (
-- SDRAM Interface
SDRAM_CLK => MEMCLK, -- sdram clock running at an offset from system clock.
SDRAM_RST => not RESET_n, -- reset the sdram controller.
SDRAM_CKE => SDRAM_CKE, -- clock enable.
SDRAM_DQ => SDRAM_DQ, -- 16 bit bidirectional data bus
SDRAM_ADDR => SDRAM_ADDR, -- 12 bit multiplexed address bus
SDRAM_DQM => SDRAM_DQM, -- two byte masks
SDRAM_BA => SDRAM_BA, -- two banks
SDRAM_CS_n => SDRAM_CS_n, -- a single chip select
SDRAM_WE_n => SDRAM_WE_n, -- write enable
SDRAM_RAS_n => SDRAM_RAS_n, -- row address select
SDRAM_CAS_n => SDRAM_CAS_n, -- columns address select
SDRAM_READY => SDRAM_READY, -- sd ready.
-- CPU Interface
CLK => SYSCLK, -- System master clock
RESET => not RESET_n, -- high active sync reset
ADDR => MEM_ADDR(ADDR_BIT_SDRAM_RANGE),
DATA_IN => MEM_DATA_WRITE, -- write data
DATA_OUT => SDRAM_DATA_READ, -- read data
WRITE_BYTE => MEM_WRITE_BYTE_ENABLE, -- Write a single byte.
WRITE_HWORD => MEM_WRITE_HWORD_ENABLE, -- Write a 16 bit word.
CS => SDRAM_SELECT, -- Chip Select.
WREN => SDRAM_WREN, -- Write enable.
RDEN => SDRAM_RDEN, -- Read enable.
BUSY => SDRAM_MEM_BUSY
);
---- Replace the SDRAM with a block of BRAM over WishBone, primarily used for testing.
--ZPUSDRAM : entity work.SinglePortBRAM
--generic map (
-- addrbits => 4
--)
--port map (
-- clk => SYSCLK,
-- memAAddr => MEM_ADDR(3 downto 0),
-- memAWriteEnable => SDRAM_WREN,
-- memAWriteByte => MEM_WRITE_BYTE_ENABLE,
-- memAWriteHalfWord => MEM_WRITE_HWORD_ENABLE,
-- memAWrite => MEM_DATA_WRITE,
-- memARead => SDRAM_DATA_READ
--);
-- SDRAM clock based on system clock.
SDRAM_CLK <= MEMCLK;
-- RAM Range SOC_ADDR_SDRAM_START) -> SOC_ADDR_SDRAM_END
SDRAM_SELECT <= '1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and (MEM_ADDR >= std_logic_vector(to_unsigned(SOC_ADDR_SDRAM_START, MEM_ADDR'LENGTH)) and MEM_ADDR < std_logic_vector(to_unsigned(SOC_ADDR_SDRAM_END, MEM_ADDR'LENGTH)))
else '0';
-- Enable write to RAM when selected and CPU in write state.
SDRAM_WREN <= MEM_WRITE_ENABLE when SDRAM_SELECT = '1'
else '0';
SDRAM_RDEN <= MEM_READ_ENABLE ' when SDRAM_SELECT = '1'
else '0';
end generate;
-- Force the CPU to wait when slower memory/IO is accessed and it cant deliver an immediate result.
MEM_BUSY <= '1' when (UART0_CS = '1' or UART1_CS = '1' or TIMER0_CS = '1') and MEM_READ_ENABLE_LAST = '0' and MEM_READ_ENABLE = '1'
else
'1' when SOC_IMPL_SDRAM = true and (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1 or ZPU_MEDIUM = 1) and SDRAM_MEM_BUSY = '1' and (BOARD_QMV = true or BOARD_CYC1000 = true)
else
-- '1' when BRAM_SELECT = '1' and (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and (MEM_READ_ENABLE = '1')
-- else
-- '1' when IO_SELECT = '1' and (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and (MEM_READ_ENABLE = '1')
-- else
'1' when SOC_IMPL_SD = true and SD_CS = '1' and MEM_READ_ENABLE_LAST = '0' and MEM_READ_ENABLE = '1'
else
-- '1' when SOC_IMPL_SPI = true and SPI_CS = '1' and MEM_READ_ENABLE_LAST = '0' and MEM_READ_ENABLE = '1' and IO_WAIT_SPI = '1'
-- else
-- '1' when SOC_IMPL_PS2 = true and PS2_CS = '1' and MEM_READ_ENABLE_LAST = '0' and MEM_READ_ENABLE = '1' and IO_WAIT_PS2 = '1'
-- else
'1' when SOC_IMPL_INTRCTL = true and INTR0_CS = '1' and MEM_READ_ENABLE_LAST = '0' and MEM_READ_ENABLE = '1' and IO_WAIT_INTR = '1'
else
'1' when SOC_IMPL_TIMER1 = true and TIMER1_CS = '1' and MEM_READ_ENABLE_LAST = '0' and MEM_READ_ENABLE = '1' and IO_WAIT_TIMER1 = '1'
else
'1' when SOC_IMPL_SOCCFG = true and SOCCFG_CS = '1' and MEM_READ_ENABLE_LAST = '0' and MEM_READ_ENABLE = '1'
else
-- '1' when SOC_IMPL_TCPU = true and TCPU_CS = '1'
'0';
-- Select CPU input source, memory or IO.
MEM_DATA_READ <= BRAM_DATA_READ when BRAM_SELECT = '1'
else
RAM_DATA_READ when SOC_IMPL_RAM = true and RAM_SELECT = '1'
else
SDRAM_DATA_READ when SOC_IMPL_SDRAM = true and SDRAM_SELECT = '1' and (BOARD_QMV = true or BOARD_CYC1000 = true)
else
IO_DATA_READ_SD when SOC_IMPL_SD = true and SD_CS = '1'
else
-- IO_DATA_READ_SPI when SOC_IMPL_SPI = true and SPI0_CS = '1'
-- else
-- IO_DATA_READ_PS2 when SOC_IMPL_PS2 = true and PS2_CS = '1'
-- else
IO_DATA_READ_INTRCTL when SOC_IMPL_INTRCTL = true and INTR0_CS = '1'
else
IO_DATA_READ_SOCCFG when SOC_IMPL_SOCCFG = true and SOCCFG_CS = '1'
else
IO_DATA_READ_TCPU when SOC_IMPL_TCPU = true and (BOARD_CYC1000 = true) and TCPU_CS = '1'
else
IO_DATA_READ when IO_SELECT = '1'
else
(others => '1');
-- If the wishbone interface is implemented, generate the control and decode logic.
WISHBONE_CTRL: if SOC_IMPL_WB = true generate
WB_DAT_I <= WB_DATA_READ_SDRAM when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and SOC_IMPL_WB_SDRAM = true and WB_SDRAM_STB = '1'
else
-- X"000000" & WB_DATA_READ_I2C(BYTE_RANGE) when SOC_IMPL_WB_I2C = true and WB_I2C_CS = '1'
-- else
(others => '0');
-- Acknowledge is a chain of all enabled device acknowledges as only the addressed device in any given occasion should generate an ACK.
WB_ACK_I <= WB_SDRAM_ACK when SOC_IMPL_WB_SDRAM = true and WB_SDRAM_STB = '1'
-- else
-- WB_I2C_ACK when SOC_IMPL_WB_I2C = true and WB_I2C_CS = '1'
-- access to an unimplemented area of memory, just ACK as there is nothing to handle the request.
else '1';
-- Halt/Wait signal is a chain of all enabled devices requiring additional bus transaction time.
WB_HALT_I <= '0'; -- WB_I2C_HALT when SOC_IMPL_WB_I2C = true and WB_I2C_HALT = '1'
-- Error signal is a chain of all enabled device error condition signals.
WB_ERR_I <= '0'; -- WB_I2C_ERR when SOC_IMPL_WB_I2C = true and WB_I2C_ERR = '1'
-- Interrupt signals are chained with the actual interrupt being stored in the main interrupt controller.
WB_INTA_I <= '0'; -- WB_I2C_IRQ when SOC_IMPL_WB_I2C = true and WB_I2C_IRQ = '1'
-- Like direct I/O, place peripherals in upper range of wishbone address space.
WB_IO_SELECT <= '1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and WB_STB_O = '1' and (WB_ADR_O >= std_logic_vector(to_unsigned(SOC_WB_IO_START, WB_ADR_O'LENGTH)) and WB_ADR_O < std_logic_vector(to_unsigned(SOC_WB_IO_END, WB_ADR_O'LENGTH)))
else '0';
WB_IO_SOC_SELECT <= WB_IO_SELECT when WB_ADR_O(19 downto 12) = X"00"
else '0';
-- WB_I2C_CS <= '1' when WB_IO_SOC_SELECT = '1' and WB_ADR_O(11 downto 8) = "0000" -- I2C Range 0x<msb=1>F000xx
-- else '0';
WB_CLK_I <= SYSCLK;
else generate
WB_DAT_I <= (others => '0');
WB_ACK_I <= '0';
WB_HALT_I <= '0';
WB_ERR_I <= '0';
end generate;
-- Enable write to System BRAM when selected and CPU in write state.
BRAM_WREN <= '1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and MEM_WRITE_ENABLE = '1' and (MEM_ADDR >= std_logic_vector(to_unsigned(SOC_ADDR_BRAM_START, MEM_ADDR'LENGTH)) and MEM_ADDR <= std_logic_vector(to_unsigned(SOC_ADDR_BRAM_END, MEM_ADDR'LENGTH)))
else
'1' when ZPU_MEDIUM = 1 and MEM_WRITE_ENABLE = '1' and MEM_ADDR(ioBit) = '0'
else
'0';
-- -- Were not interested in the mouse, so pass through connection.
-- PS2M_CLK_OUT <= PS2M_CLK_IN;
-- PS2M_DAT_OUT <= PS2M_DAT_IN;
-- Fixed peripheral Decoding.
-- BRAM Range 0x00000000 - (2^SOC_MAX_ADDR_INSN_BRAM_BIT)-1
BRAM_SELECT <= '1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and (MEM_ADDR >= std_logic_vector(to_unsigned(SOC_ADDR_BRAM_START, MEM_ADDR'LENGTH)) and MEM_ADDR < std_logic_vector(to_unsigned(SOC_ADDR_BRAM_END, MEM_ADDR'LENGTH)))
else
'1' when (ZPU_MEDIUM = 1 or ZPU_FLEX = 1 or ZPU_SMALL = 1) and MEM_ADDR(ioBit) = '0'
else '0';
-- IO Range for EVO CPU
IO_SELECT <= '1' when (ZPU_SMALL = 1 or ZPU_MEDIUM = 1 or ZPU_FLEX = 1) and MEM_ADDR(ioBit) = '1' -- IO Range for Small, Medium and Flex CPU
else
-- '1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and MEM_ADDR(IO_DECODE_RANGE) = std_logic_vector(to_unsigned(255, maxAddrBit - maxIOBit)) and MEM_ADDR(maxIOBit -1 downto 12) = std_logic_vector(to_unsigned(0, maxIOBit-12))
'1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and ((SOC_IMPL_WB = true and MEM_ADDR(WB_SELECT_BIT) = '0') or SOC_IMPL_WB = false) and MEM_ADDR(IO_DECODE_RANGE) = std_logic_vector(to_unsigned(255, maxAddrBit-WB_ACTIVE - maxIOBit)) and MEM_ADDR(maxIOBit -1 downto 12) = std_logic_vector(to_unsigned(0, maxIOBit-12))
else '0';
IO_TIMER_SELECT <= '1' when IO_SELECT = '1' and MEM_ADDR(11 downto 8) = X"C" -- Timer Range 0x<msb=0>FFFFCxx
else '0';
UART0_CS <= '1' when IO_SELECT = '1' and MEM_ADDR(11 downto 4) = "10100000" -- Uart Range 0x<msb=0>FFFFAxx, 0xA00-C0F
else '0';
UART1_CS <= '1' when IO_SELECT = '1' and MEM_ADDR(11 downto 4) = "10100001" -- Uart Range 0x<msb=0>FFFFAxx, 0xA10-A1F
else '0';
TIMER0_CS <= '1' when IO_TIMER_SELECT = '1' and MEM_ADDR(7 downto 6) = "00" -- 0xC00-C3F Millisecond timer.
else '0';
SD_CS <= '1' when IO_SELECT = '1' and MEM_ADDR(11 downto 7) = "10010" -- 0x900-90F 0x<msb=0>FFFF9xx, 0x900 - 0x90f First SD Card address range
else '0';
-- Mux the UART debug channel outputs. DBG1 is from the software controlled UART, DBG2 from the cpu channel.
DEBUGUART: if DEBUG_CPU = true generate
UART_TX_1 <= UART2_TX;
else generate
UART_TX_1 <= UART1_TX;
end generate;
------------------------------------------------------------------------------------
-- Direct Memory I/O devices
------------------------------------------------------------------------------------
TIMER : if SOC_IMPL_TIMER1 = true generate
-- TIMER
TIMER1 : entity work.timer_controller
generic map(
prescale => 1, -- Prescale incoming clock
timers => SOC_TIMER1_COUNTERS
)
port map (
clk => SYSCLK,
reset => RESET_n,
reg_addr_in => MEM_ADDR(7 downto 0),
reg_data_in => MEM_DATA_WRITE,
reg_rw => '0', -- we never read from the timers
reg_req => TIMER_REG_REQ,
ticks(0) => TIMER1_TICK -- Tick signal is used to trigger an interrupt
);
process(SYSCLK, RESET_n)
begin
------------------------
-- HIGH LEVEL --
------------------------
------------------------
-- ASYNCHRONOUS RESET --