-
Notifications
You must be signed in to change notification settings - Fork 10
/
TG68KdotC_Kernel.vhd
executable file
·4137 lines (3943 loc) · 130 KB
/
TG68KdotC_Kernel.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
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- --
-- Copyright (c) 2009-2020 Tobias Gubener --
-- Patches by MikeJ, Till Harbaum, Rok Krajnk, ... --
-- Subdesign fAMpIGA by TobiFlex --
-- --
-- This source file is free software: you can redistribute it and/or modify --
-- it under the terms of the GNU Lesser 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/>. --
-- --
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- 14.10.2020 TG bugfix chk2.b
-- 13.10.2020 TG go back to old aligned design and bugfix chk2
-- 11.10.2020 TG next try CHK2 flags
-- 10.10.2020 TG bugfix division N-flag
-- 09.10.2020 TG bugfix division overflow
-- 2/3.10.2020 some tweaks by retrofun, gyurco and robinsonb5
-- 17.03.2020 TG bugfix move data to (extended address)
-- 13.03.2020 TG bugfix extended addess mode - thanks Adam Polkosnik
-- 15.02.2020 TG bugfix DIVS.W with result $8000
-- 08.01.2020 TH fix the byte-mirroring
-- 25.11.2019 TG bugfix ILLEGAL.B handling
-- 24.11.2019 TG next try CMP2 and CHK2.l
-- 24.11.2019 retrofun(RF) commit ILLEGAL.B handling
-- 18.11.2019 TG insert CMP2 and CHK2.l
-- 17.11.2019 TG insert CAS and CAS2
-- 10.11.2019 TG insert TRAPcc
-- 08.11.2019 TG bugfix movem in 68020 mode
-- 06.11.2019 TG bugfix CHK
-- 06.11.2019 TG bugfix flags and stackframe DIVU
-- 04.11.2019 TG insert RTE from TH
-- 03.11.2019 TG insert TrapV from TH
-- 03.11.2019 TG bugfix MUL 64Bit
-- 03.11.2019 TG rework barrel shifter - some other tweaks
-- 02.11.2019 TG bugfig N-Flag and Z-Flag for DIV
-- 30.10.2019 TG bugfix RTR in 68020-mode
-- 30.10.2019 TG bugfix BFINS again
-- 19.10.2019 TG insert some bugfixes from apolkosnik
-- 05.12.2018 TG insert RTD opcode
-- 03.12.2018 TG insert barrel shifter
-- 01.11.2017 TG bugfix V-Flag for ASL/ASR - thanks Peter Graf
-- 29.05.2017 TG decode 0x4AFB as illegal, needed for QL BKP - thanks Peter Graf
-- 21.05.2017 TG insert generic for hardware multiplier for MULU & MULS
-- 04.04.2017 TG change GPL to LGPL
-- 04.04.2017 TG BCD handling with all undefined behavior!
-- 02.04.2017 TG bugfix Bitfield Opcodes
-- 19.03.2017 TG insert PACK/UNPACK
-- 19.03.2017 TG bugfix CMPI ...(PC) - thanks Till Harbaum
-- ??? MJ bugfix non_aligned movem access
-- add berr handling 10.03.2013 - needed for ATARI Core
-- bugfix session 07/08.Feb.2013
-- movem ,-(an)
-- movem (an)+, - thanks Gerhard Suttner
-- btst dn,#data - thanks Peter Graf
-- movep - thanks Till Harbaum
-- IPL vector - thanks Till Harbaum
--
-- optimize Register file
-- to do 68010:
-- (MOVEC)
-- BKPT
-- MOVES
--
-- to do 68020:
-- (CALLM)
-- (RETM)
-- bugfix CHK2, CMP2
-- rework barrel shifter
-- CHK2
-- CMP2
-- cpXXX Coprozessor stuff
-- done 020:
-- CAS, CAS2
-- TRAPcc
-- PACK
-- UNPK
-- Bitfields
-- address modes
-- long bra
-- DIVS.L, DIVU.L
-- LINK long
-- MULS.L, MULU.L
-- extb.l
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use work.TG68K_Pack.all;
entity TG68KdotC_Kernel is
generic(
SR_Read : integer:= 2; --0=>user, 1=>privileged, 2=>switchable with CPU(0)
VBR_Stackframe : integer:= 2; --0=>no, 1=>yes/extended, 2=>switchable with CPU(0)
extAddr_Mode : integer:= 2; --0=>no, 1=>yes, 2=>switchable with CPU(1)
MUL_Mode : integer := 2; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL,
DIV_Mode : integer := 2; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV,
BitField : integer := 2; --0=>no, 1=>yes, 2=>switchable with CPU(1)
BarrelShifter : integer := 1; --0=>no, 1=>yes, 2=>switchable with CPU(1)
MUL_Hardware : integer := 1 --0=>no, 1=>yes,
);
port(clk : in std_logic;
nReset : in std_logic; --low active
clkena_in : in std_logic:='1';
data_in : in std_logic_vector(15 downto 0);
IPL : in std_logic_vector(2 downto 0):="111";
IPL_autovector : in std_logic:='0';
berr : in std_logic:='0'; -- only 68000 Stackpointer dummy
CPU : in std_logic_vector(1 downto 0):="00"; -- 00->68000 01->68010 11->68020(only some parts - yet)
addr_out : out std_logic_vector(31 downto 0);
data_write : out std_logic_vector(15 downto 0);
nWr : out std_logic;
nUDS : out std_logic;
nLDS : out std_logic;
busstate : out std_logic_vector(1 downto 0); -- 00-> fetch code 10->read data 11->write data 01->no memaccess
longword : out std_logic;
nResetOut : out std_logic;
FC : out std_logic_vector(2 downto 0);
clr_berr : out std_logic;
-- for debug
skipFetch : out std_logic;
regin_out : out std_logic_vector(31 downto 0);
CACR_out : out std_logic_vector( 3 downto 0);
VBR_out : out std_logic_vector(31 downto 0)
);
end TG68KdotC_Kernel;
architecture logic of TG68KdotC_Kernel is
signal use_VBR_Stackframe : std_logic;
signal syncReset : std_logic_vector(3 downto 0);
signal Reset : std_logic;
signal clkena_lw : std_logic;
signal TG68_PC : std_logic_vector(31 downto 0);
signal tmp_TG68_PC : std_logic_vector(31 downto 0);
signal TG68_PC_add : std_logic_vector(31 downto 0);
signal PC_dataa : std_logic_vector(31 downto 0);
signal PC_datab : std_logic_vector(31 downto 0);
signal memaddr : std_logic_vector(31 downto 0);
signal state : std_logic_vector(1 downto 0);
signal datatype : std_logic_vector(1 downto 0);
signal set_datatype : std_logic_vector(1 downto 0);
signal exe_datatype : std_logic_vector(1 downto 0);
signal setstate : std_logic_vector(1 downto 0);
signal setaddrvalue : std_logic;
signal addrvalue : std_logic;
signal opcode : std_logic_vector(15 downto 0);
signal exe_opcode : std_logic_vector(15 downto 0);
signal sndOPC : std_logic_vector(15 downto 0);
signal exe_pc : std_logic_vector(31 downto 0);--TH
signal last_opc_pc : std_logic_vector(31 downto 0);--TH
signal last_opc_read : std_logic_vector(15 downto 0);
signal registerin : std_logic_vector(31 downto 0);
signal reg_QA : std_logic_vector(31 downto 0);
signal reg_QB : std_logic_vector(31 downto 0);
signal Wwrena,Lwrena : bit;
signal Bwrena : bit;
signal Regwrena_now : bit;
signal rf_dest_addr : std_logic_vector(3 downto 0);
signal rf_source_addr : std_logic_vector(3 downto 0);
signal rf_source_addrd : std_logic_vector(3 downto 0);
signal regin : std_logic_vector(31 downto 0);
type regfile_t is array(0 to 15) of std_logic_vector(31 downto 0);
signal regfile : regfile_t := (OTHERS => (OTHERS => '0')); -- mikej stops sim X issues;
signal RDindex_A : integer range 0 to 15;
signal RDindex_B : integer range 0 to 15;
signal WR_AReg : std_logic;
signal addr : std_logic_vector(31 downto 0);
signal memaddr_reg : std_logic_vector(31 downto 0);
signal memaddr_delta : std_logic_vector(31 downto 0);
signal memaddr_delta_rega : std_logic_vector(31 downto 0);
signal memaddr_delta_regb : std_logic_vector(31 downto 0);
signal use_base : bit;
signal ea_data : std_logic_vector(31 downto 0);
signal OP1out : std_logic_vector(31 downto 0);
signal OP2out : std_logic_vector(31 downto 0);
signal OP1outbrief : std_logic_vector(15 downto 0);
signal OP1in : std_logic_vector(31 downto 0);
signal ALUout : std_logic_vector(31 downto 0);
signal data_write_tmp : std_logic_vector(31 downto 0);
signal data_write_muxin : std_logic_vector(31 downto 0);
signal data_write_mux : std_logic_vector(47 downto 0);
signal nextpass : bit;
signal setnextpass : bit;
signal setdispbyte : bit;
signal setdisp : bit;
signal regdirectsource :bit; -- checken !!!
signal addsub_q : std_logic_vector(31 downto 0);
signal briefdata : std_logic_vector(31 downto 0);
signal c_out : std_logic_vector(2 downto 0);
signal mem_address : std_logic_vector(31 downto 0);
signal memaddr_a : std_logic_vector(31 downto 0);
signal TG68_PC_brw : bit;
signal TG68_PC_word : bit;
signal getbrief : bit;
signal brief : std_logic_vector(15 downto 0);
signal data_is_source : bit;
signal store_in_tmp : bit;
signal write_back : bit;
signal exec_write_back : bit;
signal setstackaddr : bit;
signal writePC : bit;
signal writePCbig : bit;
signal set_writePCbig : bit;
signal writePCnext : bit;
signal setopcode : bit;
signal decodeOPC : bit;
signal execOPC : bit;
signal execOPC_ALU : bit;
signal setexecOPC : bit;
signal endOPC : bit;
signal setendOPC : bit;
signal Flags : std_logic_vector(7 downto 0); -- ...XNZVC
signal FlagsSR : std_logic_vector(7 downto 0); -- T.S.0III
signal SRin : std_logic_vector(7 downto 0);
signal exec_DIRECT : bit;
signal exec_tas : std_logic;
signal set_exec_tas : std_logic;
signal exe_condition : std_logic;
signal ea_only : bit;
signal source_areg : std_logic;
signal source_lowbits : bit;
signal source_LDRLbits : bit;
signal source_LDRMbits : bit;
signal source_2ndHbits : bit;
signal source_2ndMbits : bit;
signal source_2ndLbits : bit;
signal dest_areg : std_logic;
signal dest_LDRareg : std_logic;
signal dest_LDRHbits : bit;
signal dest_LDRLbits : bit;
signal dest_2ndHbits : bit;
signal dest_2ndLbits : bit;
signal dest_hbits : bit;
signal rot_bits : std_logic_vector(1 downto 0);
signal set_rot_bits : std_logic_vector(1 downto 0);
signal rot_cnt : std_logic_vector(5 downto 0);
signal set_rot_cnt : std_logic_vector(5 downto 0);
signal movem_actiond : bit;
signal movem_regaddr : std_logic_vector(3 downto 0);
signal movem_mux : std_logic_vector(3 downto 0);
signal movem_presub : bit;
signal movem_run : bit;
signal ea_calc_b : std_logic_vector(31 downto 0);
signal set_direct_data : bit;
signal use_direct_data : bit;
signal direct_data : bit;
signal set_V_Flag : bit;
signal set_vectoraddr : bit;
signal writeSR : bit;
signal trap_berr : bit;
signal trap_illegal : bit;
signal trap_addr_error : bit;
signal trap_priv : bit;
signal trap_trace : bit;
signal trap_1010 : bit;
signal trap_1111 : bit;
signal trap_trap : bit;
signal trap_trapv : bit;
signal trap_interrupt : bit;
signal trapmake : bit;
signal trapd : bit;
signal trap_SR : std_logic_vector(7 downto 0);
signal make_trace : std_logic;
signal make_berr : std_logic;
signal useStackframe2 : std_logic;
signal set_stop : bit;
signal stop : bit;
signal trap_vector : std_logic_vector(31 downto 0);
signal trap_vector_vbr : std_logic_vector(31 downto 0);
signal USP : std_logic_vector(31 downto 0);
-- signal illegal_write_mode : bit;
-- signal illegal_read_mode : bit;
-- signal illegal_byteaddr : bit;
signal IPL_nr : std_logic_vector(2 downto 0);
signal rIPL_nr : std_logic_vector(2 downto 0);
signal IPL_vec : std_logic_vector(7 downto 0);
signal interrupt : bit;
signal setinterrupt : bit;
signal SVmode : std_logic;
signal preSVmode : std_logic;
signal Suppress_Base : bit;
signal set_Suppress_Base: bit;
signal set_Z_error : bit;
signal Z_error : bit;
signal ea_build_now : bit;
signal build_logical : bit;
signal build_bcd : bit;
signal data_read : std_logic_vector(31 downto 0);
signal bf_ext_in : std_logic_vector(7 downto 0);
signal bf_ext_out : std_logic_vector(7 downto 0);
-- signal byte : bit;
signal long_start : bit;
signal long_start_alu : bit;
signal non_aligned : std_logic;
signal check_aligned : std_logic;
signal long_done : bit;
signal memmask : std_logic_vector(5 downto 0);
signal set_memmask : std_logic_vector(5 downto 0);
signal memread : std_logic_vector(3 downto 0);
signal wbmemmask : std_logic_vector(5 downto 0);
signal memmaskmux : std_logic_vector(5 downto 0);
signal oddout : std_logic;
signal set_oddout : std_logic;
signal PCbase : std_logic;
signal set_PCbase : std_logic;
signal last_data_read : std_logic_vector(31 downto 0);
signal last_data_in : std_logic_vector(31 downto 0);
signal bf_offset : std_logic_vector(5 downto 0);
signal bf_width : std_logic_vector(5 downto 0);
signal bf_bhits : std_logic_vector(5 downto 0);
signal bf_shift : std_logic_vector(5 downto 0);
signal alu_width : std_logic_vector(5 downto 0);
signal alu_bf_shift : std_logic_vector(5 downto 0);
signal bf_loffset : std_logic_vector(5 downto 0);
signal bf_full_offset : std_logic_vector(31 downto 0);
signal alu_bf_ffo_offset: std_logic_vector(31 downto 0);
signal alu_bf_loffset : std_logic_vector(5 downto 0);
signal movec_data : std_logic_vector(31 downto 0);
signal VBR : std_logic_vector(31 downto 0);
signal CACR : std_logic_vector(3 downto 0);
signal DFC : std_logic_vector(2 downto 0);
signal SFC : std_logic_vector(2 downto 0);
signal set : bit_vector(lastOpcBit downto 0);
signal set_exec : bit_vector(lastOpcBit downto 0);
signal exec : bit_vector(lastOpcBit downto 0);
signal micro_state : micro_states;
signal next_micro_state : micro_states;
BEGIN
ALU: TG68K_ALU
generic map(
MUL_Mode => MUL_Mode, --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL,
MUL_Hardware => MUL_Hardware, --0=>no, 1=>yes,
DIV_Mode => DIV_Mode, --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV,
BarrelShifter => BarrelShifter --0=>no, 1=>yes, 2=>switchable with CPU(1)
)
port map(
clk => clk, --: in std_logic;
Reset => Reset, --: in std_logic;
CPU => CPU, --: in std_logic_vector(1 downto 0):="00"; -- 00->68000 01->68010 11->68020(only some parts - yet)
clkena_lw => clkena_lw, --: in std_logic:='1';
execOPC => execOPC_ALU, --: in bit;
decodeOPC => decodeOPC, --: in bit;
exe_condition => exe_condition, --: in std_logic;
exec_tas => exec_tas, --: in std_logic;
long_start => long_start_alu, --: in bit;
non_aligned => non_aligned,
check_aligned => check_aligned,
movem_presub => movem_presub, --: in bit;
set_stop => set_stop, --: in bit;
Z_error => Z_error, --: in bit;
rot_bits => rot_bits, --: in std_logic_vector(1 downto 0);
exec => exec, --: in bit_vector(lastOpcBit downto 0);
OP1out => OP1out, --: in std_logic_vector(31 downto 0);
OP2out => OP2out, --: in std_logic_vector(31 downto 0);
reg_QA => reg_QA, --: in std_logic_vector(31 downto 0);
reg_QB => reg_QB, --: in std_logic_vector(31 downto 0);
opcode => opcode, --: in std_logic_vector(15 downto 0);
exe_opcode => exe_opcode, --: in std_logic_vector(15 downto 0);
exe_datatype => exe_datatype, --: in std_logic_vector(1 downto 0);
sndOPC => sndOPC, --: in std_logic_vector(15 downto 0);
last_data_read => last_data_read(15 downto 0), --: in std_logic_vector(31 downto 0);
data_read => data_read(15 downto 0), --: in std_logic_vector(31 downto 0);
FlagsSR => FlagsSR, --: in std_logic_vector(7 downto 0);
micro_state => micro_state, --: in micro_states;
bf_ext_in => bf_ext_in,
bf_ext_out => bf_ext_out,
bf_shift => alu_bf_shift,
bf_width => alu_width,
bf_ffo_offset => alu_bf_ffo_offset,
bf_loffset => alu_bf_loffset(4 downto 0),
set_V_Flag => set_V_Flag, --: buffer bit;
Flags => Flags, --: buffer std_logic_vector(8 downto 0);
c_out => c_out, --: buffer std_logic_vector(2 downto 0);
addsub_q => addsub_q, --: buffer std_logic_vector(31 downto 0);
ALUout => ALUout --: buffer std_logic_vector(31 downto 0)
);
-- AMR - let the parent module know this is a longword access. (Easy way to enable burst writes.)
longword <= not memmaskmux(3);
long_start_alu <= to_bit(NOT memmaskmux(3));
execOPC_ALU <= execOPC OR exec(alu_exec);
process (memmaskmux)
begin
non_aligned <= '0';
if (memmaskmux(5 downto 4) = "01") or (memmaskmux(5 downto 4) = "10") then
non_aligned <= '1';
end if;
end process;
-----------------------------------------------------------------------------
-- Bus control
-----------------------------------------------------------------------------
regin_out <= regin;
nWr <= '0' WHEN state="11" ELSE '1';
busstate <= state;
nResetOut <= '0' WHEN exec(opcRESET)='1' ELSE '1';
-- does shift for byte access. note active low me
-- should produce address error on 68000
memmaskmux <= memmask when addr(0) = '1' else memmask(4 downto 0) & '1';
nUDS <= memmaskmux(5);
nLDS <= memmaskmux(4);
clkena_lw <= '1' WHEN clkena_in='1' AND memmaskmux(3)='1' ELSE '0';
clr_berr <= '1' WHEN setopcode='1' AND trap_berr='1' ELSE '0';
PROCESS (clk, nReset)
BEGIN
IF nReset='0' THEN
syncReset <= "0000";
Reset <= '1';
ELSIF rising_edge(clk) THEN
IF clkena_in='1' THEN
syncReset <= syncReset(2 downto 0)&'1';
Reset <= NOT syncReset(3);
END IF;
END IF;
IF rising_edge(clk) THEN
IF VBR_Stackframe=1 or (cpu(0)='1' and VBR_Stackframe=2) THEN
use_VBR_Stackframe<='1';
ELSE
use_VBR_Stackframe<='0';
END IF;
END IF;
END PROCESS;
PROCESS (clk, long_done, last_data_in, data_in, addr, long_start, memmaskmux, memread, memmask, data_read)
BEGIN
IF memmaskmux(4)='0' THEN
data_read <= last_data_in(15 downto 0)&data_in;
ELSE
data_read <= last_data_in(23 downto 0)&data_in(15 downto 8);
END IF;
IF memread(0)='1' OR (memread(1 downto 0)="10" AND memmaskmux(4)='1')THEN
data_read(31 downto 16) <= (OTHERS=>data_read(15));
END IF;
IF rising_edge(clk) THEN
IF clkena_lw='1' AND state="10" THEN
IF memmaskmux(4)='0' THEN
bf_ext_in <= last_data_in(23 downto 16);
ELSE
bf_ext_in <= last_data_in(31 downto 24);
END IF;
END IF;
IF Reset='1' THEN
last_data_read <= (OTHERS => '0');
ELSIF clkena_in='1' THEN
IF state="00" OR exec(update_ld)='1' THEN
last_data_read <= data_read;
IF state(1)='0' AND memmask(1)='0' THEN
last_data_read(31 downto 16) <= last_opc_read;
ELSIF state(1)='0' OR memread(1)='1' THEN
last_data_read(31 downto 16) <= (OTHERS=>data_in(15));
END IF;
END IF;
last_data_in <= last_data_in(15 downto 0)&data_in(15 downto 0);
END IF;
END IF;
long_start <= to_bit(NOT memmask(1));
long_done <= to_bit(NOT memread(1));
END PROCESS;
PROCESS (long_start, reg_QB, data_write_tmp, exec, data_read, data_write_mux, memmaskmux, bf_ext_out,
data_write_muxin, memmask, oddout, addr)
BEGIN
IF exec(write_reg)='1' THEN
data_write_muxin <= reg_QB;
ELSE
data_write_muxin <= data_write_tmp;
END IF;
IF BitField=0 THEN
IF oddout=addr(0) THEN
data_write_mux <= "--------"&"--------"&data_write_muxin;
ELSE
data_write_mux <= "--------"&data_write_muxin&"--------";
END IF;
ELSE
IF oddout=addr(0) THEN
data_write_mux <= "--------"&bf_ext_out&data_write_muxin;
ELSE
data_write_mux <= bf_ext_out&data_write_muxin&"--------";
END IF;
END IF;
IF memmaskmux(1)='0' THEN
data_write <= data_write_mux(47 downto 32);
ELSIF memmaskmux(3)='0' THEN
data_write <= data_write_mux(31 downto 16);
ELSE
-- a single byte shows up on both bus halfs
IF memmaskmux(5 downto 4) = "10" THEN
data_write <= data_write_mux(7 downto 0) & data_write_mux(7 downto 0);
ELSIF memmaskmux(5 downto 4) = "01" THEN
data_write <= data_write_mux(15 downto 8) & data_write_mux(15 downto 8);
ELSE
data_write <= data_write_mux(15 downto 0);
END IF;
END IF;
IF exec(mem_byte)='1' THEN --movep
data_write <= data_write_tmp(15 downto 8) & data_write_tmp(15 downto 8);
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- Registerfile
-----------------------------------------------------------------------------
PROCESS (clk, regfile, RDindex_A, RDindex_B, exec)
BEGIN
reg_QA <= regfile(RDindex_A);
reg_QB <= regfile(RDindex_B);
IF rising_edge(clk) THEN
IF clkena_lw='1' THEN
rf_source_addrd <= rf_source_addr;
WR_AReg <= rf_dest_addr(3);
RDindex_A <= conv_integer(rf_dest_addr(3 downto 0));
RDindex_B <= conv_integer(rf_source_addr(3 downto 0));
IF Wwrena='1' THEN
regfile(RDindex_A) <= regin;
END IF;
IF exec(to_USP)='1' THEN
USP <= reg_QA;
END IF;
END IF;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- Write Reg
-----------------------------------------------------------------------------
PROCESS (OP1in, reg_QA, Regwrena_now, Bwrena, Lwrena, exe_datatype, WR_AReg, movem_actiond, exec, ALUout, memaddr, memaddr_a, ea_only, USP, movec_data)
BEGIN
regin <= ALUout;
IF exec(save_memaddr)='1' THEN
regin <= memaddr;
ELSIF exec(get_ea_now)='1' AND ea_only='1' THEN
regin <= memaddr_a;
ELSIF exec(from_USP)='1' THEN
regin <= USP;
ELSIF exec(movec_rd)='1' THEN
regin <= movec_data;
END IF;
IF Bwrena='1' THEN
regin(15 downto 8) <= reg_QA(15 downto 8);
END IF;
IF Lwrena='0' THEN
regin(31 downto 16) <= reg_QA(31 downto 16);
END IF;
Bwrena <= '0';
Wwrena <= '0';
Lwrena <= '0';
IF exec(presub)='1' OR exec(postadd)='1' OR exec(changeMode)='1' THEN -- -(An)+
Wwrena <= '1';
Lwrena <= '1';
ELSIF Regwrena_now='1' THEN --dbcc
Wwrena <= '1';
ELSIF exec(Regwrena)='1' THEN --read (mem)
Wwrena <= '1';
CASE exe_datatype IS
WHEN "00" => --BYTE
Bwrena <= '1';
WHEN "01" => --WORD
IF WR_AReg='1' OR movem_actiond='1' THEN
Lwrena <='1';
END IF;
WHEN OTHERS => --LONG
Lwrena <= '1';
END CASE;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- set dest regaddr
-----------------------------------------------------------------------------
PROCESS (opcode, rf_source_addrd, brief, setstackaddr, dest_hbits, dest_areg, dest_LDRareg, data_is_source, sndOPC, exec, set, dest_2ndHbits, dest_2ndLbits, dest_LDRHbits, dest_LDRLbits, last_data_read)
BEGIN
IF exec(movem_action) ='1' THEN
rf_dest_addr <= rf_source_addrd;
ELSIF set(briefext)='1' THEN
rf_dest_addr <= brief(15 downto 12);
ELSIF set(get_bfoffset)='1' THEN
-- IF opcode(15 downto 12)="1110" THEN
rf_dest_addr <= '0'&sndOPC(8 downto 6);
-- ELSE
-- rf_dest_addr <= sndOPC(9 downto 6);
-- END IF;
ELSIF dest_2ndHbits='1' THEN
rf_dest_addr <= dest_LDRareg&sndOPC(14 downto 12);
ELSIF dest_LDRHbits='1' THEN
rf_dest_addr <= last_data_read(15 downto 12);
ELSIF dest_LDRLbits='1' THEN
rf_dest_addr <= '0'&last_data_read(2 downto 0);
ELSIF dest_2ndLbits='1' THEN
rf_dest_addr <= '0'&sndOPC(2 downto 0);
ELSIF setstackaddr='1' THEN
rf_dest_addr <= "1111";
ELSIF dest_hbits='1' THEN
rf_dest_addr <= dest_areg&opcode(11 downto 9);
ELSE
IF opcode(5 downto 3)="000" OR data_is_source='1' THEN
rf_dest_addr <= dest_areg&opcode(2 downto 0);
ELSE
rf_dest_addr <= '1'&opcode(2 downto 0);
END IF;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- set source regaddr
-----------------------------------------------------------------------------
PROCESS (opcode, movem_presub, movem_regaddr, source_lowbits, source_areg, sndOPC, exec, set, source_2ndLbits, source_2ndHbits, source_LDRLbits, source_LDRMbits, last_data_read, source_2ndMbits)
BEGIN
IF exec(movem_action)='1' OR set(movem_action) ='1' THEN
IF movem_presub='1' THEN
rf_source_addr <= movem_regaddr XOR "1111";
ELSE
rf_source_addr <= movem_regaddr;
END IF;
ELSIF source_2ndLbits='1' THEN
rf_source_addr <= '0'&sndOPC(2 downto 0);
ELSIF source_2ndHbits='1' THEN
rf_source_addr <= '0'&sndOPC(14 downto 12);
ELSIF source_2ndMbits='1' THEN
rf_source_addr <= '0'&sndOPC(8 downto 6);
ELSIF source_LDRLbits='1' THEN
rf_source_addr <= '0'&last_data_read(2 downto 0);
ELSIF source_LDRMbits='1' THEN
rf_source_addr <= '0'&last_data_read(8 downto 6);
ELSIF source_lowbits='1' THEN
rf_source_addr <= source_areg&opcode(2 downto 0);
ELSIF exec(linksp)='1' THEN
rf_source_addr <= "1111";
ELSE
rf_source_addr <= source_areg&opcode(11 downto 9);
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- set OP1out
-----------------------------------------------------------------------------
PROCESS (reg_QA, store_in_tmp, ea_data, long_start, addr, exec, memmaskmux)
BEGIN
OP1out <= reg_QA;
IF exec(OP1out_zero)='1' THEN
OP1out <= (OTHERS => '0');
ELSIF exec(ea_data_OP1)='1' AND store_in_tmp='1' THEN
OP1out <= ea_data;
ELSIF exec(movem_action)='1' OR memmaskmux(3)='0' OR exec(OP1addr)='1' THEN
OP1out <= addr;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- set OP2out
-----------------------------------------------------------------------------
PROCESS (OP2out, reg_QB, exe_opcode, exe_datatype, execOPC, exec, use_direct_data,
store_in_tmp, data_write_tmp, ea_data)
BEGIN
OP2out(15 downto 0) <= reg_QB(15 downto 0);
OP2out(31 downto 16) <= (OTHERS => OP2out(15));
IF exec(OP2out_one)='1' THEN
OP2out(15 downto 0) <= "1111111111111111";
ELSIF use_direct_data='1' OR (exec(exg)='1' AND execOPC='1') OR exec(get_bfoffset)='1' THEN
OP2out <= data_write_tmp;
ELSIF (exec(ea_data_OP1)='0' AND store_in_tmp='1') OR exec(ea_data_OP2)='1' THEN
OP2out <= ea_data;
ELSIF exec(opcMOVEQ)='1' THEN
OP2out(7 downto 0) <= exe_opcode(7 downto 0);
OP2out(15 downto 8) <= (OTHERS => exe_opcode(7));
ELSIF exec(opcADDQ)='1' THEN
OP2out(2 downto 0) <= exe_opcode(11 downto 9);
IF exe_opcode(11 downto 9)="000" THEN
OP2out(3) <='1';
ELSE
OP2out(3) <='0';
END IF;
OP2out(15 downto 4) <= (OTHERS => '0');
ELSIF exe_datatype="10" AND exec(opcEXT)='0' THEN
OP2out(31 downto 16) <= reg_QB(31 downto 16);
END IF;
IF exec(opcEXTB)='1' THEN
OP2out(31 downto 8) <= (OTHERS => OP2out(7));
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- handle EA_data, data_write
-----------------------------------------------------------------------------
PROCESS (clk)
BEGIN
IF rising_edge(clk) THEN
IF Reset = '1' THEN
store_in_tmp <='0';
direct_data <= '0';
use_direct_data <= '0';
Z_error <= '0';
writePCnext <= '0';
ELSIF clkena_lw='1' THEN
useStackframe2<='0';
direct_data <= '0';
IF exec(hold_OP2)='1' THEN
use_direct_data <= '1';
END IF;
IF set_direct_data='1' THEN
direct_data <= '1';
use_direct_data <= '1';
ELSIF endOPC='1' OR set(ea_data_OP2)='1' THEN
use_direct_data <= '0';
END IF;
exec_DIRECT <= set_exec(opcMOVE);
IF endOPC='1' THEN
store_in_tmp <='0';
Z_error <= '0';
writePCnext <= '0';
ELSE
IF set_Z_error='1' THEN
Z_error <= '1';
END IF;
IF set_exec(opcMOVE)='1' AND state="11" THEN
use_direct_data <= '1';
END IF;
IF state="10" OR exec(store_ea_packdata)='1' THEN
store_in_tmp <= '1';
END IF;
IF direct_data='1' AND state="00" THEN
store_in_tmp <= '1';
END IF;
END IF;
IF state="10" AND exec(hold_ea_data)='0' THEN
ea_data <= data_read;
ELSIF exec(get_2ndOPC)='1' THEN
ea_data <= addr;
ELSIF exec(store_ea_data)='1' OR (direct_data='1' AND state="00") THEN
ea_data <= last_data_read;
END IF;
IF writePC='1' THEN
data_write_tmp <= TG68_PC;
ELSIF exec(writePC_add)='1' THEN
data_write_tmp <= TG68_PC_add;
-- paste and copy form TH ---------
elsif micro_state=trap00 THEN
data_write_tmp <= exe_pc; --TH
useStackframe2<='1';
writePCnext <= trap_trap OR trap_trapv OR exec(trap_chk) OR Z_error;
elsif micro_state = trap0 then
-- this is only active for 010+ since in 000 writePC is
-- true in state trap0
-- if trap_trace='1' or set_exec(opcTRAPV)='1' or Z_error='1' then
IF useStackframe2='1' THEN
-- stack frame format #2
data_write_tmp(15 downto 0) <= "0010" & trap_vector(11 downto 0); --TH
else
data_write_tmp(15 downto 0) <= "0000" & trap_vector(11 downto 0);
writePCnext <= trap_trap OR trap_trapv OR exec(trap_chk) OR Z_error;
end if;
------------------------------------
-- ELSIF micro_state=trap0 THEN
-- data_write_tmp(15 downto 0) <= trap_vector(15 downto 0);
ELSIF exec(hold_dwr)='1' THEN
data_write_tmp <= data_write_tmp;
ELSIF exec(exg)='1' THEN
data_write_tmp <= OP1out;
ELSIF exec(get_ea_now)='1' AND ea_only='1' THEN -- ist for pea
data_write_tmp <= addr;
ELSIF execOPC='1' THEN
data_write_tmp <= ALUout;
ELSIF (exec_DIRECT='1' AND state="10") THEN
data_write_tmp <= data_read;
IF exec(movepl)='1' THEN
data_write_tmp(31 downto 8) <= data_write_tmp(23 downto 0);
END IF;
ELSIF exec(movepl)='1' THEN
data_write_tmp(15 downto 0) <= reg_QB(31 downto 16);
ELSIF direct_data='1' THEN
data_write_tmp <= last_data_read;
ELSIF writeSR='1'THEN
data_write_tmp(15 downto 0) <= trap_SR(7 downto 0)& Flags(7 downto 0);
ELSE
data_write_tmp <= OP2out;
END IF;
END IF;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- brief
-----------------------------------------------------------------------------
PROCESS (brief, OP1out, OP1outbrief, cpu)
BEGIN
IF brief(11)='1' THEN
OP1outbrief <= OP1out(31 downto 16);
ELSE
OP1outbrief <= (OTHERS=>OP1out(15));
END IF;
briefdata <= OP1outbrief&OP1out(15 downto 0);
IF extAddr_Mode=1 OR (cpu(1)='1' AND extAddr_Mode=2) THEN
CASE brief(10 downto 9) IS
WHEN "00" => briefdata <= OP1outbrief&OP1out(15 downto 0);
WHEN "01" => briefdata <= OP1outbrief(14 downto 0)&OP1out(15 downto 0)&'0';
WHEN "10" => briefdata <= OP1outbrief(13 downto 0)&OP1out(15 downto 0)&"00";
WHEN "11" => briefdata <= OP1outbrief(12 downto 0)&OP1out(15 downto 0)&"000";
WHEN OTHERS => NULL;
END CASE;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- MEM_IO
-----------------------------------------------------------------------------
PROCESS (clk, setdisp, memaddr_a, briefdata, memaddr_delta, setdispbyte, datatype, interrupt, rIPL_nr, IPL_vec,
memaddr_reg, memaddr_delta_rega, memaddr_delta_regb, reg_QA, use_base, VBR, last_data_read, trap_vector, exec, set, cpu, use_VBR_Stackframe)
BEGIN
IF rising_edge(clk) THEN
IF clkena_lw='1' THEN
trap_vector(31 downto 10) <= (others => '0');
IF trap_berr='1' THEN
trap_vector(9 downto 0) <= "00" & X"08";
END IF;
IF trap_addr_error='1' THEN
trap_vector(9 downto 0) <= "00" & X"0C";
END IF;
IF trap_illegal='1' THEN
trap_vector(9 downto 0) <= "00" & X"10";
END IF;
IF set_Z_error='1' THEN
trap_vector(9 downto 0) <= "00" & X"14";
END IF;
IF exec(trap_chk)='1' THEN
trap_vector(9 downto 0) <= "00" & X"18";
END IF;
IF trap_trapv='1' THEN
trap_vector(9 downto 0) <= "00" & X"1C";
END IF;
IF trap_priv='1' THEN
trap_vector(9 downto 0) <= "00" & X"20";
END IF;
IF trap_trace='1' THEN
trap_vector(9 downto 0) <= "00" & X"24";
END IF;
IF trap_1010='1' THEN
trap_vector(9 downto 0) <= "00" & X"28";
END IF;
IF trap_1111='1' THEN
trap_vector(9 downto 0) <= "00" & X"2C";
END IF;
IF trap_trap='1' THEN
trap_vector(9 downto 0) <= "0010" & opcode(3 downto 0) & "00";
END IF;
IF trap_interrupt='1' or set_vectoraddr = '1' THEN
trap_vector(9 downto 0) <= IPL_vec & "00"; --TH
END IF;
END IF;
END IF;
IF use_VBR_Stackframe='1' THEN
trap_vector_vbr <= trap_vector+VBR;
ELSE
trap_vector_vbr <= trap_vector;
END IF;
memaddr_a(4 downto 0) <= "00000";
memaddr_a(7 downto 5) <= (OTHERS=>memaddr_a(4));
memaddr_a(15 downto 8) <= (OTHERS=>memaddr_a(7));
memaddr_a(31 downto 16) <= (OTHERS=>memaddr_a(15));
IF setdisp='1' THEN
IF exec(briefext)='1' THEN
memaddr_a <= briefdata+memaddr_delta;
ELSIF setdispbyte='1' THEN
memaddr_a(7 downto 0) <= last_data_read(7 downto 0);
ELSE
memaddr_a <= last_data_read;
END IF;
ELSIF set(presub)='1' THEN
IF set(longaktion)='1' THEN
memaddr_a(4 downto 0) <= "11100";
ELSIF datatype="00" AND set(use_SP)='0' THEN
memaddr_a(4 downto 0) <= "11111";
ELSE
memaddr_a(4 downto 0) <= "11110";
END IF;
ELSIF interrupt='1' THEN
memaddr_a(4 downto 0) <= '1'&rIPL_nr&'0';
END IF;
IF rising_edge(clk) THEN
IF clkena_in='1' THEN
IF exec(get_2ndOPC)='1' OR (state="10" AND memread(0)='1') THEN
tmp_TG68_PC <= addr;
END IF;
use_base <= '0';
memaddr_delta_regb <= (others => '0');
IF memmaskmux(3)='0' OR exec(mem_addsub)='1' THEN
memaddr_delta_rega <= addsub_q;
ELSIF set(restore_ADDR)='1' THEN
memaddr_delta_rega <= tmp_TG68_PC;
ELSIF exec(direct_delta)='1' THEN
memaddr_delta_rega <= data_read;
ELSIF exec(ea_to_pc)='1' AND setstate="00" THEN
memaddr_delta_rega <= addr;
ELSIF set(addrlong)='1' THEN
memaddr_delta_rega <= last_data_read;
ELSIF setstate="00" THEN
memaddr_delta_rega <= TG68_PC_add;
ELSIF exec(dispouter)='1' THEN
memaddr_delta_rega <= ea_data;
memaddr_delta_regb <= memaddr_a;
ELSIF set_vectoraddr='1' THEN
memaddr_delta_rega <= trap_vector_vbr;
ELSE
memaddr_delta_rega <= memaddr_a;
IF interrupt='0' AND Suppress_Base='0' THEN
-- IF interrupt='0' AND Suppress_Base='0' AND setstate(1)='1' THEN
use_base <= '1';
END IF;
END IF;
-- only used for movem address update
-- IF (long_done='0' AND state(1)='1') OR movem_presub='0' THEN
if ((memread(0) = '1') and state(1) = '1') or movem_presub = '0' then -- fix for unaligned movem mikej
memaddr <= addr;
END IF;
END IF;
END IF;
memaddr_delta <= memaddr_delta_rega + memaddr_delta_regb;
-- if access done, and not aligned, don't increment
addr <= memaddr_reg+memaddr_delta;
addr_out <= memaddr_reg + memaddr_delta;
IF use_base='0' THEN
memaddr_reg <= (others=>'0');
ELSE
memaddr_reg <= reg_QA;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- PC Calc + fetch opcode
-----------------------------------------------------------------------------
PROCESS (clk, IPL, setstate, addrvalue, state, exec_write_back, set_direct_data, next_micro_state, stop, make_trace, make_berr, IPL_nr, FlagsSR, set_rot_cnt, opcode, writePCbig, set_exec, exec,
PC_dataa, PC_datab, setnextpass, last_data_read, TG68_PC_brw, TG68_PC_word, Z_error, trap_trap, trap_trapv, interrupt, tmp_TG68_PC, TG68_PC, use_VBR_Stackframe, writePCnext)
BEGIN
PC_dataa <= TG68_PC;