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

Subversion Repositories t48

[/] [t48/] [tags/] [rel_0_4_beta/] [rtl/] [vhdl/] [decoder.vhd] - Blame information for rev 60

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

Line No. Rev Author Line
1 4 arniml
-------------------------------------------------------------------------------
2
--
3
-- The Decoder unit.
4
-- It decodes the instruction opcodes and executes them.
5
--
6 60 arniml
-- $Id: decoder.vhd,v 1.7 2004-04-15 22:06:05 arniml Exp $
7 4 arniml
--
8
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
9
--
10
-- All rights reserved
11
--
12
-- Redistribution and use in source and synthezised forms, with or without
13
-- modification, are permitted provided that the following conditions are met:
14
--
15
-- Redistributions of source code must retain the above copyright notice,
16
-- this list of conditions and the following disclaimer.
17
--
18
-- Redistributions in synthesized form must reproduce the above copyright
19
-- notice, this list of conditions and the following disclaimer in the
20
-- documentation and/or other materials provided with the distribution.
21
--
22
-- Neither the name of the author nor the names of other contributors may
23
-- be used to endorse or promote products derived from this software without
24
-- specific prior written permission.
25
--
26
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
28
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
30
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36
-- POSSIBILITY OF SUCH DAMAGE.
37
--
38
-- Please report bugs to the author, but before you do so, please
39
-- make sure that this is not a derivative work and that
40
-- you have the latest version of this file.
41
--
42
-- The latest version of this file can be found at:
43
--      http://www.opencores.org/cvsweb.shtml/t48/
44
--
45
-------------------------------------------------------------------------------
46
 
47
library ieee;
48
use ieee.std_logic_1164.all;
49
 
50
use work.t48_pack.word_t;
51
use work.t48_pack.mstate_t;
52
use work.alu_pack.alu_op_t;
53
use work.cond_branch_pack.all;
54
use work.dmem_ctrl_pack.all;
55
use work.pmem_ctrl_pack.all;
56
 
57
entity decoder is
58
 
59
  generic (
60
    -- store mnemonic in flip-flops (registered-out)
61
    register_mnemonic_g   : integer := 1
62
  );
63
 
64
  port (
65
    -- Global Interface -------------------------------------------------------
66
    clk_i                  : in  std_logic;
67
    res_i                  : in  std_logic;
68
    en_clk_i               : in  boolean;
69
    ea_i                   : in  std_logic;
70
    ale_i                  : in  boolean;
71
    int_n_i                : in  std_logic;
72
    t0_dir_o               : out std_logic;
73
    -- T48 Bus Interface ------------------------------------------------------
74
    data_i                 : in  word_t;
75
    data_o                 : out word_t;
76
    stack_high_o           : out boolean;
77
    alu_write_accu_o       : out boolean;
78
    alu_write_shadow_o     : out boolean;
79
    alu_write_temp_reg_o   : out boolean;
80
    alu_read_alu_o         : out boolean;
81
    bus_write_bus_o        : out boolean;
82
    bus_read_bus_o         : out boolean;
83
    dm_write_dmem_addr_o   : out boolean;
84
    dm_write_dmem_o        : out boolean;
85
    dm_read_dmem_o         : out boolean;
86
    p1_write_p1_o          : out boolean;
87
    p1_read_p1_o           : out boolean;
88
    p2_write_p2_o          : out boolean;
89
    p2_write_exp_o         : out boolean;
90
    p2_read_p2_o           : out boolean;
91 21 arniml
    p2_read_exp_o          : out boolean;
92 4 arniml
    pm_write_pcl_o         : out boolean;
93
    pm_read_pcl_o          : out boolean;
94
    pm_write_pch_o         : out boolean;
95
    pm_read_pch_o          : out boolean;
96
    pm_read_pmem_o         : out boolean;
97
    psw_read_psw_o         : out boolean;
98
    psw_read_sp_o          : out boolean;
99
    psw_write_psw_o        : out boolean;
100
    psw_write_sp_o         : out boolean;
101
    -- ALU Interface ----------------------------------------------------------
102
    alu_carry_i            : in  std_logic;
103
    alu_op_o               : out alu_op_t;
104
    alu_use_carry_o        : out boolean;
105 27 arniml
    alu_da_high_o          : out boolean;
106 38 arniml
    alu_accu_low_o         : out boolean;
107 27 arniml
    alu_p06_temp_reg_o     : out boolean;
108
    alu_p60_temp_reg_o     : out boolean;
109
    alu_da_overflow_i      : in  boolean;
110 4 arniml
    -- BUS Interface ----------------------------------------------------------
111
    bus_output_pcl_o       : out boolean;
112
    bus_bidir_bus_o        : out boolean;
113
    -- Clock Controller Interface ---------------------------------------------
114
    clk_multi_cycle_o      : out boolean;
115
    clk_assert_psen_o      : out boolean;
116
    clk_assert_prog_o      : out boolean;
117
    clk_assert_rd_o        : out boolean;
118
    clk_assert_wr_o        : out boolean;
119
    clk_mstate_i           : in  mstate_t;
120
    clk_second_cycle_i     : in  boolean;
121
    -- Conditional Branch Logic Interface -------------------------------------
122
    cnd_compute_take_o     : out boolean;
123
    cnd_branch_cond_o      : out branch_conditions_t;
124
    cnd_take_branch_i      : in  boolean;
125
    cnd_comp_value_o       : out comp_value_t;
126
    cnd_f1_o               : out std_logic;
127
    cnd_tf_o               : out std_logic;
128
    -- Data Memory Controller Interface ---------------------------------------
129
    dm_addr_type_o         : out dmem_addr_ident_t;
130
    -- Port 1 Interface -------------------------------------------------------
131
    p1_read_reg_o          : out boolean;
132
    -- Port 2 Interface -------------------------------------------------------
133
    p2_read_reg_o          : out boolean;
134
    p2_output_pch_o        : out boolean;
135
    p2_output_exp_o        : out boolean;
136
    -- Program Memory Controller Interface ------------------------------------
137
    pm_inc_pc_o            : out boolean;
138
    pm_write_pmem_addr_o   : out boolean;
139
    pm_addr_type_o         : out pmem_addr_ident_t;
140
    -- Program Status Word Interface ------------------------------------------
141
    psw_special_data_o     : out std_logic;
142
    psw_carry_i            : in  std_logic;
143 27 arniml
    psw_aux_carry_i        : in  std_logic;
144 4 arniml
    psw_f0_i               : in  std_logic;
145
    psw_inc_stackp_o       : out boolean;
146
    psw_dec_stackp_o       : out boolean;
147
    psw_write_carry_o      : out boolean;
148
    psw_write_aux_carry_o  : out boolean;
149
    psw_write_f0_o         : out boolean;
150
    psw_write_bs_o         : out boolean;
151
    -- Timer Interface --------------------------------------------------------
152
    tim_read_timer_o       : out boolean;
153
    tim_write_timer_o      : out boolean;
154
    tim_start_t_o          : out boolean;
155
    tim_start_cnt_o        : out boolean;
156
    tim_stop_tcnt_o        : out boolean;
157
    tim_overflow_i         : in  boolean
158
  );
159
 
160
end decoder;
161
 
162
 
163
use work.t48_pack.all;
164
use work.alu_pack.all;
165
use work.decoder_pack.all;
166
 
167
use work.t48_comp_pack.opc_decoder;
168
use work.t48_comp_pack.int;
169
 
170 53 arniml
-- pragma translate_off
171
use work.t48_tb_pack.tb_istrobe_s;
172
-- pragma translate_on
173
 
174 4 arniml
architecture rtl of decoder is
175
 
176
  -- Opcode Decoder
177
  signal opc_multi_cycle_s : boolean;
178
  signal opc_read_bus_s    : boolean;
179
  signal opc_inj_int_s     : boolean;
180
  signal opc_opcode_s      : word_t;
181
  signal opc_mnemonic_s    : mnemonic_t;
182
  signal last_cycle_s      : boolean;
183
 
184
  -- state translators
185
  signal assert_psen_s     : boolean;
186
 
187
  -- branch taken handshake
188
  signal branch_taken_s,
189
         branch_taken_q        : boolean;
190
  signal pm_inc_pc_s           : boolean;
191
  signal pm_write_pmem_addr_s  : boolean;
192
  -- additional signal to increment PC during CALL
193
  signal add_inc_pc_s          : boolean;
194
  -- addtional signal to set PC during RET(R)
195
  signal add_write_pmem_addr_s : boolean;
196
 
197
  -- Flag 1
198
  signal clear_f1_s,
199
         cpl_f1_s          : boolean;
200
  signal f1_q              : std_logic;
201
  -- memory bank select
202
  signal clear_mb_s,
203
         set_mb_s          : boolean;
204
  signal mb_q              : std_logic;
