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

Subversion Repositories v65c816

[/] [v65c816/] [trunk/] [v65c816.vhd] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 Valerio63
----------------------------------------------------------------------
2
-- 8 bit microprocessor (65C816) VHDL project                       -- 
3
-- Full RTL synchronous pipelined architecture                      --
4
-- Project by Valerio Venturi (Italy)                               -- 
5
-- Date: 5/04/2020                                                  --
6
-- Last revision: 5/04/2020                                         --
7
----------------------------------------------------------------------
8
 
9
-- I don't makes any claims, promises or guarantees about the accuracy, completeness, or 
10
-- adequacy of the contents of this website and expressly disclaims liability for errors and 
11
-- omissions in the contents of this website. No warranty of any kind, implied, expressed or statutory, 
12
-- including to fitness for a particular purpose and freedom from computer virus, is given with respect to 
13
-- the contents of this website or its hyperlinks to other Internet resources. 
14
-- Reference in this website to any specific commercial products, processes, or services, or 
15
-- the use of any trade, firm or corporation name is for the information, and does 
16
-- not constitute endorsement, recommendation, or favoring by me. 
17
-- All the source code and tutorials are to be used on your own risk. All the ideas and views in this site are my own and 
18
-- are not by any means related to my past or current employers.
19
 
20
You can use the codes given in this website for non-commercial purposes without my permission. But if you are using it for commercial purposes then contact me with the details of your project for my permission.
21
 
22
library IEEE;
23
use IEEE.std_logic_1164.all;                             -- defines std_logic types
24
use IEEE.STD_LOGIC_unsigned.all;
25
use IEEE.STD_LOGIC_arith.all;
26
 
27
-- global architecture 
28
entity v65c816 is
29
  port(     clk0:    in STD_LOGIC;                       -- PHASE0 clock input
30
             res:    in STD_LOGIC;                       -- reset input
31
             irq:    in STD_LOGIC;                       -- interrupt request input
32
             nmi:    in STD_LOGIC;                       -- not maskable interrupt input
33
             rdy:    in STD_LOGIC;                       -- wait state request input (read/write)
34
         rdy_out:   out STD_LOGIC;                       -- CPU in wait state (WAI instruction)
35
                        stp_out:   out STD_LOGIC;                       -- CPU in stop state (STP instruction)
36
              rw:   out STD_LOGIC;                       -- read/write out
37
             vpa:   out STD_LOGIC;                       -- vpa
38
                                 vda:   out STD_LOGIC;                       -- vda
39
                                  ml:   out STD_LOGIC;                       -- ml 
40
              vp:   out STD_LOGIC;                       -- vector pull
41
             ope:   out STD_LOGIC;                       -- microcode end 
42
                                   e:   out STD_LOGIC;                       -- emulation (1)/native mode (0) 
43
                                   m:   out STD_LOGIC;                       -- M status        
44
                                   x:   out STD_LOGIC;                       -- X status        
45
                         op_exp:   out STD_LOGIC;                                 -- two byte instruction running
46
            addr:   out STD_LOGIC_VECTOR(23 downto 0);   -- 16 bit address bus out
47
         data_in:    in STD_LOGIC_VECTOR(7 downto 0);    -- 8 bit input data bus
48
        data_out:   out STD_LOGIC_VECTOR(7 downto 0)     -- 8 bit output data bus
49
--         DEBUG                  
50
--                   a_reg:   out STD_LOGIC_VECTOR(15 downto 0);   -- 16 bit A register
51
--                   x_reg:   out STD_LOGIC_VECTOR(15 downto 0);   -- 16 bit X register
52
--                   y_reg:   out STD_LOGIC_VECTOR(15 downto 0);   -- 16 bit Y register
53
--                   s_reg:   out STD_LOGIC_VECTOR(15 downto 0);   -- 16 bit S register
54
--                       op_reg:   out STD_LOGIC_VECTOR(15 downto 0);   -- 16 bit Operand register        
55
--                   p_reg:   out STD_LOGIC_VECTOR(7 downto 0);    --  8 bit P register
56
--                   k_reg:   out STD_LOGIC_VECTOR(7 downto 0);    --  8 bit K register
57
--                   b_reg:   out STD_LOGIC_VECTOR(7 downto 0);    --  8 bit B register
58
--                   o_reg:   out STD_LOGIC_VECTOR(7 downto 0);    --  8 bit Opcode register
59
--                        mcode:   out STD_LOGIC_VECTOR(3 downto 0)     --  4 bit microcode sequence register
60
      );
61
end v65c816;
62
 
63
architecture struct of v65c816 is
64
  signal          i_res: STD_LOGIC;                      -- internal global reset RES
65
  signal          i_irq: STD_LOGIC;                      -- internal interrupt request IRQ
66
  signal          i_nmi: STD_LOGIC;                      -- internal interrupt request NMI
67
  signal          i_rdy: STD_LOGIC;                      -- internal wait request RDY
68
  signal          e_rdy: STD_LOGIC;                      -- external invertedf RDY
69
  signal           i_vp: STD_LOGIC;                      -- internal VP (vector pull)
70
  signal            int: STD_LOGIC;                      -- internal global interrupt (instruction boundary synchronized)
71
  signal             we: STD_LOGIC;                      -- write enable (combinatorial from PLA)
72
  signal           we_r: STD_LOGIC;                      -- write enable (registered)
73
  signal            ien: STD_LOGIC;                      -- interrupt IRQ enable
74
  signal            emu: STD_LOGIC;                      -- emulation mode
75
  signal    two_byte_op: STD_LOGIC;                      -- two byte instruction
76
 
77
  -- microcode signals (register control)
78
  signal          regop: STD_LOGIC_VECTOR(5 downto 0);   -- register operation microcode
79
  signal           rsel: STD_LOGIC_VECTOR(4 downto 0);   -- register select microcode
80
  signal        a_l_lsb: STD_LOGIC;                      -- A load lsb
81
  signal        a_l_msb: STD_LOGIC;                      -- A load msb
82
  signal          a_dec: STD_LOGIC;                      -- A decrement (MVN/MVP)
83
  signal        x_l_lsb: STD_LOGIC;                      -- X load lsb
84
  signal        x_l_msb: STD_LOGIC;                      -- X load msb
85
  signal            x_d: STD_LOGIC;                      -- X decrement
86
  signal            x_u: STD_LOGIC;                      -- X increment
87
  signal            y_d: STD_LOGIC;                      -- Y decrement
88
  signal            y_u: STD_LOGIC;                      -- Y increment
89
  signal        y_l_lsb: STD_LOGIC;                      -- Y load lsb
90
  signal        y_l_msb: STD_LOGIC;                      -- Y load msb
91
  signal        d_l_lsb: STD_LOGIC;                      -- D load lsb
92
  signal        d_l_msb: STD_LOGIC;                      -- D load msb
93
  signal            p_l: STD_LOGIC;                      -- P load
94
  signal            k_l: STD_LOGIC;                      -- program bank register PBR K load
95
  signal            b_l: STD_LOGIC;                      -- data bank register DBR B load
96
  signal           k_cl: STD_LOGIC;                      -- program bank register PBR K clear
