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

Subversion Repositories t48

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

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

powered by: WebSVN 2.1.0

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