205
 
206
  -- T0 direction selection
207
  signal ent0_clk_s        : boolean;
208
  signal t0_dir_q          : std_logic;
209
 
210
  signal data_s            : word_t;
211
  signal read_dec_s        : boolean;
212
 
213
  signal tf_s              : std_logic;
214
 
215
  signal bus_read_bus_s    : boolean;
216
  signal add_read_bus_s    : boolean;
217
 
218
  signal dm_write_dmem_s   : boolean;
219
 
220
  -- interrupt handling
221
  signal jtf_executed_s    : boolean;
222
  signal en_tcnti_s        : boolean;
223
  signal dis_tcnti_s       : boolean;
224
  signal en_i_s            : boolean;
225
  signal dis_i_s           : boolean;
226
  signal tim_int_s         : boolean;
227
  signal retr_executed_s   : boolean;
228
  signal int_executed_s    : boolean;
229
  signal int_pending_s     : boolean;
230
 
231 38 arniml
  -- pragma translate_off
232
  signal istrobe_s         : std_logic;
233 60 arniml
  signal injected_int_q    : std_logic;
234 38 arniml
  -- pragma translate_on
235
 
236 4 arniml
begin
237
 
238
  -----------------------------------------------------------------------------
239
  -- Opcode Decoder
240
  -----------------------------------------------------------------------------
241
  opc_decoder_b : opc_decoder
242
    generic map (
243
      register_mnemonic_g => register_mnemonic_g
244
    )
245
    port map (
246
      clk_i         => clk_i,
247
      res_i         => res_i,
248
      en_clk_i      => en_clk_i,
249
      data_i        => data_i,
250
      read_bus_i    => opc_read_bus_s,
251
      inj_int_i     => opc_inj_int_s,
252
      opcode_o      => opc_opcode_s,
253
      mnemonic_o    => opc_mnemonic_s,
254
      multi_cycle_o => opc_multi_cycle_s
255
    );
256
 
257
 
258
  -----------------------------------------------------------------------------
259
  -- Interrupt Controller.
260
  -----------------------------------------------------------------------------
261
  int_b : int
262
    port map (
263
      clk_i           => clk_i,
264
      res_i           => res_i,
265
      en_clk_i        => en_clk_i,
266
      clk_mstate_i    => clk_mstate_i,
267
      jtf_executed_i  => jtf_executed_s,
268
      tim_overflow_i  => tim_overflow_i,
269
      tf_o            => tf_s,
270
      en_tcnti_i      => en_tcnti_s,
271
      dis_tcnti_i     => dis_tcnti_s,
272
      int_n_i         => int_n_i,
273
      ale_i           => ale_i,
274
      last_cycle_i    => last_cycle_s,
275
      en_i_i          => en_i_s,
276
      dis_i_i         => dis_i_s,
277
      ext_int_o       => open,
278
      tim_int_o       => tim_int_s,
279
      retr_executed_i => retr_executed_s,
280
      int_executed_i  => int_executed_s,
281
      int_pending_o   => int_pending_s
282
    );
283
 
284
  last_cycle_s <= not opc_multi_cycle_s or
285
                  (opc_multi_cycle_s and clk_second_cycle_i);
286
 
287
  -----------------------------------------------------------------------------
288
  -- Process machine_cycle
289
  --
290
  -- Purpose:
291
  --   Generates the control signals that are basically needed for the
292
  --   handling of a machine cycle.
293
  --
294
  machine_cycle: process (clk_mstate_i,
295
                          clk_second_cycle_i,
296
                          ea_i,
297
                          assert_psen_s,
298
                          branch_taken_q,
299
                          int_pending_s)
300
 
301
   variable need_address_v      : boolean;
302
 
303
  begin
304
    -- default assignments
305
    clk_assert_psen_o    <= false;
306
    pm_inc_pc_s          <= false;
307
    pm_write_pmem_addr_s <= false;
308
    pm_read_pmem_o       <= false;
309
    bus_output_pcl_o     <= false;
310
    p2_output_pch_o      <= false;
311
    opc_read_bus_s       <= false;
312
    opc_inj_int_s        <= false;
313
    bus_read_bus_s       <= false;
314
 
315
    need_address_v    := not clk_second_cycle_i or
316
                         (clk_second_cycle_i and assert_psen_s);
317
 
318
    case clk_mstate_i is
319
      when MSTATE1 =>
320
        if need_address_v and not int_pending_s then
321
          if ea_i = '0' then
322
            pm_read_pmem_o  <= true;
323
          else
324
            bus_read_bus_s  <= true;
325
          end if;
326
        end if;
327
 
328
        if not clk_second_cycle_i then
329
          if not int_pending_s then
330
            opc_read_bus_s  <= true;
331
          else
332
            opc_inj_int_s   <= true;    -- inject interrupt call
333
          end if;
334
        end if;
335
 
336
      when MSTATE2 =>
337
        if need_address_v and not branch_taken_q and
338
           not int_pending_s then
339
          pm_inc_pc_s       <= true;
340
        end if;
341
 
342
      when MSTATE3 =>
343
        if need_address_v then
344
          pm_write_pmem_addr_s <= true;
345
 
346
          if ea_i = '1' then
347
            bus_output_pcl_o   <= true;
348
          end if;
349
        end if;
350
 
351
      when MSTATE4 =>
352
        if need_address_v and ea_i = '1' then
353
          clk_assert_psen_o <= true;
354
 
355
          p2_output_pch_o  <= true;
356
        end if;
357
 
358
      when MSTATE5 =>
359
        if need_address_v and ea_i = '1' then
360
          clk_assert_psen_o <= true;
361
        end if;
362
 
363
      when others =>
364
        -- pragma translate_off
365
        assert false
366
          report "Unkown machine state!"
367
          severity error;
368
        -- pragma translate_on
369
 
370
    end case;
371
 
372
  end process machine_cycle;
373
  --
374
  -----------------------------------------------------------------------------
375
 
376
 
377
  -----------------------------------------------------------------------------
378
  -- Process decode
379
  --
380
  -- Purpose:
381
  --   Indentifies each single instruction and steps through the related
382
  --   execution sequence.
383
  --
384
  decode: process (alu_carry_i,
385 27 arniml
                   psw_aux_carry_i,
386
                   alu_da_overflow_i,
387 4 arniml
                   clk_mstate_i,
388
                   clk_second_cycle_i,
389
                   cnd_take_branch_i,
390
                   opc_opcode_s,
391
                   opc_mnemonic_s,
392
                   data_i,
393
                   psw_carry_i,
394
                   psw_f0_i,
395
                   f1_q,
396
                   mb_q,
397
                   tim_int_s,
398
                   int_pending_s)
399
 
400
    procedure address_indirect_3_f is
401
    begin
402
      -- apply dmem address from selected register for indirect mode
403
      if opc_opcode_s(3) = '0' then
404
        dm_read_dmem_o       <= true;
405
        dm_write_dmem_addr_o <= true;
406
        dm_addr_type_o       <= DM_PLAIN;
407
      end if;
408
    end;
409
 
410
    procedure and_or_xor_add_4_f is
411
    begin
412
      -- write dmem contents to Temp Reg
413
      dm_read_dmem_o         <= true;
414
      alu_write_temp_reg_o   <= true;
415
    end;
416
 
417
    procedure and_or_xor_add_5_f (alu_op : alu_op_t) is
418
    begin
419
      -- perform ALU operation and store in Accumulator
420
      alu_op_o               <= alu_op;
421
      alu_read_alu_o         <= true;
422
      alu_write_accu_o       <= true;
423
    end;
424
 
425
    procedure cond_jump_c2_m1_f is
426
    begin
427
      -- store address in Program Counter low byte if branch has to
428
      -- be taken
429
      if clk_mstate_i = MSTATE1 and cnd_take_branch_i then
430
        pm_write_pcl_o       <= true;
431
        branch_taken_s       <= true;
432
      end if;
433
    end;
434
 
435
  begin
436
    -- default assignments
437
    data_s                 <= (others => '-');
438
    read_dec_s             <= false;
439
    branch_taken_s         <= false;
440
    clear_f1_s             <= false;
441
    cpl_f1_s               <= false;
442
    clear_mb_s             <= false;
443
    set_mb_s               <= false;
444
    add_inc_pc_s           <= false;
445
    assert_psen_s          <= false;
446
    stack_high_o           <= false;
447
    alu_write_accu_o       <= false;
448
    alu_write_shadow_o     <= false;
449
    alu_write_temp_reg_o   <= false;
450 27 arniml
    alu_p06_temp_reg_o     <= false;
451
    alu_p60_temp_reg_o     <= false;
452 4 arniml
    alu_read_alu_o         <= false;
453
    bus_write_bus_o        <= false;
454
    bus_bidir_bus_o        <= false;
