OpenCores
URL https://opencores.org/ocsvn/light8080/light8080/trunk

Subversion Repositories light8080

[/] [light8080/] [trunk/] [vhdl/] [light8080.vhdl] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ja_rd
--##############################################################################
2
-- light8080 core
3
--##############################################################################
4 3 ja_rd
-- v1.0    (05 nov 2007) Jose A. Ruiz
5
-- This file and all the light8080 project is freeware (See COPYING.TXT)
6
--##############################################################################
7 2 ja_rd
 
8
library IEEE;
9
use IEEE.STD_LOGIC_1164.ALL;
10
use IEEE.STD_LOGIC_ARITH.ALL;
11
use IEEE.STD_LOGIC_UNSIGNED.ALL;
12
 
13
--##############################################################################
14
-- vma :      enable a memory or io r/w access.
15
-- io :       access in progress is io (and not memory) 
16
-- rd :       read memory or io 
17
-- wr :       write memory or io
18
-- data_out : data output
19
-- addr_out : memory and io address
20
-- data_in :  data input
21
-- halt :     halt status (1 when in halt state)
22
-- inte :     interrupt status (1 when enabled)
23
-- intr :     interrupt request
24
-- inta :     interrupt acknowledge
25
-- reset :    synchronous reset
26
-- clk :      clock
27
--##############################################################################
28
 
29
entity light8080 is
30
    Port (
31
            addr_out :  out std_logic_vector(15 downto 0);
32
 
33
            inta :      out std_logic;
34
            inte :      out std_logic;
35
            halt :      out std_logic;
36
            intr :      in std_logic;
37
 
38
            vma :       out std_logic;
39
            io :        out std_logic;
40
            rd :        out std_logic;
41
            wr :        out std_logic;
42
            data_in :   in std_logic_vector(7 downto 0);
43
            data_out :  out std_logic_vector(7 downto 0);
44
 
45
            clk :       in std_logic;
46
            reset :     in std_logic );
47
end light8080;
48
 
49
--##############################################################################
50
-- All memory and io accesses are synchronous. Signal vma works as the master
51
-- memory and io synchronous enable. More specifically:
52
--
53
--    * All memory/io control signals (io,rd,wr) are valid only when vma is 
54
--      high. They never activate when vms is inactive. 
55
--    * Signals data_out and address are only valid when vma='1'. The high 
56
--      address byte is 0x00 fir all io accesses.
57
--    * Signal data_in should be valid by the end of the cycle after vma='1'.
58
--
59
-- Signal reset needs to be active for 1 clock cycle (i.e. it is sampled on a 
60
-- positive clock edge and is subject to setup and hold times). 
61
-- Once reset is deasserted, the first fetch at address 0x0000 will happen N
62
-- cycles later.
63
--
64
-- Signal intr is sampled on all positive clock edges. If asserted when inte is
65
-- high, a fetch cycle will occur with inta signal active. During this fetch, PC
66
-- will not be incremented. After the fetch, the opcode will be executed, inta 
67
-- will be deasserted and normal execution will be resumed. 
68
-- Interrupts will be disabled upon assertion of inta, and remain disabled 
69
-- until exeplicitly enabled by the program (as in the original).
70
--
71
-- As a consequence of the above, only single-byte instructions should be
72
-- supplied in inta cycles. See the design notes.
73
--##############################################################################
74
 
75
architecture microcoded of light8080 is
76
 
77
-- addr_low: low byte of address
78
signal addr_low :     std_logic_vector(7 downto 0);
79
-- IR: instruction register. some bits left unused.  
80
signal IR :           std_logic_vector(7 downto 0);
81
-- s_field: IR field, sss source reg code
82
signal s_field :      std_logic_vector(2 downto 0);
83
-- d_field: IR field, ddd destination reg code
84
signal d_field :      std_logic_vector(2 downto 0);
85
-- p_field: IR field, pp 16-bit reg pair code
86
signal p_field :      std_logic_vector(1 downto 0);
87
-- rbh: 1 when p_field=11, used in reg bank addressing for 'special' regs
88
signal rbh :          std_logic; -- 1 when P=11 (special case)  
89
-- alu_op: uinst field, ALU operation code 
90
signal alu_op :       std_logic_vector(3 downto 0);
91
-- DI: data input to ALU block from data_in, unregistered
92
signal DI :           std_logic_vector(7 downto 0);
93
-- uc_addr: microcode (ucode) address 
94
signal uc_addr :      std_logic_vector(7 downto 0);
95
-- next_uc_addr: computed next microcode address (uaddr++/jump/ret/fetch)
96
signal next_uc_addr : std_logic_vector(8 downto 0);
97
-- uc_jmp_addr: uinst field, absolute ucode jump address
98
signal uc_jmp_addr :  std_logic_vector(7 downto 0);
99
-- uc_ret_address: ucode return address saved in previous jump
100
signal uc_ret_addr :  std_logic_vector(7 downto 0);
101
-- addr_plus_1: uaddr + 1
102
signal addr_plus_1 :  std_logic_vector(7 downto 0);
103
-- do_reset: reset, delayed 1 cycle -- used to reset the microcode sequencer
104
signal do_reset :     std_logic;
105
 
