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

Subversion Repositories v6502

[/] [v6502/] [trunk/] [v6502.vhd] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 Valerio63
----------------------------------------------------------------------
2
-- 8 bit microprocessor (65C02) with some enhances VHDL project     -- 
3
-- Full RTL synchronous pipelined architecture                      --
4
-- Project by Valerio Venturi (Italy)                               -- 
5
-- Date: 14/04/2011                                                 --
6 6 Valerio63
-- Last revision: 19/04/2020                                        --
7 4 Valerio63
----------------------------------------------------------------------
8
 
9 6 Valerio63
-- NOTE:
10
-- in this version I made some changes on the pr.vhd and mcpla.vhd files because some instructions changed the V flag by mistake
11
 
12
 
13 4 Valerio63
library IEEE;
14
use IEEE.std_logic_1164.all;                             -- defines std_logic types
15
use IEEE.STD_LOGIC_unsigned.all;
16
use IEEE.STD_LOGIC_arith.all;
17
 
18
-- global architecture 
19
entity v6502 is
20
  port(     clk0:    in STD_LOGIC;                       -- PHASE0 clock input
21
             res:    in STD_LOGIC;                       -- reset input
22
             irq:    in STD_LOGIC;                       -- interrupt request input
23
             nmi:    in STD_LOGIC;                       -- not maskable interrupt input
24
             rdy:    in STD_LOGIC;                       -- wait state input (read/write)
25
              so:    in STD_LOGIC;                       -- set overflow V input
26
              rw:   out STD_LOGIC;                       -- read/write out
27
            sync:   out STD_LOGIC;                       -- opcode fetch out
28
              vp:   out STD_LOGIC;                       -- vector pull
29
             ope:   out STD_LOGIC;                       -- microcode end 
30
            addr:   out STD_LOGIC_VECTOR(15 downto 0);   -- 16 bit address bus out
31
         data_in:    in STD_LOGIC_VECTOR(7 downto 0);    -- 8 bit input data bus
32
        data_out:   out STD_LOGIC_VECTOR(7 downto 0)     -- 8 bit output data bus
33
      );
34
end v6502;
35
 
36
architecture struct of v6502 is
37
  signal      i_res: STD_LOGIC;                      -- internal global reset RES
38
  signal      i_irq: STD_LOGIC;                      -- internal interrupt request IRQ
39
  signal      i_nmi: STD_LOGIC;                      -- internal interrupt request NMI
40
  signal      i_rdy: STD_LOGIC;                      -- internal wait request RDY
41
  signal       i_so: STD_LOGIC;                      -- internal set overflow SO
42
  signal       i_vp: STD_LOGIC;                      -- internal VP (vector pull)
43
  signal        int: STD_LOGIC;                      -- internal global interrupt (instruction boundary synchronized)
44
  signal         we: STD_LOGIC;                      -- write enable (combinatorial from PLA)
45
  signal       we_r: STD_LOGIC;                      -- write enable (registered)
46
  signal        ien: STD_LOGIC;                      -- interrupt IRQ enable
47
 
48
  -- microcode signals (register control)
49
  signal      regop: STD_LOGIC_VECTOR(3 downto 0);   -- register operation microcode
50
  signal       rsel: STD_LOGIC_VECTOR(3 downto 0);   -- register select microcode
51
  signal        a_l: STD_LOGIC;                      -- A load
52
  signal        x_l: STD_LOGIC;                      -- X load
53
  signal        y_l: STD_LOGIC;                      -- Y load
54
  signal        z_l: STD_LOGIC;                      -- Y load
55
  signal        p_l: STD_LOGIC;                      -- P load
56
  signal        o_l: STD_LOGIC;                      -- OPE load
57
  signal      sp_ll: STD_LOGIC;                      -- SP load lsb
58
  signal      sp_lh: STD_LOGIC;                      -- SP load msb
59
  signal       sp_u: STD_LOGIC;                      -- SP increment
60
  signal       sp_d: STD_LOGIC;                      -- SP decrement
61
  signal   dmux_sel: STD_LOGIC_VECTOR(1 downto 0);   -- ALU operand #2 data multiplexer
62
 
63
  -- microcode signals (ALU control)
64
  signal      aluop: STD_LOGIC_VECTOR(4 downto 0);   -- ALU operation code    
65
 
66
  -- microcode signals CPU control logic
67
  signal    opfetch: STD_LOGIC;                      -- opcode fetch 
68
  signal     i_sync: STD_LOGIC;                      -- internal SYNC not latched
69
  signal     m_sync: STD_LOGIC;                      -- internal SYNC latched
70
  signal      opdec: STD_LOGIC;                      -- opcode decode