455
    dm_write_dmem_addr_o   <= false;
456
    dm_write_dmem_s        <= false;
457
    dm_read_dmem_o         <= false;
458
    pm_write_pcl_o         <= false;
459
    pm_read_pcl_o          <= false;
460
    pm_write_pch_o         <= false;
461
    pm_read_pch_o          <= false;
462
    pm_addr_type_o         <= PM_PC;
463
    psw_read_psw_o         <= false;
464
    psw_read_sp_o          <= false;
465
    psw_write_psw_o        <= false;
466
    psw_write_sp_o         <= false;
467
    alu_op_o               <= ALU_NOP;
468
    alu_use_carry_o        <= false;
469 27 arniml
    alu_da_high_o          <= false;
470 38 arniml
    alu_accu_low_o         <= false;
471 4 arniml
    clk_assert_prog_o      <= false;
472
    clk_assert_rd_o        <= false;
473
    clk_assert_wr_o        <= false;
474
    cnd_branch_cond_o      <= COND_ON_BIT;
475
    cnd_compute_take_o     <= false;
476
    cnd_comp_value_o       <= opc_opcode_s(7 downto 5);
477
    dm_addr_type_o         <= DM_REG;
478
    tim_read_timer_o       <= false;
479
    tim_write_timer_o      <= false;
480
    tim_start_t_o          <= false;
481
    tim_start_cnt_o        <= false;
482
    tim_stop_tcnt_o        <= false;
483
    p1_write_p1_o          <= false;
484
    p1_read_p1_o           <= false;
485
    p1_read_reg_o          <= false;
486
    p2_write_p2_o          <= false;
487
    p2_write_exp_o         <= false;
488
    p2_read_p2_o           <= false;
489
    p2_read_reg_o          <= false;
490 21 arniml
    p2_read_exp_o          <= false;
491
    p2_output_exp_o        <= false;
492 4 arniml
    psw_special_data_o     <= '0';
493
    psw_inc_stackp_o       <= false;
494
    psw_dec_stackp_o       <= false;
495
    psw_write_carry_o      <= false;
496
    psw_write_aux_carry_o  <= false;
497
    psw_write_f0_o         <= false;
498
    psw_write_bs_o         <= false;
499
    jtf_executed_s         <= false;
500
    en_tcnti_s             <= false;
501
    dis_tcnti_s            <= false;
502
    en_i_s                 <= false;
503
    dis_i_s                <= false;
504
    retr_executed_s        <= false;
505
    int_executed_s         <= false;
506
    add_write_pmem_addr_s  <= false;
507
    ent0_clk_s             <= false;
508
    add_read_bus_s         <= false;
509
 
510
    -- prepare potential register indirect address mode
511
    if not clk_second_cycle_i and clk_mstate_i = MSTATE2 then
512
      data_s               <= (others => '0');
513
      if opc_opcode_s(3) = '1' then
514
        data_s(2 downto 0) <= opc_opcode_s(2 downto 0);
515
      else
516
        data_s(2 downto 0) <= "00" & opc_opcode_s(0);
517
      end if;
518
 
519
      read_dec_s           <= true;
520
      dm_write_dmem_addr_o <= true;
521
      dm_addr_type_o       <= DM_REG;
522
    end if;
523
 
524
    case opc_mnemonic_s is
525
 
526
      -- Mnemonic ADD ---------------------------------------------------------
527
      when MN_ADD =>
528
        case clk_mstate_i is
529
          -- read RAM once for indirect address mode
530
          when MSTATE3 =>
531
            address_indirect_3_f;
532
 
533
          -- store data from RAM to Temp Reg
534
          when MSTATE4 =>
535
            and_or_xor_add_4_f;
536
 
537
          -- perform ADD and store in Accumulator
538
          when MSTATE5 =>
539
            and_or_xor_add_5_f(alu_op => ALU_ADD);
540
 
541
            if opc_opcode_s(4) = '1' then
542 27 arniml
              alu_use_carry_o     <= true;
543 4 arniml
            end if;
544
 
545 27 arniml
            psw_special_data_o    <= alu_carry_i;
546
            psw_write_carry_o     <= true;
547
            psw_write_aux_carry_o <= true;
548 4 arniml
 
549
          when others =>
550
            null;
551
 
552
        end case;
553
 
554
      -- Mnemonic ADD_A_DATA --------------------------------------------------
555
      when MN_ADD_A_DATA =>
556 27 arniml
        assert_psen_s               <= true;
557 4 arniml
 
558
        if clk_second_cycle_i then
559
          case clk_mstate_i is
560
            -- write Temp Reg when contents of Program Memory is on bus
561
            when MSTATE1 =>
562 27 arniml
              alu_write_temp_reg_o  <= true;
563 4 arniml
 
564
            -- perform ADD and store in Accumulator
565
            when MSTATE3 =>
566
              and_or_xor_add_5_f(alu_op => ALU_ADD);
567
 
568
              if opc_opcode_s(4) = '1' then
569 27 arniml
                alu_use_carry_o     <= true;
570 4 arniml
              end if;
571
 
572 27 arniml
              psw_special_data_o    <= alu_carry_i;
573
              psw_write_carry_o     <= true;
574
              psw_write_aux_carry_o <= true;
575 4 arniml
 
576
            when others =>
577
              null;
578
 
579
          end case;
580
 
581
        end if;
582
 
583
      -- Mnemonic ANL ---------------------------------------------------------
584
      when MN_ANL =>
585
        case clk_mstate_i is
586
          -- read RAM once for indirect address mode
587
          when MSTATE3 =>
588
            address_indirect_3_f;
589
 
590
          -- store data from RAM to Temp Reg
591
          when MSTATE4 =>
592
            and_or_xor_add_4_f;
593
 
594
          -- perform AND and store in Accumulator
595
          when MSTATE5 =>
596
            and_or_xor_add_5_f(alu_op => ALU_AND);
597
 
598
          when others =>
599
            null;
600
 
601
        end case;
602
 
603
      -- Mnemonic ANL_A_DATA --------------------------------------------------
604
      when MN_ANL_A_DATA =>
605
        assert_psen_s              <= true;
606
 
607
        if clk_second_cycle_i then
608
          case clk_mstate_i is
609
            -- write Temp Reg when contents of Program Memory is on bus
610
            when MSTATE1 =>
611
              alu_write_temp_reg_o <= true;
612
 
613
            -- perform AND and store in Accumulator
614
            when MSTATE3 =>
615
              and_or_xor_add_5_f(alu_op => ALU_AND);
616
 
617
            when others =>
618
              null;
619
 
620
          end case;
621
 
622
        end if;
623
 
624
      -- Mnemonic ANL_EXT -----------------------------------------------------
625
      when MN_ANL_EXT =>
626
        assert_psen_s            <= true;
627
 
628
        if not clk_second_cycle_i then
629
          -- read port to Temp Reg
630
          if clk_mstate_i = MSTATE5 then
631
            if opc_opcode_s(1 downto 0) = "00" then
632
              add_read_bus_s     <= true;
633
            elsif opc_opcode_s(1) = '0' then
634
              p1_read_p1_o       <= true;
635
              p1_read_reg_o      <= true;
636
            else
637
              p2_read_p2_o       <= true;
638
              p2_read_reg_o      <= true;
639
            end if;
640
 
641
            alu_write_temp_reg_o <= true;
642
          end if;
643
 
644
        else
645
          case clk_mstate_i is
646
            -- write shadow Accumulator when contents of Program Memory is
647
            -- on bus
648
            when MSTATE1 =>
649
              alu_write_shadow_o <= true;
650
 
651
            -- loop shadow Accumulator through ALU to prevent update from
652
            -- real Accumulator
653
            when MSTATE2 =>
654
              alu_read_alu_o     <= true;
655
              alu_write_shadow_o <= true;
656
 
657
            -- write result of AND operation back to port
658
            when MSTATE3 =>
659
              alu_op_o           <= ALU_AND;
660
              alu_read_alu_o     <= true;
661
 
662
              if opc_opcode_s(1 downto 0) = "00" then
663
                bus_write_bus_o  <= true;
664
              elsif opc_opcode_s(1) = '0' then
665
                p1_write_p1_o    <= true;
666
              else
667
                p2_write_p2_o    <= true;
668
              end if;
669
 
670
            when others =>
671
              null;
672
 
673
          end case;
674
 
675
        end if;
676
 
677
      -- Mnemonic CALL --------------------------------------------------------
678
      when MN_CALL =>
679
        assert_psen_s              <= true;
680
 
681
        if not clk_second_cycle_i then
682
          case clk_mstate_i is
683
            -- read Stack Pointer and address Data Memory for low byte
684
            -- also increment Program Counter to point to next instruction
685
            when MSTATE3 =>
686
              psw_read_sp_o        <= true;
