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

Subversion Repositories rise

[/] [rise/] [trunk/] [vhdl/] [id_stage.vhd] - Diff between revs 9 and 11

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

Rev 9 Rev 11
Line 6... Line 6...
-- Description:
-- Description:
-- Instruction decode stage
-- Instruction decode stage
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
 
library IEEE;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.numeric_std.all;
 
 
use WORK.RISE_PACK.all;
use WORK.RISE_PACK.all;
 
 
 
 
entity id_stage is
entity id_stage is
 
 
Line 43... Line 42...
 
 
end id_stage;
end id_stage;
 
 
architecture id_stage_rtl of id_stage is
architecture id_stage_rtl of id_stage is
 
 
 
  signal rx_addr_int : REGISTER_ADDR_T;
 
  signal ry_addr_int : REGISTER_ADDR_T;
 
  signal rz_addr_int : REGISTER_ADDR_T;
  signal id_ex_register_int     : ID_EX_REGISTER_T;
  signal id_ex_register_int     : ID_EX_REGISTER_T;
  signal id_ex_register_next    : ID_EX_REGISTER_T;
  signal id_ex_register_next    : ID_EX_REGISTER_T;
 
 
  function opcode_modifies_rx( opcode: in OPCODE_T ) return std_logic is
  function opcode_modifies_rx( opcode: in OPCODE_T ) return std_logic is
    variable modifies : std_logic;
    variable modifies : std_logic;
  begin
  begin
    case opcode is
    case opcode is
      when OPCODE_LD_IMM => modifies := '1';
      when OPCODE_JMP => modifies := '0';
      when others => modifies := '0';
      when OPCODE_TST => modifies := '0';
 
      when OPCODE_NOP => modifies := '0';
 
      when OPCODE_ST_DISP => modifies := '0';
 
      when others => modifies := '1';
    end case;
    end case;
    return modifies;
    return modifies;
  end;
  end;
 
 
  function register_is_ready( reg_addr: in REGISTER_ADDR_T ) return std_logic is
 
    variable index : integer range 0 to REGISTER_COUNT - 1;
 
  begin
 
    return '1';
 
  end;
 
 
 
begin  -- id_stage_rtl
begin  -- id_stage_rtl
 
 
 
  rx_addr <= rx_addr_int;
 
  ry_addr <= ry_addr_int;
 
  rz_addr <= rz_addr_int;
  id_ex_register        <= id_ex_register_int;
  id_ex_register        <= id_ex_register_int;
 
 
--  process (clk, reset)
--  process (clk, reset)
--  begin  -- process
--  begin  -- process
--    if reset = '0' then                 -- asynchronous reset (active low)
--    if reset = '0' then                 -- asynchronous reset (active low)
Line 95... Line 97...
    end if;
    end if;
  end process;
  end process;
 
 
  -- The opc_extender decodes the two different formats used for the opcodes
  -- The opc_extender decodes the two different formats used for the opcodes
  -- in the instruction set into a single 5-bit opcode format.
  -- in the instruction set into a single 5-bit opcode format.
  opc_extender: process (clk, reset )
  opc_extender: process ( clk, reset, if_id_register )
  begin
  begin
    if reset = '0' then
    if reset = '0' then
      id_ex_register_next.opcode <= OPCODE_NOP;
      id_ex_register_next.opcode <= OPCODE_NOP;
      -- decodes: OPCODE_LD_IMM, OPCODE_LD_IMM_HB
      -- decodes: OPCODE_LD_IMM, OPCODE_LD_IMM_HB
    elsif if_id_register.ir( 15 downto 13 ) = "100" then
    elsif if_id_register.ir( 15 downto 13 ) = "100" then