97
  signal           b_cl: STD_LOGIC;                      -- data bank register DBR B clear
98
  signal            o_l: STD_LOGIC;                      -- OPE load msb & lsb
99
  signal        o_l_lsb: STD_LOGIC;                      -- OPE load lsb
100
  signal        o_l_msb: STD_LOGIC;                      -- OPE load msb
101
  signal          sp_ll: STD_LOGIC;                      -- SP load lsb
102
  signal          sp_lh: STD_LOGIC;                      -- SP load msb
103
  signal           sp_u: STD_LOGIC;                      -- SP increment
104
  signal           sp_d: STD_LOGIC;                      -- SP decrement
105
  signal       dmux_sel: STD_LOGIC_VECTOR(2 downto 0);   -- ALU operand #2 data multiplexer
106
  signal       kr_clear: STD_LOGIC;                      -- K clear
107
  signal       br_clear: STD_LOGIC;                      -- B clear
108
  signal         sp_emu: STD_LOGIC;                      -- '1' when S must be set in emulation mode
109
 
110
  -- microcode signals (ALU control)
111
  signal          aluop: STD_LOGIC_VECTOR(4 downto 0);    -- ALU operation code    
112
 
113
  -- microcode signals CPU control logic
114
  signal        mc_addr: STD_LOGIC_VECTOR(12 downto 0);  -- microcode PLA address
115
  signal        opfetch: STD_LOGIC;                      -- opcode fetch 
116
  signal         i_sync: STD_LOGIC;                      -- internal SYNC not latched
117
  signal         m_sync: STD_LOGIC;                      -- internal SYNC latched
118
  signal          opdec: STD_LOGIC;                      -- opcode decode
119
  signal           pcmp: STD_LOGIC_VECTOR(2 downto 0);   -- PC/MP out control effective
120
  signal        pcmp_mc: STD_LOGIC_VECTOR(2 downto 0);   -- PC/MP out control microcode
121
  signal          pcinc: STD_LOGIC;                      -- PC increment
122
  signal          e_eop: STD_LOGIC;                      -- early microcode sequence end (for some opcodes)
123
  signal         mc_eop: STD_LOGIC;                      -- microcode sequence end
124
  signal            eop: STD_LOGIC;                      -- microcode sequence end (effective)
125
  signal          we_mc: STD_LOGIC;                      -- microcode write enable
126
  signal        we_mc_l: STD_LOGIC;                      -- microcode write enable to latch
127
  signal           fbrk: STD_LOGIC;                      -- force BRK opcode (used by hardware interrupts) 
128
  signal          opbrk: STD_LOGIC;                      -- BRK opcode (used for distinguish between hardware/software interrupts) 
129
  signal          opcop: STD_LOGIC;                      -- COP opcode
130
  signal         sw_int: STD_LOGIC;                      -- software interrupt request
131
  signal   branch_taken: STD_LOGIC;                      -- branch condition resolved
132
  signal            pcc: STD_LOGIC;                      -- PC carry
133
  signal           clri: STD_LOGIC;                      -- clear interrupt request pending microcode
134
  signal         mc_vda: STD_LOGIC;                      -- microcode VDA
135
  signal         mc_vpa: STD_LOGIC;                      -- microcode VPA
136
  signal          mc_ml: STD_LOGIC;                      -- microcode ML
137
  signal     adc_sbc_mc: STD_LOGIC;                      -- ADC/SBC opcode (used for decimal adjustment)
138
  signal          ai_op: STD_LOGIC;                      -- opcode with absolute indexed addressing mode
139
  signal        daa_req: STD_LOGIC;                      -- DAA required
140
  signal           mcad: STD_LOGIC_VECTOR(11 downto 0);  -- microcode address
141
  signal         mcscan: STD_LOGIC_VECTOR(3 downto 0);   -- microcode pointer control
142
  signal           p_op: STD_LOGIC_VECTOR(4 downto 0);   -- microcode control bits register P
143
  signal         pcr_fc: STD_LOGIC_VECTOR(3 downto 0);   -- microcode control PC 
144
  signal         mpr_fc: STD_LOGIC_VECTOR(4 downto 0);   -- microcode control MP 
145
  signal          mcbit: STD_LOGIC_VECTOR(44 downto 0);  -- microcode control bits
146
  signal         regbit: STD_LOGIC_VECTOR(29 downto 0);  -- microcode control bits on registers
147
  signal         ivoffs: STD_LOGIC_VECTOR(7 downto 0);   -- interrupt vector offset encoding
148
  signal            mcn: STD_LOGIC;                      -- microcode does NOPs
149
  signal     add_sub_op: STD_LOGIC;                      -- ADC/SBC opcode
150
  signal          m_bit: STD_LOGIC;                      -- M bit of status register   
151
  signal          x_bit: STD_LOGIC;                      -- X bit of status register   
152
  signal     index_size: STD_LOGIC;                      -- index register size: 1 = 8 bit, 0 = 16 bit
153
  signal        m_size8: STD_LOGIC;                      -- memory operation size: 1 = 8 bit
154
  signal       m_size16: STD_LOGIC;                      -- memory operation size: 1 = 16 bit
155
  signal       s_size16: STD_LOGIC;                      -- memory operation size: 1 = 16 bit for special cases 
156
  signal         m_size: STD_LOGIC;                      -- memory operation size: 1 = 8 bit, 0 = 16 bit
157
  signal       acc_size: STD_LOGIC;                      -- accumulator C size: 1 = 8 bit, 0 = 16 bit
158
  signal        mov_end: STD_LOGIC;                      -- MVN/MVP end transfer
159
  signal         ld_acc: STD_LOGIC;                      -- load accumulator C register (16 bit) 
160
  signal          ld_xy: STD_LOGIC;                      -- load X/Y registers (16 bit)
161
 
162
  -- ALU signals 
163
  signal          c_flg: STD_LOGIC;                      -- ALU carry flag
164
  signal          z_flg: STD_LOGIC;                      -- ALU zero flag  
165
  signal          v_flg: STD_LOGIC;                      -- ALU overflow flag  
166
  signal          n_flg: STD_LOGIC;                      -- ALU negative flag  
167
  signal   pc_c_alu_flg: STD_LOGIC;                      -- ALU PC carry flag  
168
  signal        acr_reg: STD_LOGIC;                      -- ALU auxiliary carry (registered)
169
 
170
  -- multiplier signals
171
  signal       mul_init: STD_LOGIC;                      -- multiplier initialize
172
  signal    mul_start_u: STD_LOGIC;                      -- multiplier unsigned start
173
  signal    mul_start_s: STD_LOGIC;                      -- multiplier signed start 
174
  signal       mul_busy: STD_LOGIC;                      -- multiplier busy
175
  signal      mul_r_lsb: STD_LOGIC_VECTOR(15 downto 0);  -- multiplier lsb result
176
  signal      mul_r_msb: STD_LOGIC_VECTOR(15 downto 0);  -- multiplier msb result
177
  signal      mul_l_res: STD_LOGIC;                      -- load multiplier lsb result on register A/B and multiplier msb result on register X
178
  signal      mul_z_flg: STD_LOGIC;                      -- multiplier Z flag
179
  signal      mul_n_flg: STD_LOGIC;                      -- multiplier N flag
