-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
-- --
|
-- --
|
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
-- --
|
-- --
|
-- Copyright (C) 2015 Stefano Tonello --
|
-- Copyright (C) 2015 Stefano Tonello --
|
-- --
|
-- --
|
-- This source file may be used and distributed without --
|
-- This source file may be used and distributed without --
|
-- restriction provided that this copyright statement is not --
|
-- restriction provided that this copyright statement is not --
|
-- removed from the file and that any derivative work contains --
|
-- removed from the file and that any derivative work contains --
|
-- the original copyright notice and the associated disclaimer.--
|
-- the original copyright notice and the associated disclaimer.--
|
-- --
|
-- --
|
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY --
|
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY --
|
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --
|
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --
|
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --
|
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --
|
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR --
|
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR --
|
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, --
|
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, --
|
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES --
|
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES --
|
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE --
|
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE --
|
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR --
|
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR --
|
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --
|
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --
|
-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
|
-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
|
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT --
|
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT --
|
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --
|
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --
|
-- POSSIBILITY OF SUCH DAMAGE. --
|
-- POSSIBILITY OF SUCH DAMAGE. --
|
-- --
|
-- --
|
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
|
|
---------------------------------------------------------------
|
---------------------------------------------------------------
|
-- RV01 pipeline-A (dedicated) decoder
|
-- RV01 pipeline-A (dedicated) decoder
|
---------------------------------------------------------------
|
---------------------------------------------------------------
|
|
|
library IEEE;
|
library IEEE;
|
use IEEE.std_logic_1164.all;
|
use IEEE.std_logic_1164.all;
|
use IEEE.numeric_std.all;
|
use IEEE.numeric_std.all;
|
|
|
library WORK;
|
library WORK;
|
use WORK.RV01_CONSTS_PKG.all;
|
use WORK.RV01_CONSTS_PKG.all;
|
use WORK.RV01_TYPES_PKG.all;
|
use WORK.RV01_TYPES_PKG.all;
|
use work.RV01_IDEC_PKG.all;
|
use work.RV01_IDEC_PKG.all;
|
use WORK.RV01_OP_PKG.all;
|
use WORK.RV01_OP_PKG.all;
|
|
|
entity RV01_PIPE_A_DEC is
|
entity RV01_PIPE_A_DEC is
|
port(
|
port(
|
INSTR_i : in DEC_INSTR_T;
|
INSTR_i : in DEC_INSTR_T;
|
|
|
FWDE_o : out std_logic;
|
FWDE_o : out std_logic;
|
SEL_o : out std_logic_vector(4-1 downto 0)
|
SEL_o : out std_logic_vector(4-1 downto 0)
|
);
|
);
|
end RV01_PIPE_A_DEC;
|
end RV01_PIPE_A_DEC;
|
|
|
architecture ARC of RV01_PIPE_A_DEC is
|
architecture ARC of RV01_PIPE_A_DEC is
|
|
|
begin
|
begin
|
|
|
-- Result forward-enable flag
|
-- Result forward-enable flag
|
|
|
FWDE_o <= '1' when (
|
FWDE_o <= '1' when (
|
INSTR_i.IMNMC = IM_ADD or
|
INSTR_i.IMNMC = IM_ADD or
|
INSTR_i.IMNMC = IM_ADDI or
|
INSTR_i.IMNMC = IM_ADDI or
|
INSTR_i.IMNMC = IM_SLL or
|
INSTR_i.IMNMC = IM_SLL or
|
INSTR_i.IMNMC = IM_SLLI or
|
INSTR_i.IMNMC = IM_SLLI or
|
INSTR_i.IMNMC = IM_SRL or
|
INSTR_i.IMNMC = IM_SRL or
|
INSTR_i.IMNMC = IM_SRLI or
|
INSTR_i.IMNMC = IM_SRLI or
|
INSTR_i.IMNMC = IM_SRA or
|
INSTR_i.IMNMC = IM_SRA or
|
INSTR_i.IMNMC = IM_SRAI or
|
INSTR_i.IMNMC = IM_SRAI or
|
INSTR_i.IMNMC = IM_AND or
|
INSTR_i.IMNMC = IM_AND or
|
INSTR_i.IMNMC = IM_ANDI or
|
INSTR_i.IMNMC = IM_ANDI or
|
INSTR_i.IMNMC = IM_OR or
|
INSTR_i.IMNMC = IM_OR or
|
INSTR_i.IMNMC = IM_ORI or
|
INSTR_i.IMNMC = IM_ORI or
|
INSTR_i.IMNMC = IM_XOR or
|
INSTR_i.IMNMC = IM_XOR or
|
INSTR_i.IMNMC = IM_XORI or
|
INSTR_i.IMNMC = IM_XORI or
|
INSTR_i.IMNMC = IM_LW
|
INSTR_i.IMNMC = IM_LW
|
) else '0';
|
) else '0';
|
|
|
-- pipe-A operation selector
|
-- pipe-A operation selector
|
|
|
process(INSTR_i)
|
process(INSTR_i)
|
begin
|
begin
|
case INSTR_i.IMNMC is
|
case INSTR_i.IMNMC is
|
when IM_ADD|IM_ADDI => SEL_o <= "0001";
|
when IM_ADD|IM_ADDI => SEL_o <= "0001";
|
when IM_SLL|IM_SLLI|IM_SRL|IM_SRLI|IM_SRA|IM_SRAI => SEL_o <= "0010";
|
when IM_SLL|IM_SLLI|IM_SRL|IM_SRLI|IM_SRA|IM_SRAI => SEL_o <= "0010";
|
when IM_AND|IM_ANDI|IM_OR|IM_ORI|IM_XOR|IM_XORI => SEL_o <= "0100";
|
when IM_AND|IM_ANDI|IM_OR|IM_ORI|IM_XOR|IM_XORI => SEL_o <= "0100";
|
when others => SEL_o <= "1000"; -- lw
|
when others => SEL_o <= "1000"; -- lw
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|
end ARC;
|
end ARC;
|
|
|
---------------------------------------------------------------
|
---------------------------------------------------------------
|
-- A-pipeline ALU
|
-- A-pipeline ALU
|
---------------------------------------------------------------
|
---------------------------------------------------------------
|
|
|
library IEEE;
|
library IEEE;
|
use IEEE.std_logic_1164.all;
|
use IEEE.std_logic_1164.all;
|
use IEEE.numeric_std.all;
|
use IEEE.numeric_std.all;
|
|
|
library WORK;
|
library WORK;
|
use WORK.RV01_CONSTS_PKG.all;
|
use WORK.RV01_CONSTS_PKG.all;
|
use WORK.RV01_TYPES_PKG.all;
|
use WORK.RV01_TYPES_PKG.all;
|
use WORK.RV01_FUNCS_PKG.all;
|
use WORK.RV01_FUNCS_PKG.all;
|
use WORK.RV01_ARITH_PKG.all;
|
use WORK.RV01_ARITH_PKG.all;
|
use work.RV01_IDEC_PKG.all;
|
use work.RV01_IDEC_PKG.all;
|
use WORK.RV01_OP_PKG.all;
|
use WORK.RV01_OP_PKG.all;
|
|
|
entity RV01_PIPE_A_ALU is
|
entity RV01_PIPE_A_ALU is
|
port(
|
port(
|
SEL_i : in std_logic_vector(4-1 downto 0);
|
SEL_i : in std_logic_vector(4-1 downto 0);
|
SU_i : in std_logic;
|
SU_i : in std_logic;
|
OP_i : in ALU_OP_T;
|
OP_i : in ALU_OP_T;
|
OPA_i : in SDWORD_T;
|
OPA_i : in SDWORD_T;
|
OPB_i : in SDWORD_T;
|
OPB_i : in SDWORD_T;
|
|
|
RES_o : out SDWORD_T -- result
|
RES_o : out SDWORD_T -- result
|
);
|
);
|
end RV01_PIPE_A_ALU;
|
end RV01_PIPE_A_ALU;
|
|
|
architecture ARC of RV01_PIPE_A_ALU is
|
architecture ARC of RV01_PIPE_A_ALU is
|
|
|
constant OP_ADD : natural := 0;
|
constant OP_ADD : natural := 0;
|
constant OP_SHF : natural := 1;
|
constant OP_SHF : natural := 1;
|
constant OP_LOG : natural := 2;
|
constant OP_LOG : natural := 2;
|
constant OP_LOAD : natural := 3;
|
constant OP_LOAD : natural := 3;
|
|
|
component RV01_ADDER_F is
|
component RV01_ADDER_F is
|
generic(
|
generic(
|
LEN1 : integer := 16;
|
LEN1 : integer := 16;
|
LEN2 : integer := 16
|
LEN2 : integer := 16
|
);
|
);
|
port(
|
port(
|
OPA_i : in signed(LEN1+LEN2-1 downto 0);
|
OPA_i : in signed(LEN1+LEN2-1 downto 0);
|
OPB_i : in signed(LEN1+LEN2-1 downto 0);
|
OPB_i : in signed(LEN1+LEN2-1 downto 0);
|
CI_i : in std_logic;
|
CI_i : in std_logic;
|
|
|
SUM_o : out signed(LEN1+LEN2-1 downto 0)
|
SUM_o : out signed(LEN1+LEN2-1 downto 0)
|
);
|
);
|
end component;
|
end component;
|
|
|
component RV01_LOGICU is
|
component RV01_LOGICU is
|
port(
|
port(
|
CTRL_i : in LOG_CTRL;
|
CTRL_i : in LOG_CTRL;
|
OPA_i : in SDWORD_T;
|
OPA_i : in SDWORD_T;
|
OPB_i : in SDWORD_T;
|
OPB_i : in SDWORD_T;
|
|
|
RES_o : out SDWORD_T
|
RES_o : out SDWORD_T
|
);
|
);
|
end component;
|
end component;
|
|
|
signal ZERO : std_logic := '0';
|
signal ZERO : std_logic := '0';
|
signal ONE : std_logic := '1';
|
signal ONE : std_logic := '1';
|
signal ADD_RES : SDWORD_T;
|
signal ADD_RES : SDWORD_T;
|
signal LOG_RES : SDWORD_T;
|
signal LOG_RES : SDWORD_T;
|
signal LC : LOG_CTRL;
|
signal LC : LOG_CTRL;
|
signal RES : SDWORD_T;
|
signal RES : SDWORD_T;
|
|
|
begin
|
begin
|
|
|
------------------------------------
|
------------------------------------
|
-- addition
|
-- addition
|
------------------------------------
|
------------------------------------
|
|
|
-- carry-select adder (to improve timing)
|
-- carry-select adder (to improve timing)
|
|
|
U_ADD : RV01_ADDER_F
|
U_ADD : RV01_ADDER_F
|
generic map(
|
generic map(
|
LEN1 => SDLEN/2,
|
LEN1 => SDLEN/2,
|
LEN2 => SDLEN/2
|
LEN2 => SDLEN/2
|
)
|
)
|
port map(
|
port map(
|
OPA_i => OPA_i,
|
OPA_i => OPA_i,
|
OPB_i => OPB_i,
|
OPB_i => OPB_i,
|
CI_i => ZERO,
|
CI_i => ZERO,
|
SUM_o => ADD_RES
|
SUM_o => ADD_RES
|
);
|
);
|
|
|
------------------------------------
|
------------------------------------
|
-- Logic unit operation selection
|
-- Logic unit operation selection
|
------------------------------------
|
------------------------------------
|
|
|
process(OP_i)
|
process(OP_i)
|
begin
|
begin
|
case OP_i is
|
case OP_i is
|
when ALU_AND =>
|
when ALU_AND =>
|
LC <= LC_AND;
|
LC <= LC_AND;
|
when ALU_OR =>
|
when ALU_OR =>
|
LC <= LC_OR;
|
LC <= LC_OR;
|
when others =>
|
when others =>
|
LC <= LC_XOR;
|
LC <= LC_XOR;
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|
------------------------------------
|
------------------------------------
|
-- Logic unit
|
-- Logic unit
|
------------------------------------
|
------------------------------------
|
|
|
U_LOG : RV01_LOGICU
|
U_LOG : RV01_LOGICU
|
port map(
|
port map(
|
CTRL_i => LC,
|
CTRL_i => LC,
|
OPA_i => OPA_i,
|
OPA_i => OPA_i,
|
OPB_i => OPB_i,
|
OPB_i => OPB_i,
|
|
|
RES_o => LOG_RES
|
RES_o => LOG_RES
|
);
|
);
|
|
|
-- Result mux
|
-- Result mux
|
|
|
RES <= ADD_RES when (SEL_i(OP_ADD) = '1') else LOG_RES;
|
RES <= ADD_RES when (SEL_i(OP_ADD) = '1') else LOG_RES;
|
|
|
RES_o <= RES;
|
RES_o <= RES;
|
|
|
end ARC;
|
end ARC;
|
|
|
---------------------------------------------------------------
|
|
-- A-pipeline result mux (IX2 stage)
|
|
---------------------------------------------------------------
|
|
|
|
library IEEE;
|
|
use IEEE.std_logic_1164.all;
|
|
use IEEE.numeric_std.all;
|
|
|
|
library WORK;
|
|
use WORK.RV01_CONSTS_PKG.all;
|
|
use WORK.RV01_TYPES_PKG.all;
|
|
use WORK.RV01_FUNCS_PKG.all;
|
|
use work.RV01_IDEC_PKG.all;
|
|
|
|
entity RV01_PIPE_A_RMX_X2 is
|
|
generic(
|
|
NW : natural := 2
|
|
);
|
|
port(
|
|
OPA_V_i : in std_logic;
|
|
OPB_V_i : in std_logic;
|
|
OPA_i : in SDWORD_T;
|
|
OPB_i : in SDWORD_T;
|
|
INSTR_i : in DEC_INSTR_T;
|
|
IX3_V_i : in std_logic_vector(NW-1 downto 0);
|
|
IX3_INSTR_i : in DEC_INSTR_VEC_T(NW-1 downto 0);
|
|
IX3_RES0_i : in SDWORD_T;
|
|
IX3_RES1_i : in SDWORD_T;
|
|
|
|
OPA_V_o : out std_logic;
|
|
OPB_V_o : out std_logic;
|
|
OPA_o : out SDWORD_T;
|
|
OPB_o : out SDWORD_T
|
|
|
|
);
|
|
end RV01_PIPE_A_RMX_X2;
|
|
|
|
architecture ARC of RV01_PIPE_A_RMX_X2 is
|
|
|
|
signal SELA1,SELB1 : std_logic;
|
|
signal UOPA,UOPB : SDWORD_T;
|
|
signal UOPA_V,UOPB_V : std_logic;
|
|
|
|
begin
|
|
|
|
------------------------------------
|
|
-- Notes
|
|
------------------------------------
|
|
|
|
-- Stage IX3 provides (up to) two results per cycle,
|
|
-- requiring a mux to select the desired one.
|
|
|
|
-- OPA source selection flag
|
|
SELA1 <= IX3_V_i(1) when (
|
|
IX3_INSTR_i(1).WRD = '1' and
|
|
IX3_INSTR_i(1).RD = INSTR_i.RS1
|
|
) else '0';
|
|
|
|
-- Updated OPA operand source mux
|
|
UOPA <= IX3_RES1_i when (SELA1 = '1') else IX3_RES0_i;
|
|
|
|
-- Updated OPA operand valid flag (flag is set if there's
|
|
-- a valid value for it from IX3 stage).
|
|
|
|
UOPA_V <= '1' when (
|
|
(
|
|
IX3_V_i(0) = '1' and
|
|
IX3_INSTR_i(0).WRD = '1' and
|
|
IX3_INSTR_i(0).RD = INSTR_i.RS1
|
|
) or (
|
|
IX3_V_i(1) = '1' and
|
|
IX3_INSTR_i(1).WRD = '1' and
|
|
IX3_INSTR_i(1).RD = INSTR_i.RS1
|
|
)
|
|
) else '0';
|
|
|
|
-- OPB source selection flag
|
|
SELB1 <= IX3_V_i(1) when (
|
|
IX3_INSTR_i(1).WRD = '1' and
|
|
IX3_INSTR_i(1).RD = INSTR_i.RS2
|
|
) else '0';
|
|
|
|
-- Updated OPB operand source mux
|
|
UOPB <= IX3_RES1_i when (SELB1 = '1') else IX3_RES0_i;
|
|
|
|
-- Updated OPB operand valid flag (flag is set if there's
|
|
-- a valid value for it from IX3 stage).
|
|
|
|
UOPB_V <= '1' when (
|
|
(
|
|
IX3_V_i(0) = '1' and
|
|
IX3_INSTR_i(0).WRD = '1' and
|
|
IX3_INSTR_i(0).RD = INSTR_i.RS2
|
|
) or (
|
|
IX3_V_i(1) = '1' and
|
|
IX3_INSTR_i(1).WRD = '1' and
|
|
IX3_INSTR_i(1).RD = INSTR_i.RS2
|
|
)
|
|
) else '0';
|
|
|
|
OPA_V_o <= OPA_V_i or UOPA_V;
|
|
|
|
OPB_V_o <= OPB_V_i or UOPB_V;
|
|
|
|
OPA_o <= OPA_i when (OPA_V_i = '1') else UOPA;
|
|
|
|
OPB_o <= OPB_i when (OPB_V_i = '1') else UOPB;
|
|
|
|
end ARC;
|
|
|
|
---------------------------------------------------------------
|
|
-- A-pipeline result mux (IX1 stage)
|
|
---------------------------------------------------------------
|
|
|
|
library IEEE;
|
|
use IEEE.std_logic_1164.all;
|
|
use IEEE.numeric_std.all;
|
|
|
|
library WORK;
|
|
use WORK.RV01_CONSTS_PKG.all;
|
|
use WORK.RV01_TYPES_PKG.all;
|
|
use WORK.RV01_FUNCS_PKG.all;
|
|
use work.RV01_IDEC_PKG.all;
|
|
|
|
entity RV01_PIPE_A_RMX_X1 is
|
|
generic(
|
|
NW : natural := 2
|
|
);
|
|
port(
|
|
OPA_V_i : in std_logic;
|
|
OPB_V_i : in std_logic;
|
|
OPA_i : in SDWORD_T;
|
|
OPB_i : in SDWORD_T;
|
|
INSTR_i : in DEC_INSTR_T;
|
|
IX2_V_i : in std_logic_vector(NW-1 downto 0);
|
|
IX2_INSTR_i : in DEC_INSTR_VEC_T(NW-1 downto 0);
|
|
IX2_RES0_i : in SDWORD_T;
|
|
IX2_RES1_i : in SDWORD_T;
|
|
IX3_V_i : in std_logic_vector(NW-1 downto 0);
|
|
IX3_INSTR_i : in DEC_INSTR_VEC_T(NW-1 downto 0);
|
|
IX3_RES0_i : in SDWORD_T;
|
|
IX3_RES1_i : in SDWORD_T;
|
|
|
|
OPA_V_o : out std_logic;
|
|
OPB_V_o : out std_logic;
|
|
OPA_o : out SDWORD_T;
|
|
OPB_o : out SDWORD_T
|
|
|
|
);
|
|
end RV01_PIPE_A_RMX_X1;
|
|
|
|
architecture ARC of RV01_PIPE_A_RMX_X1 is
|
|
|
|
signal SELA0_X2,SELB0_X2 : std_logic;
|
|
signal SELA0_X3,SELB0_X3 : std_logic;
|
|
signal SELA1_X2,SELB1_X2 : std_logic;
|
|
signal SELA1_X3,SELB1_X3 : std_logic;
|
|
signal UOPA,UOPB : SDWORD_T;
|
|
signal UOPA_V,UOPB_V : std_logic;
|
|
|
|
begin
|
|
|
|
------------------------------------
|
|
-- Notes
|
|
------------------------------------
|
|
|
|
-- Stages IX2 and IX3 provide (up to) two results per
|
|
-- cycle, each, requiring a mux to select the desired one.
|
|
|
|
-- OPA source selection flag
|
|
|
|
SELA0_X2 <= IX2_V_i(0) when (
|
|
IX2_INSTR_i(0).WRD = '1' and
|
|
IX2_INSTR_i(0).RD = INSTR_i.RS1
|
|
) else '0';
|
|
|
|
SELA1_X2 <= IX2_V_i(1) when (
|
|
IX2_INSTR_i(1).WRD = '1' and
|
|
IX2_INSTR_i(1).RD = INSTR_i.RS1
|
|
) else '0';
|
|
|
|
SELA0_X3 <= IX3_V_i(0) when (
|
|
IX3_INSTR_i(0).WRD = '1' and
|
|
IX3_INSTR_i(0).RD = INSTR_i.RS1
|
|
) else '0';
|
|
|
|
SELA1_X3 <= IX3_V_i(1) when (
|
|
IX3_INSTR_i(1).WRD = '1' and
|
|
IX3_INSTR_i(1).RD = INSTR_i.RS1
|
|
) else '0';
|
|
|
|
-- Updated OPA operand source mux
|
|
process(
|
|
SELA0_X2,SELA1_X2,SELA0_X3,SELA1_X3,
|
|
IX2_RES0_i,IX2_RES1_i,IX3_RES0_i,IX3_RES1_i
|
|
)
|
|
variable S : std_logic_vector(4-1 downto 0);
|
|
begin
|
|
S := SELA1_X3 & SELA0_X3 & SELA1_X2 & SELA0_X2;
|
|
case S is
|
|
when "0001"|"0101"|"1001"|"1101" =>
|
|
UOPA <= IX2_RES0_i;
|
|
when "0010"|"0011"|"0110"|"0111"|"1010"|"1011"|"1110"|"1111" =>
|
|
UOPA <= IX2_RES1_i;
|
|
when "0100" =>
|
|
UOPA <= IX3_RES0_i;
|
|
when others =>
|
|
UOPA <= IX3_RES1_i;
|
|
end case;
|
|
end process;
|
|
|
|
-- Updated OPA operand valid flag (flag is set if there's
|
|
-- a valid value for it from IX2 or IX3 stage).
|
|
|
|
UOPA_V <=
|
|
SELA0_X2 or
|
|
SELA1_X2 or
|
|
SELA0_X3 or
|
|
SELA1_X3;
|
|
|
|
-- OPB source selection flag
|
|
|
|
SELB0_X2 <= IX2_V_i(0) when (
|
|
IX2_INSTR_i(0).WRD = '1' and
|
|
IX2_INSTR_i(0).RD = INSTR_i.RS2
|
|
) else '0';
|
|
|
|
-- OPA source selection flag
|
|
SELB1_X2 <= IX2_V_i(1) when (
|
|
IX2_INSTR_i(1).WRD = '1' and
|
|
IX2_INSTR_i(1).RD = INSTR_i.RS2
|
|
) else '0';
|
|
|
|
-- OPA source selection flag
|
|
SELB0_X3 <= IX3_V_i(0) when (
|
|
IX3_INSTR_i(0).WRD = '1' and
|
|
IX3_INSTR_i(0).RD = INSTR_i.RS2
|
|
) else '0';
|
|
|
|
SELB1_X3 <= IX3_V_i(1) when (
|
|
IX3_INSTR_i(1).WRD = '1' and
|
|
IX3_INSTR_i(1).RD = INSTR_i.RS2
|
|
) else '0';
|
|
|
|
-- Updated OPB operand source mux
|
|
process(
|
|
SELB0_X2,SELB1_X2,SELB0_X3,SELB1_X3,
|
|
IX2_RES0_i,IX2_RES1_i,IX3_RES0_i,IX3_RES1_i
|
|
)
|
|
variable S : std_logic_vector(4-1 downto 0);
|
|
begin
|
|
S := SELB1_X3 & SELB0_X3 & SELB1_X2 & SELB0_X2;
|
|
case S is
|
|
when "0001"|"0101"|"1001"|"1101" =>
|
|
UOPB <= IX2_RES0_i;
|
|
when "0010"|"0011"|"0110"|"0111"|"1010"|"1011"|"1110"|"1111" =>
|
|
UOPB <= IX2_RES1_i;
|
|
when "0100" =>
|
|
UOPB <= IX3_RES0_i;
|
|
when others =>
|
|
UOPB <= IX3_RES1_i;
|
|
end case;
|
|
end process;
|
|
|
|
-- Updated OPB operand valid flag (flag is set if there's
|
|
-- a valid value for it from IX2 or IX3 stages).
|
|
|
|
UOPB_V <=
|
|
SELB0_X2 or
|
|
SELB1_X2 or
|
|
SELB0_X3 or
|
|
SELB1_X3;
|
|
|
|
OPA_V_o <= OPA_V_i or UOPA_V;
|
|
|
|
OPB_V_o <= OPB_V_i or UOPB_V;
|
|
|
|
OPA_o <= OPA_i when (OPA_V_i = '1') else UOPA;
|
|
|
|
OPB_o <= OPB_i when (OPB_V_i = '1') else UOPB;
|
|
|
|
end ARC;
|
|
|
|
No newline at end of file
|
No newline at end of file
|