Line 111... Line 113...
    else
    else
      id_ex_register_next.opcode <= if_id_register.ir( 15 downto 11 );
      id_ex_register_next.opcode <= if_id_register.ir( 15 downto 11 );
    end if;
    end if;
  end process;
  end process;
 
 
  cond_decode: process (clk, reset )
  cond_decode: process ( clk, reset, if_id_register )
  begin
  begin
    if reset = '0' then
    if reset = '0' then
      id_ex_register_next.cond <= COND_NONE;
      id_ex_register_next.cond <= COND_NONE;
      -- decodes: OPCODE_LD_IMM, OPCODE_LD_IMM_HB
      -- decodes: OPCODE_LD_IMM, OPCODE_LD_IMM_HB
    elsif if_id_register.ir( 15 downto 13 ) = "100" then
    elsif if_id_register.ir( 15 downto 13 ) = "100" then
      id_ex_register_next.cond <= COND_UNCONDITIONAL;
      id_ex_register_next.cond <= COND_UNCONDITIONAL;
      -- decodes: OPCODE_LD_DISP, OPCODE_LD_DISP_MS, OPCODE_ST_DISP      
      -- decodes: OPCODE_LD_DISP, OPCODE_LD_DISP_MS, OPCODE_ST_DISP      
    elsif if_id_register.ir(15) = '1' then
    elsif if_id_register.ir(15) = '1' then
      id_ex_register_next.cond <= if_id_register.ir( 15 downto 13 );
      id_ex_register_next.cond <= if_id_register.ir( 12 downto 10 );
      -- decodes: OPCODE_XXX
      -- decodes: OPCODE_XXX
    else
    else
      id_ex_register_next.cond <= if_id_register.ir( 10 downto 8 );
      id_ex_register_next.cond <= if_id_register.ir( 10 downto 8 );
    end if;
    end if;
  end process;
  end process;
 
 
  pc: process( if_id_register )
  pc: process( reset, if_id_register )
  begin
  begin
    if reset = '0' then
    if reset = '0' then
      id_ex_register_next.pc <= RESET_PC_VALUE;
      id_ex_register_next.pc <= RESET_PC_VALUE;
    else
    else
      id_ex_register_next.pc <= if_id_register.pc;
      id_ex_register_next.pc <= if_id_register.pc;
    end if;
    end if;
  end process;
  end process;
 
 
  rx_decode_and_fetch: process (reset, if_id_register, id_ex_register_next)
  rx_decode_and_fetch: process ( reset, if_id_register, id_ex_register_next, rx)
  begin
  begin
    -- make sure we don't synthesize a latch for rx_addr
    -- make sure we don't synthesize a latch for rx_addr
    rx_addr <= ( others => '0' );
    rx_addr_int <= ( others => '0' );
 
 
    if reset = '0' then
    if reset = '0' then
      id_ex_register_next.rX <= ( others => '0' );
      id_ex_register_next.rX <= ( others => '0' );
      id_ex_register_next.rX_addr <= ( others => '0' );
      id_ex_register_next.rX_addr <= ( others => '0' );
    elsif id_ex_register_next.opcode = OPCODE_LD_IMM or
    elsif id_ex_register_next.opcode = OPCODE_LD_IMM or
      id_ex_register_next.opcode = OPCODE_LD_IMM_HB then
      id_ex_register_next.opcode = OPCODE_LD_IMM_HB then
      rx_addr <= if_id_register.ir( 11 downto 8 );
      rx_addr_int <= if_id_register.ir( 11 downto 8 );
      id_ex_register_next.rX <= rx;
      id_ex_register_next.rX <= rx;
      id_ex_register_next.rX_addr <= if_id_register.ir( 11 downto 8 );
      id_ex_register_next.rX_addr <= if_id_register.ir( 11 downto 8 );
    else
    else
      rx_addr <= if_id_register.ir( 7 downto 4 );
      rx_addr_int <= if_id_register.ir( 7 downto 4 );
      id_ex_register_next.rX <= rx;
      id_ex_register_next.rX <= rx;
      id_ex_register_next.rX_addr <= if_id_register.ir( 7 downto 4 );
      id_ex_register_next.rX_addr <= if_id_register.ir( 7 downto 4 );
    end if;
    end if;
 
 
    if opcode_modifies_rx( id_ex_register_next.opcode ) = '1' then
    if opcode_modifies_rx( id_ex_register_next.opcode ) = '1' then