180
 
181
  -- WAI/STP signals
182
  signal         wai_ff: STD_LOGIC;                      -- WAI instruction flipflop
183
  signal         stp_ff: STD_LOGIC;                      -- STP instruction flipflop
184
  signal        wai_set: STD_LOGIC;                      -- WAI flipflop set
185
  signal        stp_set: STD_LOGIC;                      -- STP flipflop set
186
 
187
  -- bus
188
  signal           dbin: STD_LOGIC_VECTOR(7 downto 0);   -- input data bus D0..D7 
189
  signal          dbout: STD_LOGIC_VECTOR(7 downto 0);   -- output data bus D0..D7
190
  signal          a_bus: STD_LOGIC_VECTOR(15 downto 0);  -- accumulator register A/B/C bus
191
  signal          x_bus: STD_LOGIC_VECTOR(15 downto 0);  -- index register X bus
192
  signal          y_bus: STD_LOGIC_VECTOR(15 downto 0);  -- index register Y bus
193
  signal          k_bus: STD_LOGIC_VECTOR(7 downto 0);   -- program bank PBR K bus
194
  signal          b_bus: STD_LOGIC_VECTOR(7 downto 0);   -- program data DBR B bus
195
  signal          d_bus: STD_LOGIC_VECTOR(15 downto 0);  -- zero page/direct register D bus
196
  signal         sp_bus: STD_LOGIC_VECTOR(15 downto 0);  -- stack pointer register S bus
197
  signal          p_bus: STD_LOGIC_VECTOR(7 downto 0);   -- status register P bus
198
  signal         op_bus: STD_LOGIC_VECTOR(7 downto 0);   -- opcode register bus
199
  signal          o_bus: STD_LOGIC_VECTOR(15 downto 0);  -- operand register bus