687
              dm_write_dmem_addr_o <= true;
688
              dm_addr_type_o       <= DM_STACK;
689
 
690
              -- only increment PC if this is not an injected CALL
691
              -- injected CALLS are not located in Program Memory,
692
              -- the PC points already to the instruction to be executed
693
              -- after the interrupt
694
              if not int_pending_s then
695
                add_inc_pc_s       <= true;
696
              end if;
697
 
698
            -- store Program Counter low byte on stack
699
            when MSTATE4 =>
700
              pm_read_pcl_o        <= true;
701
              dm_write_dmem_s      <= true;
702
 
703
            -- store Program Counter high byte and PSW on stack
704
            -- increment Stack pointer
705
            when MSTATE5 =>
706
              psw_read_psw_o       <= true;
707
              pm_read_pch_o        <= true;
708
              dm_write_dmem_addr_o <= true;
709
              dm_addr_type_o       <= DM_STACK_HIGH;
710
              dm_write_dmem_s      <= true;
711
              psw_inc_stackp_o     <= true;
712
 
713
            when others =>
714
              null;
715
 
716
          end case;
717
 
718
        else
719
          case clk_mstate_i is
720
            -- store address in Program Counter low byte
721
            when MSTATE1 =>
722
              pm_write_pcl_o       <= true;
723
              branch_taken_s       <= true;
724
              if int_pending_s then
725
                -- apply low part of vector address manually
726
                data_s             <= (others => '0');
727
                data_s(1 downto 0) <= "11";
728
                if tim_int_s then
729
                  data_s(2)        <= '1';
730
                end if;
731
                read_dec_s         <= true;
732
              end if;
733
 
734
            when MSTATE2 =>
735
              pm_write_pch_o       <= true;
736
              read_dec_s           <= true;
737
              if not int_pending_s then
738
                -- store high part of target address in Program Counter
739
                data_s             <= "0000" & mb_q & opc_opcode_s(7 downto 5);
740
              else
741
                -- apply high part of vector address manually
742
                data_s             <= (others => '0');
743
                int_executed_s     <= true;
744
              end if;
745
 
746
            when others =>
747
              null;
748
 
749
          end case;
750
 
751
        end if;
752
 
753
      -- Mnemonic CLR_A -------------------------------------------------------
754
      when MN_CLR_A =>
755
        -- write CLR output of ALU to Accumulator
756
        if clk_mstate_i = MSTATE3 then
757
          alu_op_o         <= ALU_CLR;
758
          alu_read_alu_o   <= true;
759
          alu_write_accu_o <= true;
760
        end if;
761
 
762
      -- Mnemonic CLR_C -------------------------------------------------------
763
      when MN_CLR_C =>
764
        -- store 0 to Carry
765
        if clk_mstate_i = MSTATE3 then
766
          psw_special_data_o <= '0';
767
          psw_write_carry_o  <= true;
768
        end if;
769
 
770
      -- Mnemonic CLR_F -------------------------------------------------------
771
      when MN_CLR_F =>
772
        -- store 0 to selected flag
773
        if clk_mstate_i = MSTATE3 then
774
          if opc_opcode_s(5) = '0' then
775
            psw_special_data_o <= '0';
776
            psw_write_f0_o     <= true;
777
          else
778
            clear_f1_s         <= true;
779
          end if;
780
 
781
        end if;
782
 
783
      -- Mnemonic CPL_A -------------------------------------------------------
784
      when MN_CPL_A =>
785
        -- write CPL output of ALU to Accumulator
786
        if clk_mstate_i = MSTATE3 then
787
          alu_op_o         <= ALU_CPL;
788
          alu_read_alu_o   <= true;
789
          alu_write_accu_o <= true;
790
        end if;
791
 
792
      -- Mnemnonic CPL_C ------------------------------------------------------
793
      when MN_CPL_C =>
794
        -- write inverse of Carry to PSW
795
        if clk_mstate_i = MSTATE3 then
796
          psw_special_data_o <= not psw_carry_i;
797
          psw_write_carry_o  <= true;
798
        end if;
799
 
800
      -- Mnemonic CPL_F -------------------------------------------------------
801
      when MN_CPL_f =>
802
        -- write inverse of selected flag back to flag
803
        if clk_mstate_i = MSTATE3 then
804
          if opc_opcode_s(5) = '0' then
805
            psw_special_data_o <= not psw_f0_i;
806
            psw_write_f0_o     <= true;
807
          else
808
            cpl_f1_s           <= true;
809
          end if;
810
 
811
        end if;
812
 
813 27 arniml
      -- Mnemonic DA ----------------------------------------------------------
814
      when MN_DA =>
815
        alu_op_o                 <= ALU_ADD;
816
 
817
        case clk_mstate_i is
818
          -- Step 1: Preload Temp Reg with 0x06
819
          when MSTATE3 =>
820
            alu_p06_temp_reg_o   <= true;
821
 
822
          -- Step 2: Check Auxiliary Carry and overflow on low nibble
823
          --         Add 0x06 to shadow Accumulator if one is true
824
          when MSTATE4 =>
825
            if psw_aux_carry_i = '1' or alu_da_overflow_i then
826
              alu_read_alu_o     <= true;
827
              alu_write_shadow_o <= true;
828
            end if;
829
 
830
            -- preload Temp Reg with 0x60
831
            alu_p60_temp_reg_o  <= true;
832
 
833
          -- Step 3: Check overflow on high nibble
834
          --         Add 0x60 to shadow Accumulator if true and store result
835
          --         in Accumulator and PSW (only Carry)
836
          when MSTATE5 =>
837
            alu_da_high_o        <= true;
838
 
839
            if alu_da_overflow_i then
840
              psw_special_data_o <= alu_carry_i;
841
            else
842
              alu_op_o           <= ALU_NOP;
843
              psw_special_data_o <= '0';
844
            end if;
845
            alu_read_alu_o       <= true;
846
            alu_write_accu_o     <= true;
847
            psw_write_carry_o    <= true;
848
 
849
          when others =>
850
            null;
851
 
852
        end case;
853
 
854 4 arniml
      -- Mnemonic DEC ---------------------------------------------------------
855
      when MN_DEC =>
856
        case clk_mstate_i is
857
          when MSTATE4 =>
858
            -- DEC Rr: store data from RAM to shadow Accumulator
859
            if opc_opcode_s(6) = '1' then
860
              dm_read_dmem_o         <= true;
861
              alu_write_shadow_o     <= true;
862
            end if;
863
 
864
          when MSTATE5 =>
865
            alu_op_o                 <= ALU_DEC;
866
            alu_read_alu_o           <= true;
867
 
868
            if opc_opcode_s(6) = '0' then
869
              -- write DEC of Accumulator to Accumulator
870
              alu_write_accu_o       <= true;
871
            else
872
              -- store DEC of shadow Accumulator back to dmem
873
              dm_write_dmem_s        <= true;
874
            end if;
875
 
876
          when others =>
877
            null;
878
 
879
        end case;
880
 
881
      -- Mnemonic DIS_EN_I ----------------------------------------------------
882
      when MN_DIS_EN_I =>
883
        if clk_mstate_i = MSTATE3 then
884
          if opc_opcode_s(4) = '1' then
885
            dis_i_s <= true;
886
          else
887
            en_i_s  <= true;
888
          end if;
889
        end if;
890
 
891
      -- Mnemonic DIS_EN_TCNTI ------------------------------------------------
892
      when MN_DIS_EN_TCNTI =>
893
        if clk_mstate_i = MSTATE3 then
894
          if opc_opcode_s(4) = '1' then
895
            dis_tcnti_s <= true;
896
          else
897
            en_tcnti_s  <= true;
898
          end if;
899
        end if;
900
 
901
      -- Mnemonic DJNZ --------------------------------------------------------
902
      when MN_DJNZ =>
903
        assert_psen_s              <= true;
904
 
905
        if not clk_second_cycle_i then
906
          case clk_mstate_i is
907
            -- store data from RAM to shadow Accumulator
908
            when MSTATE4 =>
909
              dm_read_dmem_o         <= true;
910
              alu_write_shadow_o     <= true;
911
 
912
            -- write DEC result of shadow Accumulator back to dmem and
913
            -- conditional branch logic
914
            when MSTATE5 =>
915
              alu_op_o               <= ALU_DEC;
916
              alu_read_alu_o         <= true;
917
              dm_write_dmem_s        <= true;
918
 
919
              cnd_compute_take_o     <= true;
920
              cnd_branch_cond_o      <= COND_Z;
921
              cnd_comp_value_o(0)    <= '0';
922
 
923
            when others =>
924
              null;
925
 
926
          end case;
927
 
928
        else
929
          -- store address in Program Counter low byte if branch has to
930
          -- be taken
931
          cond_jump_c2_m1_f;