106
-- uc_flags1: uinst field, encoded flag of group 1 (see ucode file)
107
signal uc_flags1 :    std_logic_vector(2 downto 0);
108
-- uc_flags2: uinst field, encoded flag of group 2 (see ucode file)
109
signal uc_flags2 :    std_logic_vector(2 downto 0);
110
-- uc_addr_sel: selection of next uc_addr, composition of 4 flags
111
signal uc_addr_sel :  std_logic_vector(3 downto 0);
112
-- NOTE: see microcode file for information on flags
113
signal uc_jsr :       std_logic;  -- uinst field, decoded 'jsr' flag
114
signal uc_tjsr :      std_logic;  -- uinst field, decoded 'tjsr' flag
115
signal uc_decode :    std_logic;  -- uinst field, decoded 'decode' flag
116
signal uc_end :       std_logic;  -- uinst field, decoded 'end' flag
117
signal condition_reg :std_logic;  -- registered tjst condition
118
-- condition: tjsr condition (computed ccc condition from '80 instructions)
119
signal condition :    std_logic;
120
-- condition_sel: IR field, ccc condition code
121
signal condition_sel :std_logic_vector(2 downto 0);
122
signal uc_do_jmp :    std_logic;  -- uinst jump (jsr/tjsr) flag, pipelined
123
signal uc_do_ret :    std_logic;  -- ret flag, pipelined
124
signal uc_halt_flag : std_logic;  -- uinst field, decoded 'halt' flag
125
signal uc_halt :      std_logic;  -- halt command
126
signal halt_reg :     std_logic;  -- halt status reg, output as 'halt' signal
127
signal uc_ei :        std_logic;  -- uinst field, decoded 'ei' flag
128
signal uc_di :        std_logic;  -- uinst field, decoded 'ei' flag
129
signal inte_reg :     std_logic;  -- inte status reg, output as 'inte' signal
130
signal int_pending :  std_logic;  -- intr requested, inta not active yet
131
signal inta_reg :     std_logic;  -- inta status reg, output as 'inta'
132
signal clr_t1 :       std_logic;  -- uinst field, explicitly erase T1
133
signal do_clr_t1 :    std_logic;  -- clr_t1 pipelined
134
signal clr_t2 :       std_logic;  -- uinst field, explicitly erase T2
135
signal do_clr_t2 :    std_logic;  -- clr_t2 pipelined
136
signal ucode :        std_logic_vector(31 downto 0); -- microcode word
137
signal ucode_field2 : std_logic_vector(24 downto 0); -- pipelined microcode
138
 
139
-- microcode ROM : see design notes and microcode source file 
140
type t_rom is array (0 to 511) of std_logic_vector(31 downto 0);
141
 
142
signal rom : t_rom := (
143
 
144
"00000000000000000000000000000000", -- 000
145
"00000000000001001000000001000100", -- 001
146
"00000000000001000000000001000100", -- 002
147
"10111101101001001000000001001101", -- 003
148
"10110110101001000000000001001101", -- 004
149
"00100000000000000000000000000000", -- 005
150
"00000000000000000000000000000000", -- 006
151
"11100100000000000000000000000000", -- 007
152
"00000000101010000000000000000000", -- 008
153
"00000100000100000000000001010111", -- 009
154
"00001000000000000000110000011001", -- 00a
155
"00000100000100000000000001010111", -- 00b
156
"00000000101010000000000010010111", -- 00c
157
"00001000000000000000110000011100", -- 00d
158
"00001000000000000000110000011111", -- 00e
159
"00000100000100000000000001010111", -- 00f
160
"00001000000000000000110000011111", -- 010
161
"00001000000000000000110000011100", -- 011
162
"00001000000000000000110000011111", -- 012
163
"00000000000110001000000001010111", -- 013
164
"00001000000000000000110000011111", -- 014
165
"00000100000110000000000001010111", -- 015
166
"00001000000000000000110000101110", -- 016
167
"00001000000000000000110000100010", -- 017
168
"00000100000000111000000001010111", -- 018
169
"00001000000000000000110000101110", -- 019
170
"00000000101000111000000010010111", -- 01a
171
"00001000000000000000110000100101", -- 01b
172
"00001000000000000000110000101110", -- 01c
173
"10111101101001100000000001001101", -- 01d
174
"10110110101001101000000001001101", -- 01e
175
"00000000100000101000000001010111", -- 01f
176
"00001000000000000000110000100010", -- 020
177
"00000100000000100000000001010111", -- 021
178
"00001000000000000000110000101110", -- 022
179
"00000000101000101000000010010111", -- 023
180
"10111101101001100000000001001101", -- 024
181
"10111010101001101000000001001101", -- 025
182
"00000000101000100000000010010111", -- 026
183
"00001000000000000000110000100101", -- 027
184
"00001000000000000000110000101000", -- 028
185
"00000100000000111000000001010111", -- 029
186
"00000000101000111000000010010111", -- 02a
187
"00001000000000000000110000101011", -- 02b
188
"00000000101000010000000000000000", -- 02c
189
"00000000000001010000000001010111", -- 02d
190
"00000000101000011000000000000000", -- 02e
191
"00000000000001011000000001010111", -- 02f
192
"00000000101000100000000000000000", -- 030
193
"00000000000000010000000001010111", -- 031
194
"00000000101000101000000000000000", -- 032
195
"00000000000000011000000001010111", -- 033
196
"00000000101001010000000000000000", -- 034
197
"00000000000000100000000001010111", -- 035
198
"00000000101001011000000000000000", -- 036
199
"00000100000000101000000001010111", -- 037
200
"00001000000000000000110000011111", -- 038
201
"00000100011000111000001101001100", -- 039
202
"00001000000000000000110000011111", -- 03a
203
"00000100011000111000001101001101", -- 03b
204
"00001000000000000000110000011111", -- 03c
205
"00000100011000111000001101001110", -- 03d
206
"00001000000000000000110000011111", -- 03e
207
"00000100011000111000001101001111", -- 03f
208
"00001000000000000000110000011111", -- 040
209
"00000100011000111000001101000100", -- 041
210
"00001000000000000000110000011111", -- 042
211
"00000100011000111000001101000101", -- 043
212
"00001000000000000000110000011111", -- 044
213
"00000100011000111000001101000110", -- 045
214
"00001000000000000000110000011111", -- 046
215
"00000100011000111000001110001110", -- 047
216
"00000000101010000000000000000000", -- 048
217
"00000100011000111000001101001100", -- 049
218
"00000000101010000000000000000000", -- 04a
219
"00000100011000111000001101001101", -- 04b
220
"00000000101010000000000000000000", -- 04c
221
"00000100011000111000001101001110", -- 04d
222
"00000000101010000000000000000000", -- 04e
223
"00000100011000111000001101001111", -- 04f
224
"00000000101010000000000000000000", -- 050
225
"00000100011000111000001101000100", -- 051
226
"00000000101010000000000000000000", -- 052
227
"00000100011000111000001101000101", -- 053
228
"00000000101010000000000000000000", -- 054
229
"00000100011000111000001101000110", -- 055
230
"00000000101010000000000000000000", -- 056
231
"00000100011000111000001110001110", -- 057
232
"00001000000000000000110000011001", -- 058
233
"00000100011000111000001101001100", -- 059
234
"00001000000000000000110000011001", -- 05a
235
"00000100011000111000001101001101", -- 05b
236
"00001000000000000000110000011001", -- 05c
237
"00000100011000111000001101001110", -- 05d
238
"00001000000000000000110000011001", -- 05e
239
"00000100011000111000001101001111", -- 05f
240
"00001000000000000000110000011001", -- 060
241
"00000100011000111000001101000100", -- 061
242
"00001000000000000000110000011001", -- 062
243
"00000100011000111000001101000101", -- 063
244
"00001000000000000000110000011001", -- 064
245
"00000100011000111000001101000110", -- 065
246
"00001000000000000000110000011001", -- 066
247
"00000100011000111000001110001110", -- 067
248
"10111100101100000000001001001101", -- 068
249
"00000100000000000000000000000000", -- 069
250
"00001000000000000000110000011001", -- 06a
251
"10100000000000000000001010001101", -- 06b
252
"00001000000000000000110000011100", -- 06c
253
"10111100011100000000001001001111", -- 06d
254
"00000100000000000000000000000000", -- 06e
255
"00001000000000000000110000011001", -- 06f
256
"11000000000000000000000000000000", -- 070
257
"10111100011001010000001010001111", -- 071
258
"00001000000000000000110000011100", -- 072
259
"10111100101110001000000001001101", -- 073
260
"10100100101110000000000001001101", -- 074
261
"10111100011110001000000001001111", -- 075
262
"10100100011110000000000001001111", -- 076
263
"00000000011110001000000000000000", -- 077
264
"00000000101000101000000101001100", -- 078
265
"00000000011110000000000000000000", -- 079
266
"00000100101000100000000101001101", -- 07a
267
"00000000101000111000000010101000", -- 07b
268
"00000100101000111000001101101000", -- 07c
269
"00000100101000111000000101000000", -- 07d
270
"00000100101000111000000101000001", -- 07e
271
"00000100101000111000000101000010", -- 07f
272
"00000100101000111000000101000011", -- 080
273
"00000100101000111000000001000111", -- 081
274
"00000100000000000000000100101100", -- 082
275
"00000100000000000000000100101101", -- 083
276
"00001000000000000000110000101110", -- 084
277
"00000000101001100000000000000000", -- 085
278
"00000000000001001000000001010111", -- 086
279
"00000000101001101000000000000000", -- 087
280
"00000100000001000000000001010111", -- 088
281
"00000100000000000000000000000000", -- 089
282
"00001000000000000000110000101110", -- 08a
283
"00010000000000000000100000000101", -- 08b
284
"00001000000000000000110000101110", -- 08c
285
"11000000101001000000000010010111", -- 08d
286
"00001000000000000000110000110100", -- 08e
287
"11000000101001001000000010010111", -- 08f
288
"00001000000000000000110000110100", -- 090
289
"00000000101001100000000000000000", -- 091
290
"00000000000001001000000001010111", -- 092
291
"00000000101001101000000000000000", -- 093
292
"00000100000001000000000001010111", -- 094
293
"00001000000000000000110000101110", -- 095
294
"00010000000000000000100000001101", -- 096
295
"00001000000000000000110000111001", -- 097
296
"00000000000001001000000001010111", -- 098
297
"00001000000000000000110000111001", -- 099
298
"00000100000001000000000001010111", -- 09a
299
"00010000000000000000100000010111", -- 09b
300
"11000000101001000000000010010111", -- 09c
301
"00001000000000000000110000110100", -- 09d
302
"11000000101001001000000010010111", -- 09e
303
"00001000000000000000110000110100", -- 09f
304
"11000000000001001000000001011111", -- 0a0
305
"00000100000001000000000001000100", -- 0a1
306
"00000000101000101000000000000000", -- 0a2
307
"00000000000001001000000001010111", -- 0a3
308
"00000000101000100000000000000000", -- 0a4
309
"00000100000001000000000001010111", -- 0a5
310
"11000000101110000000000010010111", -- 0a6
311
"00001000000000000000110000110100", -- 0a7
312
"11000000101110001000000010010111", -- 0a8
313
"00001000000000000000110000110100", -- 0a9
314
"00000100000000000000000000000000", -- 0aa
315
"11000000101000111000000010010111", -- 0ab
316
"00001000000000000000110000110100", -- 0ac
317
"11000000000000000000000010110000", -- 0ad
318
"00001000000000000000110000110100", -- 0ae
319
"00000100000000000000000000000000", -- 0af
320
"00001000000000000000110000111001", -- 0b0
321
"00000000000110001000000001010111", -- 0b1
322
"00001000000000000000110000111001", -- 0b2
323
"00000100000110000000000001010111", -- 0b3
324
"00001000000000000000110000111001", -- 0b4
325
"00000000000000110000001101010111", -- 0b5
326
"00001000000000000000110000111001", -- 0b6
327
"00000100000000111000000001010111", -- 0b7
328
"00001000000000000000110000111001", -- 0b8
329
"00000000000001100000000001010111", -- 0b9
330
"00001000000000000000110000111001", -- 0ba
331
"00000000000001101000000001010111", -- 0bb
332
"11000000101000100000000010010111", -- 0bc
333
"00001000000000000000110000110100", -- 0bd
334
"11000000101000101000000010010111", -- 0be
335
"00001000000000000000110000110100", -- 0bf
336
"00000000101001100000000000000000", -- 0c0
337
"00000000000000101000000001010111", -- 0c1
338
"00000000101001101000000000000000", -- 0c2
339
"00000100000000100000000001010111", -- 0c3
340
"00000000101000101000000000000000", -- 0c4
341
"00000000000001111000000001010111", -- 0c5
342
"00000000101000100000000000000000", -- 0c6
343
"00000100000001110000000001010111", -- 0c7
344
"01100100000000000000000000000000", -- 0c8
345
"01000100000000000000000000000000", -- 0c9
346
"00000000000001101000000001010111", -- 0ca
347
"00001000000000000000110000011111", -- 0cb
348
"00000000000001100000000001010111", -- 0cc
349
"00000000000000000000000000000000", -- 0cd
350
"00000001101001100000000000000000", -- 0ce
351
"10010110101001101000000000000000", -- 0cf
352
"00000100100000111000000001010111", -- 0d0
353
"00000000000001101000000001010111", -- 0d1
354
"00001000000000000000110000011111", -- 0d2
355
"00000000000001100000000001010111", -- 0d3
356
"00000000101000111000000010010111", -- 0d4
357
"00000001101001100000000000000000", -- 0d5
358
"10011010101001101000000000000000", -- 0d6
359
"00000100000000000000000000000000", -- 0d7
360
"11100100000000000000000000000000", -- 0d8
361
"00000001101000101000000000000000", -- 0d9
362
"00010110101000100000000000000000", -- 0da
363
"00001100100001010000000001010111", -- 0db
364
"00000001101000101000000000000000", -- 0dc
365
"00011010101000100000000000000000", -- 0dd
366
"00000100000000000000000000000000", -- 0de
367
"10111101101001001000000001001101", -- 0df
368
"10110110101001000000000001001101", -- 0e0
369
"00001100100000000000000010010111", -- 0e1
370
"00000001101001100000000000000000", -- 0e2
371
"00010110101001101000000000000000", -- 0e3
372
"00001100100000000000000000000000", -- 0e4
373
"00000001101001100000000000000000", -- 0e5
374
"00011010101001101000000000000000", -- 0e6
375
"00000100000000000000000000000000", -- 0e7
376
"00000001101110001000000000000000", -- 0e8
377
"00010110101110000000000000000000", -- 0e9
378
"00001100100000000000000000000000", -- 0ea
379
"00000001101110001000000000000000", -- 0eb
380
"00011010101110000000000000000000", -- 0ec
381
"00000100000000000000000000000000", -- 0ed
382
"10111101101001001000000001001101", -- 0ee
383
"10110110101001000000000001001101", -- 0ef
384
"00000000100001100000000001010111", -- 0f0
385
"10111101101001001000000001001101", -- 0f1
386
"10110110101001000000000001001101", -- 0f2
387
"00001100100001101000000001010111", -- 0f3
388
"10111100011001111000000001001111", -- 0f4
389
"10100000011001110000000001001111", -- 0f5
390
"00000001101001111000000000000000", -- 0f6
391
"00011010101001110000000000000000", -- 0f7
392
"00001100000000000000000000000000", -- 0f8
393
"10111101101001111000000001001101", -- 0f9
394
"10110110101001110000000001001101", -- 0fa
395
"00001100100000000000000000000000", -- 0fb
396
"00000100000000000000000000000000", -- 0fc
397
"00000100000000000000000000000000", -- 0fd
398
"00000100000000000000000000000000", -- 0fe
399
"00000100000000000000000000000000", -- 0ff
400
"00001000000000000000100000001001", -- 100
401
"00001000000000000000000000010010", -- 101
402
"00001000000000000000000000101010", -- 102
403
"00001000000000000000010000110011", -- 103
404
"00001000000000000000010000101000", -- 104
405
"00001000000000000000010000101101", -- 105
406
"00001000000000000000000000001110", -- 106
407
"00001000000000000000010000111101", -- 107
408
"00001000000000000000000000000000", -- 108
409
"00001000000000000000010000110111", -- 109
410
"00001000000000000000000000101000", -- 10a
411
"00001000000000000000010000110101", -- 10b
412
"00001000000000000000010000101000", -- 10c
413
"00001000000000000000010000101101", -- 10d
414
"00001000000000000000000000001110", -- 10e
415
"00001000000000000000010000111110", -- 10f
416
"00001000000000000000000000000000", -- 110
417
"00001000000000000000000000010010", -- 111
418
"00001000000000000000000000101010", -- 112
419
"00001000000000000000010000110011", -- 113
420
"00001000000000000000010000101000", -- 114
421
"00001000000000000000010000101101", -- 115
422
"00001000000000000000000000001110", -- 116
423
"00001000000000000000010000111111", -- 117
424
"00001000000000000000000000000000", -- 118
425
"00001000000000000000010000110111", -- 119
426
"00001000000000000000000000101000", -- 11a
427
"00001000000000000000010000110101", -- 11b
428
"00001000000000000000010000101000", -- 11c
429
"00001000000000000000010000101101", -- 11d
430
"00001000000000000000000000001110", -- 11e
431
"00001000000000000000100000000000", -- 11f
432
"00001000000000000000000000000000", -- 120
433
"00001000000000000000000000010010", -- 121
434
"00001000000000000000000000100010", -- 122
435
"00001000000000000000010000110011", -- 123
436
"00001000000000000000010000101000", -- 124
437
"00001000000000000000010000101101", -- 125
438
"00001000000000000000000000001110", -- 126
439
"00001000000000000000010000111011", -- 127
440
"00001000000000000000000000000000", -- 128
441
"00001000000000000000010000110111", -- 129
442
"00001000000000000000000000011100", -- 12a
443
"00001000000000000000010000110101", -- 12b
444
"00001000000000000000010000101000", -- 12c
445
"00001000000000000000010000101101", -- 12d
446
"00001000000000000000000000001110", -- 12e
447
"00001000000000000000100000000001", -- 12f
448
"00001000000000000000000000000000", -- 130
449
"00001000000000000000000000010010", -- 131
450
"00001000000000000000000000011001", -- 132
451
"00001000000000000000010000110011", -- 133
452
"00001000000000000000010000101010", -- 134
453
"00001000000000000000010000101111", -- 135
454
"00001000000000000000000000010000", -- 136
455
"00001000000000000000100000000011", -- 137
456
"00001000000000000000000000000000", -- 138
457
"00001000000000000000010000110111", -- 139
458
"00001000000000000000000000010110", -- 13a
459
"00001000000000000000010000110101", -- 13b
460
"00001000000000000000010000101000", -- 13c
461
"00001000000000000000010000101101", -- 13d
462
"00001000000000000000000000001110", -- 13e
463
"00001000000000000000100000000010", -- 13f
464
"00001000000000000000000000001000", -- 140
465
"00001000000000000000000000001000", -- 141
466
"00001000000000000000000000001000", -- 142
467
"00001000000000000000000000001000", -- 143
468
"00001000000000000000000000001000", -- 144
469
"00001000000000000000000000001000", -- 145
470
"00001000000000000000000000001010", -- 146
471
"00001000000000000000000000001000", -- 147
472
"00001000000000000000000000001000", -- 148
473
"00001000000000000000000000001000", -- 149
474
"00001000000000000000000000001000", -- 14a
475
"00001000000000000000000000001000", -- 14b
476
"00001000000000000000000000001000", -- 14c
477
"00001000000000000000000000001000", -- 14d
478
"00001000000000000000000000001010", -- 14e
479
"00001000000000000000000000001000", -- 14f
480
"00001000000000000000000000001000", -- 150
481
"00001000000000000000000000001000", -- 151
482
"00001000000000000000000000001000", -- 152
483
"00001000000000000000000000001000", -- 153
484
"00001000000000000000000000001000", -- 154
485
"00001000000000000000000000001000", -- 155
486
"00001000000000000000000000001010", -- 156
487
"00001000000000000000000000001000", -- 157
488
"00001000000000000000000000001000", -- 158
489
"00001000000000000000000000001000", -- 159
490
"00001000000000000000000000001000", -- 15a
491
"00001000000000000000000000001000", -- 15b
492
"00001000000000000000000000001000", -- 15c
493
"00001000000000000000000000001000", -- 15d
494
"00001000000000000000000000001010", -- 15e
495
"00001000000000000000000000001000", -- 15f
496
"00001000000000000000000000001000", -- 160
497
"00001000000000000000000000001000", -- 161
498
"00001000000000000000000000001000", -- 162
499
"00001000000000000000000000001000", -- 163
500
"00001000000000000000000000001000", -- 164
501
"00001000000000000000000000001000", -- 165
502
"00001000000000000000000000001010", -- 166
503
"00001000000000000000000000001000", -- 167
504
"00001000000000000000000000001000", -- 168
505
"00001000000000000000000000001000", -- 169
506
"00001000000000000000000000001000", -- 16a
507
"00001000000000000000000000001000", -- 16b
508
"00001000000000000000000000001000", -- 16c
509
"00001000000000000000000000001000", -- 16d
510
"00001000000000000000000000001010", -- 16e
511
"00001000000000000000000000001000", -- 16f
512
"00001000000000000000000000001100", -- 170
513
"00001000000000000000000000001100", -- 171
514
"00001000000000000000000000001100", -- 172
515
"00001000000000000000000000001100", -- 173
516
"00001000000000000000000000001100", -- 174
517
"00001000000000000000000000001100", -- 175
518
"00001000000000000000110000011000", -- 176
519
"00001000000000000000000000001100", -- 177
520
"00001000000000000000000000001000", -- 178
521
"00001000000000000000000000001000", -- 179
522
"00001000000000000000000000001000", -- 17a
523
"00001000000000000000000000001000", -- 17b
524
"00001000000000000000000000001000", -- 17c
525
"00001000000000000000000000001000", -- 17d
526
"00001000000000000000000000001010", -- 17e
527
"00001000000000000000000000001000", -- 17f
528
"00001000000000000000010000001000", -- 180
529
"00001000000000000000010000001000", -- 181
530
"00001000000000000000010000001000", -- 182
531
"00001000000000000000010000001000", -- 183
532
"00001000000000000000010000001000", -- 184
533
"00001000000000000000010000001000", -- 185
534
"00001000000000000000010000011000", -- 186
535
"00001000000000000000010000001000", -- 187
536
"00001000000000000000010000001010", -- 188
537
"00001000000000000000010000001010", -- 189
538
"00001000000000000000010000001010", -- 18a
539
"00001000000000000000010000001010", -- 18b
540
"00001000000000000000010000001010", -- 18c
541
"00001000000000000000010000001010", -- 18d
542
"00001000000000000000010000011010", -- 18e
543
"00001000000000000000010000001010", -- 18f
544
"00001000000000000000010000001100", -- 190
545
"00001000000000000000010000001100", -- 191
546
"00001000000000000000010000001100", -- 192
547
"00001000000000000000010000001100", -- 193
548
"00001000000000000000010000001100", -- 194
549
"00001000000000000000010000001100", -- 195
550
"00001000000000000000010000011100", -- 196
551
"00001000000000000000010000001100", -- 197
552
"00001000000000000000010000001110", -- 198
553
"00001000000000000000010000001110", -- 199
554
"00001000000000000000010000001110", -- 19a
555
"00001000000000000000010000001110", -- 19b
556
"00001000000000000000010000001110", -- 19c
557
"00001000000000000000010000001110", -- 19d
558
"00001000000000000000010000011110", -- 19e
559
"00001000000000000000010000001110", -- 19f
560
"00001000000000000000010000010000", -- 1a0
561
"00001000000000000000010000010000", -- 1a1
562
"00001000000000000000010000010000", -- 1a2
563
"00001000000000000000010000010000", -- 1a3
564
"00001000000000000000010000010000", -- 1a4
565
"00001000000000000000010000010000", -- 1a5
566
"00001000000000000000010000100000", -- 1a6
567
"00001000000000000000010000010000", -- 1a7
568
"00001000000000000000010000010010", -- 1a8
569
"00001000000000000000010000010010", -- 1a9
570
"00001000000000000000010000010010", -- 1aa
571
"00001000000000000000010000010010", -- 1ab
572
"00001000000000000000010000010010", -- 1ac
573
"00001000000000000000010000010010", -- 1ad
574
"00001000000000000000010000100010", -- 1ae
575
"00001000000000000000010000010010", -- 1af
576
"00001000000000000000010000010100", -- 1b0
577
"00001000000000000000010000010100", -- 1b1
578
"00001000000000000000010000010100", -- 1b2
579
"00001000000000000000010000010100", -- 1b3
580
"00001000000000000000010000010100", -- 1b4
581
"00001000000000000000010000010100", -- 1b5
582
"00001000000000000000010000100100", -- 1b6
583
"00001000000000000000010000010100", -- 1b7
584
"00001000000000000000010000010110", -- 1b8
585
"00001000000000000000010000010110", -- 1b9
586
"00001000000000000000010000010110", -- 1ba
587
"00001000000000000000010000010110", -- 1bb
588
"00001000000000000000010000010110", -- 1bc
589
"00001000000000000000010000010110", -- 1bd
590
"00001000000000000000010000100110", -- 1be
591
"00001000000000000000010000010110", -- 1bf
592
"00001000000000000000100000011011", -- 1c0
593
"00001000000000000000100000110000", -- 1c1
594
"00001000000000000000100000001010", -- 1c2
595
"00001000000000000000100000000100", -- 1c3
596
"00001000000000000000100000010101", -- 1c4
597
"00001000000000000000100000100110", -- 1c5
598
"00001000000000000000000000111000", -- 1c6
599
"00001000000000000000100000011100", -- 1c7
600
"00001000000000000000100000011011", -- 1c8
601
"00001000000000000000100000010111", -- 1c9
602
"00001000000000000000100000001010", -- 1ca
603
"00001000000000000000000000000000", -- 1cb
604
"00001000000000000000100000010101", -- 1cc
605
"00001000000000000000100000001100", -- 1cd
606
"00001000000000000000000000111010", -- 1ce
607
"00001000000000000000100000011100", -- 1cf
608
"00001000000000000000100000011011", -- 1d0
609
"00001000000000000000100000110000", -- 1d1
610
"00001000000000000000100000001010", -- 1d2
611
"00001000000000000000110000010001", -- 1d3
612
"00001000000000000000100000010101", -- 1d4
613
"00001000000000000000100000100110", -- 1d5
614
"00001000000000000000000000111100", -- 1d6
615
"00001000000000000000100000011100", -- 1d7
616
"00001000000000000000100000011011", -- 1d8
617
"00001000000000000000000000000000", -- 1d9
618
"00001000000000000000100000001010", -- 1da
619
"00001000000000000000110000001010", -- 1db
620
"00001000000000000000100000010101", -- 1dc
621
"00001000000000000000000000000000", -- 1dd
622
"00001000000000000000000000111110", -- 1de
623
"00001000000000000000100000011100", -- 1df
624
"00001000000000000000100000011011", -- 1e0
625
"00001000000000000000100000110000", -- 1e1
626
"00001000000000000000100000001010", -- 1e2
627
"00001000000000000000100000111000", -- 1e3
628
"00001000000000000000100000010101", -- 1e4
629
"00001000000000000000100000100110", -- 1e5
630
"00001000000000000000010000000000", -- 1e6
631
"00001000000000000000100000011100", -- 1e7
632
"00001000000000000000100000011011", -- 1e8
633
"00001000000000000000100000100010", -- 1e9
634
"00001000000000000000100000001010", -- 1ea
635
"00001000000000000000000000101100", -- 1eb
636
"00001000000000000000100000010101", -- 1ec
637
"00001000000000000000000000000000", -- 1ed
638
"00001000000000000000010000000010", -- 1ee
639
"00001000000000000000100000011100", -- 1ef
640
"00001000000000000000100000011011", -- 1f0
641
"00001000000000000000100000110100", -- 1f1
642
"00001000000000000000100000001010", -- 1f2
643
"00001000000000000000110000001001", -- 1f3
644
"00001000000000000000100000010101", -- 1f4
645
"00001000000000000000100000101011", -- 1f5
646
"00001000000000000000010000000100", -- 1f6
647
"00001000000000000000100000011100", -- 1f7
648
"00001000000000000000100000011011", -- 1f8
649
"00001000000000000000110000000100", -- 1f9
650
"00001000000000000000100000001010", -- 1fa
651
"00001000000000000000110000001000", -- 1fb
652
"00001000000000000000100000010101", -- 1fc
653
"00001000000000000000000000000000", -- 1fd
654
"00001000000000000000010000000110", -- 1fe
655
"00001000000000000000100000011100"  -- 1ff
656
 
657
);
658
 
659
-- end of microcode ROM
660
 
661
signal load_al :      std_logic; -- uinst field, load AL reg from rbank
662
signal load_addr :    std_logic; -- uinst field, enable external addr reg load
663
signal load_t1 :      std_logic; -- uinst field, load reg T1 
664
signal load_t2 :      std_logic; -- uinst field, load reg T2
665
signal mux_in :       std_logic; -- uinst field, T1/T2 input data selection
666
signal load_do :      std_logic; -- uinst field, pipelined, load DO reg
667
-- rb_addr_sel: uinst field, rbank address selection: (sss,ddd,pp,ra_field)
668
signal rb_addr_sel :  std_logic_vector(1 downto 0);
669
-- ra_field: uinst field, explicit reg bank address
670
signal ra_field :     std_logic_vector(3 downto 0);
671
signal rbank_data :   std_logic_vector(7 downto 0); -- rbank output
672
signal alu_output :   std_logic_vector(7 downto 0); -- ALU output
673
-- data_output: datapath output: ALU output vs. F reg 
674
signal data_output :  std_logic_vector(7 downto 0);
675
signal T1 :           std_logic_vector(7 downto 0); -- T1 reg (ALU operand)
676
signal T2 :           std_logic_vector(7 downto 0); -- T2 reg (ALU operand)
677
-- alu_input: data loaded into T1, T2: rbank data vs. DI
678
signal alu_input :    std_logic_vector(7 downto 0);
679
signal we_rb :        std_logic; -- uinst field, commands a write to the rbank
680
signal inhibit_pc_increment : std_logic; -- avoid PC changes (during INTA)
681
signal rbank_rd_addr: std_logic_vector(3 downto 0); -- rbank rd addr
682
signal rbank_wr_addr: std_logic_vector(3 downto 0); -- rbank wr addr
683
signal DO :           std_logic_vector(7 downto 0); -- data output reg
684
 
685
-- Register bank as an array of 16 bytes (asynch. LUT ram)
686
type t_reg_bank is array(0 to 15) of std_logic_vector(7 downto 0);
687
-- Register bank : BC, DE, HL, AF, [PC, XY, ZW, SP]
688
signal rbank :        t_reg_bank;
689
 
690
signal flag_reg :     std_logic_vector(7 downto 0); -- F register
691
-- flag_pattern: uinst field, F update pattern: which flags are updated
692
signal flag_pattern : std_logic_vector(1 downto 0);
693
signal flag_s :       std_logic; -- new computed S flag  
694
signal flag_z :       std_logic; -- new computed Z flag
695
signal flag_p :       std_logic; -- new computed P flag
696
signal flag_cy :      std_logic; -- new computed C flag
697
signal flag_cy_1 :    std_logic; -- C flag computed from arith/logic operation
698
signal flag_cy_2 :    std_logic; -- C flag computed from CPC circuit
699
signal do_cy_op :     std_logic; -- ALU explicit CY operation (CPC, etc.)
700
signal do_cy_op_d :   std_logic; -- do_cy_op, pipelined
701
signal do_cpc :       std_logic; -- ALU operation is CPC
702
signal do_cpc_d :     std_logic; -- do_cpc, pipelined
703
signal do_daa :       std_logic; -- ALU operation is DAA
704
signal flag_ac :      std_logic; -- new computed half carry flag
705
-- flag_aux_cy: new computed half carry flag (used in 16-bit ops)
706
signal flag_aux_cy :  std_logic;
707
signal load_psw :     std_logic; -- load F register
708
 
709
-- aux carry computation and control signals
710
signal use_aux :      std_logic; -- decoded from flags in 1st phase
711
signal use_aux_cy :   std_logic; -- 2nd phase signal
712
signal reg_aux_cy :   std_logic;
713
signal aux_cy_in :    std_logic;
714
signal set_aux_cy :   std_logic;
715
signal set_aux  :     std_logic;
716
 
717
-- ALU control signals -- together they select ALU operation
718
signal alu_fn :       std_logic_vector(1 downto 0);
719
signal use_logic :    std_logic; -- logic/arith mux control 
720
signal mux_fn :       std_logic_vector(1 downto 0);
721
signal use_psw :      std_logic; -- ALU/F mux control
722
 
723
-- ALU arithmetic operands and result
724
signal arith_op1 :    std_logic_vector(8 downto 0);
725
signal arith_op2 :    std_logic_vector(8 downto 0);
726
signal arith_op2_sgn: std_logic_vector(8 downto 0);
727
signal arith_res :    std_logic_vector(8 downto 0);
728
signal arith_res8 :   std_logic_vector(7 downto 0);
729
 
730
-- ALU DAA intermediate signals (DAA has fully dedicated logic)
731
signal daa_res :      std_logic_vector(8 downto 0);
732
signal daa_res8 :     std_logic_vector(7 downto 0);
733
signal daa_res9 :     std_logic_vector(8 downto 0);
734
signal daa_test1 :    std_logic;
735
signal daa_test1a :   std_logic;
736
signal daa_test2 :    std_logic;
737
signal daa_test2a :   std_logic;
738
signal arith_daa_res :std_logic_vector(7 downto 0);
739
signal cy_daa :       std_logic;
740
 
741
-- ALU CY flag intermediate signals
742
signal cy_in_sgn :    std_logic;
743
signal cy_in :        std_logic;
744
signal cy_in_gated :  std_logic;
745
signal cy_adder :     std_logic;
746
signal cy_arith :     std_logic;
747
signal cy_shifter :   std_logic;
748
 
749
-- ALU intermediate results
750
signal logic_res :    std_logic_vector(7 downto 0);
751
signal shift_res :    std_logic_vector(7 downto 0);
752
signal alu_mux1 :     std_logic_vector(7 downto 0);
753
 
754
begin
755
 
756
DI <= data_in;
757
 
758
process(clk)    -- IR register, load when uc_decode flag activates
759
begin
760
  if clk'event and clk='1' then
761
    if uc_decode = '1' then
762
      IR <= DI;
763
    end if;
764
  end if;
765
end process;
766
 
767
s_field <= IR(2 downto 0); -- IR field extraction : sss reg code
768
d_field <= IR(5 downto 3); -- ddd reg code
769
p_field <= IR(5 downto 4); -- pp 16-bit reg pair code   
770
 
771
 
772
--##############################################################################
773
-- Microcode sequencer
774
 
775
process(clk)    -- do_reset is reset delayed 1 cycle
776
begin
777
  if clk'event and clk='1' then
778
    do_reset <= reset;
779
  end if;
780
end process;
781
 
782
uc_flags1 <= ucode(31 downto 29);
783
uc_flags2 <= ucode(28 downto 26);
784
 
785
-- microcode address control flags are gated by do_reset (reset has priority)
786
uc_do_ret <= '1' when uc_flags2 = "011" and do_reset = '0' else '0';
787
uc_jsr    <= '1' when uc_flags2 = "010" and do_reset = '0' else '0';
788
uc_tjsr   <= '1' when uc_flags2 = "100" and do_reset = '0' else '0';
789
uc_decode <= '1' when uc_flags1 = "001" and do_reset = '0' else '0';
790
uc_end    <= '1' when (uc_flags2 = "001" or (uc_tjsr='1' and condition_reg='0'))
791
                  and do_reset = '0' else '0';
792
 
793
-- other microinstruction flags are decoded
794
uc_halt_flag  <= '1' when uc_flags1 = "111" else '0';
795
uc_halt   <= '1' when uc_halt_flag='1' and inta_reg='0' else '0';
796
uc_ei     <= '1' when uc_flags1 = "011" else '0';
797
uc_di     <= '1' when uc_flags1 = "010" or inta_reg='1' else '0';
798
-- clr_t1/2 clears T1/T2 when explicitly commanded; T2 and T1 clear implicitly 
799
-- at the end of each instruction (by uc_decode)
800
clr_t2    <= '1' when uc_flags2 = "001" else '0';
801
clr_t1    <= '1' when uc_flags1 = "110" else '0';
802
use_aux   <= '1' when uc_flags1 = "101" else '0';
803
set_aux   <= '1' when uc_flags2 = "111" else '0';
804
 
805
load_al <= ucode(24);
806
load_addr <= ucode(25);
807
 
808
do_cy_op_d <= '1' when ucode(5 downto 2)="1011" else '0'; -- decode CY ALU op
809
do_cpc_d <= ucode(0); -- decode CPC ALU op
810
 
811
-- uinst jump command, either unconditional or on a given condition
812
uc_do_jmp <= uc_jsr or (uc_tjsr and condition_reg);
813
 
814
vma <= load_addr;  -- addr is valid, either for memmory or io
815
 
816
-- external bus interface control signals
817
io <= '1' when uc_flags1="100" else '0'; -- IO access (vs. memory)
818
rd <= '1' when uc_flags2="101" else '0'; -- RD access
819
wr <= '1' when uc_flags2="110" else '0'; -- WR access  
820
 
821
uc_jmp_addr <= ucode(11 downto 10) & ucode(5 downto 0);
822
 
823
uc_addr_sel <= uc_do_ret & uc_do_jmp & uc_decode & uc_end;
824
 
825
addr_plus_1 <= uc_addr + 1;
826
 
827
-- TODO simplify this!!
828
 
829
-- NOTE: when end='1' we jump either to the FETCH ucode ot to the HALT ucode
830
-- depending on the value of the halt signal.
831
-- We use the unregistered uc_halt instead of halt_reg because otherwise #end
832
-- should be on the cycle following #halt, wasting a cycle.
833
-- This means that the flag #halt has to be used with #end or will be ignored. 
834
 
835
with uc_addr_sel select
836
  next_uc_addr <= '0'&uc_ret_addr when "1000", -- ret
837
                  '0'&uc_jmp_addr when "0100", -- jsr/tjsr
838
                  '0'&addr_plus_1 when "0000", -- uaddr++
839
                  "000000"&uc_halt&"11"
840
                                  when "0001", -- end: go to fetch/halt uaddr
841
                  '1'&DI          when others; -- decode fetched address 
842
 
843
-- Note how we used DI (containing instruction opcode) as a microcode address
844
 
845
-- read microcode rom 
846
process (clk)
847
begin
848
  if clk'event and clk='1' then
849
    ucode <= rom(conv_integer(next_uc_addr));
850
  end if;
851
end process;
852
 
853
-- microcode address register
854
process (clk)
855
begin
856
  if clk'event and clk='1' then
857
    if reset = '1' then
858
      uc_addr <= X"00";
859
    else
860
      uc_addr <= next_uc_addr(7 downto 0);
861
    end if;
862
  end if;
863
end process;
864
 
865
-- ucode address 1-level 'return stack'
866
process (clk)
867
begin
868
  if clk'event and clk='1' then
869
    if reset = '1' then
870
      uc_ret_addr <= X"00";
871
    elsif uc_do_jmp='1' then
872
      uc_ret_addr <= addr_plus_1;
873
    end if;
874
  end if;
875
end process;
876
 
877
 
878
alu_op <= ucode(3 downto 0);
879
 
880
-- pipeline uinst field2 for 1-cycle delayed execution.
881
-- note the same rbank addr field is used in cycles 1 and 2; this enforces
882
-- some constraints on uinst programming but simplifies the system.
883
process(clk)
884
begin
885
  if clk'event and clk='1' then
886
    ucode_field2 <= do_cy_op_d & do_cpc_d & clr_t2 & clr_t1 &
887
                    set_aux & use_aux & rbank_rd_addr &
888
                    ucode(14 downto 4) & alu_op;
889
  end if;
890
end process;
891
 
892
--#### HALT logic
893
process(clk)
894
begin
895
  if clk'event and clk='1' then
896
    if reset = '1' or int_pending = '1' then --inta_reg
897
      halt_reg <= '0';
898
    else
899
      if uc_halt = '1' then
900
        halt_reg <= '1';
901
      end if;
902
    end if;
903
  end if;
904
end process;
905
 
906
halt <= halt_reg;
907
 
908
--#### INTE logic -- inte_reg = '1' means interrupts ENABLED
909
process(clk)
910
begin
911
  if clk'event and clk='1' then
912
    if reset = '1' then
913
      inte_reg <= '0';
914
    else
915
      if uc_di='1' or uc_ei='1' then
916
        inte_reg <= uc_ei;
917
      end if;
918
    end if;
919
  end if;
920
end process;
921
 
922
inte <= inte_reg;
923
 
924
-- interrupts are ignored when inte='0'
925
process(clk)
926
begin
927
  if clk'event and clk='1' then
928
    if reset = '1' then
929
      int_pending <= '0';
930
    else
931
      if intr = '1' and inte_reg = '1' then
932
        int_pending <= '1';
933
      else
934
        if inte_reg = '1' and uc_end='1' then
935
          int_pending <= '0';
936
        end if;
937
      end if;
938
    end if;
939
  end if;
940
end process;
941
 
942
 
943
--#### INTA logic
944
-- INTA goes high from END to END, that is for the entire time the instruction
945
-- takes to fetch and execute; in the original 8080 it was asserted only for 
946
-- the M1 cycle.
947
-- All instructions can be used in an inta cycle, including XTHL which was
948
-- forbidden in the original 8080. 
949
-- It's up to you figuring out which cycle is which in multibyte instructions.
950
process(clk)
951
begin
952
  if clk'event and clk='1' then
953
    if reset = '1' then
954
      inta_reg <= '0';
955
    else
956
      if int_pending = '1' and uc_end='1' then
957
        -- enter INTA state
958
        inta_reg <= '1';
959
      else
960
        -- exit INTA state
961
        -- NOTE: don't reset inta when exiting halt state (uc_halt_flag='1').
962
        -- If we omit this condition, when intr happens on halt state, inta
963
        -- will only last for 1 cycle, because in halt state uc_end is 
964
        -- always asserted.
965
        if uc_end = '1' and uc_halt_flag='0' then
966
          inta_reg <= '0';
967
        end if;
968
      end if;
969
    end if;
970
  end if;
971
end process;
972
 
973
inta <= inta_reg;
974
 
975
 
976
--##############################################################################
977
-- Datapath
978
 
979
-- extract pipelined microcode fields
980
ra_field <= ucode(18 downto 15);
981
load_t1 <= ucode(23);
982
load_t2 <= ucode(22);
983
mux_in <= ucode(21);
984
rb_addr_sel <= ucode(20 downto 19);
985
load_do <= ucode_field2(7);
986
set_aux_cy <= ucode_field2(20);
987
do_clr_t1 <= ucode_field2(21);
988
do_clr_t2 <= ucode_field2(22);
989
 
990
 
991
-- T1 register 
992
process (clk)
993
begin
994
  if clk'event and clk='1' then
995
    if reset = '1' or uc_decode = '1' or do_clr_t1='1' then
996
      T1 <= X"00";
997
    else
998
      if load_t1 = '1' then
999
        T1 <= alu_input;
1000
      end if;
1001
    end if;
1002
  end if;
1003
end process;
1004
 
1005
-- T2 register
1006
process (clk)
1007
begin
1008
  if clk'event and clk='1' then
1009
    if reset = '1' or uc_decode = '1' or do_clr_t2='1' then
1010
      T2 <= X"00";
1011
    else
1012
      if load_t2 = '1' then
1013
        T2 <= alu_input;
1014
      end if;
1015
    end if;
1016
  end if;
1017
end process;
1018
 
1019
-- T1/T2 input data mux
1020
alu_input <= rbank_data when mux_in = '1' else DI;
1021
 
1022
-- register bank address mux logic
1023
 
1024
rbh <= '1' when p_field = "11" else '0';
1025
 
1026
with rb_addr_sel select
1027
  rbank_rd_addr <=  ra_field    when "00",
1028
                    "0"&s_field when "01",
1029
                    "0"&d_field when "10",
1030
                    rbh&p_field&ra_field(0) when others;
1031
 
1032
-- RBank writes are inhibited in INTA state, but only for PC increments.
1033
inhibit_pc_increment <= '1' when inta_reg='1' and use_aux_cy='1'
1034
                                 and rbank_wr_addr(3 downto 1) = "100"
1035
                                 else '0';
1036
we_rb <= ucode_field2(6) and not inhibit_pc_increment;
1037
 
1038
-- Register bank logic
1039
-- NOTE: read is asynchronous, while write is synchronous; but note also
1040
-- that write phase for a given uinst happens the cycle after the read phase.
1041
-- This way we give the ALU time to do its job.
1042
rbank_wr_addr <= ucode_field2(18 downto 15);
1043
process(clk)
1044
begin
1045
  if clk'event and clk='1' then
1046
    if we_rb = '1' then
1047
      rbank(conv_integer(rbank_wr_addr)) <= alu_output;
1048
    end if;
1049
  end if;
1050
end process;
1051
rbank_data <= rbank(conv_integer(rbank_rd_addr));
1052
 
1053
-- should we read F register or ALU output?
1054
use_psw <= '1' when ucode_field2(5 downto 4)="11" else '0';
1055
data_output <= flag_reg when use_psw = '1' else alu_output;
1056
 
1057
 
1058
process (clk)
1059
begin
1060
  if clk'event and clk='1' then
1061
    if load_do = '1' then
1062
        DO <= data_output;
1063
    end if;
1064
  end if;
1065
end process;
1066
 
1067
--##############################################################################
1068
-- ALU 
1069
 
1070
alu_fn <= ucode_field2(1 downto 0);
1071
use_logic <= ucode_field2(2);
1072
mux_fn <= ucode_field2(4 downto 3);
1073
--#### make sure this is "00" in the microcode when no F updates should happen!
1074
flag_pattern <=  ucode_field2(9 downto 8);
1075
use_aux_cy <= ucode_field2(19);
1076
do_cpc <= ucode_field2(23);
1077
do_cy_op <= ucode_field2(24);
1078
do_daa <= '1' when ucode_field2(5 downto 2) = "1010" else '0';
1079
 
1080
aux_cy_in <= reg_aux_cy when set_aux_cy = '0' else '1';
1081
 
1082
-- carry input selection: normal or aux (for 16 bit increments)?
1083
cy_in <= flag_reg(0) when use_aux_cy = '0' else aux_cy_in;
1084
 
1085
-- carry is not used (0) in add/sub operations
1086
cy_in_gated <= cy_in and alu_fn(0);
1087
 
1088
--##### Adder/substractor
1089
 
1090
-- zero extend adder operands to 9 bits to ease CY output synthesis
1091
-- use zero extension because we're only interested in cy from 7 to 8
1092
arith_op1 <= '0' & T2;
1093
arith_op2 <= '0' & T1;
1094
 
1095
-- The adder/substractor is done in 2 stages to help XSL synth it properly
1096
-- Other codings result in 1 adder + a substractor + 1 mux
1097
 
1098
-- do 2nd op 2's complement if substracting...
1099
arith_op2_sgn <=  arith_op2 when alu_fn(1) = '0' else not arith_op2;
1100
-- ...and complement cy input too
1101
cy_in_sgn <= cy_in_gated when alu_fn(1) = '0' else not cy_in_gated;
1102
 
1103
-- once 2nd operand has been negated (or not) add operands normally
1104
arith_res <= arith_op1 + arith_op2_sgn + cy_in_sgn;
1105
 
1106
-- take only 8 bits; 9th bit of adder is cy output
1107
arith_res8 <= arith_res(7 downto 0);
1108
cy_adder <= arith_res(8);
1109
 
1110
--##### DAA dedicated logic
1111
-- Note a DAA takes 2 cycles to complete! 
1112
 
1113
--daa_test1a='1' when daa_res9(7 downto 4) > 0x06
1114
daa_test1a <= arith_op2(3) and (arith_op2(2) or arith_op2(1) or arith_op2(0));
1115
daa_test1 <= '1' when flag_reg(4)='1' or daa_test1a='1' else '0';
1116
 
1117
process(clk)
1118
begin
1119
  if clk'event and clk='1' then
1120
    if reset='1' then
1121
      daa_res9 <= "000000000";
1122
    else
1123
      if daa_test1='1' then
1124
        daa_res9 <= arith_op2 + "000000110";
1125
      else
1126
        daa_res9 <= arith_op2;
1127
      end if;
1128
    end if;
1129
  end if;
1130
end process;
1131
 
1132
--daa_test2a='1' when daa_res9(7 downto 4) > 0x06 FIXME unused?
1133
daa_test2a <= daa_res9(7) and (daa_res9(6) or daa_res9(5) or daa_res9(4));
1134
daa_test2 <= '1' when flag_reg(0)='1' or daa_test1a='1' else '0';
1135
 
1136
daa_res <= '0'&daa_res9(7 downto 0) + "01100000" when daa_test2='1'
1137
           else daa_res9;
1138
 
1139
cy_daa <= daa_res(8);
1140
 
1141
-- DAA vs. adder mux
1142
arith_daa_res <= daa_res(7 downto 0) when do_daa='1' else arith_res8;
1143
 
1144
-- DAA vs. adder CY mux
1145
cy_arith <= cy_daa when do_daa='1' else cy_adder;
1146
 
1147
--##### Logic operations block
1148
logic_res <=  T1 and T2 when alu_fn = "00" else
1149
              T1 xor T2 when alu_fn = "01" else
1150
              T1 or  T2 when alu_fn = "10" else
1151
              not T1;
1152
 
1153
--##### Shifter
1154
shifter:
1155
for i in 1 to 6 generate
1156
begin
1157
  shift_res(i) <= T1(i-1) when alu_fn(0) = '0' else T1(i+1);
1158
end generate;
1159
shift_res(0) <= T1(7) when alu_fn = "00" else -- rot left 
1160
                cy_in when alu_fn = "10" else -- rot left through carry
1161
                T1(1); -- rot right
1162
shift_res(7) <= T1(0) when alu_fn = "01" else -- rot right
1163
                cy_in when alu_fn = "11" else -- rot right through carry
1164
                T1(6); -- rot left
1165
 
1166
cy_shifter   <= T1(7) when alu_fn(0) = '0' else -- left
1167
                T1(0);                          -- right
1168
 
1169
alu_mux1 <= logic_res when use_logic = '1' else shift_res;
1170
 
1171
 
1172
with mux_fn select
1173
  alu_output <= alu_mux1      when "00",
1174
                arith_daa_res when "01",
1175
                not alu_mux1  when "10",
1176
                "00"&d_field&"000" when others; -- RST  
1177
 
1178
--###### flag computation 
1179
 
1180
flag_s <= alu_output(7);
1181
flag_p <= not(alu_output(7) xor alu_output(6) xor alu_output(5) xor alu_output(4) xor
1182
         alu_output(3) xor alu_output(2) xor alu_output(1) xor alu_output(0));
1183
flag_z <= '1' when alu_output=X"00" else '0';
1184
flag_ac <= (arith_op1(4) xor arith_op2_sgn(4) xor alu_output(4));
1185
 
1186
flag_cy_1 <= cy_arith when use_logic = '1' else cy_shifter;
1187
flag_cy_2 <= not flag_reg(0) when do_cpc='0' else '1'; -- cmc, stc
1188
flag_cy <= flag_cy_1 when do_cy_op='0' else flag_cy_2;
1189
 
1190
flag_aux_cy <= cy_adder;
1191
 
1192
-- auxiliary carry reg
1193
process(clk)
1194
begin
1195
  if clk'event and clk='1' then
1196
    if reset='1' or uc_decode = '1' then
1197
      reg_aux_cy <= '1'; -- inits to 0 every instruction
1198
    else
1199
      reg_aux_cy <= flag_aux_cy;
1200
    end if;
1201
  end if;
1202
end process;
1203
 
1204
-- load PSW from ALU (i.e. POP AF) or from flag signals
1205
load_psw <= '1' when we_rb='1' and rbank_wr_addr="0110" else '0';
1206
 
1207
-- The F register has been split in two separate groupt that always update
1208
-- together (C and all others).
1209
 
1210
-- F register, flags S,Z,AC,P
1211
process(clk)
1212
begin
1213
  if clk'event and clk='1' then
1214
    if reset='1' then
1215
      flag_reg(7) <= '0';
1216
      flag_reg(6) <= '0';
1217
      flag_reg(4) <= '0';
1218
      flag_reg(2) <= '0';
1219
    elsif flag_pattern(1) = '1' then
1220
      if load_psw = '1' then
1221
        flag_reg(7) <= alu_output(7);
1222
        flag_reg(6) <= alu_output(6);
1223
        flag_reg(4) <= alu_output(4);
1224
        flag_reg(2) <= alu_output(2);
1225
      else
1226
        flag_reg(7) <= flag_s;
1227
        flag_reg(6) <= flag_z;
1228
        flag_reg(4) <= flag_ac;
1229
        flag_reg(2) <= flag_p;
1230
      end if;
1231
    end if;
1232
  end if;
1233
end procesS;
1234
 
1235
-- F register, flag C
1236
process(clk)
1237
begin
1238
  if clk'event and clk='1' then
1239
    if reset = '1' then
1240
      flag_reg(0) <= '0';
1241
    elsif flag_pattern(0) = '1' then
1242
      if load_psw = '1' then
1243
        flag_reg(0) <= alu_output(0);
1244
      else
1245
        flag_reg(0) <= flag_cy;
1246
      end if;
1247
    end if;
1248
  end if;
1249
end procesS;
1250
 
1251
flag_reg(5) <= '0'; -- constant flag
1252
flag_reg(3) <= '0'; -- constant flag
1253
flag_reg(1) <= '1'; -- constant flag
1254
 
1255
--##### Condition computation
1256
 
1257
condition_sel <= d_field(2 downto 0);
1258
with condition_sel select
1259
  condition <=
1260
            not flag_reg(6) when "000", -- NZ
1261
                flag_reg(6) when "001", -- Z
1262
            not flag_reg(0) when "010", -- NC
1263
                flag_reg(0) when "011", -- C
1264
            not flag_reg(2) when "100", -- PO
1265
                flag_reg(2) when "101", -- PE  
1266
            not flag_reg(7) when "110", -- P  
1267
                flag_reg(7) when others;-- M                  
1268
 
1269
 
1270
-- condition is registered to shorten the delay path; the extra 1-cycle
1271
-- delay is not relevant because conditions are tested in the next instruction
1272
-- at the earliest, and there's at least the fetch uinsts intervening.                
1273
process(clk)
1274
begin
1275
  if clk'event and clk='1' then
1276
    if reset = '1' then
1277
      condition_reg <= '0';
1278
    else
1279
      condition_reg <= condition;
1280
    end if;
1281
  end if;
1282
end process;
1283
 
1284
-- low byte address register
1285
process(clk)
1286
begin
1287
  if clk'event and clk='1' then
1288
    if reset = '1' then
1289
      addr_low <= X"00";
1290
    elsif load_al = '1' then
1291
      addr_low <= rbank_data;
1292
    end if;
1293
  end if;
1294
end process;
1295
 
1296
-- note external address registers (high byte) are loaded directly from rbank
1297
addr_out <= rbank_data & addr_low;
1298
 
1299
data_out <= DO;
1300
 
1301
end microcoded;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.