71
  signal       pcmp: STD_LOGIC_VECTOR(1 downto 0);   -- PC/MP out control effective
72
  signal    pcmp_mc: STD_LOGIC_VECTOR(1 downto 0);   -- PC/MP out control microcode
73
  signal      pcinc: STD_LOGIC;                      -- PC increment
74
  signal      e_eop: STD_LOGIC;                      -- early microcode sequence end (for some opcodes)
75
  signal     mc_eop: STD_LOGIC;                      -- microcode sequence end (for some opcodes)
76
  signal        eop: STD_LOGIC;                      -- microcode sequence end (effective)
77
  signal      we_mc: STD_LOGIC;                      -- microcode write enable
78
  signal    we_mc_l: STD_LOGIC;                      -- microcode write enable to latch
79
  signal       fbrk: STD_LOGIC;                      -- force BRK opcode (used by hardware interrupts) 
80
  signal      opbrk: STD_LOGIC;                      -- BRK opcode (used for distinguish between hardware/software interrupts) 
81
  signal        bcf: STD_LOGIC;                      -- branch condition resolved
82
  signal        pcc: STD_LOGIC;                      -- PC carry
83
  signal       clri: STD_LOGIC;                      -- clear interrupt request pending microcode
84
  signal        vso: STD_LOGIC;                      -- SO input high to low edge flag
85
  signal  mc_branch: STD_LOGIC;                      -- branch (relative) opcode 
86
  signal adc_sbc_mc: STD_LOGIC;                      -- ADC/SBC opcode (used for decimal adjustment)
87
  signal      ai_op: STD_LOGIC;                      -- opcode with absolute indexed addressing mode
88
  signal    daa_req: STD_LOGIC;                      -- DAA required
89
  signal       mcad: STD_LOGIC_VECTOR(10 downto 0);  -- microcode address
90
  signal     mcscan: STD_LOGIC_VECTOR(2 downto 0);   -- microcode pointer control
91
  signal       p_op: STD_LOGIC_VECTOR(3 downto 0);   -- microcode control bits register P
92
  signal     pcr_fc: STD_LOGIC_VECTOR(2 downto 0);   -- microcode control PC 
93
  signal     mpr_fc: STD_LOGIC_VECTOR(3 downto 0);   -- microcode control MP 
94
  signal      mcbit: STD_LOGIC_VECTOR(34 downto 0);  -- microcode control bits
95
  signal     regbit: STD_LOGIC_VECTOR(8 downto 0);   -- microcode control bits
96
  signal     ivoffs: STD_LOGIC_VECTOR(2 downto 0);   -- microcode interrupt vector offset encoding
97
  signal        mcn: STD_LOGIC;                      -- microcode does NOPs
98
  signal add_sub_op: STD_LOGIC;                      -- ADC/SBC opcode
99
 
100
  -- ALU signals 
101
  signal        bcd: STD_LOGIC;                      -- ALU binary/bcd mode
102
  signal      c_flg: STD_LOGIC;                      -- ALU carry flag
103
  signal      z_flg: STD_LOGIC;                      -- ALU zero flag  
104
  signal      v_flg: STD_LOGIC;                      -- ALU overflow flag  
105
  signal      n_flg: STD_LOGIC;                      -- ALU negative flag  
106
  signal   pc_c_alu_flg: STD_LOGIC;                  -- ALU PC carry flag  
107
  signal    acr_reg: STD_LOGIC;                      -- ALU auxiliary carry (registered)
108
  signal    bcd_lsb: STD_LOGIC;                      -- bcd lsb overflow flag
109
  signal    bcd_msb: STD_LOGIC;                      -- bcd msb overflow flag
110
  signal branch_neg: STD_LOGIC;                      -- branch negative offset flag          
111
 
112
  -- bus
113
  signal       dbin: STD_LOGIC_VECTOR(7 downto 0);   -- input data bus D0..D7 
114
  signal      dbout: STD_LOGIC_VECTOR(7 downto 0);   -- output data bus D0..D7
115
  signal      a_bus: STD_LOGIC_VECTOR(7 downto 0);   -- accumulator register A bus
116
  signal      x_bus: STD_LOGIC_VECTOR(7 downto 0);   -- index register X bus
117
  signal      y_bus: STD_LOGIC_VECTOR(7 downto 0);   -- index register Y bus
118
  signal      z_bus: STD_LOGIC_VECTOR(7 downto 0);   -- index register Z bus
119
  signal     sp_bus: STD_LOGIC_VECTOR(15 downto 0);  -- stack pointer register S bus
120
  signal      p_bus: STD_LOGIC_VECTOR(7 downto 0);   -- status register P bus
