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

Subversion Repositories igor

[/] [igor/] [trunk/] [processor/] [pl/] [id.vhd] - Rev 4

Compare with Previous | Blame | View Log

library ieee;
use ieee.std_logic_1164.all;
use work.whisk_constants.all;
 
entity instr_decode is
    port (
    clk : in std_logic;
    -- data lines
    reg1 : out std_logic_vector(WORD_BITS - 1 downto 0);
    reg2 : out std_logic_vector(WORD_BITS - 1 downto 0);
    immediate : out std_logic_vector(IMM_SIZE - 1 downto 0);
    regs_data_in : in std_logic_vector(WORD_BITS - 1 downto 0);
    --branch_target : out std_logic_vector(MC_ADDR_BITS - 1 downto 0);
 
    instr : in std_logic_vector(MC_INSTR_BITS - 1 downto 0);
 
    -- Let the control unit know if we're using indirect addressing
    indir_reg1_sel : out std_logic;
    indir_reg2_sel : out std_logic;
    alu_funct : out std_logic_vector(ALU_FUNCT_SIZE - 1 downto 0);
    reg_write : out std_logic; -- feed forward to next stage
 
 
    wb_reg_write : in std_logic; -- from write-back stage.
    ctrl_regs_we : in std_logic; -- from control unit
    ctrl_alu_funct : in std_logic_vector(ALU_FUNCT_SIZE - 1 downto 0);
 
    -- Select source of register address. Either direct or indirect register.
    regs_addr_src_1 : in std_logic;
    regs_addr_src_2 : in std_logic
    );  
end entity;
 
 
architecture mixed of instr_decode is
    signal regs_addr_1 : std_logic_vector(REGS_ADDR_BITS - 1 downto 0);
    signal regs_addr_2 : std_logic_vector(REGS_ADDR_BITS - 1 downto 0);
    signal regs_data_1 : std_logic_vector(WORD_BITS - 1 downto 0);
    signal regs_data_2 : std_logic_vector(WORD_BITS - 1 downto 0);
--    signal regs_data_in : std_logic_vector(WORD_BITS - 1 downto 0);
 
    --storage for the indirect registers
    signal indir_reg_1 : std_logic_vector(REGS_ADDR_BITS - 1 downto 0);
    signal indir_reg_2 : std_logic_vector(REGS_ADDR_BITS - 1 downto 0);
begin
    regfile : entity dualport_mem 
    generic map (
        memsize => REGS_SIZE,
        addr_width => REGS_ADDR_BITS,
        data_width => WORD_BITS,
        initfile => SCRATCH_MEM_INIT)
    port map (
        clk => clk,
        a => regs_addr_1,
        b => regs_addr_2,
        doa => regs_data_1,
        dob => regs_data_2,
        dia => regs_data_in,
        we => wb_reg_write);
 
    -- Indirect register addressing
    regs_addr_1 <= indir_reg_1 when regs_addr_src_1 = '1' 
                               else instr(INSTR_REG1_START - 1 downto INSTR_REG1_END);
    regs_addr_2 <= indir_reg_2 when regs_addr_src_2 = '1' 
                               else instr(INSTR_REG2_START - 1 downto INSTR_REG2_END);
 
    -- Update pipeline registers.
    update_id_regs : process (clk)
    begin
        if rising_edge(clk) then
            immediate <= instr(INSTR_IMM_START downto 0);
            -- Control signals that are fed forward.
            reg_write <= ctrl_regs_we;
            -- Lets us know if the next cycle is an indirect addressing
            indir_reg1_sel <= instr(INSTR_REG1_INDIR);
            indir_reg2_sel <= instr(INSTR_REG2_INDIR);
            indir_reg_1 <= regs_data_1(REGS_ADDR_BITS - 1 downto 0);
            indir_reg_2 <= regs_data_2(REGS_ADDR_BITS - 1 downto 0);
            alu_funct <= ctrl_alu_funct;
       end if;
       -- output ports are registered, no need to be under flank.
       reg1 <= regs_data_1;
       reg2 <= regs_data_2;
 
    end process;
end architecture;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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