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

Subversion Repositories t48

[/] [t48/] [tags/] [rel_0_3_beta/] [rtl/] [vhdl/] [decoder.vhd] - Blame information for rev 53

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

powered by: WebSVN 2.1.0

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