200
  signal       oper_bus: STD_LOGIC_VECTOR(15 downto 0);  -- operand bus (ALU operand #2 bus)
201
  signal          r_bus: STD_LOGIC_VECTOR(15 downto 0);  -- general register bus (ALU operand #2 bus)
202
  signal        alu_bus: STD_LOGIC_VECTOR(15 downto 0);  -- ALU output bus
203
  signal         pc_bus: STD_LOGIC_VECTOR(15 downto 0);  -- program counter register PC bus
204
  signal         mp_bus: STD_LOGIC_VECTOR(23 downto 0);  -- memory data pointer register bus
205
  signal         ad_bus: STD_LOGIC_VECTOR(15 downto 0);  -- address bus
206
  signal     i_addr_bus: STD_LOGIC_VECTOR(23 downto 0);  -- internal 24 bit address bus  
207
 
208
  -- 16 bit program counter register (PC)
209
  component pcr
210
    port(       clk:  in STD_LOGIC;                        -- clock
211
                  i:  in STD_LOGIC;                        -- increment 
212
              fwait:  in STD_LOGIC;                        -- wait
213
                            brk_op:  in STD_LOGIC;                        -- forced BRK (by interrupt request) 
214
                   branch_flg:  in STD_LOGIC;                        -- branch flag   
215
                             mov_f:  in STD_LOGIC;                        -- MVN/MVP end transfer
216
                 fc:  in STD_LOGIC_VECTOR(3 downto 0);     -- function code
217
               din1:  in STD_LOGIC_VECTOR(7 downto 0);     -- input
218
               din2:  in STD_LOGIC_VECTOR(15 downto 0);    -- input
219
               dout: out STD_LOGIC_VECTOR(15 downto 0)     -- output
220
        );
221
  end component;
222
 
223
  -- 8 bit PBR program bank register K 
224
  component kr
225
    port(    clk:  in STD_LOGIC;                       -- clock       
226
             clr:  in STD_LOGIC;                       -- reset  
227
           fwait:  in STD_LOGIC;
228
              ld:  in STD_LOGIC;                       -- load
229
             din:  in STD_LOGIC_VECTOR(7 downto 0);    -- input 
230
            dout: out STD_LOGIC_VECTOR(7 downto 0)     -- output
231
        );
232
  end component;
233
 
234
  -- 8 bit DBR program bank register B 
235
  component br
236
    port(    clk:  in STD_LOGIC;                       -- clock       
237
             clr:  in STD_LOGIC;                       -- reset  
238
           fwait:  in STD_LOGIC;
239
              ld:  in STD_LOGIC;                       -- load
240
             din:  in STD_LOGIC_VECTOR(7 downto 0);    -- input 
241
            dout: out STD_LOGIC_VECTOR(7 downto 0)     -- output
242
        );
243
  end component;
244
 
245
  -- 16 bit memory pointer register (MP)
246
  component mpr
247
    port(   clk:  in STD_LOGIC;                       -- clock
248
          fwait:  in STD_LOGIC;                       -- wait
249
         dbr_ld:  in STD_LOGIC;                       -- load DBR
250
                        c:  in STD_LOGIC;                       -- carry 
251
             fc:  in STD_LOGIC_VECTOR(4 downto 0);    -- function code
252
          din_l:  in STD_LOGIC_VECTOR(7 downto 0);    -- input LSB
253
          din_h:  in STD_LOGIC_VECTOR(7 downto 0);    -- input MSB
254
            dbr:  in STD_LOGIC_VECTOR(7 downto 0);
255
             dr:  in STD_LOGIC_VECTOR(15 downto 0);
256
                            op:  in STD_LOGIC_VECTOR(15 downto 0);
257
                            xr:  in STD_LOGIC_VECTOR(15 downto 0);
258
                            yr:  in STD_LOGIC_VECTOR(15 downto 0);
259
                            sr:  in STD_LOGIC_VECTOR(15 downto 0);
260
              v:  in STD_LOGIC_VECTOR(7 downto 0);    -- vector offset input
261
           dout: out STD_LOGIC_VECTOR(23 downto 0)    -- output
262
        );
263
  end component;
264
 
265
  -- 8 bit opcode register opr (pipeline opcode prefetch register)
266
  component opr
267
    port(   clk:  in STD_LOGIC;                        -- clock
268
            clr:  in STD_LOGIC;                        -- force BRK opcode
269
          fwait:  in STD_LOGIC;                        -- wait
270
             ld:  in STD_LOGIC;                        -- load
271
            din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input 
272
          brk_f: out STD_LOGIC;                        -- BRK opcode         
273
          cop_f: out STD_LOGIC;                        -- COP opcode
274
           dout: out STD_LOGIC_VECTOR(7 downto 0)      -- output
275
        );
276
  end component;
277
 
278
  -- 16 bit operand hold register oper
279
  component oper
280
    port(    clk:  in STD_LOGIC;                       -- clock
281
                  clr:  in STD_LOGIC;                       -- clear
282
           fwait:  in STD_LOGIC;                       -- wait
283
              ld:  in STD_LOGIC;
284
          ld_lsb:  in STD_LOGIC;                       -- load lsb
285
          ld_msb:  in STD_LOGIC;                       -- load msb
286
             din:  in STD_LOGIC_VECTOR(15 downto 0);   -- input 
287
            dout: out STD_LOGIC_VECTOR(15 downto 0)    -- output
288
        );
289
  end component;
290
 
291
  -- 16 bit accumulator register A
292
  component ar
293
    port(       clk:  in STD_LOGIC;                    -- clock                      
294
              fwait:  in STD_LOGIC;
295
                         size:  in STD_LOGIC;                      -- accumulator register size: 1 = 8 bit, 0 = 16 bit
296
             ld_lsb:  in STD_LOGIC;                    -- load lsb
297
             ld_msb:  in STD_LOGIC;                    -- load msb 
298
              ld_mul_lsb:  in STD_LOGIC;                    -- load multiplication lsb result
299
                            d:  in STD_LOGIC;                    -- decrement
300
                    end_count: out STD_LOGIC;                    -- '1' when a is 0xFF or 0xFFFF 
301
                din:  in STD_LOGIC_VECTOR(15 downto 0); -- input
302
                           mul_lsb:  in STD_LOGIC_VECTOR(15 downto 0); -- input multiplication lsb result          
303
               dout: out STD_LOGIC_VECTOR(15 downto 0)  -- output
304
        );
305
  end component;
306
 
307
  -- 16 bit index register X 
308
  component xr
309
    port(       clk:  in STD_LOGIC;                       -- clock                         
310
              fwait:  in STD_LOGIC;
311
                         size:  in STD_LOGIC;                         -- index register size: 1 = 8 bit, 0 = 16 bit
312
             ld_lsb:  in STD_LOGIC;                       -- load lsb
313
             ld_msb:  in STD_LOGIC;                       -- load msb
314
              ld_mul_msb:  in STD_LOGIC;
315
                            u:  in STD_LOGIC;                       -- increment
316
                            d:  in STD_LOGIC;                       -- decrement
317
                din:  in STD_LOGIC_VECTOR(15 downto 0);   -- input 
318
                      mul_msb:  in STD_LOGIC_VECTOR(15 downto 0);   -- input multiplication msb result     
319
               dout: out STD_LOGIC_VECTOR(15 downto 0)    -- output
320
        );
321
  end component;
322
 
323
  -- 16 bit index register Y 
324
  component yr
325
    port(    clk:  in STD_LOGIC;                       -- clock
326
           fwait:  in STD_LOGIC;
327
                      size:  in STD_LOGIC;                            -- index register size: 1 = 8 bit, 0 = 16 bit
328
          ld_lsb:  in STD_LOGIC;                       -- load lsb
329
          ld_msb:  in STD_LOGIC;                       -- load msb
330
                         u:  in STD_LOGIC;                       -- increment
331
                         d:  in STD_LOGIC;                       -- decrement
332
             din:  in STD_LOGIC_VECTOR(15 downto 0);   -- input 
333
            dout: out STD_LOGIC_VECTOR(15 downto 0)    -- output
334
        );
335
  end component;
336
 
337
  -- 16 bit zero page/direct register D 
338
  component dr
339
    port(     clk:  in STD_LOGIC;                      -- clock
340
              clr:  in STD_LOGIC;                      -- reset
341
            fwait:  in STD_LOGIC;
342
           ld_lsb:  in STD_LOGIC;                      -- load lsb
343
           ld_msb:  in STD_LOGIC;                      -- load msb
344
              din:  in STD_LOGIC_VECTOR(15 downto 0);  -- input 
345
             dout: out STD_LOGIC_VECTOR(15 downto 0)   -- output
346
        );
347
  end component;
348
 
349
  -- 16 bit stack pointer SP 
350
  component spr
351
    port(   clk:  in STD_LOGIC;                        -- clock
352
          fwait:  in STD_LOGIC;                        -- wait
353
                       em:   in STD_LOGIC;                       -- emulation mode (1)/native mode (0)
354
            clr:  in STD_LOGIC;                        -- load init value
355
           ld_l:  in STD_LOGIC;                        -- load lsb
356
           ld_h:  in STD_LOGIC;                        -- load msb
357
              u:  in STD_LOGIC;                        -- increment
358
              d:  in STD_LOGIC;                        -- decrement
359
            din:  in STD_LOGIC_VECTOR(15 downto 0);    -- input
360
           dout: out STD_LOGIC_VECTOR(15 downto 0)     -- output
361
      );
362
  end component;
363
 
364
-- 8 bit processor status register P
365
-- NV1BDIZC    
366
-- 76543210
367
-- ||||||||
368
-- ||||||||--- C/E = carry/borrow flag (emulation bit: 1 = emulation mode, 0 = native mode)
369
-- |||||||---- Z = zero flag
370
-- ||||||----- I = interrupt mask
371
-- |||||------ D = decimal/binary alu mode
372
-- ||||------- B/X = index reg. select (1 = 8 bit, 0 = 16 bit) (B Break: 0 on stack after interrupt if E emulation mode = 1)
373
-- |||-------- M = memory/acc. select (1 = 8 bit, 0 = 16 bit) (always 1 if E = 1) 
374
-- ||--------- V = overflow flag
375
-- |---------- N = negative flag
376
  -- The P register also contains an additional carry/borrow flag (ACR) used for effective address calculation but
377
  -- it is not visible at program level
378
  component pr
379
    port(      clk:  in STD_LOGIC;                        -- clock
380
               clr:  in STD_LOGIC;                        -- clear
381
             fwait:  in STD_LOGIC;                        -- wait
382
                 n:  in STD_LOGIC;                        -- N input
383
                 v:  in STD_LOGIC;                        -- V input
384
                 z:  in STD_LOGIC;                        -- Z input
385
                 c:  in STD_LOGIC;                        -- C input
386
                       mpy_z:  in STD_LOGIC;                        -- Z input from multiplier                  
387
                       mpy_n:  in STD_LOGIC;                        -- N input from multiplier                  
388
               swi:  in STD_LOGIC;                        -- software interrupt (BRK/COP opcode)
389
            acr_in:  in STD_LOGIC;                        -- auxiliary carry in   
390
                fc:  in STD_LOGIC_VECTOR(4 downto 0);     -- function code 
391
               din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input
392
              dout: out STD_LOGIC_VECTOR(7 downto 0);     -- output
393
           acr_out: out STD_LOGIC;                        -- auxiliary carry out   
394
                               em: out STD_LOGIC;                        -- emulation (1)/native mode (0)
395
                      two_op: out STD_LOGIC                         -- two byte instruction                              
396
        );
397
  end component;
398
 
399
  -- 16 bit (binary/bcd) two-way through pass ALU   
400
  component alu_bin
401
    port( alu_byp:  in STD_LOGIC;                      -- ALU bypass (no operation)    
402
              bcd:  in STD_LOGIC;                      -- BCD mode 
403
                            size:  in STD_LOGIC;                           -- ALU size operation: 1 = 8 bit, 0 = 16 bit
404
              cin:  in STD_LOGIC;                      -- carry/borrow in
405
              vin:  in STD_LOGIC;                      -- overflow in
406
              op1:  in STD_LOGIC_VECTOR(15 downto 0);  -- 16 bit operand #1
407
              op2:  in STD_LOGIC_VECTOR(15 downto 0);  -- 16 bit operand #2
408
               fc:  in STD_LOGIC_VECTOR(4 downto 0);   -- function code
409
               cf: out STD_LOGIC;                      -- carry/borrow (byte) out 
410
               zf: out STD_LOGIC;                      -- zero flag out
411
               nf: out STD_LOGIC;                      -- negative flag out
412
               vf: out STD_LOGIC;                      -- overflow flag out
413
            pc_cf: out STD_LOGIC;                      -- carry/borrow out for PC operation 
414
             dout: out STD_LOGIC_VECTOR(15 downto 0)   -- 16 bit result out
415
        );
416
  end component;
417
 
418
  -- PC/MP address multiplexer
419
  component addrmux
420
    port(  sel:  in STD_LOGIC_VECTOR(2 downto 0);
421
             a:  in STD_LOGIC_VECTOR(23 downto 0);
422
             b:  in STD_LOGIC_VECTOR(23 downto 0);
423
                          dbr:  in STD_LOGIC_VECTOR(7 downto 0);
424
             s:  in STD_LOGIC_VECTOR(15 downto 0);
425
                           xr:  in STD_LOGIC_VECTOR(15 downto 0);
426
                           yr:  in STD_LOGIC_VECTOR(15 downto 0);
427
             y: out STD_LOGIC_VECTOR(23 downto 0)
428
        );
429
  end component;
430
 
431
  -- register multiplexer
432
  component regmux
433
    port(  sel:  in STD_LOGIC_VECTOR(4 downto 0);
434
             a:  in STD_LOGIC_VECTOR(7 downto 0);
435
             b:  in STD_LOGIC_VECTOR(15 downto 0);
436
             c:  in STD_LOGIC_VECTOR(15 downto 0);
437
             d:  in STD_LOGIC_VECTOR(15 downto 0);
438
             e:  in STD_LOGIC_VECTOR(15 downto 0);
439
             g:  in STD_LOGIC_VECTOR(7 downto 0);
440
             h:  in STD_LOGIC_VECTOR(7 downto 0);
441
             i:  in STD_LOGIC_VECTOR(7 downto 0);
442
             j:  in STD_LOGIC_VECTOR(15 downto 0);
443
             k:  in STD_LOGIC_VECTOR(15 downto 0);
444
             l:  in STD_LOGIC_VECTOR(7 downto 0);
445
             m:  in STD_LOGIC_VECTOR(7 downto 0);
446
             y: out STD_LOGIC_VECTOR(15 downto 0)
447
        );
448
  end component;
449
 
450
  -- data multiplexer (register "O" bypass)
451
  component dmux is
452
    port(  sel:  in STD_LOGIC_VECTOR(2 downto 0);
453
             a:  in STD_LOGIC_VECTOR(15 downto 0);
454
             b:  in STD_LOGIC_VECTOR(7 downto 0);
455
             y: out STD_LOGIC_VECTOR(15 downto 0)
456
        );
457
  end component dmux;
458
 
459
  -- microcode sequencer logic
460
  component mcseq
461
    port(    clk:  in STD_LOGIC;
462
             clr:  in STD_LOGIC;
463
          mc_nop:  in STD_LOGIC;
464
           fwait:  in STD_LOGIC;
465
               q: out STD_LOGIC_VECTOR(3 downto 0)
466
        );
467
  end component;
468
 
469
  -- micropla logic
470
  -- output fields format:
471
  -- a[12]    is two byte instruction bit
472
  -- a[11..4] is 8 bit opcode  
473
  -- a[3..0]  is 4 bit microinstruction counter
474
  component mcpla
475
    port(    em:  in STD_LOGIC;                           -- emulation mode (1)/native mode (0)
476
              m:  in STD_LOGIC;                           -- M memory/acc. 8 bit (1), M memory/acc. 16 bit (0)  
477
              x:  in STD_LOGIC;                           -- X index reg. 8 bit (1), X index reg. 16 bit (0)  
478
                   a:  in STD_LOGIC_VECTOR(12 downto 0);       -- two byte bit & 8 bit opcode & 4 bit microinstruction counter
479
              q: out STD_LOGIC_VECTOR(44 downto 0)        -- microcode output
480
        );
481
  end component;
482
 
483
  -- register operation decoding logic
484
  component decreg
485
    port(    r:  in STD_LOGIC_VECTOR(5 downto 0);
486
             y: out STD_LOGIC_VECTOR(29 downto 0)
487
        );
488
  end component;
489
 
490
  -- cpu main state machine
491
  component cpufsm
492
    port(     clk:  in STD_LOGIC;
493
              clr:  in STD_LOGIC;
494
            fwait:  in STD_LOGIC;
495
             ireq:  in STD_LOGIC;
496
              aim:  in STD_LOGIC;
497
           bcarry:  in STD_LOGIC;
498
           icarry:  in STD_LOGIC;
499
               p1:  in STD_LOGIC_VECTOR(2 downto 0);
500
             e_ei:  in STD_LOGIC;
501
            mc_ei:  in STD_LOGIC;
502
           addsub:  in STD_LOGIC;
503
         dec_mode:  in STD_LOGIC;
504
            fetch: out STD_LOGIC;
505
          op_sync: out STD_LOGIC;
506
              pci: out STD_LOGIC;
507
               pq: out STD_LOGIC_VECTOR(2 downto 0);
508
               fb: out STD_LOGIC;
509
               od: out STD_LOGIC;
510
           mc_nop: out STD_LOGIC
511
        );
512
  end component;
513
 
514
  -- interrupt logic
515
  component intlog
516
  port(    clk:  in STD_LOGIC;
517
          iack:  in STD_LOGIC;                    -- interrupt acknowledge by microcode 
518
             r:  in STD_LOGIC;                    -- RESET request
519
             n:  in STD_LOGIC;                    -- NMI request
520
             i:  in STD_LOGIC;                    -- IRQ request
521
           brk:  in STD_LOGIC;                    -- BRK opcode
522
                          cop:  in STD_LOGIC;                    -- COP opcode
523
                            e:  in STD_LOGIC;                    -- native\emulation mode
524
                        gmask:  in STD_LOGIC;                    -- interrupt mask valid for IRQ and NMI (used by two byte instruction)  
525
         imask:  in STD_LOGIC;                    -- interrupt mask (valid only for IRQ)
526
         ioffs:  in STD_LOGIC_VECTOR(7 downto 0); -- interrupt servicing offset
527
          ireq: out STD_LOGIC;                    -- global interrupt requestb (IRQ/NMI)
528
         voffs: out STD_LOGIC_VECTOR(7 downto 0)  -- interrupt vector offset 
529
        );
530
  end component;
531
 
532
  -- branch logic
533
  component branch
534
    port(    op:  in STD_LOGIC_VECTOR(3 downto 0);
535
              n:  in STD_LOGIC;
536
              v:  in STD_LOGIC;
537
              z:  in STD_LOGIC;
538
              c:  in STD_LOGIC;
539
           bres: out STD_LOGIC
540
        );
541
  end component;
542
 
543
  -- opcode decimal instructions and prefetch prediction logic
544
  component pre_dec
545
    port(    op:  in STD_LOGIC_VECTOR(7 downto 0);
546
          fetch:  in STD_LOGIC;
547
             ei: out STD_LOGIC;
548
            dec: out STD_LOGIC
549
        );
550
  end component;
551
 
552
  -- 16X16->32 bit multiplier signed/unsigned
553
  component multiplier
554
    port(     clk:   in STD_LOGIC;
555
              clr:   in STD_LOGIC;
556
             init:   in STD_LOGIC;
557
          start_u:   in STD_LOGIC;
558
               start_s:   in STD_LOGIC;
559
           mpcand:   in STD_LOGIC_VECTOR(15 downto 0);
560
                          mplier:   in STD_LOGIC_VECTOR(15 downto 0);
561
                            busy:  out STD_LOGIC;
562
          res_lsb:  out STD_LOGIC_VECTOR(15 downto 0);
563
          res_msb:  out STD_LOGIC_VECTOR(15 downto 0);
564
                           z_flg:  out STD_LOGIC;
565
                                n_flg:  out STD_LOGIC
566
      );
567
  end component;
568
 
569
  begin
570
    u1:pcr      port map(clk=>clk0,
571
                         i=>pcinc,
572
                         fwait=>i_rdy,
573
                                                                 brk_op=>opbrk,
574
                                                                 branch_flg=>branch_taken,
575
                                                                 mov_f=>mov_end,
576
                         fc=>pcr_fc,
577
                         din1=>alu_bus(7 downto 0),
578
                         din2=>o_bus,
579
                         dout=>pc_bus
580
                        );
581
 
582
    u2:kr       port map(clk=>clk0,
583
                              clr=>kr_clear,
584
                         fwait=>i_rdy,
585
                         ld=>k_l,
586
                         din=>alu_bus(7 downto 0),
587
                         dout=>k_bus
588
                        );
589
 
590
    u3:br       port map(clk=>clk0,
591
                              clr=>br_clear,
592
                         fwait=>i_rdy,
593
                         ld=>b_l,
594
                         din=>alu_bus(7 downto 0),
595
                         dout=>b_bus
596
                        );
597
 
598
    u4:mpr      port map(clk=>clk0,
599
                         fwait=>i_rdy,
600
                         dbr_ld=>opfetch,
601
                         c=>acr_reg,
602
                         fc=>mpr_fc,
603
                         din_l=>alu_bus(7 downto 0),
604
                         din_h=>dbin,
605
                         dbr=>b_bus,
606
                         dr=>d_bus,
607
                                        op=>o_bus,
608
                                        xr=>x_bus,
609
                                        yr=>y_bus,
610
                                        sr=>sp_bus,
611
                         v=>ivoffs,
612
                         dout=>mp_bus
613
                        );
614
 
615
    u5:ar       port map(clk=>clk0,
616
                         fwait=>i_rdy,
617
                                                                 size=>acc_size,
618
                         ld_lsb=>a_l_lsb,
619
                         ld_msb=>a_l_msb,
620
                                                                 ld_mul_lsb=>mul_l_res,
621
                                                                 d=>a_dec,
622
                                                                 end_count=>mov_end,
623
                         din=>alu_bus,
624
                                                                 mul_lsb=>mul_r_lsb,
625
                         dout=>a_bus
626
                        );
627
 
628
    u6:xr       port map(clk=>clk0,
629
                         fwait=>i_rdy,
630
                                                                 size=>index_size,
631
                         ld_lsb=>x_l_lsb,
632
                         ld_msb=>x_l_msb,
633
                                                                 ld_mul_msb=>mul_l_res,
634
                                                                 u=>x_u,
635
                                                                 d=>x_d,
636
                         din=>alu_bus,
637
                                                                 mul_msb=>mul_r_msb,
638
                         dout=>x_bus
639
                        );
640
 
641
    u7:yr       port map(clk=>clk0,
642
                         fwait=>i_rdy,
643
                                                                 size=>index_size,
644
                         ld_lsb=>y_l_lsb,
645
                         ld_msb=>y_l_msb,
646
                                                                 u=>y_u,
647
                                                                 d=>y_d,
648
                         din=>alu_bus,
649
                         dout=>y_bus
650
                        );
651
 
652
    u8:dr       port map(clk=>clk0,
653
                         clr=>i_res,
654
                         fwait=>i_rdy,
655
                         ld_lsb=>d_l_lsb,
656
                         ld_msb=>d_l_msb,
657
                         din=>alu_bus,
658
                         dout=>d_bus
659
                        );
660
 
661
    u9:spr      port map(clk=>clk0,
662
                         clr=>i_res,
663
                         fwait=>i_rdy,
664
                                                                 em=>sp_emu,
665
                         ld_l=>sp_ll,
666
                         ld_h=>sp_lh,
667
                         u=>sp_u,
668
                         d=>sp_d,
669
                         din=>alu_bus,
670
                         dout=>sp_bus
671
                        );
672
 
673
    u10:pr      port map(clk=>clk0,
674
                         clr=>i_res,
675
                         fwait=>i_rdy,
676
                         n=>n_flg,
677
                         v=>v_flg,
678
                         z=>z_flg,
679
                         c=>c_flg,
680
                                                                 mpy_z=>mul_z_flg,
681
                                                                 mpy_n=>mul_n_flg,
682
                         swi=>sw_int,
683
                         acr_in=>pc_c_alu_flg,
684
                         fc=>p_op,
685
                         din=>dbin,
686
                         dout=>p_bus,
687
                         acr_out=>acr_reg,
688
                                                                 em=>emu,
689
                                                                 two_op=>two_byte_op
690
                        );
691
 
692
    u11:opr     port map(clk=>clk0,
693
                         clr=>fbrk,
694
                         fwait=>i_rdy,
695
                         ld=>opfetch,
696
                         din=>dbin,
697
                         brk_f=>opbrk,
698
                                                                 cop_f=>opcop,
699
                         dout=>op_bus
700
                        );
701
 
702
    u12:oper    port map(clk=>clk0,
703
                              clr=>opfetch,
704
                         fwait=>i_rdy,
705
                                                                 ld=>o_l,
706
                         ld_lsb=>o_l_lsb,
707
                         ld_msb=>o_l_msb,
708
                         din=>alu_bus,
709
                         dout=>o_bus
710
                        );
711
 
712
    u13:alu_bin port map(alu_byp=>acr_reg,
713
                              bcd=>p_bus(3),
714
                                                                 size=>m_size,
715
                         cin=>p_bus(0),
716
                         vin=>p_bus(6),
717
                         op1=>r_bus,
718
                         op2=>oper_bus,
719
                         fc=>aluop,
720
                         cf=>c_flg,
721
                         zf=>z_flg,
722
                         nf=>n_flg,
723
                         vf=>v_flg,
724
                         pc_cf=>pc_c_alu_flg,
725
                         dout=>alu_bus
726
                        );
727
 
728
    u14:addrmux port map(sel=>pcmp,
729
                         a=>i_addr_bus,
730
                         b=>mp_bus,
731
                                                                 dbr=>b_bus,
732
                         s=>sp_bus,
733
                                                                 xr=>x_bus,
734
                                                                 yr=>y_bus,
735
                         y=>addr
736
                        );
737
 
738
    u15:regmux  port map(sel=>rsel,
739
                         a=>dbin,
740
                         b=>a_bus,
741
                         c=>x_bus,
742
                         d=>y_bus,
743
                         e=>sp_bus,
744
                         g=>p_bus,
745
                         h=>pc_bus(7 downto 0),
746
                         i=>pc_bus(15 downto 8),
747
                         j=>o_bus,
748
                         k=>d_bus,
749
                                                                 l=>k_bus,
750
                                                                 m=>b_bus,
751
                         y=>r_bus
752
                        );
753
 
754
    u16:dmux    port map(sel=>dmux_sel,
755
                         a=>o_bus,
756
                         b=>dbin,
757
                         y=>oper_bus
758
                        );
759
 
760
    u17:mcseq   port map(clk=>clk0,
761
                         clr=>opdec,
762
                         mc_nop=>mcn,
763
                         fwait=>i_rdy or mul_busy,
764
                         q=>mcscan
765
                        );
766
 
767
    u18:mcpla   port map(em=>emu,
768
                              m=>m_bit,
769
                              x=>x_bit,
770
                              a=>mc_addr,
771
                         q=>mcbit
772
                        );
773
 
774
    u19:decreg  port map(r=>regop,
775
                         y=>regbit
776
                        );
777
 
778
    u20:cpufsm  port map(clk=>clk0,
779
                         clr=>i_res,
780
                         fwait=>i_rdy,
781
                         ireq=>int,
782
                         aim=>ai_op,
783
                         bcarry=>pcc,
784
                         icarry=>acr_reg,
785
                         p1=>pcmp_mc,
786
                         e_ei=>e_eop,
787
                         mc_ei=>mc_eop,
788
                         addsub=>add_sub_op,
789
                         dec_mode=>p_bus(3),
790
                         fetch=>opfetch,
791
                         op_sync=>i_sync,
792
                         pci=>pcinc,
793
                         pq=>pcmp,
794
                         fb=>fbrk,
795
                         od=>opdec,
796
                         mc_nop=>mcn
797
                        );
798
 
799
    u21:intlog  port map(clk=>clk0,
800
                         iack=>clri,
801
                         r=>i_res,
802
                         n=>i_nmi,
803
                         i=>i_irq,
804
                         brk=>opbrk,
805
                                                                 cop=>opcop,
806
                                                                 e=>emu,
807
                         gmask=>two_byte_op,
808
                         imask=>ien,
809
                         ioffs=>mp_bus(7 downto 0),
810
                         ireq=>int,
811
                         voffs=>ivoffs
812
                        );
813
 
814
    u22:branch  port map(op=>op_bus(7 downto 4),
815
                         n=>p_bus(7),
816
                         v=>p_bus(6),
817
                         z=>p_bus(1),
818
                         c=>p_bus(0),
819
                         bres=>branch_taken
820
                        );
821
 
822
    u23:pre_dec port map(op=>dbin,
823
                         fetch=>opfetch,
824
                         ei=>e_eop,
825
                         dec=>add_sub_op
826
                        );
827
 
828
    u24:multiplier port map(clk=>clk0,
829
                                 clr=>i_res,
830
                            init=>mul_init,
831
                            start_u=>mul_start_u,
832
                                                                         start_s=>mul_start_s,
833
                            mpcand=>a_bus,
834
                                           mplier=>x_bus,
835
                                           busy=>mul_busy,
836
                            res_lsb=>mul_r_lsb,
837
                            res_msb=>mul_r_msb,
838
                                                                         z_flg=>mul_z_flg,
839
                                                                         n_flg=>mul_n_flg
840
                                                                   );
841
 
842
    -- asynchronous CPU link section 
843
         mc_addr    <= two_byte_op & mcad;
844
         e          <= emu;                                     -- emulation mode
845
    ien        <= p_bus(2);                                -- P(I) flag 
846
    i_res      <= not res;                                 -- internal reset
847
    i_nmi      <= not nmi;                                 -- internal NMI
848
    i_irq      <= not irq;                                 -- internal IRQ
849
    e_rdy      <= not rdy;                                 -- external RDY inverted
850
         i_rdy      <= e_rdy or wai_ff or stp_ff;               -- internal RDY
851
    mcad       <= op_bus & mcscan;                         -- microcode address
852
    rsel       <= mcbit(4 downto 0);                       -- registers read microcode
853
    regop      <= mcbit(10 downto 5);                      -- registers operation microcode
854
    aluop      <= mcbit(15 downto 11);                     -- ALU microcode
855
    p_op       <= mcbit(20 downto 16);                     -- register P microcode 
856
    mpr_fc     <= mcbit(25 downto 21);                     -- MPR microcode
857
    pcr_fc     <= mcbit(29 downto 26);                     -- PCR microcode
858
    pcmp_mc    <= mcbit(32 downto 30);                     -- PCR/MPR multiplexer microcode
859
    clri       <= mcbit(33);                               -- clear interrupt request
860
    we_mc      <= mcbit(34);                               -- write enable (combinatorial) microcode
861
    we_mc_l    <= mcbit(35);                               -- write enable (latched) microcode
862
    mc_eop     <= mcbit(36);                               -- end of instruction reached                             
863
    mc_vda     <= mcbit(37);                               -- microcode VDA
864
         mc_vpa     <= mcbit(38);                               -- microcode VPA
865
         mc_ml      <= mcbit(39);                               -- microcode ML
866
    i_vp       <= mcbit(40);                               -- vector pull 
867
    ai_op      <= mcbit(41);                               -- opcode with addressing indexed microcode
868
    dmux_sel   <= mcbit(44 downto 42);                     -- data multiplexer microcode
869
    ope        <= eop;
870
         i_addr_bus <= k_bus & pc_bus;
871
    eop <= '1' when mc_eop = '1' or e_eop = '1' else '0';
872
    vp <= not i_vp;
873
         op_exp <= two_byte_op;
874
         vda <= m_sync or mc_vda;
875
    vpa <= m_sync or mc_vpa;
876
         ml <= mc_ml;
877
         sw_int <= opbrk or opcop;
878
 
879
         -- ALU/memory size 
880
    m_size8  <= '1' when emu = '1' or m_bit = '1' else
881
                     '1' when op_bus = x"EB" or op_bus = x"AB" else                     -- when XBA and PLB opcodes the ALU size is always 8 bit
882
                     '1' when (op_bus = x"AA" or op_bus = x"A8") and x_bit = '1' else   -- when TAX and TAY opcodes and X is '1' the ALU size is 8 bit
883
                     '1' when (op_bus = x"8A" or op_bus = x"98") and m_bit = '1' else   -- when TXA and TXA opcodes and M is '1' the ALU size is 8 bit
884
                     '1' when op_bus = x"68" and m_bit = '1' else                       -- when PLA opcode and M is '1' the ALU size is 8 bit
885
                     '1' when (op_bus = x"FA" or op_bus = x"7A") and x_bit = '1' else   -- when PLX or PLY opcode and X = '1' the ALU size is 8 bit
886
                                         '0';
887
         m_size16 <= '0' when (op_bus = x"5B" or op_bus = x"7B") else                   -- when TCD or TDC opcodes the transfer size is always 16 bit
888
                     '0' when (op_bus = x"1B" or op_bus = x"3B") else                   -- when TCS or TSC opcodes the transfer size is always 16 bit
889
                     '0' when (op_bus = x"82" or op_bus = x"62") else                   -- when BRL or PER opcodes the transfer size is always 16 bit
890
                     '0' when op_bus = x"2B" else                                       -- when PLD opcode the transfer size is always 16 bit
891
                                         '0' when (op_bus = x"AB" and two_byte_op = '1') and emu = '0' else -- when PLR opcode and native mode
892
                                         '0' when ld_acc = '1' and m_bit = '0' else                         -- when load accumulator C register 
893
                                         '0' when ld_xy = '1' and x_bit = '0' else                          -- when load X/Y registers (16 bit size)   
894
                                    '1';
895
         s_size16 <= '0' when op_bus = x"EB" else '1';                                  -- special case for XBA: accumulator size is 16 bit so it can reloads itself swapped in only one cycle                                                    
896
         m_size <= m_size8 and m_size16;                                                       -- ALU size                       
897
         acc_size <= m_size8 and m_size16 and s_size16;                                 -- accumulator register C size
898
    index_size <= emu or x_bit;                                                    -- index registers size 
899
 
900
         -- S native/emulation mode (set by XCE opcode and E bit)
901
    sp_emu <= p_bus(0) when op_bus = x"FB" else emu;
902
 
903
    -- register operations
904
    a_l_lsb     <= regbit(0);                               -- A load lsb
905
    a_l_msb     <= regbit(1);                               -- A load msb
906
    a_dec       <= regbit(2);                               -- A decrement
907
    x_l_lsb     <= regbit(3);                               -- X load lsb
908
    x_l_msb     <= regbit(4);                               -- X load msb
909
         x_d         <= regbit(5);                               -- X -= 1
910
         x_u         <= regbit(6);                               -- X += 1
911
    y_l_lsb     <= regbit(7);                               -- Y load lsb
912
    y_l_msb     <= regbit(8);                               -- Y load msb
913
         y_d         <= regbit(9);                               -- Y -= 1
914
         y_u         <= regbit(10);                              -- Y += 1
915
    d_l_lsb     <= regbit(11);                              -- D load lsb
916
    d_l_msb     <= regbit(12);                              -- D load msb
917
    o_l         <= regbit(13);                              -- O load msb & lsb
918
    o_l_lsb     <= regbit(14);                              -- O load lsb
919
    o_l_msb     <= regbit(15);                              -- O load msb
920
    sp_ll       <= regbit(16);                              -- S load lsb
921
    sp_lh       <= regbit(17);                              -- S load msb
922
    sp_u        <= regbit(18);                              -- S += 1
923
    sp_d        <= regbit(19);                              -- S -= 1
924
    k_l         <= regbit(20);                              -- PBR K load
925
    b_l         <= regbit(21);                              -- DBR B load
926
    k_cl        <= regbit(22);                              -- PBR K clear
927
    b_cl        <= regbit(23);                              -- DBR B clear
928
         mul_l_res   <= regbit(24);                              -- load multiplication result on A/B and X
929
         mul_init    <= regbit(25);                              -- init multiplier
930
         mul_start_u <= regbit(26);                              -- start multiplier unsigned 
931
         mul_start_s <= regbit(27);                              -- start multiplier signed
932
         wai_set     <= regbit(28);                              -- WAI enter wait
933
         stp_set     <= regbit(29);                              -- STP enter wait
934
    we          <= we_mc or opfetch;                        -- write enable
935
    m_bit       <= p_bus(5) or emu;                         -- M bit
936
    x_bit       <= p_bus(4) or emu;                         -- X bit
937
    m           <= m_bit;
938
    x           <= x_bit;
939
         kr_clear    <= i_res or k_cl;
940
         br_clear    <= i_res or b_cl;
941
         ld_acc      <= regbit(0) and regbit(1);
942
    ld_xy       <= (regbit(3) and regbit(4)) or (regbit(7) and regbit(8));
943
    -- VPA latched
944
    process(clk0)
945
    begin
946
      if (clk0'event and clk0 = '1') then
947
        if i_rdy = '0' then
948
          m_sync <= i_sync;
949
        else
950
          m_sync <= m_sync;
951
        end if;
952
      end if;
953
    end process;
954
 
955
    -- PC carry logic
956
    process(o_bus,pc_c_alu_flg)
957
    begin
958
      if o_bus(7) = '0' then              -- check for positive/negative branch offset (bit 7)
959
        pcc <= pc_c_alu_flg;
960
      else
961
        pcc <= not pc_c_alu_flg;
962
      end if;
963
    end process;
964
 
965
    -- write enable registered
966
    process(clk0)
967
    begin
968
      if (clk0'event and clk0 = '1') then
969
        if i_res = '1' then
970
          we_r <= '1';
971
        else
972
          if i_rdy = '0' then
973
            we_r <= we_mc_l;
974
          else
975
            we_r <= we_r;
976
          end if;
977
        end if;
978
      end if;
979
    end process;
980
 
981
    rw <= we and we_r;
982
 
983
         -- WAI 
984
         process(clk0)
985
         begin
986
      if (clk0'event and clk0 = '1') then
987
             if wai_ff = '0' then
988
          if wai_set then
989
             wai_ff <= '1';
990
          else
991
             wai_ff <= wai_ff;
992
          end if;
993
                  else
994
          if i_res = '1' or i_nmi = '1' or i_irq = '1' then
995
                       wai_ff <= '0';
996
          else
997
                       wai_ff <= wai_ff;
998
          end if;
999
        end if;
1000
                end if;
1001
    end process;
1002
    rdy_out <= not wai_ff;
1003
 
1004
         -- STP 
1005
         process(clk0)
1006
         begin
1007
      if (clk0'event and clk0 = '1') then
1008
             if stp_ff = '0' then
1009
          if stp_set then
1010
             stp_ff <= '1';
1011
          else
1012
             stp_ff <= stp_ff;
1013
          end if;
1014
                  else
1015
          if i_res = '1' then
1016
                       stp_ff <= '0';
1017
          else
1018
                       stp_ff <= stp_ff;
1019
          end if;
1020
        end if;
1021
                end if;
1022
    end process;
1023
    stp_out <= not stp_ff;
1024
 
1025
 
1026
    -- data bus tristate (buffer ring gated) control logic
1027
    --process(clk0,we,we_r,alu_bus)
1028
    --begin
1029
    --  if clock = '0' and (we = '0' or we_r = '0') then
1030
    --    data <= alu_bus;
1031
    --  else
1032
    --    data <= "ZZZZZZZZ";
1033
    --  end if;
1034
    --end process;
1035
 
1036
 
1037
    data_out <= alu_bus(7 downto 0);
1038
    dbin <= data_in or "00000000";
1039
         -- DEBUG
1040
--  a_reg <= a_bus;
1041
--  x_reg <= x_bus;
1042
--  y_reg <= y_bus;
1043
--       s_reg <= sp_bus;
1044
--       op_reg <= o_bus;
1045
--       p_reg <= p_bus;
1046
--       k_reg <= k_bus;
1047
--       b_reg <= b_bus;
1048
--       o_reg <= op_bus;
1049
--       mcode <= mcscan;
1050
 
1051
end struct;
1052
 
1053
 
1054
 

powered by: WebSVN 2.1.0

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