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

Subversion Repositories t400

[/] [t400/] [trunk/] [rtl/] [vhdl/] [t400_decoder.vhd] - Diff between revs 70 and 88

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 70 Rev 88
Line 1... Line 1...
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
--
-- The decoder unit.
-- The decoder unit.
-- Implements the instruction opcodes and controls all units of the T400 core.
-- Implements the instruction opcodes and controls all units of the T400 core.
--
--
-- $Id: t400_decoder.vhd,v 1.4 2006-05-27 19:14:18 arniml Exp $
-- $Id: t400_decoder.vhd,v 1.5 2006-05-28 15:32:14 arniml Exp $
--
--
-- Copyright (c) 2006 Arnim Laeuger (arniml@opencores.org)
-- Copyright (c) 2006 Arnim Laeuger (arniml@opencores.org)
--
--
-- All rights reserved
-- All rights reserved
--
--
Line 208... Line 208...
          end if;
          end if;
        end if;
        end if;
 
 
        -- instruction byte 1 and mnemonic info -------------------------------
        -- instruction byte 1 and mnemonic info -------------------------------
        if icyc_en_i and last_cycle_s then
        if icyc_en_i and last_cycle_s then
 
          if not ack_int_s then
 
            -- update instruction descriptors in normal mode
          ibyte1_q     <= pm_data_i;
          ibyte1_q     <= pm_data_i;
          mnemonic_q   <= mnemonic_s;
          mnemonic_q   <= mnemonic_s;
          multi_byte_q <= multi_byte_s;
          multi_byte_q <= multi_byte_s;
 
          else
 
            -- force NOP instruction when vectoring to interrupt routine
 
            ibyte1_q     <= "01000100";
 
            mnemonic_q   <= MN_NOP;
 
            multi_byte_q <= false;
 
          end if;
        end if;
        end if;
 
 
        -- instruction byte 2 -------------------------------------------------
        -- instruction byte 2 -------------------------------------------------
        if icyc_en_i and not last_cycle_s then
        if icyc_en_i and not last_cycle_s then
          ibyte2_q     <= pm_data_i;
          ibyte2_q     <= pm_data_i;
Line 271... Line 279...
                         en_q, int_i,
                         en_q, int_i,
                         pm_addr_i, pm_data_i)
                         pm_addr_i, pm_data_i)
    variable cyc_v        : natural range 0 to 4;
    variable cyc_v        : natural range 0 to 4;
    variable t41x_type_v,
    variable t41x_type_v,
             t420_type_v  : boolean;
             t420_type_v  : boolean;
    variable no_int_v     : boolean;
    variable en_int_v     : boolean;
  begin
  begin
    -- default assignments
    -- default assignments
    pc_op_o     <= PC_NONE;
    pc_op_o     <= PC_NONE;
    stack_op_o  <= STACK_NONE;
    stack_op_o  <= STACK_NONE;
    dmem_op_o   <= DMEM_RB;             -- default is read via B
    dmem_op_o   <= DMEM_RB;             -- default is read via B
Line 289... Line 297...
    sio_op_o    <= SIO_NONE;
    sio_op_o    <= SIO_NONE;
    dec_data_o  <= (others => '0');
    dec_data_o  <= (others => '0');
    is_lbi_o    <= false;
    is_lbi_o    <= false;
    set_en_s    <= false;
    set_en_s    <= false;
    force_mc_s  <= false;
    force_mc_s  <= false;
    no_int_v    := false;
    en_int_v    := true;
    ack_int_s   <= false;
    ack_int_s   <= false;
    cyc_v       := to_integer(cyc_cnt_q);
    cyc_v       := to_integer(cyc_cnt_q);
    -- determine type
    -- determine type
    t41x_type_v := opt_type_g = t400_opt_type_410_c;
    t41x_type_v := opt_type_g = t400_opt_type_410_c;
    t420_type_v := opt_type_g = t400_opt_type_420_c;
    t420_type_v := opt_type_g = t400_opt_type_420_c;