932
 
933
        end if;
934
 
935
      -- Mnemonic ENT0_CLK ----------------------------------------------------
936
      when MN_ENT0_CLK =>
937
        if clk_mstate_i = MSTATE3 then
938
          ent0_clk_s <= true;
939
        end if;
940
 
941
      -- Mnemonic IN ----------------------------------------------------------
942
      when MN_IN =>
943
        -- read Port and store in Accumulator
944
        if clk_second_cycle_i and clk_mstate_i = MSTATE2 then
945
          alu_write_accu_o <= true;
946
 
947
          if opc_opcode_s(1) = '0' then
948
            p1_read_p1_o   <= true;
949
          else
950
            p2_read_p2_o   <= true;
951
          end if;
952
        end if;
953
 
954
      -- Mnemonic INS ---------------------------------------------------------
955
      when MN_INS =>
956
        -- read BUS and store in Accumulator
957
        if clk_second_cycle_i and clk_mstate_i = MSTATE2 then
958
          alu_write_accu_o <= true;
959
 
960
          add_read_bus_s   <= true;
961
        end if;
962
 
963
      -- Mnemonic INC ---------------------------------------------------------
964
      when MN_INC =>
965
        case clk_mstate_i is
966
          -- read RAM once for indirect address mode
967
          when MSTATE3 =>
968
            address_indirect_3_f;
969
 
970
          when MSTATE4 =>
971
            -- INC Rr; INC @ Rr: store data from RAM to shadow Accumulator
972
            if opc_opcode_s(3 downto 2) /= "01" then
973
              dm_read_dmem_o         <= true;
974
              alu_write_shadow_o     <= true;
975
            end if;
976
 
977
          when MSTATE5 =>
978
            alu_op_o                 <= ALU_INC;
979
            alu_read_alu_o           <= true;
980
 
981
            if opc_opcode_s(3 downto 2) = "01" then
982
              -- write INC output of ALU to Accumulator
983
              alu_write_accu_o       <= true;
984
            else
985
              -- store INC of shadow Accumulator back to dmem
986
              dm_write_dmem_s        <= true;
987
            end if;
988
 
989
          when others =>
990
            null;
991
 
992
        end case;
993
 
994
      -- Mnemonic JBB ---------------------------------------------------------
995
      when MN_JBB =>
996
        assert_psen_s          <= true;
997
        cnd_branch_cond_o      <= COND_ON_BIT;
998
 
999
        if not clk_second_cycle_i then
1000
          -- read Accumulator and start branch calculation
1001
          if clk_mstate_i = MSTATE3 then
1002
            alu_read_alu_o     <= true;
1003
            cnd_compute_take_o <= true;
1004
            -- cnd_comp_value_o is ok by default assignment
1005
          end if;
1006
 
1007
        else
1008
          -- store address in Program Counter low byte if branch has to
1009
          -- be taken
1010
          cond_jump_c2_m1_f;
1011
 
1012
        end if;
1013
 
1014
      -- Mnemonic JC ----------------------------------------------------------
1015
      when MN_JC =>
1016
        assert_psen_s           <= true;
1017
        cnd_branch_cond_o       <= COND_C;
1018
 
1019
        if not clk_second_cycle_i then
1020
          -- start branch calculation
1021
          if clk_mstate_i = MSTATE3 then
1022
            cnd_compute_take_o  <= true;
1023
            cnd_comp_value_o(0) <= opc_opcode_s(4);
1024
          end if;
1025
 
1026
        else
1027
          -- store address in Program Counter low byte if branch has to
1028
          -- be taken
1029
          cond_jump_c2_m1_f;
1030
 
1031
        end if;
1032
 
1033
      -- Mnemonic JF ----------------------------------------------------------
1034
      when MN_JF =>
1035
        assert_psen_s           <= true;
1036
 
1037
        if not clk_second_cycle_i then
1038
          -- start branch calculation
1039
          if clk_mstate_i = MSTATE3 then
1040
            cnd_compute_take_o  <= true;
1041
            if opc_opcode_s(7) = '1' then
1042
              -- JF0
1043
              cnd_branch_cond_o <= COND_F0;
1044
            else
1045
              -- JF1
1046
              cnd_branch_cond_o <= COND_F1;
1047
            end if;
1048
 
1049
          end if;
1050
 
1051
        else
1052
          -- store address in Program Counter low byte if branch has to
1053
          -- be taken
1054
          cond_jump_c2_m1_f;
1055
 
1056
        end if;
1057
 
1058
 
1059
      -- Mnemonic JMP ---------------------------------------------------------
1060
      when MN_JMP =>
1061
        assert_psen_s        <= true;
1062
 
1063
        if clk_second_cycle_i then
1064
          case clk_mstate_i is
1065
            -- store address in Program Counter low byte
1066
            when MSTATE1 =>
1067
              pm_write_pcl_o <= true;
1068
              branch_taken_s <= true;
1069
 
1070
            -- store high part of target address in Program Counter
1071
            when MSTATE2 =>
1072
              data_s         <= "0000" & mb_q & opc_opcode_s(7 downto 5);
1073
              read_dec_s     <= true;
1074
              pm_write_pch_o <= true;
1075
 
1076
 
1077
            when others =>
1078
              null;
1079
 
1080
          end case;
1081
 
1082
        end if;
1083
 
1084
      -- Mnemonic JMPP --------------------------------------------------------
1085
      when MN_JMPP =>
1086
        assert_psen_s    <= true;
1087
 
1088
        if not clk_second_cycle_i then
1089
          -- write Accumulator to Program Memory address
1090
          -- (skip page offset update from Program Counter)
1091
          if clk_mstate_i = MSTATE3 then
1092
            alu_read_alu_o <= true;
1093
            pm_addr_type_o <= PM_PAGE;
1094
          end if;
1095
 
1096
        else
1097
          if clk_mstate_i = MSTATE1 then
1098
            -- store address in Program Counter low byte
1099
            pm_write_pcl_o <= true;
1100
            branch_taken_s <= true;
1101
          end if;
1102
 
1103
        end if;
1104
 
1105
      -- Mnemonic JNI ---------------------------------------------------------
1106
      when MN_JNI =>
1107
        assert_psen_s          <= true;
1108
        cnd_branch_cond_o      <= COND_INT;
1109
 
1110
        if not clk_second_cycle_i then
1111
          -- start branch calculation
1112
          if clk_mstate_i = MSTATE3 then
1113
            cnd_compute_take_o <= true;
1114
          end if;
1115
 
1116
        else
1117
          -- store address in Program Counter low byte if branch has to
1118
          -- be taken
1119
          cond_jump_c2_m1_f;
1120
 
1121
        end if;
1122
 
1123
      -- Mnemonic JT ----------------------------------------------------------
1124
      when MN_JT =>
1125
        assert_psen_s           <= true;
1126
        if opc_opcode_s(6) = '0' then
1127
          cnd_branch_cond_o     <= COND_T0;
1128
        else
1129
          cnd_branch_cond_o     <= COND_T1;
1130
        end if;
1131
 
1132
        if not clk_second_cycle_i then
1133
          -- start branch calculation
1134
          if clk_mstate_i = MSTATE3 then
1135
            cnd_compute_take_o  <= true;
1136
            cnd_comp_value_o(0) <= opc_opcode_s(4);
1137
          end if;
1138
 
1139
        else
1140
          -- store address in Program Counter low byte if branch has to
1141
          -- be taken
1142
          cond_jump_c2_m1_f;
1143
 
1144
        end if;
1145
 
1146
      -- Mnemonic JTF ---------------------------------------------------------
1147
      when MN_JTF =>
1148
        assert_psen_s          <= true;
1149
        cnd_branch_cond_o      <= COND_TF;
1150
 
1151
        if not clk_second_cycle_i then
1152
          -- start branch calculation
1153
          if clk_mstate_i = MSTATE3 then
1154
            cnd_compute_take_o <= true;
1155
            jtf_executed_s     <= true;
1156
          end if;
1157
 
1158
        else
1159
          -- store address in Program Counter low byte if branch has to
1160
          -- be taken
1161
          cond_jump_c2_m1_f;
1162
 
1163
        end if;
1164
 
1165
      -- Mnemonic JZ ----------------------------------------------------------
1166
      when MN_JZ =>
1167
        assert_psen_s           <= true;
1168
        cnd_branch_cond_o       <= COND_Z;
1169
 
1170
        if not clk_second_cycle_i then
1171
          -- read Accumulator and start branch calculation
1172
          if clk_mstate_i = MSTATE3 then
1173
            alu_read_alu_o      <= true;
1174
            cnd_compute_take_o  <= true;
1175
            cnd_comp_value_o(0) <= opc_opcode_s(6);
1176
          end if;
1177
 
1178
        else
1179
          -- store address in Program Counter low byte if branch has to
