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

Subversion Repositories v65c816

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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