121
  signal     op_bus: STD_LOGIC_VECTOR(7 downto 0);   -- opcode register bus
122
  signal      o_bus: STD_LOGIC_VECTOR(7 downto 0);   -- operand register bus
123
  signal    bcd_bus: STD_LOGIC_VECTOR(7 downto 0);   -- bcd constants bus (used for decimal adjustement)
124
  signal   oper_bus: STD_LOGIC_VECTOR(7 downto 0);   -- operand bus (ALU operand #2 bus)
125
  signal      r_bus: STD_LOGIC_VECTOR(7 downto 0);   -- general register bus (ALU operand #2 bus)
126
  signal    alu_bus: STD_LOGIC_VECTOR(7 downto 0);   -- ALU output bus
127
  signal     pc_bus: STD_LOGIC_VECTOR(15 downto 0);  -- program counter register PC bus
128
  signal     mp_bus: STD_LOGIC_VECTOR(15 downto 0);  -- memory pointer register PC bus
129
  signal     ad_bus: STD_LOGIC_VECTOR(15 downto 0);  -- address bus
130
 
131
  -- 16 bit program counter register (PC)
132
  component pcr
133
    port(   clk:  in STD_LOGIC;                        -- clock
134
              i:  in STD_LOGIC;                        -- increment 
135
          fwait:  in STD_LOGIC;                        -- wait
136
             fc:  in STD_LOGIC_VECTOR(3 downto 0);     -- function code
137
           din1:  in STD_LOGIC_VECTOR(7 downto 0);     -- input
138
           din2:  in STD_LOGIC_VECTOR(7 downto 0);     -- input
139
           dout: out STD_LOGIC_VECTOR(15 downto 0)     -- output
140
        );
141
  end component;
142
 
143
  -- 16 bit memory pointer register (MP)
144
  component mpr
145
    port(   clk:  in STD_LOGIC;                       -- clock
146
          fwait:  in STD_LOGIC;                       -- wait
147
              c:  in STD_LOGIC;                       -- carry input
148
             fc:  in STD_LOGIC_VECTOR(3 downto 0);    -- function code
149
          din_l:  in STD_LOGIC_VECTOR(7 downto 0);    -- input LSB
150
          din_h:  in STD_LOGIC_VECTOR(7 downto 0);    -- input MSB
151
             zp:  in STD_LOGIC_VECTOR(7 downto 0);    -- input zero bage register Z 
152
              v:  in STD_LOGIC_VECTOR(2 downto 0);    -- vector offset input
153
           dout: out STD_LOGIC_VECTOR(15 downto 0)    -- output
154
        );
155
  end component;
156
 
157
  -- 8 bit opcode register opr (pipeline opcode prefetch register)
158
  component opr
159
    port(   clk:  in STD_LOGIC;                        -- clock
160
            clr:  in STD_LOGIC;                        -- force BRK opcode
161
          fwait:  in STD_LOGIC;                        -- wait
162
             ld:  in STD_LOGIC;                        -- load
163
            din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input 
164
              b: out STD_LOGIC;                        -- BRK opcode          
165
           dout: out STD_LOGIC_VECTOR(7 downto 0)      -- output
166
        );
167
  end component;
168
 
169
  -- 8 bit operand hold register oper
170
  component oper
171
    port(   clk:  in STD_LOGIC;                        -- clock
172
          fwait:  in STD_LOGIC;                        -- wait
173
             ld:  in STD_LOGIC;                        -- load
174
            din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input 
175
           dout: out STD_LOGIC_VECTOR(7 downto 0)      -- output
176
        );
177
  end component;
178
 
179
  -- 8 bit accumulator register A
180
  component ar
181
    port(   clk:  in STD_LOGIC;                        -- clock                      
182
          fwait:  in STD_LOGIC;
183
             ld:  in STD_LOGIC;                        -- load
184
            din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input
185
           dout: out STD_LOGIC_VECTOR(7 downto 0)      -- output
186
        );
187
  end component;
188
 
189
  -- 8 bit index register X 
190
  component xr
191
    port(   clk:  in STD_LOGIC;                        -- clock                         
192
          fwait:  in STD_LOGIC;
193
             ld:  in STD_LOGIC;                        -- load
194
            din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input 
195
           dout: out STD_LOGIC_VECTOR(7 downto 0)      -- output
196
        );
197
  end component;
198
 
199
  -- 8 bit index register Y 
200
  component yr
201
    port(   clk:  in STD_LOGIC;                        -- clock
202
          fwait:  in STD_LOGIC;
203
             ld:  in STD_LOGIC;                        -- load
204
            din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input 
205
           dout: out STD_LOGIC_VECTOR(7 downto 0)      -- output
206
        );
207
  end component;
208
 
209
  -- 8 bit zero page register Z 
210
  -- cleared by any interrupts
211
  component zr
212
    port(   clk:  in STD_LOGIC;                        -- clock
213
            clr:  in STD_LOGIC;                        -- reset
214
          fwait:  in STD_LOGIC;
215
             ld:  in STD_LOGIC;                        -- load
216
            din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input 
217
           dout: out STD_LOGIC_VECTOR(7 downto 0)      -- output
218
        );
219
  end component;
220
 
221
  -- 16 bit stack pointer SP 
222
  component spr
223
    port(   clk:  in STD_LOGIC;                        -- clock
224
          fwait:  in STD_LOGIC;                        -- wait
225
            clr:  in STD_LOGIC;                        -- load init value
226
           ld_l:  in STD_LOGIC;                        -- load lsb
227
           ld_h:  in STD_LOGIC;                        -- load msb
228
              u:  in STD_LOGIC;                        -- increment
229
              d:  in STD_LOGIC;                        -- decrement
230
            din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input
231
           dout: out STD_LOGIC_VECTOR(15 downto 0)     -- output
232
      );
233
  end component;
234
 
235
  -- 8 bit processor status register P
236
  --  NV1BDIZC    
237
  --  76543210
238
  --  ||||||||
239
  --  ||||||||---    C = carry/borrow flag
240
  --  |||||||----    Z = zero flag
241
  --  ||||||-----    I = interrupt mask
242
  --  |||||------    D = decimal/binary alu mode
243
  --  ||||-------    B = break opcode flag
244
  --  |||--------    1 = always "1'
245
  --  ||---------    V = overflow flag
246
  --  |----------    N = negative flag
247
  -- The P register also contains an additional carry/borrow flag (ACR) used for effective address calculation but
248
  -- it is not visible at program level
249
  component pr
250
    port(      clk:  in STD_LOGIC;                        -- clock
251
               clr:  in STD_LOGIC;                        -- clear
252
             fwait:  in STD_LOGIC;                        -- wait
253
                 n:  in STD_LOGIC;                        -- N input
254
                 v:  in STD_LOGIC;                        -- V input
255
                 z:  in STD_LOGIC;                        -- Z input
256
                 c:  in STD_LOGIC;                        -- C input
257
                 b:  in STD_LOGIC;                        -- B input
258
                sv:  in STD_LOGIC;                        -- set overflow  
259
            acr_in:  in STD_LOGIC;                        -- auxiliary carry in   
260
                fc:  in STD_LOGIC_VECTOR(3 downto 0);     -- function code 
261
               din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input
262
              dout: out STD_LOGIC_VECTOR(7 downto 0);     -- output
263
           acr_out: out STD_LOGIC                         -- auxiliary carry out   
264
        );
265
  end component;
266
 
267
  -- BCD register (used for decimal adjustement)
268
  component bcd_reg is
269
    port(    clk:  in STD_LOGIC;
270
             clr:  in STD_LOGIC;
271
           fwait:  in STD_LOGIC;
272
              en:  in STD_LOGIC;
273
          bcd_sl:  in STD_LOGIC;                          -- loads "6" to lsb
274
          bcd_sh:  in STD_LOGIC;                          -- loads "6" to msb
275
            dout: out STD_LOGIC_VECTOR(7 downto 0)
276
        );
277
  end component;
278
 
279
  -- 8 bit (binary/bcd) two-way through pass ALU   
280
  -- operation:
281
  -- aluop = "0000" => dout <= op1 (pass/test)
282
  -- aluop = "0001" => dout <= op1 + op2 + carry 
283
  -- aluop = "0010" => dout <= op1 - op2 - carry 
284
  -- aluop = "0011" => dout <= op1 and op2       
285
  -- aluop = "0100" => dout <= op1  or op2       
286
  -- aluop = "0101" => dout <= op1 xor op2       
287
  -- aluop = "0110" => dout <= op1 + 1           
288
  -- aluop = "0111" => dout <= op1 - 1
289
  -- aluop = "1000" => dout <= op1 << 1 (ASL)
290
  -- aluop = "1001" => dout <= op1 >> 1 (LSR)
291
  -- aluop = "1010" => dout <= op1 << 1 (ROL)
292
  -- aluop = "1011" => dout <= op1 >> 1 (ROR)
293
  component alu_bin
294
    port( alu_byp:  in STD_LOGIC;                      -- ALU bypass (no operation)    
295
              cin:  in STD_LOGIC;                      -- carry/borrow in
296
              vin:  in STD_LOGIC;                      -- overflow in
297
              op1:  in STD_LOGIC_VECTOR(7 downto 0);   -- 8 bit operand #1
298
              op2:  in STD_LOGIC_VECTOR(7 downto 0);   -- 8 bit operand #2
299
               fc:  in STD_LOGIC_VECTOR(5 downto 0);   -- function code
300
               cf: out STD_LOGIC;                      -- carry/borrow (byte) out 
301
               zf: out STD_LOGIC;                      -- zero flag out
302
               nf: out STD_LOGIC;                      -- negative flag out
303
               vf: out STD_LOGIC;                      -- overflow flag out
304
            pc_cf: out STD_LOGIC;                      -- carry/borrow out for PC operation 
305
           bcd_ol: out STD_LOGIC;                      -- bcd lsb overflow  
306
           bcd_oh: out STD_LOGIC;                      -- bcd msb overflow  
307
             dout: out STD_LOGIC_VECTOR(7 downto 0)    -- 8 bit result out
308
        );
309
  end component;
310
 
311
  -- PC/MP address multiplexer
312
  component addrmux
313
    port(  sel:  in STD_LOGIC_VECTOR(1 downto 0);
314
             a:  in STD_LOGIC_VECTOR(15 downto 0);
315
             b:  in STD_LOGIC_VECTOR(15 downto 0);
316
             s:  in STD_LOGIC_VECTOR(15 downto 0);
317
             y: out STD_LOGIC_VECTOR(15 downto 0)
318
        );
319
  end component;
320
 
321
  -- register multiplexer
322
  component regmux
323
    port(  sel:  in STD_LOGIC_VECTOR(3 downto 0);
324
             a:  in STD_LOGIC_VECTOR(7 downto 0);
325
             b:  in STD_LOGIC_VECTOR(7 downto 0);
326
             c:  in STD_LOGIC_VECTOR(7 downto 0);
327
             d:  in STD_LOGIC_VECTOR(7 downto 0);
328
             e:  in STD_LOGIC_VECTOR(7 downto 0);
329
             f:  in STD_LOGIC_VECTOR(7 downto 0);
330
             g:  in STD_LOGIC_VECTOR(7 downto 0);
331
             h:  in STD_LOGIC_VECTOR(7 downto 0);
332
             i:  in STD_LOGIC_VECTOR(7 downto 0);
333
             j:  in STD_LOGIC_VECTOR(7 downto 0);
334
             k:  in STD_LOGIC_VECTOR(7 downto 0);
335
             y: out STD_LOGIC_VECTOR(7 downto 0)
336
        );
337
  end component;
338
 
339
  -- data multiplexer (register "O" bypass)
340
  component dmux is
341
    port(  sel:  in STD_LOGIC_VECTOR(1 downto 0);
342
             a:  in STD_LOGIC_VECTOR(7 downto 0);
343
             b:  in STD_LOGIC_VECTOR(7 downto 0);
344
             c:  in STD_LOGIC_VECTOR(7 downto 0);
345
             y: out STD_LOGIC_VECTOR(7 downto 0)
346
        );
347
  end component dmux;
348
 
349
  -- microcode sequencer logic
350
  component mcseq
351
    port(    clk:  in STD_LOGIC;
352
             clr:  in STD_LOGIC;
353
          mc_nop:  in STD_LOGIC;
354
           fwait:  in STD_LOGIC;
355
               q: out STD_LOGIC_VECTOR(2 downto 0)
356
        );
357
  end component;
358
 
359
  -- micropla logic
360
  -- output fields format:
361
  component mcpla
362
    port(    a:  in STD_LOGIC_VECTOR(10 downto 0);
363
             q: out STD_LOGIC_VECTOR(34 downto 0)
364
        );
365
  end component;
366
 
367
  -- register operation decoding logic
368
  component decreg
369
    port(    r:  in STD_LOGIC_VECTOR(3 downto 0);
370
             y: out STD_LOGIC_VECTOR(8 downto 0)
371
        );
372
  end component;
373
 
374
  -- cpu main state machine
375
  component cpufsm
376
    port(     clk:  in STD_LOGIC;
377
              clr:  in STD_LOGIC;
378
            fwait:  in STD_LOGIC;
379
             ireq:  in STD_LOGIC;
380
           branch:  in STD_LOGIC;
381
            bflag:  in STD_LOGIC;
382
              aim:  in STD_LOGIC;
383
           bcarry:  in STD_LOGIC;
384
           icarry:  in STD_LOGIC;
385
               p1:  in STD_LOGIC_VECTOR(1 downto 0);
386
             e_ei:  in STD_LOGIC;
387
            mc_ei:  in STD_LOGIC;
388
           addsub:  in STD_LOGIC;
389
         dec_mode:  in STD_LOGIC;
390
            fetch: out STD_LOGIC;
391
          op_sync: out STD_LOGIC;
392
              pci: out STD_LOGIC;
393
               pq: out STD_LOGIC_VECTOR(1 downto 0);
394
               fb: out STD_LOGIC;
395
               od: out STD_LOGIC;
396
           mc_nop: out STD_LOGIC
397
        );
398
  end component;
399
 
400
  -- interrupt logic
401
  component intlog
402
  port(    clk:  in STD_LOGIC;
403
          iack:  in STD_LOGIC;                    -- interrupt acknowledge by microcode 
404
             r:  in STD_LOGIC;                    -- RESET request
405
             n:  in STD_LOGIC;                    -- NMI request
406
             i:  in STD_LOGIC;                    -- IRQ request
407
             b:  in STD_LOGIC;                    -- BRK opcode
408
             s:  in STD_LOGIC;                    -- SO
409
         imask:  in STD_LOGIC;                    -- interrupt mask (valid only for IRQ)
410
         ioffs:  in STD_LOGIC_VECTOR(1 downto 0); -- interrupt servicing offset
411
          ireq: out STD_LOGIC;                    -- global interrupt requestb (IRQ/NMI)
412
          vset: out STD_LOGIC;                    -- SO output
413
         voffs: out STD_LOGIC_VECTOR(2 downto 0)  -- interrupt vector offset 
414
        );
415
  end component;
416
 
417
  -- branch logic
418
  component branch
419
    port(    op:  in STD_LOGIC_VECTOR(3 downto 0);
420
              n:  in STD_LOGIC;
421
              v:  in STD_LOGIC;
422
              z:  in STD_LOGIC;
423
              c:  in STD_LOGIC;
424
           bres: out STD_LOGIC
425
        );
426
  end component;
427
 
428
  -- opcode decimal instructions and prefetch prediction logic
429
  component pre_dec
430
    port(    op:  in STD_LOGIC_VECTOR(7 downto 0);
431
          fetch:  in STD_LOGIC;
432
             ei: out STD_LOGIC;
433
            dec: out STD_LOGIC
434
        );
435
  end component;
436
 
437
  begin
438
    u1:pcr      port map(clk=>clk0,
439
                         i=>pcinc,
440
                         fwait=>i_rdy,
441
                         fc(3 downto 1)=>pcr_fc,
442
                         fc(0)=>o_bus(7),
443
                         din1=>alu_bus,
444
                         din2=>o_bus,
445
                         dout=>pc_bus
446
                        );
447
 
448
    u2:mpr      port map(clk=>clk0,
449
                         fwait=>i_rdy,
450
                         c=>acr_reg,
451
                         fc=>mpr_fc,
452
                         din_l=>alu_bus,
453
                         din_h=>dbin,
454
                         zp=>z_bus,
455
                         v=>ivoffs,
456
                         dout=>mp_bus
457
                        );
458
 
459
    u3:ar       port map(clk=>clk0,
460
                         fwait=>i_rdy,
461
                         ld=>a_l,
462
                         din=>alu_bus,
463
                         dout=>a_bus
464
                        );
465
 
466
    u4:xr       port map(clk=>clk0,
467
                         fwait=>i_rdy,
468
                         ld=>x_l,
469
                         din=>alu_bus,
470
                         dout=>x_bus
471
                        );
472
 
473
    u5:yr       port map(clk=>clk0,
474
                         fwait=>i_rdy,
475
                         ld=>y_l,
476
                         din=>alu_bus,
477
                         dout=>y_bus
478
                        );
479
 
480
    u6:zr       port map(clk=>clk0,
481
                         clr=>clri,
482
                         fwait=>i_rdy,
483
                         ld=>z_l,
484
                         din=>alu_bus,
485
                         dout=>z_bus
486
                        );
487
 
488
    u7:spr      port map(clk=>clk0,
489
                         clr=>i_res,
490
                         fwait=>i_rdy,
491
                         ld_l=>sp_ll,
492
                         ld_h=>sp_lh,
493
                         u=>sp_u,
494
                         d=>sp_d,
495
                         din=>alu_bus,
496
                         dout=>sp_bus
497
                        );
498
 
499
    u8:pr       port map(clk=>clk0,
500
                         clr=>i_res,
501
                         fwait=>i_rdy,
502
                         n=>n_flg,
503
                         v=>v_flg,
504
                         z=>z_flg,
505
                         c=>c_flg,
506
                         b=>opbrk,
507
                         sv=>vso,
508
                         acr_in=>pc_c_alu_flg,
509
                         fc=>p_op,
510
                         din=>dbin,
511
                         dout=>p_bus,
512
                         acr_out=>acr_reg
513
                        );
514
 
515
    u9:opr      port map(clk=>clk0,
516
                         clr=>fbrk,
517
                         fwait=>i_rdy,
518
                         ld=>opfetch,
519
                         din=>dbin,
520
                         b=>opbrk,
521
                         dout=>op_bus
522
                        );
523
 
524
    u10:oper    port map(clk=>clk0,
525
                         fwait=>i_rdy,
526
                         ld=>o_l,
527
                         din=>alu_bus,
528
                         dout=>o_bus
529
                        );
530
 
531
    u11:bcd_reg port map(clk=>clk0,
532
                         clr=>opfetch,
533
                         fwait=>i_rdy,
534
                         en=>bcd,
535
                         bcd_sl=>bcd_lsb,
536
                         bcd_sh=>bcd_msb,
537
                         dout=>bcd_bus
538
                        );
539
 
540
    u12:alu_bin port map(alu_byp=>acr_reg,
541
                         cin=>p_bus(0),
542
                         vin=>p_bus(6),
543
                         op1=>r_bus,
544
                         op2=>oper_bus,
545
                         fc(5 downto 1)=>aluop,
546
                         fc(0)=>branch_neg,
547
                         cf=>c_flg,
548
                         zf=>z_flg,
549
                         nf=>n_flg,
550
                         vf=>v_flg,
551
                         pc_cf=>pc_c_alu_flg,
552
                         bcd_ol=>bcd_lsb,
553
                         bcd_oh=>bcd_msb,
554
                         dout=>alu_bus
555
                        );
556
 
557
    u13:addrmux port map(sel=>pcmp,
558
                         a=>pc_bus,
559
                         b=>mp_bus,
560
                         s=>sp_bus,
561
                         y=>addr
562
                        );
563
 
564
    u14:regmux  port map(sel=>rsel,
565
                         a=>dbin,
566
                         b=>a_bus,
567
                         c=>x_bus,
568
                         d=>y_bus,
569
                         e=>sp_bus(7 downto 0),
570
                         f=>sp_bus(15 downto 8),
571
                         g=>p_bus,
572
                         h=>pc_bus(7 downto 0),
573
                         i=>pc_bus(15 downto 8),
574
                         j=>o_bus,
575
                         k=>z_bus,
576
                         y=>r_bus
577
                        );
578
 
579
    u15:dmux    port map(sel=>dmux_sel,
580
                         a=>o_bus,
581
                         b=>dbin,
582
                         c=>bcd_bus,
583
                         y=>oper_bus
584
                        );
585
 
586
    u16:mcseq   port map(clk=>clk0,
587
                         clr=>opdec,
588
                         mc_nop=>mcn,
589
                         fwait=>i_rdy,
590
                         q=>mcscan
591
                        );
592
 
593
    u17:mcpla   port map(a=>mcad,
594
                         q=>mcbit
595
                        );
596
 
597
    u18:decreg  port map(r=>regop,
598
                         y=>regbit
599
                        );
600
 
601
    u19:cpufsm  port map(clk=>clk0,
602
                         clr=>i_res,
603
                         fwait=>i_rdy,
604
                         ireq=>int,
605
                         branch=>mc_branch,
606
                         bflag=>bcf,
607
                         aim=>ai_op,
608
                         bcarry=>pcc,
609
                         icarry=>acr_reg,
610
                         p1=>pcmp_mc,
611
                         e_ei=>e_eop,
612
                         mc_ei=>mc_eop,
613
                         addsub=>add_sub_op,
614
                         dec_mode=>p_bus(3),
615
                         fetch=>opfetch,
616
                         op_sync=>i_sync,
617
                         pci=>pcinc,
618
                         pq=>pcmp,
619
                         fb=>fbrk,
620
                         od=>opdec,
621
                         mc_nop=>mcn
622
                        );
623
 
624
    u20:intlog  port map(clk=>clk0,
625
                         iack=>clri,
626
                         r=>i_res,
627
                         n=>i_nmi,
628
                         i=>i_irq,
629
                         b=>opbrk,
630
                         s=>i_so,
631
                         imask=>ien,
632
                         ioffs=>mp_bus(2 downto 1),
633
                         ireq=>int,
634
                         vset=>vso,
635
                         voffs=>ivoffs
636
                        );
637
 
638
    u21:branch  port map(op=>op_bus(7 downto 4),
639
                         n=>p_bus(7),
640
                         v=>p_bus(6),
641
                         z=>p_bus(1),
642
                         c=>p_bus(0),
643
                         bres=>bcf
644
                        );
645
 
646
    u22:pre_dec port map(op=>dbin,
647
                         fetch=>opfetch,
648
                         ei=>e_eop,
649
                         dec=>add_sub_op
650
                        );
651
 
652
    -- asynchronous CPU link section 
653
    ien        <= p_bus(2);                                -- P(I) flag 
654
    bcd        <= p_bus(3);                                -- P(D) flag
655
    i_res      <= not res;                                 -- internal reset
656
    i_nmi      <= not nmi;                                 -- internal NMI
657
    i_irq      <= not irq;                                 -- internal IRQ
658
    i_rdy      <= not rdy;                                 -- internal RDY
659
    i_so       <= not so;                                  -- internal SO
660
    mcad       <= op_bus & mcscan;                         -- microcode address
661
    rsel       <= mcbit(3 downto 0);                       -- registers read microcode
662
    regop      <= mcbit(7 downto 4);                       -- registers operation microcode
663
    aluop      <= mcbit(12 downto 8);                      -- ALU microcode
664
    p_op       <= mcbit(16 downto 13);                     -- register P microcode 
665
    mpr_fc     <= mcbit(20 downto 17);                     -- MPR microcode
666
    pcr_fc     <= mcbit(23 downto 21);                     -- PCR microcode
667
    pcmp_mc    <= mcbit(25 downto 24);                     -- PCR/MPR multiplexer microcode
668
    clri       <= mcbit(26);                               -- clear interrupt request (also serves as register Z clear)
669
    we_mc      <= mcbit(27);                               -- write enable (combinatorial) microcode
670
    we_mc_l    <= mcbit(28);                               -- write enable (latched) microcode
671
    mc_eop     <= mcbit(29);                               -- end of instruction reached                             
672
    mc_branch  <= mcbit(30);                               -- branch opcode
673
    i_vp       <= mcbit(31);                               -- vector pull 
674
    ai_op      <= mcbit(32);                               -- opcode with addressing indexed microcode
675
    dmux_sel   <= mcbit(34 downto 33);                     -- data multiplexer microcode
676
    ope        <= eop;
677
    eop <= '1' when mc_eop = '1' or e_eop = '1' else '0';
678
    branch_neg <= '0' when mc_branch = '0' else o_bus(7);  -- flag for branch negative offset is valid only with branches opcode 
679
    vp <= not i_vp;
680
 
681
    -- register operations
682
    a_l        <= regbit(0);                               -- A load
683
    x_l        <= regbit(1);                               -- X load
684
    y_l        <= regbit(2);                               -- Y load
685
    z_l        <= regbit(3);                               -- Z load
686
    o_l        <= regbit(4);                               -- O load
687
    sp_ll      <= regbit(5);                               -- S load lsb
688
    sp_lh      <= regbit(6);                               -- S load msb
689
    sp_u       <= regbit(7);                               -- S += 1
690
    sp_d       <= regbit(8);                               -- S -= 1
691
    we         <= we_mc or opfetch;                        -- write enable
692
    sync       <= m_sync;
693
 
694
    -- SYNC latched
695
    process(clk0)
696
    begin
697
      if (clk0'event and clk0 = '1') then
698
        if i_rdy = '0' then
699
          m_sync <= i_sync;
700
        else
701
          m_sync <= m_sync;
702
        end if;
703
      end if;
704
    end process;
705
 
706
    -- PC carry logic
707
    process(o_bus,pc_c_alu_flg)
708
    begin
709
      if o_bus(7) = '0' then              -- check for positive/negative branch offset (bit 7)
710
        pcc <= pc_c_alu_flg;
711
      else
712
        pcc <= not pc_c_alu_flg;
713
      end if;
714
    end process;
715
 
716
    -- write enable registered
717
    process(clk0)
718
    begin
719
      if (clk0'event and clk0 = '1') then
720
        if i_res = '1' then
721
          we_r <= '1';
722
        else
723
          if i_rdy = '0' then
724
            we_r <= we_mc_l;
725
          else
726
            we_r <= we_r;
727
          end if;
728
        end if;
729
      end if;
730
    end process;
731
 
732
    rw <= we and we_r;
733
 
734
    -- data bus tristate (buffer ring gated) control logic
735
    --process(clk0,we,we_r,alu_bus)
736
    --begin
737
    --  if clock = '0' and (we = '0' or we_r = '0') then
738
    --    data <= alu_bus;
739
    --  else
740
    --    data <= "ZZZZZZZZ";
741
    --  end if;
742
    --end process;
743
    data_out <= alu_bus;
744
    dbin <= data_in or "00000000";
745
 
746
end struct;
747
 
748
 
749
 

powered by: WebSVN 2.1.0

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