1180
          -- be taken
1181
          cond_jump_c2_m1_f;
1182
 
1183
        end if;
1184
 
1185
      -- Mnemonic MOV_A_DATA --------------------------------------------------
1186
      when MN_MOV_A_DATA =>
1187
        assert_psen_s      <= true;
1188
 
1189
        -- Write Accumulator when contents of Program Memory is on bus
1190
        -- during machine state 1 of second cycle.
1191
        if clk_second_cycle_i and clk_mstate_i = MSTATE1 then
1192
          alu_write_accu_o <= true;
1193
        end if;
1194
 
1195
      -- Mnemonic MOV_A_RR ----------------------------------------------------
1196
      when MN_MOV_A_RR =>
1197
        case clk_mstate_i is
1198
          -- read RAM once for indirect address mode
1199
          when MSTATE3 =>
1200
            address_indirect_3_f;
1201
 
1202
          -- read data from RAM and store in Accumulator
1203
          when MSTATE4 =>
1204
            and_or_xor_add_4_f;
1205
            alu_write_accu_o <= true;
1206
 
1207
          when others =>
1208
            null;
1209
 
1210
        end case;
1211
 
1212
      -- Mnemonic MOV_A_PSW ---------------------------------------------------
1213
      when MN_MOV_A_PSW =>
1214
        if clk_mstate_i = MSTATE3 then
1215
          psw_read_psw_o   <= true;
1216
          psw_read_sp_o    <= true;
1217
          alu_write_accu_o <= true;
1218
        end if;
1219
 
1220
      -- Mnemoniv MOV_PSW_A ---------------------------------------------------
1221
      when MN_MOV_PSW_A =>
1222
        if clk_mstate_i = MSTATE3 then
1223
          alu_read_alu_o  <= true;
1224
          psw_write_psw_o <= true;
1225
          psw_write_sp_o  <= true;
1226
        end if;
1227
 
1228
      -- Mnemonic MOV_RR ------------------------------------------------------
1229
      when MN_MOV_RR =>
1230
        case clk_mstate_i is
1231
          -- read RAM once for indirect address mode
1232
          when MSTATE3 =>
1233
            address_indirect_3_f;
1234
 
1235
          -- write Accumulator to dmem
1236
          when MSTATE5 =>
1237
            alu_read_alu_o       <= true;
1238
            dm_write_dmem_s      <= true;
1239
 
1240
          when others =>
1241
            null;
1242
 
1243
        end case;
1244
 
1245
      -- Mnemonic MOV_RR_DATA -------------------------------------------------
1246
      when MN_MOV_RR_DATA =>
1247
        assert_psen_s     <= true;
1248
 
1249
        -- read RAM once for indirect address mode
1250
        if not clk_second_cycle_i and clk_mstate_i = MSTATE3 then
1251
          address_indirect_3_f;
1252
        end if;
1253
 
1254
        -- Write Data Memory when contents of Program Memory is on bus
1255
        -- during machine state 1 of second cycle.
1256
        if clk_second_cycle_i and clk_mstate_i = MSTATE1 then
1257
          dm_write_dmem_s <= true;
1258
        end if;
1259
 
1260
      -- Mnemonic MOV_T -------------------------------------------------------
1261
      when MN_MOV_T =>
1262
        if clk_mstate_i = MSTATE3 then
1263
          if opc_opcode_s(5) = '1' then
1264
            alu_read_alu_o    <= true;  -- MOV T, A
1265
            tim_write_timer_o <= true;
1266
          else
1267
            tim_read_timer_o  <= true;  -- MOV A, T
1268
            alu_write_accu_o  <= true;
1269
          end if;
1270
        end if;
1271
 
1272 21 arniml
      -- Mnemonic OUTD_PP_A ---------------------------------------------------
1273
      when MN_OUTD_PP_A =>
1274
        clk_assert_prog_o     <= true;
1275
 
1276
        if not clk_second_cycle_i then
1277
          case clk_mstate_i is
1278
            -- propagate expander port number to Port 2
1279
            when MSTATE3 =>
1280
 
1281
              data_s(7 downto 4)     <= (others => '0');
1282
              data_s(1 downto 0)     <= opc_opcode_s(1 downto 0);
1283
              -- decide which 8243 command to use
1284
              case opc_opcode_s(7 downto 4) is
1285
                when "1001" =>
1286
                  data_s(3 downto 2) <= "11";  -- ANLD command
1287
                when "1000" =>
1288
                  data_s(3 downto 2) <= "10";  -- ORLD command
1289
                when "0011" =>
1290
                  data_s(3 downto 2) <= "01";  -- MOVD command
1291
                when others =>
1292
                  null;
1293
              end case;
1294
 
1295
              read_dec_s      <= true;
1296
              p2_write_exp_o  <= true;
1297
 
1298
            -- output expander port number on Port 2 while active edge of PROG
1299
            -- write Accumulator to expander port
1300
            when MSTATE4 =>
1301
              p2_output_exp_o <= true;
1302
 
1303
              alu_read_alu_o  <= true;
1304
              p2_write_exp_o  <= true;
1305
 
1306
            when MSTATE5 =>
1307
              p2_output_exp_o <= true;
1308
 
1309
            when others =>
1310
              null;
1311
 
1312
          end case;
1313
 
1314
        else
1315
          -- hold expander port until inactive edge of PROG 
1316
          if clk_mstate_i = MSTATE1 or clk_mstate_i = MSTATE2 then
1317
            p2_output_exp_o   <= true;
1318
          end if;
1319
 
1320
        end if;
1321
 
1322
      -- Mnemonic MOVD_A_PP ---------------------------------------------------
1323
      when MN_MOVD_A_PP =>
1324
        clk_assert_prog_o            <= true;
1325
 
1326
        if not clk_second_cycle_i then
1327
          case clk_mstate_i is
1328
            -- propagate expander port number to Port 2
1329
            when MSTATE3 =>
1330
              data_s                 <= "0000" &
1331
                                        "00"   &  -- 8243 command: read
1332
                                        opc_opcode_s(1 downto 0);
1333
              read_dec_s             <= true;
1334
              p2_write_exp_o         <= true;
1335
 
1336
            -- output expander port number on Port 2 while active edge of PROG
1337
            -- write 1's to expander port to set lower nibble of Port 2 to input
1338
            when MSTATE4 =>
1339
              p2_output_exp_o        <= true;
1340
 
