Line 91... |
Line 91... |
end if;
|
end if;
|
|
|
return x;
|
return x;
|
end isOverflowSub;
|
end isOverflowSub;
|
|
|
|
procedure getSRStatusBits ( value : in REGISTER_T; sr_reg : out SR_REGISTER_T ) is
|
|
begin
|
|
if value = CONV_STD_LOGIC_VECTOR(0, REGISTER_WIDTH) then
|
|
sr_reg( SR_REGISTER_ZERO ) := '1';
|
|
else
|
|
sr_reg( SR_REGISTER_ZERO ) := '0';
|
|
end if;
|
|
if value( REGISTER_WIDTH - 1 ) = '1' then
|
|
sr_reg( SR_REGISTER_NEGATIVE ) := '1';
|
|
else
|
|
sr_reg( SR_REGISTER_NEGATIVE ) := '0';
|
|
end if;
|
|
end getSRStatusBits;
|
|
|
component barrel_shifter
|
component barrel_shifter
|
port(
|
port(
|
reg_a : in std_logic_vector(15 downto 0);
|
reg_a : in std_logic_vector(15 downto 0);
|
reg_b : in std_logic_vector(15 downto 0);
|
reg_b : in std_logic_vector(15 downto 0);
|
left : in std_logic;
|
left : in std_logic;
|
Line 183... |
Line 197... |
ex_mem_register_next.aluop2 <= aluop2_int;
|
ex_mem_register_next.aluop2 <= aluop2_int;
|
end if;
|
end if;
|
end process aluop;
|
end process aluop;
|
|
|
alu: process (id_ex_register, ex_mem_register_next, bs_out)
|
alu: process (id_ex_register, ex_mem_register_next, bs_out)
|
|
variable new_sr : SR_REGISTER_T;
|
begin
|
begin
|
|
|
|
new_sr := id_ex_register.sr;
|
ex_mem_register_next.alu <= (others => '0');
|
ex_mem_register_next.alu <= (others => '0');
|
ex_mem_register_next.dreg_addr <= id_ex_register.rX_addr;
|
ex_mem_register_next.dreg_addr <= id_ex_register.rX_addr;
|
ex_mem_register_next.reg <= (others => '0');
|
ex_mem_register_next.reg <= (others => '0');
|
ex_mem_register_next.lr <= (others => '0');
|
ex_mem_register_next.lr <= (others => '0');
|
ex_mem_register_next.sr <= (others => '0');
|
|
|
|
aluop1_int(ALUOP1_LD_MEM_BIT) <= '0';
|
aluop1_int(ALUOP1_LD_MEM_BIT) <= '0';
|
aluop1_int(ALUOP1_ST_MEM_BIT) <= '0';
|
aluop1_int(ALUOP1_ST_MEM_BIT) <= '0';
|
aluop1_int(ALUOP1_WB_REG_BIT) <= '1';
|
aluop1_int(ALUOP1_WB_REG_BIT) <= '1';
|
|
|
Line 204... |
Line 219... |
|
|
case id_ex_register.opcode is
|
case id_ex_register.opcode is
|
-- load opcodes
|
-- load opcodes
|
when OPCODE_LD_IMM =>
|
when OPCODE_LD_IMM =>
|
ex_mem_register_next.alu <= x"00" & id_ex_register.immediate(7 downto 0);
|
ex_mem_register_next.alu <= x"00" & id_ex_register.immediate(7 downto 0);
|
|
getSRStatusBits( ex_mem_register_next.alu, new_sr );
|
isLoadOp <= '1';
|
isLoadOp <= '1';
|
when OPCODE_LD_IMM_HB =>
|
when OPCODE_LD_IMM_HB =>
|
ex_mem_register_next.alu <= id_ex_register.rX or (id_ex_register.immediate(7 downto 0) & x"00");
|
ex_mem_register_next.alu <= id_ex_register.rX or (id_ex_register.immediate(7 downto 0) & x"00");
|
|
getSRStatusBits( ex_mem_register_next.alu, new_sr );
|
isLoadOp <= '1';
|
isLoadOp <= '1';
|
when OPCODE_LD_DISP =>
|
when OPCODE_LD_DISP =>
|
ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
|
ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
|
aluop1_int(ALUOP1_LD_MEM_BIT) <= '1';
|
aluop1_int(ALUOP1_LD_MEM_BIT) <= '1';
|
isLoadOp <= '1';
|
isLoadOp <= '1';
|
Line 224... |
Line 241... |
|
|
-- store opcodes
|
-- store opcodes
|
when OPCODE_ST_DISP =>
|
when OPCODE_ST_DISP =>
|
ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
|
ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
|
ex_mem_register_next.reg <= id_ex_register.rX;
|
ex_mem_register_next.reg <= id_ex_register.rX;
|
|
getSRStatusBits( ex_mem_register_next.reg, new_sr );
|
aluop1_int(ALUOP1_ST_MEM_BIT) <= '1';
|
aluop1_int(ALUOP1_ST_MEM_BIT) <= '1';
|
aluop2_int(ALUOP2_SR_BIT) <= '0';
|
aluop2_int(ALUOP2_SR_BIT) <= '0';
|
|
|
-- arithmetic opcodes
|
-- arithmetic opcodes
|
when OPCODE_ADD =>
|
when OPCODE_ADD =>
|
ex_mem_register_next.alu <= id_ex_register.rX + id_ex_register.rY;
|
ex_mem_register_next.alu <= id_ex_register.rX + id_ex_register.rY;
|
ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowAdd(id_ex_register.rX,
|
getSRStatusBits( ex_mem_register_next.alu, new_sr );
|
|
new_sr(SR_OVERFLOW_BIT) := isOverflowAdd(id_ex_register.rX,
|
id_ex_register.rY,
|
id_ex_register.rY,
|
ex_mem_register_next.alu);
|
ex_mem_register_next.alu);
|
when OPCODE_ADD_IMM =>
|
when OPCODE_ADD_IMM =>
|
ex_mem_register_next.alu <= id_ex_register.rX + id_ex_register.immediate;
|
ex_mem_register_next.alu <= id_ex_register.rX + id_ex_register.immediate;
|
ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowAdd(id_ex_register.rX,
|
getSRStatusBits( ex_mem_register_next.alu, new_sr );
|
|
new_sr(SR_OVERFLOW_BIT) := isOverflowAdd(id_ex_register.rX,
|
id_ex_register.immediate,
|
id_ex_register.immediate,
|
ex_mem_register_next.alu);
|
ex_mem_register_next.alu);
|
when OPCODE_SUB =>
|
when OPCODE_SUB =>
|
ex_mem_register_next.alu <= id_ex_register.rX - id_ex_register.rY;
|
ex_mem_register_next.alu <= id_ex_register.rX - id_ex_register.rY;
|
ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowSub(id_ex_register.rX,
|
getSRStatusBits( ex_mem_register_next.alu, new_sr );
|
|
new_sr(SR_OVERFLOW_BIT) := isOverflowSub(id_ex_register.rX,
|
id_ex_register.rY,
|
id_ex_register.rY,
|
ex_mem_register_next.alu);
|
ex_mem_register_next.alu);
|
when OPCODE_SUB_IMM =>
|
when OPCODE_SUB_IMM =>
|
ex_mem_register_next.alu <= id_ex_register.rX - id_ex_register.immediate;
|
ex_mem_register_next.alu <= id_ex_register.rX - id_ex_register.immediate;
|
ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowSub(id_ex_register.rX,
|
getSRStatusBits( ex_mem_register_next.reg, new_sr );
|
|
new_sr(SR_OVERFLOW_BIT) := isOverflowSub(id_ex_register.rX,
|
id_ex_register.immediate,
|
id_ex_register.immediate,
|
ex_mem_register_next.alu);
|
ex_mem_register_next.alu);
|
when OPCODE_NEG =>
|
when OPCODE_NEG =>
|
ex_mem_register_next.alu <= not id_ex_register.rY + x"0001";
|
ex_mem_register_next.alu <= not id_ex_register.rY + x"0001";
|
|
getSRStatusBits( ex_mem_register_next.alu, new_sr );
|
-- when OPCODE_ALS =>
|
-- when OPCODE_ALS =>
|
-- ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-2 downto 0) & "0";
|
-- ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-2 downto 0) & "0";
|
-- ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= id_ex_register.rY(REGISTER_WIDTH-1) xor
|
-- ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= id_ex_register.rY(REGISTER_WIDTH-1) xor
|
-- id_ex_register.rY(REGISTER_WIDTH-2);
|
-- id_ex_register.rY(REGISTER_WIDTH-2);
|
-- when OPCODE_ARS =>
|
-- when OPCODE_ARS =>
|
-- ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-1) & id_ex_register.rY(REGISTER_WIDTH-1 downto 1);
|
-- ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-1) & id_ex_register.rY(REGISTER_WIDTH-1 downto 1);
|
when OPCODE_ALS =>
|
when OPCODE_ALS =>
|
bs_left <= '1';
|
bs_left <= '1';
|
bs_arithmetic <= '1';
|
bs_arithmetic <= '1';
|
ex_mem_register_next.alu <= bs_out;
|
ex_mem_register_next.alu <= bs_out;
|
ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= id_ex_register.rY(REGISTER_WIDTH-1) xor
|
getSRStatusBits( bs_out, new_sr );
|
|
new_sr(SR_OVERFLOW_BIT) := id_ex_register.rY(REGISTER_WIDTH-1) xor
|
id_ex_register.rY(REGISTER_WIDTH-2);
|
id_ex_register.rY(REGISTER_WIDTH-2);
|
when OPCODE_ARS =>
|
when OPCODE_ARS =>
|
bs_left <= '0';
|
bs_left <= '0';
|
bs_arithmetic <= '1';
|
bs_arithmetic <= '1';
|
ex_mem_register_next.alu <= bs_out;
|
ex_mem_register_next.alu <= bs_out;
|
ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= id_ex_register.rY(REGISTER_WIDTH-1) xor
|
getSRStatusBits( bs_out, new_sr );
|
|
new_sr(SR_OVERFLOW_BIT) := id_ex_register.rY(REGISTER_WIDTH-1) xor
|
id_ex_register.rY(REGISTER_WIDTH-2);
|
id_ex_register.rY(REGISTER_WIDTH-2);
|
-- logical opcodes
|
-- logical opcodes
|
when OPCODE_AND =>
|
when OPCODE_AND =>
|
ex_mem_register_next.alu <= id_ex_register.rX and id_ex_register.rY;
|
ex_mem_register_next.alu <= id_ex_register.rX and id_ex_register.rY;
|
|
getSRStatusBits( ex_mem_register_next.alu, new_sr );
|
when OPCODE_NOT =>
|
when OPCODE_NOT =>
|
ex_mem_register_next.alu <= not id_ex_register.rY;
|
ex_mem_register_next.alu <= not id_ex_register.rY;
|
|
getSRStatusBits( ex_mem_register_next.alu, new_sr );
|
when OPCODE_EOR =>
|
when OPCODE_EOR =>
|
ex_mem_register_next.alu <= id_ex_register.rX xor id_ex_register.rY;
|
ex_mem_register_next.alu <= id_ex_register.rX xor id_ex_register.rY;
|
|
getSRStatusBits( ex_mem_register_next.alu, new_sr );
|
-- when OPCODE_LS =>
|
-- when OPCODE_LS =>
|
-- ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-2 downto 0) & "0";
|
-- ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-2 downto 0) & "0";
|
-- when OPCODE_RS =>
|
-- when OPCODE_RS =>
|
-- ex_mem_register_next.alu <= "0" & id_ex_register.rY(REGISTER_WIDTH-1 downto 1);
|
-- ex_mem_register_next.alu <= "0" & id_ex_register.rY(REGISTER_WIDTH-1 downto 1);
|
when OPCODE_LS =>
|
when OPCODE_LS =>
|
bs_left <= '1';
|
bs_left <= '1';
|
bs_arithmetic <= '0';
|
bs_arithmetic <= '0';
|
ex_mem_register_next.alu <= bs_out;
|
ex_mem_register_next.alu <= bs_out;
|
|
getSRStatusBits( bs_out, new_sr );
|
when OPCODE_RS =>
|
when OPCODE_RS =>
|
bs_left <= '0';
|
bs_left <= '0';
|
bs_arithmetic <= '0';
|
bs_arithmetic <= '0';
|
ex_mem_register_next.alu <= bs_out;
|
ex_mem_register_next.alu <= bs_out;
|
|
getSRStatusBits( bs_out, new_sr );
|
-- program control
|
-- program control
|
when OPCODE_JMP =>
|
when OPCODE_JMP =>
|
ex_mem_register_next.lr <= id_ex_register.pc;
|
ex_mem_register_next.lr <= id_ex_register.pc;
|
ex_mem_register_next.dreg_addr <= PC_ADDR;
|
ex_mem_register_next.dreg_addr <= PC_ADDR;
|
ex_mem_register_next.alu <= id_ex_register.rX;
|
ex_mem_register_next.alu <= id_ex_register.rX;
|
|
getSRStatusBits( ex_mem_register_next.alu, new_sr );
|
aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
|
aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
|
aluop2_int(ALUOP2_SR_BIT) <= '0';
|
aluop2_int(ALUOP2_SR_BIT) <= '0';
|
aluop2_int(ALUOP2_LR_BIT) <= '1';
|
aluop2_int(ALUOP2_LR_BIT) <= '1';
|
isJmpOp <= '1';
|
isJmpOp <= '1';
|
|
|
Line 304... |
Line 335... |
aluop2_int(ALUOP2_SR_BIT) <= '0';
|
aluop2_int(ALUOP2_SR_BIT) <= '0';
|
|
|
when OPCODE_TST =>
|
when OPCODE_TST =>
|
aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
|
aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
|
aluop2_int(ALUOP2_SR_BIT) <= '1';
|
aluop2_int(ALUOP2_SR_BIT) <= '1';
|
|
getSRStatusBits( id_ex_register.rX, new_sr );
|
|
|
when others =>
|
when others =>
|
aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
|
aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
|
aluop2_int(ALUOP2_SR_BIT) <= '0';
|
aluop2_int(ALUOP2_SR_BIT) <= '0';
|
|
|
end case;
|
end case;
|
|
|
|
-- update current SR register value.
|
|
ex_mem_register_next.sr <= new_sr;
|
end process;
|
end process;
|
|
|
branch_logic: process (id_ex_register, isLoadOp, isJmpOp)
|
branch_logic: process (id_ex_register, isLoadOp, isJmpOp)
|
begin -- process branch_logic
|
begin -- process branch_logic
|
branch_int <= '0';
|
branch_int <= '0';
|