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

Subversion Repositories t48

[/] [t48/] [tags/] [rel_0_1_beta/] [rtl/] [vhdl/] [decoder.vhd] - Blame information for rev 78

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

powered by: WebSVN 2.1.0

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