Line 164... Line 166...
      lock_reg_addr <= ( others => '0' );
      lock_reg_addr <= ( others => '0' );
      set_reg_lock <= '0';
      set_reg_lock <= '0';
    end if;
    end if;
  end process;
  end process;
 
 
  ry_decode_and_fetch: process (reset, if_id_register, id_ex_register_next)
  ry_decode_and_fetch: process ( reset, if_id_register, id_ex_register_next, ry )
  begin
  begin
    -- make sure we don't synthesize a latch for ry_addr
    -- make sure we don't synthesize a latch for ry_addr_int
    ry_addr <= ( others => '0' );
    ry_addr_int <= ( others => '0' );
 
 
    if reset = '0' then
    if reset = '0' then
      id_ex_register_next.rY <= ( others => '0' );
      id_ex_register_next.rY <= ( others => '0' );
    else
    else
      ry_addr <= if_id_register.ir( 3 downto 0 );
      ry_addr_int <= if_id_register.ir( 3 downto 0 );
      id_ex_register_next.rZ <= rz;
      id_ex_register_next.rY <= ry;
    end if;
    end if;
  end process;
  end process;
 
 
  rz_decode_and_fetch: process (reset, if_id_register, id_ex_register_next)
  rz_decode_and_fetch: process ( reset, if_id_register, id_ex_register_next, rz )
  begin
  begin
    -- make sure we don't synthesize a latch for rz_addr
    -- make sure we don't synthesize a latch for rz_addr_int
    rz_addr <= ( others => '0' );
    rz_addr_int <= ( others => '0' );
 
 
    if reset = '0' then
    if reset = '0' then
      id_ex_register_next.rZ <= ( others => '0' );
      id_ex_register_next.rZ <= ( others => '0' );
    else
    else
      -- only the lower 2-bits of rz are encoded in the instruction
      -- only the lower 2-bits of rz are encoded in the instruction
      rz_addr <= "00" & if_id_register.ir( 9 downto 8 );
      rz_addr_int <= "00" & if_id_register.ir( 9 downto 8 );
      id_ex_register_next.rZ <= rz;
      id_ex_register_next.rZ <= rz;
    end if;
    end if;
  end process;
  end process;
 
 
  -- The immediate fetch process checks for all opcodes needing constants
  -- The immediate fetch process checks for all opcodes needing constants
Line 210... Line 212...
      when others =>
      when others =>
        id_ex_register_next.immediate <= x"000" & if_id_register.ir( 3 downto 0 );
        id_ex_register_next.immediate <= x"000" & if_id_register.ir( 3 downto 0 );
    end case;
    end case;
  end process;
  end process;
 
 
 
  -- Check if all registers are available. If not stall the pipeline.
 
  lock: process( reset, id_ex_register_next, rx_addr_int, ry_addr_int, rz_addr_int, lock_register )
 
    variable required: LOCK_REGISTER_T;
 
  begin
 
    required := ( others => '0' );
 
    if id_ex_register_next.cond /= COND_UNCONDITIONAL then
 
      required( TO_INTEGER( UNSIGNED( SR_REGISTER_ADDR ) ) ) := '1';
 
    end if;
 
    case id_ex_register_next.opcode is
 
      when OPCODE_LD_DISP =>
 
        required( TO_INTEGER( UNSIGNED( rz_addr_int ) ) ) := '1';
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_LD_DISP_MS =>
 
        required( TO_INTEGER( UNSIGNED( rz_addr_int ) ) ) := '1';
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_LD_REG =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_ST_DISP =>
 
        required( TO_INTEGER( UNSIGNED( rx_addr_int ) ) ) := '1';
 
        required( TO_INTEGER( UNSIGNED( rz_addr_int ) ) ) := '1';
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_ADD =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_SUB =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_NEG =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_ARS =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_ALS =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_AND =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_NOT =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_EOR =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_LS =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_RS =>
 
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
 
      when OPCODE_JMP =>
 
        required( TO_INTEGER( UNSIGNED( rx_addr_int ) ) ) := '1';
 
      when OPCODE_TST =>
 
        required( TO_INTEGER( UNSIGNED( rx_addr_int ) ) ) := '1';
 
      when others => null;
 
    end case;
 
 
 
    -- no checks if all registers are not locked.
 
    stall_out <= '0';
 
    if ( required & lock_register ) /= x"0000" then
 
      stall_out <= '1';
 
    end if;
 
  end process;
 
 
end id_stage_rtl;
end id_stage_rtl;
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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