1341
              data_s(nibble_t'range) <= (others => '1');
1342
              read_dec_s             <= true;
1343
              p2_write_exp_o         <= true;
1344
 
1345
            when MSTATE5 =>
1346
              p2_output_exp_o        <= true;
1347
 
1348
            when others =>
1349
              null;
1350
 
1351
          end case;
1352
 
1353
        else
1354
          case clk_mstate_i is
1355
            -- hold expander port until inactive edge of PROG
1356
            when MSTATE1 =>
1357
              p2_output_exp_o  <= true;
1358
 
1359
            -- hold expander port until inactive edge of PROG
1360
            -- write Accumulator with nibble of expander port
1361
            when MSTATE2 =>
1362
              p2_output_exp_o  <= true;
1363
              p2_read_exp_o    <= true;
1364
              alu_write_accu_o <= true;
1365
 
1366
            when others =>
1367
              null;
1368
 
1369
          end case;
1370
 
1371
        end if;
1372
 
1373 4 arniml
      -- Mnemonic MOVP --------------------------------------------------------
1374
      when MN_MOVP =>
1375
        assert_psen_s        <= true;
1376
 
1377
        if not clk_second_cycle_i then
1378
          -- write Accumulator to Program Memory address
1379
          -- (skip page offset update from Program Counter)
1380
          if clk_mstate_i = MSTATE3 then
1381
            alu_read_alu_o   <= true;
1382
            if opc_opcode_s(6) = '0' then
1383
              pm_addr_type_o <= PM_PAGE;
1384
            else
1385
              pm_addr_type_o <= PM_PAGE3;
1386
            end if;
1387
          end if;
1388
 
1389
        else
1390
          if clk_mstate_i = MSTATE1 then
1391
            -- store data from Program Memory in Accumulator
1392
            alu_write_accu_o <= true;
1393
            -- trick & treat to prevent additional PC increment
1394
            -- our branch target is the previously incremented PC!
1395
            branch_taken_s   <= true;
1396
          end if;
1397
 
1398
        end if;
1399
 
1400
      -- Mnemonic MOVX --------------------------------------------------------
1401
      when MN_MOVX =>
1402
        bus_bidir_bus_o        <= true;
1403
 
1404
        if opc_opcode_s(4) = '0' then
1405
          clk_assert_rd_o      <= true;
1406
        else
1407
          clk_assert_wr_o      <= true;
1408
        end if;
1409
 
1410
        if not clk_second_cycle_i then
1411
          -- read dmem and put contents on BUS as external address
1412
          if clk_mstate_i = MSTATE3 then
1413
            dm_read_dmem_o     <= true;
1414
            bus_write_bus_o    <= true;
1415
          end if;
1416
 
1417
        else
1418
          if clk_mstate_i = MSTATE1 then
1419
            if opc_opcode_s(4) = '0' then
1420
              -- store contents of BUS in Accumulator
1421
              add_read_bus_s   <= true;
1422
              alu_write_accu_o <= true;
1423
            else
1424
              -- store contents of Accumulator to BUS
1425
              alu_read_alu_o   <= true;
1426
              bus_write_bus_o  <= true;
1427
            end if;
1428
          end if;
1429
 
1430
        end if;
1431
 
1432
      -- Mnemonic NOP ---------------------------------------------------------
1433
      when MN_NOP =>
1434
        -- nothing to do
1435
 
1436
      -- Mnemonic ORL ---------------------------------------------------------
1437
      when MN_ORL =>
1438
        case clk_mstate_i is
1439
          -- read RAM once for indirect address mode
1440
          when MSTATE3 =>
1441
            address_indirect_3_f;
1442
 
1443
          -- store data from RAM to Temp Reg
1444
          when MSTATE4 =>
1445
            and_or_xor_add_4_f;
1446
 
1447
          -- perform OR and store in Accumulator
1448
          when MSTATE5 =>
1449
            and_or_xor_add_5_f(alu_op => ALU_OR);
1450
 
1451
          when others =>
1452
            null;
1453
 
1454
        end case;
1455
 
1456
      -- Mnemonic ORL_A_DATA --------------------------------------------------
1457
      when MN_ORL_A_DATA =>
1458
        assert_psen_s              <= true;
1459
 
1460
        if clk_second_cycle_i then
1461
          case clk_mstate_i is
1462
            -- write Temp Reg when contents of Program Memory is on bus
1463
            when MSTATE1 =>
1464
              alu_write_temp_reg_o <= true;
1465
 
1466
            -- perform OR and store in Accumulator
1467
            when MSTATE3 =>
1468
              and_or_xor_add_5_f(alu_op => ALU_OR);
1469
 
1470
            when others =>
1471
              null;
1472
 
1473
          end case;
1474
 
1475
        end if;
1476
 
1477
      -- Mnemonic ORL_EXT -----------------------------------------------------
1478
      when MN_ORL_EXT =>
1479
        assert_psen_s            <= true;
1480
 
1481
        if not clk_second_cycle_i then
1482
          -- read port to Temp Reg
1483
          if clk_mstate_i = MSTATE5 then
1484
            if opc_opcode_s(1 downto 0) = "00" then
1485
              add_read_bus_s     <= true;
1486
            elsif opc_opcode_s(1) = '0' then
1487
              p1_read_p1_o       <= true;
1488
              p1_read_reg_o      <= true;
1489
            else
1490
              p2_read_p2_o       <= true;
1491
              p2_read_reg_o      <= true;
1492
            end if;
1493
 
1494
            alu_write_temp_reg_o <= true;
1495
          end if;
1496
 
1497
        else
1498
          case clk_mstate_i is
1499
            -- write shadow Accumulator when contents of Program Memory is
1500
            -- on bus
1501
            when MSTATE1 =>
1502
              alu_write_shadow_o <= true;
1503
 
1504
            -- loop shadow Accumulator through ALU to prevent update from
1505
            -- real Accumulator
1506
            when MSTATE2 =>
1507
              alu_read_alu_o     <= true;
1508
              alu_write_shadow_o <= true;
1509
 
1510
            -- write result of OR operation back to port
1511
            when MSTATE3 =>
1512
              alu_op_o           <= ALU_OR;
1513
              alu_read_alu_o     <= true;
1514
 
1515
              if opc_opcode_s(1 downto 0) = "00" then
1516
                bus_write_bus_o  <= true;
1517
              elsif opc_opcode_s(1) = '0' then
1518
                p1_write_p1_o    <= true;
1519
              else
1520
                p2_write_p2_o    <= true;
1521
              end if;
1522
 
1523
            when others =>
1524
              null;
1525
 
1526
          end case;
1527
 
1528
        end if;
1529
 
1530
      -- Mnemonic OUTL_EXT ----------------------------------------------------
1531
      when MN_OUTL_EXT =>
1532
        -- read Accumulator and store in Port/BUS output register
1533
        if clk_second_cycle_i and clk_mstate_i = MSTATE4 then
1534
          alu_read_alu_o  <= true;
1535
 
1536
          if opc_opcode_s(4) = '1' then
1537
            if opc_opcode_s(1) = '0' then
1538
              p1_write_p1_o <= true;
1539
            else
1540
              p2_write_p2_o <= true;
1541
            end if;
1542
 
1543
          else
1544
            bus_write_bus_o <= true;
1545
 
1546
          end if;
1547
 
1548
        end if;
1549
 
1550
      -- Mnemonic RET ---------------------------------------------------------
1551
      when MN_RET =>
1552
        if not clk_second_cycle_i then
1553
          case clk_mstate_i is
1554
            -- decrement Stack Pointer
1555
            when MSTATE3 =>
1556
              psw_dec_stackp_o     <= true;
1557
 
1558
            -- read Stack Pointer and address Data Memory for low byte
1559
            when MSTATE4 =>
1560
              psw_read_sp_o        <= true;
1561
              dm_write_dmem_addr_o <= true;
1562
              dm_addr_type_o       <= DM_STACK;
1563
 
1564
            -- read Data Memory and store to Program Counter low
1565
            -- prepare address to Data memory for high byte
1566
            when MSTATE5 =>
1567
              dm_read_dmem_o       <= true;
1568
              pm_write_pcl_o       <= true;
1569
              dm_write_dmem_addr_o <= true;
1570
              dm_addr_type_o       <= DM_STACK_HIGH;
1571
 
1572
            when others =>
1573
              null;
1574
 
1575
          end case;
1576
 
1577
        else
1578
          case clk_mstate_i is
1579
            -- read Data Memory and store to Program Counter high and PSW
1580
            when MSTATE1 =>
1581
              dm_read_dmem_o         <= true;
1582
              pm_write_pch_o         <= true;
1583
              if opc_opcode_s(4) = '1' then
1584
                psw_write_psw_o      <= true;
1585
                retr_executed_s      <= true;
1586
              end if;
1587
 
1588
            when MSTATE2 =>
1589
              add_write_pmem_addr_s  <= true;
1590
 
1591
            when others =>
1592
              null;
1593
 
1594
          end case;
1595
 
1596
        end if;
1597
 
1598
      -- Mnemonic RL ----------------------------------------------------------
1599
      when MN_RL =>
1600
        if clk_mstate_i = MSTATE3 then
1601
          alu_op_o             <= ALU_RL;
1602
          alu_read_alu_o       <= true;
1603
          alu_write_accu_o     <= true;
1604
 
1605
          if opc_opcode_s(4) = '1' then
1606
            psw_special_data_o <= alu_carry_i;
1607
            psw_write_carry_o  <= true;
1608
            alu_use_carry_o    <= true;
1609
          end if;
1610
        end if;
1611
 
1612
      -- Mnemonic RR ----------------------------------------------------------
1613
      when MN_RR =>
1614
        if clk_mstate_i = MSTATE3 then
1615
          alu_op_o             <= ALU_RR;
1616
          alu_read_alu_o       <= true;
1617
          alu_write_accu_o     <= true;
1618
 
1619
          if opc_opcode_s(4) = '0' then
1620
            psw_special_data_o <= alu_carry_i;
1621
            psw_write_carry_o  <= true;
1622
            alu_use_carry_o    <= true;
1623
          end if;
1624
        end if;
1625
 
1626
      -- Mnemonic SEL_MB ------------------------------------------------------
1627
      when MN_SEL_MB =>
1628
        if clk_mstate_i = MSTATE3 then
1629
          if opc_opcode_s(4) = '1' then
1630
            set_mb_s   <= true;
1631
          else
1632
            clear_mb_s <= true;
1633
          end if;
1634
        end if;
1635
 
1636
      -- Mnemonic SEL_RB ------------------------------------------------------
1637
      when MN_SEL_RB =>
1638
        if clk_mstate_i = MSTATE3 then
1639
          psw_special_data_o <= opc_opcode_s(4);
1640
          psw_write_bs_o     <= true;
1641
        end if;
1642
 
1643
      -- Mnemonic STOP_TCNT ---------------------------------------------------
1644
      when MN_STOP_TCNT =>
1645
        if clk_mstate_i = MSTATE3 then
1646
          tim_stop_tcnt_o <= true;
1647
        end if;
1648
 
1649
      -- Mnemonic STRT --------------------------------------------------------
1650
      when MN_STRT =>
1651
        if clk_mstate_i = MSTATE3 then
1652
          if opc_opcode_s(4) = '1' then
1653
            tim_start_t_o   <= true;
1654
          else
1655
            tim_start_cnt_o <= true;
1656
          end if;
1657
        end if;
1658
 
1659
      -- Mnemonic SWAP --------------------------------------------------------
1660
      when MN_SWAP =>
1661
        alu_op_o           <= ALU_SWAP;
1662
 
1663
        if clk_mstate_i = MSTATE3 then
1664
          alu_read_alu_o   <= true;
1665
          alu_write_accu_o <= true;
1666
        end if;
1667
 
1668
      -- Mnemonic XCH ---------------------------------------------------------
1669
      when MN_XCH =>
1670
        case clk_mstate_i is
1671
          -- read RAM once for indirect address mode
1672
          when MSTATE3 =>
1673
            address_indirect_3_f;
1674
 
1675 38 arniml
          -- store data from RAM in Accumulator and Temp Reg
1676 4 arniml
          -- Accumulator is already shadowed!
1677
          when MSTATE4 =>
1678 38 arniml
            dm_read_dmem_o       <= true;
1679
            alu_write_accu_o     <= true;
1680
            alu_write_temp_reg_o <= true;
1681
            if opc_opcode_s(4) = '1' then
1682
              -- XCHD
1683
              -- only write lower nibble of Accumulator
1684
              alu_accu_low_o     <= true;
1685
            end if;
1686 4 arniml
 
1687
          -- store data from shadow (previous) Accumulator to dmem
1688
          when MSTATE5 =>
1689 38 arniml
            dm_write_dmem_s      <= true;
1690
            alu_read_alu_o       <= true;
1691
            if opc_opcode_s(4) = '1' then
1692
              -- XCHD
1693
              -- concatenate shadow Accumulator and Temp Reg
1694
              alu_op_o           <= ALU_CONCAT;
1695
            end if;
1696 4 arniml
 
1697
          when others =>
1698
            null;
1699
 
1700
        end case;
1701
 
1702
      -- Mnemonic XRL ---------------------------------------------------------
1703
      when MN_XRL =>
1704
        case clk_mstate_i is
1705
          -- read RAM once for indirect address mode
1706
          when MSTATE3 =>
1707
            address_indirect_3_f;
1708
 
1709
          -- store data from RAM to Temp Reg
1710
          when MSTATE4 =>
1711
            and_or_xor_add_4_f;
1712
 
1713
          -- perform XOR and store in Accumulator
1714
          when MSTATE5 =>
1715
            and_or_xor_add_5_f(alu_op => ALU_XOR);
1716
 
1717
          when others =>
1718
            null;
1719
 
1720
        end case;
1721
 
1722
      -- Mnemonic XRL_A_DATA --------------------------------------------------
1723
      when MN_XRL_A_DATA =>
1724
        assert_psen_s              <= true;
1725
 
1726
        if clk_second_cycle_i then
1727
          case clk_mstate_i is
1728
            -- write Temp Reg when contents of Program Memory is on bus
1729
            when MSTATE1 =>
1730
              alu_write_temp_reg_o <= true;
1731
 
1732
            -- perform XOR and store in Accumulator
1733
            when MSTATE3 =>
1734
              and_or_xor_add_5_f(alu_op => ALU_XOR);
1735
 
1736
            when others =>
1737
              null;
1738
 
1739
          end case;
1740
 
1741
        end if;
1742
 
1743
      -- Unimplemented mnemonic -----------------------------------------------
1744
      when others =>
1745
        -- this will behave like a NOP
1746
 
1747
        -- pragma translate_off
1748
        assert false
1749
          report "Mnemonic not yet implemented."
1750
          severity warning;
1751
        -- pragma translate_on
1752
 
1753
    end case;
1754
 
1755
  end process decode;
1756
  --
1757
  -----------------------------------------------------------------------------
1758
 
1759
 
1760
  -----------------------------------------------------------------------------
1761
  -- Process regs
1762
  --
1763
  -- Purpose:
1764
  --   Implements the various registes.
1765
  --
1766
  regs: process (res_i, clk_i)
1767
  begin
1768
    if res_i = res_active_c then
1769
      branch_taken_q <= false;
1770
      f1_q           <= '0';
1771
      mb_q           <= '0';
1772
      t0_dir_q       <= '0';
1773 38 arniml
      -- pragma translate_off
1774
      istrobe_s      <= '0';
1775 60 arniml
      injected_int_q <= '0';
1776 38 arniml
      -- pragma translate_on
1777 4 arniml
 
1778
    elsif clk_i'event and clk_i = clk_active_c then
1779
      if en_clk_i then
1780
 
1781
        -- branch taken flag
1782
        if branch_taken_s then
1783
          branch_taken_q <= true;
1784
        elsif clk_mstate_i = MSTATE5 then
1785
          -- release flag when new instruction starts
1786
          branch_taken_q <= false;
1787
        end if;
1788
 
1789
        -- Flag 1
1790
        if clear_f1_s then
1791
          f1_q         <= '0';
1792
        elsif cpl_f1_s then
1793
          f1_q         <= not f1_q;
1794
        end if;
1795
 
1796
        -- Memory Bank select
1797
        if clear_mb_s then
1798
          mb_q         <= '0';
1799
        elsif set_mb_s then
1800
          mb_q         <= '1';
1801
        end if;
1802
 
1803
        -- T0 direction selection
1804
        if ent0_clk_s then
1805
          t0_dir_q     <= '1';
1806
        end if;
1807
 
1808 60 arniml
        -- pragma translate_off
1809
        -- Instruction Strobe -------------------------------------------------
1810
        if clk_mstate_i = MSTATE5 and last_cycle_s and
1811
          injected_int_q = '0' then
1812
          istrobe_s      <= '1';
1813
        else
1814
          istrobe_s      <= '0';
1815
        end if;
1816 4 arniml
 
1817 60 arniml
        -- Marker for injected instruction ------------------------------------
1818
        if opc_inj_int_s then
1819
          injected_int_q <= '1';
1820
        elsif clk_mstate_i = MSTATE5 and last_cycle_s then
1821
          injected_int_q <= '0';
1822
        end if;
1823
        -- pragma translate_on
1824
 
1825 38 arniml
      end if;
1826
 
1827 4 arniml
    end if;
1828
 
1829
  end process regs;
1830
  --
1831
  -----------------------------------------------------------------------------
1832
 
1833 53 arniml
  -- pragma translate_off
1834
  -- assign to global signal for testbench
1835
  tb_istrobe_s <= istrobe_s;
1836
  -- pragma translate_on
1837 4 arniml
 
1838 53 arniml
 
1839 4 arniml
  -----------------------------------------------------------------------------
1840
  -- Output Mapping.
1841
  -----------------------------------------------------------------------------
1842
  clk_multi_cycle_o    <= opc_multi_cycle_s;
1843
  cnd_f1_o             <= f1_q;
1844
  cnd_tf_o             <= tf_s;
1845
  data_o               <=   data_s
1846
                          when read_dec_s else
1847
                            (others => bus_idle_level_c);
1848
  dm_write_dmem_o      <= dm_write_dmem_s      and en_clk_i;
1849
  pm_inc_pc_o          <= pm_inc_pc_s          or add_inc_pc_s;
1850
  pm_write_pmem_addr_o <= pm_write_pmem_addr_s or add_write_pmem_addr_s;
1851
  t0_dir_o             <= t0_dir_q;
1852
  bus_read_bus_o       <= bus_read_bus_s       or add_read_bus_s;
1853
 
1854
end rtl;
1855
 
1856
 
1857
-------------------------------------------------------------------------------
1858
-- File History:
1859
--
1860
-- $Log: not supported by cvs2svn $
1861 60 arniml
-- Revision 1.6  2004/04/14 20:53:33  arniml
1862
-- make istrobe visible through testbench package
1863
--
1864 53 arniml
-- Revision 1.5  2004/04/07 22:09:03  arniml
1865
-- remove unused signals
1866
--
1867 45 arniml
-- Revision 1.4  2004/04/04 14:18:53  arniml
1868
-- add measures to implement XCHD
1869
--
1870 38 arniml
-- Revision 1.3  2004/03/28 21:15:48  arniml
1871
-- implemented mnemonic DA
1872
--
1873 27 arniml
-- Revision 1.2  2004/03/28 13:06:32  arniml
1874
-- implement mnemonics:
1875
--    + MOVD_A_PP
1876
--    + OUTD_PP_A -> ANLD PP, A; MOVD PP, A; ORLD PP, A
1877
--
1878 21 arniml
-- Revision 1.1  2004/03/23 21:31:52  arniml
1879
-- initial check-in
1880 27 arniml
--
1881 4 arniml
-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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