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

Subversion Repositories t48

[/] [t48/] [tags/] [rel_0_6__beta/] [rtl/] [vhdl/] [decoder.vhd] - Blame information for rev 45

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

powered by: WebSVN 2.1.0

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