Line 388... Line 396...
          end if;
          end if;
 
 
        -- Mnemonic JID -------------------------------------------------------
        -- Mnemonic JID -------------------------------------------------------
        when MN_JID =>
        when MN_JID =>
          force_mc_s     <= true;
          force_mc_s     <= true;
          no_int_v       := true;
          en_int_v       := false;
          dec_data_o(byte_t'range) <= pm_data_i;
          dec_data_o(byte_t'range) <= pm_data_i;
          if cyc_v = 1 then
          if cyc_v = 1 then
            if not second_cyc_q then
            if not second_cyc_q then
              -- first cycle: load PC from A and M
              -- first cycle: load PC from A and M
              pc_op_o    <= PC_LOAD_A_M;
              pc_op_o    <= PC_LOAD_A_M;
Line 407... Line 415...
            pc_op_o      <= PC_NONE;
            pc_op_o      <= PC_NONE;
          end if;
          end if;
 
 
        -- Mnemonic JMP -------------------------------------------------------
        -- Mnemonic JMP -------------------------------------------------------
        when MN_JMP =>
        when MN_JMP =>
          no_int_v       := true;
          en_int_v       := false;
          dec_data_o <= ibyte1_q(1) & ibyte1_q(0) & ibyte2_q;
          dec_data_o <= ibyte1_q(1) & ibyte1_q(0) & ibyte2_q;
          if second_cyc_q and cyc_v = 1 then
          if second_cyc_q and cyc_v = 1 then
            pc_op_o      <= PC_LOAD;
            pc_op_o      <= PC_LOAD;
          end if;
          end if;
 
 
        -- Mnemonic JP_JSRP ---------------------------------------------------
        -- Mnemonic JP_JSRP ---------------------------------------------------
        when MN_JP_JSRP =>
        when MN_JP_JSRP =>
          no_int_v       := true;
          en_int_v       := false;
          -- universal decoder data
          -- universal decoder data
          dec_data_o <= '0' & "01" & ibyte1_q(6 downto 0);
          dec_data_o <= '0' & "01" & ibyte1_q(6 downto 0);
          if cyc_v = 1 then
          if cyc_v = 1 then
            if    pm_addr_i(9 downto 7) = "001" then
            if    pm_addr_i(9 downto 7) = "001" then
              -- JP within pages 2 & 3
              -- JP within pages 2 & 3
Line 434... Line 442...
            end if;
            end if;
          end if;
          end if;
 
 
        -- Mnemonic JSR -------------------------------------------------------
        -- Mnemonic JSR -------------------------------------------------------
        when MN_JSR =>
        when MN_JSR =>
          no_int_v       := true;
          en_int_v       := false;
          dec_data_o <= ibyte1_q(1) & ibyte1_q(0) & ibyte2_q;
          dec_data_o <= ibyte1_q(1) & ibyte1_q(0) & ibyte2_q;
          if second_cyc_q and cyc_v = 1 then
          if second_cyc_q and cyc_v = 1 then
            pc_op_o      <= PC_LOAD;
            pc_op_o      <= PC_LOAD;
            stack_op_o   <= STACK_PUSH;
            stack_op_o   <= STACK_PUSH;
          end if;
          end if;
 
 
        -- Mnemonic RET -------------------------------------------------------
        -- Mnemonic RET -------------------------------------------------------
        when MN_RET =>
        when MN_RET =>
          no_int_v       := true;
          en_int_v       := false;
          if cyc_v = 1 then
          if cyc_v = 1 then
            pc_op_o      <= PC_POP;
            pc_op_o      <= PC_POP;
            stack_op_o   <= STACK_POP;
            stack_op_o   <= STACK_POP;
 
 
            if t420_type_v then
            if t420_type_v then
Line 456... Line 464...
            end if;
            end if;
          end if;
          end if;
 
 
        -- Mnemonic RETSK -----------------------------------------------------
        -- Mnemonic RETSK -----------------------------------------------------
        when MN_RETSK =>
        when MN_RETSK =>
          no_int_v       := true;
          en_int_v       := false;
          if cyc_v = 1 then
          if cyc_v = 1 then
            pc_op_o      <= PC_POP;
            pc_op_o      <= PC_POP;
            stack_op_o   <= STACK_POP;
            stack_op_o   <= STACK_POP;
            skip_op_o    <= SKIP_NOW;
            skip_op_o    <= SKIP_NOW;
          end if;
          end if;
Line 513... Line 521...
          end if;
          end if;
 
 
        -- Mnemonic LQID ------------------------------------------------------
        -- Mnemonic LQID ------------------------------------------------------
        when MN_LQID =>
        when MN_LQID =>
          force_mc_s     <= true;
          force_mc_s     <= true;
          no_int_v       := true;
          en_int_v       := false;
          if not second_cyc_q then
          if not second_cyc_q then
            -- first cycle: push PC and set PC from A/M,
            -- first cycle: push PC and set PC from A/M,
            --              read IOL from program memory
            --              read IOL from program memory
            if cyc_v = 1 then
            if cyc_v = 1 then
              stack_op_o <= STACK_PUSH;
              stack_op_o <= STACK_PUSH;
Line 638... Line 646...
          end if;
          end if;
 
 
        -- Mnemonic LBI -------------------------------------------------------
        -- Mnemonic LBI -------------------------------------------------------
        when MN_LBI =>
        when MN_LBI =>
          is_lbi_o       <= true;
          is_lbi_o       <= true;
          no_int_v       := true;
          en_int_v       := false;
          dec_data_o(br_range_t) <= ibyte1_q(br_range_t);
          dec_data_o(br_range_t) <= ibyte1_q(br_range_t);
          dec_data_o(bd_range_t) <= ibyte1_q(bd_range_t);
          dec_data_o(bd_range_t) <= ibyte1_q(bd_range_t);
          if cyc_v = 1 and not skip_lbi_i then
          if cyc_v = 1 and not skip_lbi_i then
            -- increment Bd by 1
            -- increment Bd by 1
            b_op_o       <= B_SET_B_INC;
            b_op_o       <= B_SET_B_INC;
Line 780... Line 788...
                -- apply default decoder output, largest required vector
                -- apply default decoder output, largest required vector
                dec_data_o(b_range_t) <= ibyte2_q(b_range_t);
                dec_data_o(b_range_t) <= ibyte2_q(b_range_t);
                -- LBI
                -- LBI
                if ibyte2_q(7 downto 6) = "10" and not t41x_type_v then
                if ibyte2_q(7 downto 6) = "10" and not t41x_type_v then
                  is_lbi_o    <= true;
                  is_lbi_o    <= true;
                  no_int_v    := true;
                  en_int_v    := false;
                  if cyc_v > 0 and not skip_lbi_i then
                  if cyc_v > 0 and not skip_lbi_i then
                    b_op_o    <= B_SET_B;
                    b_op_o    <= B_SET_B;
                    skip_op_o <= SKIP_LBI;
                    skip_op_o <= SKIP_LBI;
                  end if;
                  end if;
                end if;
                end if;
Line 815... Line 823...
    end if;
    end if;
 
 
 
 
    -- Interrupt handling -----------------------------------------------------
    -- Interrupt handling -----------------------------------------------------
    if t420_type_v and
    if t420_type_v and
       en_q(1) = '1' and int_i and not no_int_v then
       en_q(1) = '1' and int_i and en_int_v then
      if last_cycle_s then
      if last_cycle_s then
        if cyc_v = 1 then
        if cyc_v = 1 then
          pc_op_o    <= PC_INT;
 
          stack_op_o <= STACK_PUSH;
          stack_op_o <= STACK_PUSH;
        end if;
        end if;
        if icyc_en_i then
        if icyc_en_i then
          ack_int_s  <= true;
          ack_int_s  <= true;
          io_in_op_o <= IOIN_INTACK;
          io_in_op_o <= IOIN_INTACK;
 
          pc_op_o    <= PC_INT;
          -- push skip state that was determined by current instruction
          -- push skip state that was determined by current instruction
          -- and will be valid for the next instruction which is delayed
          -- and will be valid for the next instruction which is delayed
          -- by the interrupt
          -- by the interrupt
          skip_op_o  <= SKIP_PUSH;
          skip_op_o  <= SKIP_PUSH;
        end if;
        end if;
Line 849... Line 857...
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- File History:
-- File History:
--
--
-- $Log: not supported by cvs2svn $
-- $Log: not supported by cvs2svn $
 
-- Revision 1.4  2006/05/27 19:14:18  arniml
 
-- interrupt functionality added
 
--
-- Revision 1.3  2006/05/22 00:02:36  arniml
-- Revision 1.3  2006/05/22 00:02:36  arniml
-- instructions ININ and INIL implemented
-- instructions ININ and INIL implemented
--
--
-- Revision 1.2  2006/05/07 02:24:16  arniml
-- Revision 1.2  2006/05/07 02:24:16  arniml
-- fix sensitivity list
-- fix sensitivity list

powered by: WebSVN 2.1.0

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