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

Subversion Repositories t48

[/] [t48/] [tags/] [rel_0_2_beta/] [rtl/] [vhdl/] [decoder.vhd] - Blame information for rev 21

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

powered by: WebSVN 2.1.0

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