1
0
mirror of https://github.com/j-core/j-core-ice40.git synced 2026-01-11 23:52:49 +00:00
j-core.j-core-ice40/decode_table_simple.vhd

3644 lines
134 KiB
VHDL

-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
-- This file is generated. Changing this file directly is probably
-- not what you want to do. Any changes will be overwritten next time
-- the generator is run.
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
use work.cpu2j0_pack.all;
architecture simple_logic of decode_table is
signal imm_enum : immval_t;
signal mac_busy : mac_busy_t;
signal imms_12_1 : std_logic_vector(31 downto 0);
signal imms_8_0 : std_logic_vector(31 downto 0);
signal imms_8_1 : std_logic_vector(31 downto 0);
begin
-- Immediate value mux
with imm_enum select
ex.imm_val <=
x"fffffff0" when IMM_N16,
x"fffffff8" when IMM_N8,
x"fffffffe" when IMM_N2,
x"ffffffff" when IMM_N1,
x"00000000" when IMM_ZERO,
x"00000001" when IMM_P1,
x"00000002" when IMM_P2,
x"00000004" when IMM_P4,
x"00000008" when IMM_P8,
x"00000010" when IMM_P16,
imms_8_0 when IMM_S_8_0,
imms_8_1 when IMM_S_8_1,
imms_12_1 when IMM_S_12_1,
x"0000000" & op.code(3 downto 0) when IMM_U_4_0,
"000000000000000000000000000" & op.code(3 downto 0) & "0" when IMM_U_4_1,
"00000000000000000000000000" & op.code(3 downto 0) & "00" when IMM_U_4_2,
x"000000" & op.code(7 downto 0) when IMM_U_8_0,
"00000000000000000000000" & op.code(7 downto 0) & "0" when IMM_U_8_1,
"0000000000000000000000" & op.code(7 downto 0) & "00" when IMM_U_8_2;
-- Sign extend parts of opcode
process(op)
begin
-- Sign extend 8 right-most bits
for i in 8 to 31 loop
imms_8_0(i) <= op.code(7);
end loop;
imms_8_0(7 downto 0) <= op.code(7 downto 0);
-- Sign extend 8 right-most bits shifted by 1
for i in 9 to 31 loop
imms_8_1(i) <= op.code(7);
end loop;
imms_8_1(8 downto 1) <= op.code(7 downto 0);
imms_8_1(0) <= '0';
-- Sign extend 12 right-most bits shifted by 1
for i in 13 to 31 loop
imms_12_1(i) <= op.code(11);
end loop;
imms_12_1(12 downto 1) <= op.code(11 downto 0);
imms_12_1(0) <= '0';
end process;
-- Mac busy muxes
with mac_busy select
ex.mac_busy <=
'0' when NOT_BUSY,
not next_id_stall when EX_NOT_STALL,
'0' when WB_NOT_STALL,
'1' when EX_BUSY,
'0' when WB_BUSY;
with mac_busy select
wb.mac_busy <=
'0' when NOT_BUSY,
'0' when EX_NOT_STALL,
not next_id_stall when WB_NOT_STALL,
'0' when EX_BUSY,
'1' when WB_BUSY;
process(t_bcc, op)
variable cond : std_logic_vector(16 downto 0);
variable fmt : isa_type_t;
variable rm : std_logic_vector(4 downto 0);
variable rn : std_logic_vector(4 downto 0);
begin
cond := std_logic_vector(TO_UNSIGNED(instruction_plane_t'pos(op.plane), 1)) & op.code;
fmt := isa_fmt(op.code);
rn := '0' & cond(11 downto 8);
rm := '0' & cond(7 downto 4);
-- Set default values for outputs
ilevel_cap <= '0';
mac_stall_sense <= '0';
dispatch <= '0';
event_ack_0 <= '0';
slp <= '0';
mac_s_latch <= '0';
ex_stall <= ('0', '0', '0', '0', SEL_ARITH, SEL_PREV, SEL_CLEAR, SEL_ZBUS, SEL_YBUS, '0', '0', '0', LOGIC, '0', NOP, SEL_XBUS, SEL_YBUS);
debug <= '0';
wb_stall <= ('0', '0', '0', '0', '0', SEL_XBUS, SEL_YBUS, NOP);
delay_jump <= '0';
id <= ('0', '0', '0');
maskint_next <= '0';
ex.arith_func <= ADD;
ex.aluinx_sel <= SEL_XBUS;
ex.alumanip <= SWAP_BYTE;
ex.aluiny_sel <= SEL_YBUS;
ex.arith_ci_en <= '0';
ex.xbus_sel <= SEL_REG;
wb.regnum_w <= rn;
ex.regnum_x <= rn;
ex.mem_size <= LONG;
ex.regnum_y <= rm;
ex.regnum_z <= rn;
ex.ma_wr <= '0';
ex.logic_sr_func <= ZERO;
ex.logic_func <= LOGIC_XOR;
ex.ybus_sel <= SEL_REG;
ex.mem_lock <= '0';
ex.arith_sr_func <= ZERO;
imm_enum <= IMM_P4;
mac_busy <= NOT_BUSY;
-- if fmt.fmt = NMX and
-- ((fmt.ln = "0000" and fmt.op(0) = '1') or
-- ((fmt.ln = "0010" or fmt.ln = "0110") and fmt.op(1 downto 0) = "00"))
if (std_match(cond, "00000---------1--") or std_match(cond, "00-10--------00--") or std_match(cond, "00010--------01--"))
and cond(1 downto 0) /= "11" then
-- MOV.B Rm,@-Rn [2nm4]
-- MOV.BWL Rm, @Rn [2nm0]
-- MOV.BWL @Rm, Rn [6nm0]
-- MOV.BWL Rm, @(R0, Rn) [0nm4]
-- MOV.BWL @(R0, Rm), Rn [0nmC]
-- (R0 +Rm)->sign extension -> Rn
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
if (cond(3) or cond(14)) = '1' then ex.regnum_x <= rm; end if;
-- ex.regnum_x <= rn; end if;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X + R0
if cond(13) = '1' then ex.aluiny_sel <= SEL_IMM; ex.arith_func <= SUB;
else ex.aluiny_sel <= SEL_R0; end if;
-- ex_stall.zbus_sel <= SEL_ARITH;
if cond(1 downto 0) = "00" then imm_enum <= IMM_P1;
elsif cond(1 downto 0) = "01" then imm_enum <= IMM_P2; end if;
-- else imm_enum <= IMM_P4; end if;
-- ex.arith_func <= ADD;
-- W = MEM[Z] or MEM[X]
ex_stall.ma_issue <= '1';
ex.ma_wr <= not (cond(3) or cond(14));
if cond(13) = '1' and cond(2) = '0' then ex_stall.mem_addr_sel <= SEL_XBUS;
-- else ex_stall.mem_addr_sel <= SEL_ZBUS; end if;
end if;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
ex.mem_size <= fmt.sz;
-- Rn = W
if (cond(2) and cond(13)) = '1' then ex_stall.wrreg_z <= '1';
elsif (cond(3) or cond(14)) = '1' then wb_stall.wrreg_w <= '1'; end if;
-- ex.regnum_z <= rn;
-- wb.regnum_w <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------01--") and cond(1 downto 0) /= "11" then
-- MOV.BWL @Rm+, Rn [6nm4]
-- (Rm) -> sign extension -> Rn, Rm +1 ->Rm : Note: add first in case Rm=Rn
if cond(1 downto 0) = "00" then imm_enum <= IMM_P1;
elsif cond(1 downto 0) = "01" then imm_enum <= IMM_P2; end if;
-- else imm_enum <= IMM_P4; end if;
case op.addr(3 downto 0) is
when x"0" =>
-- X = Rm
--- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= rm;
-- Z = X + 1
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- Rm = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= rm;
when x"1" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= rm;
-- Z = X - 1
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- W = MEM[Z] byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
ex.mem_size <= fmt.sz;
-- Rn = W
wb_stall.wrreg_w <= '1';
-- wb.regnum_w <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "011000-----------") and cond(10 downto 8) /= "011" then
-- MOV.BWL R0, @(disp, GBR) [C0dd]
-- MOV.BWL @(disp, GBR), R0 [C4dd]
-- MOVA @(disp, PC), R0 [C7dd]
-- R0-> (disp + GBR)
-- X = GBR
if cond(10 downto 8) = "111" then ex.xbus_sel <= SEL_PC; end if;
-- else ex.xbus_sel <= SEL_REG; end if;
ex.regnum_x <= "10000";
-- if MOVA, use PC
if cond(9 downto 8) = "11" then ex.aluinx_sel <= SEL_FC; end if;
-- Y = R0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "00000";
-- Z = X + [:u 8 0]
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
if cond(9 downto 8) = "00" then imm_enum <= IMM_U_8_0;
elsif cond(9 downto 8) = "01" then imm_enum <= IMM_U_8_1;
else imm_enum <= IMM_U_8_2; end if;
-- MEM[Z] = Y byte W = MEM[Z] byte
ex_stall.ma_issue <= not (cond(10) and cond(9) and cond(8));
ex.ma_wr <= not cond(10);
wb_stall.wrreg_w <= cond(10) and not (cond(9) and cond(8));
ex_stall.wrreg_z <= cond(10) and cond(9) and cond(8);
wb.regnum_w <= "00000";
ex.regnum_z <= "00000";
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
ex.mem_size <= fmt.sz;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "01101------------") then
-- MOV.L @(disp, PC), Rn [Dndd]
-- (disp x 4 + PC) -> Rn
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Y = UCONST * 4
ex.ybus_sel <= SEL_IMM;
-- Z = (X & FC) + Y
ex.aluinx_sel <= SEL_FC;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_8_2;
-- W = MEM[Z] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex.mem_size <= LONG;
-- Rn = W
wb_stall.wrreg_w <= '1';
-- wb.regnum_w <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
-- set control signals for each opcode
elsif std_match(cond, "00000000000001000") then
-- CLRT [0008]
-- 0 -> T
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_CLEAR;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000000000101000") then
-- CLRMAC [0028]
-- 0 -> MACH, MACL
-- X = TEMP1
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10100";
-- Y = TEMP1
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10100";
-- Z = X xor Y
ex_stall.zbus_sel <= SEL_LOGIC;
-- ex.logic_func <= LOGIC_XOR;
ex_stall.macsel1 <= SEL_ZBUS;
ex_stall.macsel2 <= SEL_ZBUS;
ex_stall.wrmacl <= '1';
ex_stall.wrmach <= '1';
mac_stall_sense <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000000000011001") then
-- DIV0U [0019]
-- 0 -> M/Q/T
ex_stall.sr_sel <= SEL_DIV0U;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000000000001001") then
-- NOP [0009]
-- no operation
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000000000101011") then
-- RTE [002B]
-- Delayed branch, stack -> PC/SR
case op.addr(3 downto 0) is
when x"0" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- imm_enum <= IMM_P4;
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
id.incpc <= '1';
when x"1" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
wb_stall.wrsr_w <= '1';
-- imm_enum <= IMM_P4;
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
when x"2" =>
ex_stall.zbus_sel <= SEL_WBUS;
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"3" =>
id.ifadsel <= '1';
dispatch <= '1';
id.if_issue <= '1';
delay_jump <= '1';
when others =>
end case;
elsif std_match(cond, "00000000000001011") then
-- RTS [000B]
-- Delayed branch, PR -> PC
case op.addr(3 downto 0) is
when x"0" =>
-- Y = PR
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10010";
ex_stall.zbus_sel <= SEL_YBUS;
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"1" =>
id.ifadsel <= '1';
dispatch <= '1';
id.if_issue <= '1';
delay_jump <= '1';
when others =>
end case;
elsif std_match(cond, "00000000000011000") then
-- SETT [0018]
-- 1 -> T
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_SET;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000000000011011") then
-- SLEEP [001B]
-- Sleep
case op.addr(3 downto 0) is
when x"0" =>
when x"1" =>
slp <= '1';
when x"2" =>
when x"3" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "00000000000111011") then
-- BGND [003B]
-- Sleep
id.incpc <= '1';
dispatch <= '1';
debug <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00010101") then
-- CMP/PL Rn [4n15]
-- Rn > 0, 1 -> T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = 0
ex.ybus_sel <= SEL_IMM;
ex.arith_sr_func <= SGRTER;
ex.arith_func <= SUB;
ex_stall.sr_sel <= SEL_ARITH;
imm_enum <= IMM_ZERO;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00010001") then
-- CMP/PZ Rn [4n11]
-- Rn >= 0, 1->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = 0
ex.ybus_sel <= SEL_IMM;
ex.arith_sr_func <= SGRTER_EQ;
ex.arith_func <= SUB;
ex_stall.sr_sel <= SEL_ARITH;
imm_enum <= IMM_ZERO;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00010000") then
-- DT Rn [4n10]
-- Rn-1 ->Rn; If Rn is 0, 1 -> T, if Rn is nonzero, 0 -> T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = 1
ex.ybus_sel <= SEL_IMM;
-- Z = X - Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_sr_func <= ZERO;
ex.arith_func <= SUB;
ex_stall.sr_sel <= SEL_ARITH;
imm_enum <= IMM_P1;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000----00101001") then
-- MOVT Rn [0n29]
-- T->Rn
-- X = 1
ex.xbus_sel <= SEL_IMM;
-- Y = SR
ex.ybus_sel <= SEL_SR;
-- Z = X and Y
ex_stall.zbus_sel <= SEL_LOGIC;
ex.logic_func <= LOGIC_AND;
imm_enum <= IMM_P1;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00000100") then
-- ROTL Rn [4n04]
-- T<-Rn<-MSB
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = 1
ex.ybus_sel <= SEL_IMM;
-- Z = X shift rotate Y
ex_stall.zbus_sel <= SEL_SHIFT;
ex_stall.shiftfunc <= ROTATE;
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_SHIFT;
imm_enum <= IMM_P1;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00000101") then
-- ROTR Rn [4n05]
-- LSB->Rn->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = -1
ex.ybus_sel <= SEL_IMM;
-- Z = X shift rotate Y
ex_stall.zbus_sel <= SEL_SHIFT;
ex_stall.shiftfunc <= ROTATE;
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_SHIFT;
imm_enum <= IMM_N1;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00100100") then
-- ROTCL Rn [4n24]
-- T<-Rn<-T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = 1
ex.ybus_sel <= SEL_IMM;
-- Z = X shift rotatec Y
ex_stall.zbus_sel <= SEL_SHIFT;
ex_stall.shiftfunc <= ROTC;
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_SHIFT;
imm_enum <= IMM_P1;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00100101") then
-- ROTCR Rn [4n25]
-- T->Rn->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = -1
ex.ybus_sel <= SEL_IMM;
-- Z = X shift rotatec Y
ex_stall.zbus_sel <= SEL_SHIFT;
ex_stall.shiftfunc <= ROTC;
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_SHIFT;
imm_enum <= IMM_N1;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00100000") then
-- SHAL Rn [4n20]
-- T<-Rn<-0
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = 1
ex.ybus_sel <= SEL_IMM;
-- Z = X shift logic Y
ex_stall.zbus_sel <= SEL_SHIFT;
-- ex_stall.shiftfunc <= LOGIC;
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_SHIFT;
imm_enum <= IMM_P1;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00100001") then
-- SHAR Rn [4n21]
-- MSB->Rn->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = -1
ex.ybus_sel <= SEL_IMM;
-- Z = X shift arith Y
ex_stall.zbus_sel <= SEL_SHIFT;
ex_stall.shiftfunc <= ARITH;
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_SHIFT;
imm_enum <= IMM_N1;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00000000") then
-- SHLL Rn [4n00]
-- T<-Rn<-0
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = 1
ex.ybus_sel <= SEL_IMM;
-- Z = X shift logic Y
ex_stall.zbus_sel <= SEL_SHIFT;
-- ex_stall.shiftfunc <= LOGIC;
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_SHIFT;
imm_enum <= IMM_P1;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00000001") then
-- SHLR Rn [4n01]
-- 0->Rn->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = -1
ex.ybus_sel <= SEL_IMM;
-- Z = X shift logic Y
ex_stall.zbus_sel <= SEL_SHIFT;
-- ex_stall.shiftfunc <= LOGIC;
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_SHIFT;
imm_enum <= IMM_N1;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00001000") then
-- SHLL2 Rn [4n08]
-- Rn<<2 -> Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = 2
ex.ybus_sel <= SEL_IMM;
-- Z = X shift logic Y
ex_stall.zbus_sel <= SEL_SHIFT;
-- ex_stall.shiftfunc <= LOGIC;
imm_enum <= IMM_P2;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00001001") then
-- SHLR2 Rn [4n09]
-- Rn>>2 -> Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = -2
ex.ybus_sel <= SEL_IMM;
-- Z = X shift logic Y
ex_stall.zbus_sel <= SEL_SHIFT;
-- ex_stall.shiftfunc <= LOGIC;
imm_enum <= IMM_N2;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00011000") then
-- SHLL8 Rn [4n18]
-- Rn<<8 -> Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = 8
ex.ybus_sel <= SEL_IMM;
-- Z = X shift logic Y
ex_stall.zbus_sel <= SEL_SHIFT;
-- ex_stall.shiftfunc <= LOGIC;
imm_enum <= IMM_P8;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00011001") then
-- SHLR8 Rn [4n19]
-- Rn>>8 -> Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = -8
ex.ybus_sel <= SEL_IMM;
-- Z = X shift logic Y
ex_stall.zbus_sel <= SEL_SHIFT;
-- ex_stall.shiftfunc <= LOGIC;
imm_enum <= IMM_N8;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00101000") then
-- SHLL16 Rn [4n28]
-- Rn<<16 -> Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = 16
ex.ybus_sel <= SEL_IMM;
-- Z = X shift logic Y
ex_stall.zbus_sel <= SEL_SHIFT;
-- ex_stall.shiftfunc <= LOGIC;
imm_enum <= IMM_P16;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00101001") then
-- SHLR16 Rn [4n29]
-- Rn>>16 -> Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = -16
ex.ybus_sel <= SEL_IMM;
-- Z = X shift logic Y
ex_stall.zbus_sel <= SEL_SHIFT;
-- ex_stall.shiftfunc <= LOGIC;
imm_enum <= IMM_N16;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000----00000010") then
-- STC SR, Rn [0n02]
-- SR->Rn
-- Y = SR
ex.ybus_sel <= SEL_SR;
ex_stall.zbus_sel <= SEL_YBUS;
maskint_next <= '1';
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000----00010010") then
-- STC GBR, Rn [0n12]
-- GBR->Rn
-- Y = GBR
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10000";
ex_stall.zbus_sel <= SEL_YBUS;
maskint_next <= '1';
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000----00100010") then
-- STC VBR, Rn [0n22]
-- VBR->Rn
-- Y = VBR
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10001";
ex_stall.zbus_sel <= SEL_YBUS;
maskint_next <= '1';
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000----00001010") then
-- STS MACH, Rn [0n0A]
-- MACH->Rn
-- Y = MACH
ex.ybus_sel <= SEL_MACH;
ex_stall.zbus_sel <= SEL_YBUS;
mac_stall_sense <= '1';
maskint_next <= '1';
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000----00011010") then
-- STS MACL, Rn [0n1A]
-- MACL->Rn
-- Y = MACL
ex.ybus_sel <= SEL_MACL;
ex_stall.zbus_sel <= SEL_YBUS;
mac_stall_sense <= '1';
maskint_next <= '1';
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000----00101010") then
-- STS PR, Rn [0n2A]
-- PR->Rn
-- Y = PR
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10010";
ex_stall.zbus_sel <= SEL_YBUS;
maskint_next <= '1';
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00011011") then
-- TAS.B @Rn [4n1B]
-- When (Rn) is 0, 1 -> T, 1 -> MSB of (Rn)
case op.addr(3 downto 0) is
when x"0" =>
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- W = MEM[X] byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
ex.mem_size <= BYTE;
ex.mem_lock <= '1';
-- TEMP0 = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "10011";
when x"1" =>
ex.mem_lock <= '1';
when x"2" =>
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = TEMP0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10011";
-- Z = 0 :bit7 Y
ex.aluinx_sel <= SEL_ZERO;
ex_stall.zbus_sel <= SEL_MANIP;
ex.alumanip <= SET_BIT_7;
-- ex.arith_sr_func <= ZERO;
-- ex.arith_func <= ADD;
ex_stall.sr_sel <= SEL_ARITH;
-- MEM[X] = Z byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
ex_stall.mem_addr_sel <= SEL_XBUS;
ex_stall.mem_wdata_sel <= SEL_ZBUS;
ex.mem_size <= BYTE;
ex.mem_lock <= '1';
when x"3" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "00100----00000011") then
-- STC.L SR, @-Rn [4n03]
-- Rn-4 ->Rn,SR ->(Rn)
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = SR
ex.ybus_sel <= SEL_SR;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
maskint_next <= '1';
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00010011") then
-- STC.L GBR, @-Rn [4n13]
-- Rn-4 ->Rn,GBR ->(Rn)
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = GBR
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10000";
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
maskint_next <= '1';
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00100011") then
-- STC.L VBR, @-Rn [4n23]
-- Rn - 4 -> Rn, VBR -> (Rn)
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = VBR
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10001";
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
maskint_next <= '1';
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00000010") then
-- STS.L MACH, @-Rn [4n02]
-- Rn - 4 -> Rn, MACH -> (Rn)
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = MACH
ex.ybus_sel <= SEL_MACH;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
mac_stall_sense <= '1';
maskint_next <= '1';
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00010010") then
-- STS.L MACL, @-Rn [4n12]
-- Rn-4->Rn,MACL->(Rn)
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = MACL
ex.ybus_sel <= SEL_MACL;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
mac_stall_sense <= '1';
maskint_next <= '1';
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00100010") then
-- STS.L PR, @-Rn [4n22]
-- Rn-4->Rn,PR->(Rn)
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = PR
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10010";
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
maskint_next <= '1';
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00001110") then
-- LDC Rm, SR [4m0E]
-- Rm -> SR
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= rn;
ex_stall.zbus_sel <= SEL_YBUS;
ex_stall.sr_sel <= SEL_ZBUS;
maskint_next <= '1';
-- SR = Z
ex_stall.wrsr_z <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00011110") then
-- LDC, Rm, GBR [4m1E]
-- Rm -> GBR
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= rn;
ex_stall.zbus_sel <= SEL_YBUS;
maskint_next <= '1';
-- GBR = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10000";
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00101110") then
-- LDC Rm, VBR [4m2E]
-- Rm -> VBR
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= rn;
ex_stall.zbus_sel <= SEL_YBUS;
maskint_next <= '1';
-- VBR = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10001";
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00001010") then
-- LDS Rm, MACH [4m0A]
-- Rm-> MACH
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= rn;
ex_stall.zbus_sel <= SEL_YBUS;
ex_stall.macsel1 <= SEL_ZBUS;
ex_stall.wrmach <= '1';
mac_stall_sense <= '1';
maskint_next <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00011010") then
-- LDS Rm, MACL [4m1A]
-- Rm -> MACL
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= rn;
ex_stall.zbus_sel <= SEL_YBUS;
ex_stall.macsel2 <= SEL_ZBUS;
ex_stall.wrmacl <= '1';
mac_stall_sense <= '1';
maskint_next <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00101010") then
-- LDS Rm, PR [4m2A]
-- Rm -> PR
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= rn;
ex_stall.zbus_sel <= SEL_YBUS;
maskint_next <= '1';
-- PR = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10010";
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00101011") then
-- JMP @Rm [4m2B]
-- Rm -> PC
case op.addr(3 downto 0) is
when x"0" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Z = X + 0
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_ZERO;
-- PC = Z
ex_stall.wrpc_z <= '1';
id.incpc <= '1';
when x"1" =>
id.ifadsel <= '1';
dispatch <= '1';
id.if_issue <= '1';
delay_jump <= '1';
when others =>
end case;
elsif std_match(cond, "00100----00001011") then
-- JSR @Rm [4m0B]
-- PC -> PR, Rm -> PC
case op.addr(3 downto 0) is
when x"0" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Z = X + 0
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_ZERO;
-- PC = Z
ex_stall.wrpc_z <= '1';
-- PR = PC
ex_stall.wrpr_pc <= '1';
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10010";
id.incpc <= '1';
when x"1" =>
id.ifadsel <= '1';
dispatch <= '1';
id.if_issue <= '1';
delay_jump <= '1';
when others =>
end case;
elsif std_match(cond, "00100----00000111") then
-- LDC.L @Rm+, SR [4m07]
-- (Rm)->SR,Rm+4->Rm
case op.addr(3 downto 0) is
when x"0" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
wb_stall.wrsr_w <= '1';
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
when x"1" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- imm_enum <= IMM_P4;
-- Rm = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
when x"2" =>
maskint_next <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "00100----00010111") then
-- LDC.L @Rm+, GBR [4m17]
-- (Rm)->GBR,Rm+4->Rm
case op.addr(3 downto 0) is
when x"0" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
-- GBR = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "10000";
when x"1" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- imm_enum <= IMM_P4;
-- Rm = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
when x"2" =>
maskint_next <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "00100----00100111") then
-- LDC.L @Rm+, VBR [4m27]
-- (Rm)->VBR,Rm+4->Rm
case op.addr(3 downto 0) is
when x"0" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
-- VBR = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "10001";
when x"1" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- imm_enum <= IMM_P4;
-- Rm = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
when x"2" =>
maskint_next <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "00100----00000110") then
-- LDS.L @Rm+, MACH [4m06]
-- (Rm)->MACH,Rm+4->Rm
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- imm_enum <= IMM_P4;
wb_stall.macsel1 <= SEL_WBUS;
wb_stall.wrmach <= '1';
mac_busy <= WB_NOT_STALL;
mac_stall_sense <= '1';
maskint_next <= '1';
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
-- Rm = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00010110") then
-- LDS.L @Rm+, MACL [4m16]
-- (Rm)->MACL,Rm+4->Rm
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- imm_enum <= IMM_P4;
wb_stall.macsel2 <= SEL_WBUS;
wb_stall.wrmacl <= '1';
mac_busy <= WB_NOT_STALL;
mac_stall_sense <= '1';
maskint_next <= '1';
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
-- Rm = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100----00100110") then
-- LDS.L @Rm+, PR [4m26]
-- (Rm)->PR,Rm+4->Rm
case op.addr(3 downto 0) is
when x"0" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
maskint_next <= '1';
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
-- PR = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "10010";
when x"1" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- imm_enum <= IMM_P4;
maskint_next <= '1';
-- Rm = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "00000----00100011") then
-- BRAF Rm [0m23]
-- Delayed branch, Rm + PC -> PC
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= rn;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- PC = Z
ex_stall.wrpc_z <= '1';
id.incpc <= '1';
when x"1" =>
id.ifadsel <= '1';
dispatch <= '1';
id.if_issue <= '1';
delay_jump <= '1';
when others =>
end case;
elsif std_match(cond, "00000----00000011") then
-- BSRF Rm [0m03]
-- Delayed branch, PC -> PR, Rm + PC -> PC
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= rn;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- PC = Z
ex_stall.wrpc_z <= '1';
-- PR = PC
ex_stall.wrpr_pc <= '1';
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10010";
id.incpc <= '1';
when x"1" =>
id.ifadsel <= '1';
dispatch <= '1';
id.if_issue <= '1';
delay_jump <= '1';
when others =>
end case;
elsif std_match(cond, "00011--------1100") then
-- ADD Rm, Rn [3nmC]
-- Rn+Rm->Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------1110") then
-- ADDC Rm, Rn [3nmE]
-- Rn + Rm + T -> Rn, carry ->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
ex.arith_ci_en <= '1';
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_CARRY;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------1111") then
-- ADDV Rm, Rn [3nmF]
-- Rn + Rm -> Rn, overflow ->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_sr_func <= OVERUNDERFLOW;
-- ex.arith_func <= ADD;
ex_stall.sr_sel <= SEL_ARITH;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00010--------1001") then
-- AND Rm, Rn [2nm9]
-- Rn&Rm->Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X and Y
ex_stall.zbus_sel <= SEL_LOGIC;
ex.logic_func <= LOGIC_AND;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------0000") then
-- CMP /EQ Rm, Rn [3nm0]
-- When Rn=Rm,1->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- ex.logic_sr_func <= ZERO;
-- ex.logic_func <= LOGIC_XOR;
ex_stall.sr_sel <= SEL_LOGIC;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------0010") then
-- CMP /HS Rm, Rn [3nm2]
-- When unsigned and Rn >= Rm,1->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
ex.arith_sr_func <= UGRTER_EQ;
ex.arith_func <= SUB;
ex_stall.sr_sel <= SEL_ARITH;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------0011") then
-- CMP /GE Rm, Rn [3nm3]
-- When signed and Rn >= Rm,1->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
ex.arith_sr_func <= SGRTER_EQ;
ex.arith_func <= SUB;
ex_stall.sr_sel <= SEL_ARITH;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------0110") then
-- CMP /HI Rm, Rn [3nm6]
-- When unsigned and Rn > Rm,1->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
ex.arith_sr_func <= UGRTER;
ex.arith_func <= SUB;
ex_stall.sr_sel <= SEL_ARITH;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------0111") then
-- CMP /GT Rm, Rn [3nm7]
-- When signed and Rn > Rm,1->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
ex.arith_sr_func <= SGRTER;
ex.arith_func <= SUB;
ex_stall.sr_sel <= SEL_ARITH;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00010--------1100") then
-- CMP /STR Rm, Rn [2nmC]
-- When a byte in Rn equals a byte in Rm, 1-> T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
ex.logic_sr_func <= BYTE_EQ;
-- ex.logic_func <= LOGIC_XOR;
ex_stall.sr_sel <= SEL_LOGIC;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00010--------0011") then
-- CAS Rm, Rn, @R0 [2nm3]
-- When a byte in Rn equals a byte in Rm, 1-> T
case op.addr(3 downto 0) is
when x"0" =>
-- Y = Rn
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= rn;
ex_stall.zbus_sel <= SEL_YBUS;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"1" =>
-- X = R0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "00000";
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
ex.mem_lock <= '1';
-- Rn = W
wb_stall.wrreg_w <= '1';
-- wb.regnum_w <= rn;
when x"2" =>
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- ex.logic_sr_func <= ZERO;
-- ex.logic_func <= LOGIC_XOR;
ex_stall.sr_sel <= SEL_LOGIC;
ex.mem_lock <= '1';
when x"3" =>
ex.mem_lock <= '1';
id.incpc <= '1';
dispatch <= not t_bcc;
id.if_issue <= not t_bcc;
when x"4" =>
-- X = R0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "00000";
-- Y = TEMP0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10011";
-- MEM[X] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
ex.mem_lock <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "00011--------0100") then
-- DIV1 Rm, Rn [3nm4]
-- 1-step division (Rn ÷ Rm)
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = (2*X + T) + Y
ex.aluinx_sel <= SEL_ROTCL;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_sr_func <= DIV1;
-- ex.arith_func <= ADD;
ex_stall.sr_sel <= SEL_ARITH;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00010--------0111") then
-- DIV0S Rm, Rn [2nm7]
-- MSB of Rn-> Q, MSB of Rm->M,M^Q->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
ex.arith_sr_func <= DIV0S;
-- ex.arith_func <= ADD;
ex_stall.sr_sel <= SEL_ARITH;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------1101") then
-- DMULS.L Rm, Rn [3nmD]
-- Signed, Rn x Rm, MACH, MACL
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- ex_stall.macsel1 <= SEL_XBUS;
ex_stall.mulcom1 <= '1';
-- ex_stall.macsel2 <= SEL_YBUS;
ex_stall.mulcom2 <= DMULSL;
mac_busy <= EX_NOT_STALL;
mac_stall_sense <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------0101") then
-- DMULU.L Rm, Rn [3nm5]
-- Unsigned, Rn x Rm, MACH, MACL
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- ex_stall.macsel1 <= SEL_XBUS;
ex_stall.mulcom1 <= '1';
-- ex_stall.macsel2 <= SEL_YBUS;
ex_stall.mulcom2 <= DMULUL;
mac_busy <= EX_NOT_STALL;
mac_stall_sense <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------1110") then
-- EXTS.B Rm, Rn [6nmE]
-- Sign-extends Rm from byte -> Rn
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm);
-- Z = (int8) Y
ex_stall.zbus_sel <= SEL_MANIP;
ex.alumanip <= EXTEND_SBYTE;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------1111") then
-- EXTS.W Rm, Rn [6nmF]
-- Sign-extends Rm from word -> Rn
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = (int16) Y
ex_stall.zbus_sel <= SEL_MANIP;
ex.alumanip <= EXTEND_SWORD;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------1100") then
-- EXTU.B Rm, Rn [6nmC]
-- Zero-extends Rm from byte -> Rn
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = (uint8) Y
ex_stall.zbus_sel <= SEL_MANIP;
ex.alumanip <= EXTEND_UBYTE;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------1101") then
-- EXTU.W Rm, Rn [6nmD]
-- Zero-extends Rm from word -> Rn
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = (uint16) Y
ex_stall.zbus_sel <= SEL_MANIP;
ex.alumanip <= EXTEND_UWORD;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------0011") then
-- MOV Rm, Rn [6nm3]
-- Rm->Rn
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
ex_stall.zbus_sel <= SEL_YBUS;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000--------0111") then
-- MUL.L Rm, Rn [0nm7]
-- RnxRm->MACL
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- ex_stall.macsel1 <= SEL_XBUS;
ex_stall.mulcom1 <= '1';
-- ex_stall.macsel2 <= SEL_YBUS;
ex_stall.mulcom2 <= MULL;
mac_busy <= EX_NOT_STALL;
mac_stall_sense <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00010--------1111") then
-- MULS.W Rm, Rn [2nmF]
-- Signed, Rn x Rm -> MAC
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- ex_stall.macsel1 <= SEL_XBUS;
ex_stall.mulcom1 <= '1';
-- ex_stall.macsel2 <= SEL_YBUS;
ex_stall.mulcom2 <= MULSW;
mac_busy <= EX_NOT_STALL;
mac_stall_sense <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00010--------1110") then
-- MULU.W Rm, Rn [2nmE]
-- Unsigned, Rn x Rm -> MAC
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- ex_stall.macsel1 <= SEL_XBUS;
ex_stall.mulcom1 <= '1';
-- ex_stall.macsel2 <= SEL_YBUS;
ex_stall.mulcom2 <= MULUW;
mac_busy <= EX_NOT_STALL;
mac_stall_sense <= '1';
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------1011") then
-- NEG Rm, Rn [6nmB]
-- 0-Rm->Rn
-- X = 0
ex.xbus_sel <= SEL_IMM;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X - Y
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
imm_enum <= IMM_ZERO;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------1010") then
-- NEGC Rm, Rn [6nmA]
-- 0-Rm-T -> Rn, borrow ->T
-- X = 0
ex.xbus_sel <= SEL_IMM;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X - Y
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
ex.arith_ci_en <= '1';
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_CARRY;
imm_enum <= IMM_ZERO;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------0111") then
-- NOT Rm, Rn [6nm7]
-- ~Rm->Rn
-- X = 0
ex.xbus_sel <= SEL_IMM;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X not Y
ex_stall.zbus_sel <= SEL_LOGIC;
ex.logic_func <= LOGIC_NOT;
imm_enum <= IMM_ZERO;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00010--------1011") then
-- OR Rm, Rn [2nmB]
-- Rn | Rm-> Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X or Y
ex_stall.zbus_sel <= SEL_LOGIC;
ex.logic_func <= LOGIC_OR;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------1000") then
-- SUB Rm, Rn [3nm8]
-- Rn - Rm ->Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X - Y
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------1010") then
-- SUBC Rm, Rn [3nmA]
-- Rn - Rm-T ->Rn, borrow -> T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X - Y
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
ex.arith_ci_en <= '1';
ex_stall.sr_sel <= SEL_SET_T;
ex_stall.t_sel <= SEL_CARRY;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00011--------1011") then
-- SUBV Rm, Rn [3nmB]
-- Rn - Rm -> Rn, underflow ->T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X - Y
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_sr_func <= OVERUNDERFLOW;
ex.arith_func <= SUB;
ex_stall.sr_sel <= SEL_ARITH;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------1000") then
-- SWAP.B Rm, Rn [6nm8]
-- Rm -> Swap upper and lower halves of lower 2 bytes -> Rn
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X [:swap :b] Y
ex_stall.zbus_sel <= SEL_MANIP;
-- ex.alumanip <= SWAP_BYTE;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00110--------1001") then
-- SWAP.W Rm, Rn [6nm9]
-- Rm -> Swap upper and lower word -> Rn
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X [:swap :w] Y
ex_stall.zbus_sel <= SEL_MANIP;
ex.alumanip <= SWAP_WORD;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00010--------1000") then
-- TST Rm, Rn [2nm8]
-- Rn & Rm, when result is 0, 1 -> T
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- ex.logic_sr_func <= ZERO;
ex.logic_func <= LOGIC_AND;
ex_stall.sr_sel <= SEL_LOGIC;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00010--------1010") then
-- XOR Rm, Rn [2nmA]
-- Rn ^ Rm-> Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X xor Y
ex_stall.zbus_sel <= SEL_LOGIC;
-- ex.logic_func <= LOGIC_XOR;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00010--------1101") then
-- XTRACT Rm, Rn [2nmD]
-- Centre 32 bits of Rm and Rn -> Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X :xtract Y
ex_stall.zbus_sel <= SEL_MANIP;
ex.alumanip <= EXTRACT;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100--------1100") then
-- SHAD Rm, Rn [4nmC]
--
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X shift arith Y
ex_stall.zbus_sel <= SEL_SHIFT;
ex_stall.shiftfunc <= ARITH;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00100--------1101") then
-- SHLD Rm, Rn [4nmD]
--
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X shift logic Y
ex_stall.zbus_sel <= SEL_SHIFT;
-- ex_stall.shiftfunc <= LOGIC;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00000--------1111") then
-- MAC.L @Rm+, @Rn+ [0nmF]
-- Signed, (Rn) x (Rm) + MAC -> MAC
case op.addr(3 downto 0) is
when x"0" =>
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- imm_enum <= IMM_P4;
wb_stall.macsel1 <= SEL_WBUS;
wb_stall.mulcom1 <= '1';
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
when x"1" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= rm;
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- imm_enum <= IMM_P4;
wb_stall.macsel2 <= SEL_WBUS;
wb_stall.mulcom2 <= MACL;
mac_busy <= WB_BUSY;
mac_s_latch <= '1';
-- W = MEM[X] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
-- ex.mem_size <= LONG;
-- Rm = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= rm;
when x"2" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "00100--------1111") then
-- MAC.W @Rm+, @Rn+ [4nmF]
-- Signed, (Rn) x (Rm) + MAC -> MAC
case op.addr(3 downto 0) is
when x"0" =>
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Z = X + 2
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_P2;
wb_stall.macsel1 <= SEL_WBUS;
wb_stall.mulcom1 <= '1';
-- W = MEM[X] word
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
ex.mem_size <= WORD;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
when x"1" =>
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= rm;
-- Z = X + 2
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_P2;
wb_stall.macsel2 <= SEL_WBUS;
wb_stall.mulcom2 <= MACW;
mac_busy <= WB_BUSY;
mac_s_latch <= '1';
-- W = MEM[X] word
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
ex_stall.mem_addr_sel <= SEL_XBUS;
ex.mem_size <= WORD;
-- Rm = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= rm;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "010000100--------") then
-- MOV.B @(disp, Rm), R0 [84md]
-- (disp + Rm) -> sign extension -> R0
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= rm;
-- Z = X + [:u 4 0]
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_4_0;
-- W = MEM[Z] byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
ex.mem_size <= BYTE;
-- R0 = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "00000";
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "010000101--------") then
-- MOV.W @(disp, Rm), R0 [85md]
-- (disp x2 +Rm)-> sign extension -> R0
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= rm;
-- Z = X + [:u 4 1]
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_4_1;
-- W = MEM[Z] word
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
ex.mem_size <= WORD;
-- R0 = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "00000";
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "010000000--------") then
-- MOV.B R0, @(disp, Rn) [80nd]
-- R0 -> (disp + Rn)
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= rm;
-- Y = R0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "00000";
-- Z = X + [:u 4 0]
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_4_0;
-- MEM[Z] = Y byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
ex.mem_size <= BYTE;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "010000001--------") then
-- MOV.W R0, @(disp, Rn) [81nd]
-- R0 -> (disp x 2+ Rn)
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= rm;
-- Y = R0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "00000";
-- Z = X + [:u 4 1]
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_4_1;
-- MEM[Z] = Y word
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
ex.mem_size <= WORD;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00001------------") then
-- MOV.L Rm, @(disp, Rn) [1nmd]
-- Rm -> (disp x 4 + Rn)
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = Rm
-- ex.ybus_sel <= SEL_REG;
-- ex.regnum_y <= rm;
-- Z = X + [:u 4 2]
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_4_2;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "00101------------") then
-- MOV.L @(disp, Rm), Rn [5nmd]
-- (disp x 4+ Rm) -> Rn
-- X = Rm
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= rm;
-- Z = X + [:u 4 2]
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_4_2;
-- W = MEM[Z] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex.mem_size <= LONG;
-- Rn = W
wb_stall.wrreg_w <= '1';
-- wb.regnum_w <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "010001011--------") then
-- BF label [8Bdd]
-- When T=0, disp x2+PC-> PC; When T = 1, nop
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Y = CONST * 2
ex.ybus_sel <= SEL_IMM;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_S_8_1;
-- if (not T) PC = Z
ex_stall.wrpc_z <= not t_bcc;
id.incpc <= '1';
dispatch <= t_bcc;
id.if_issue <= '1';
when x"1" =>
id.ifadsel <= '1';
id.if_issue <= '1';
when x"2" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "010001111--------") then
-- BF /S label [8Fdd]
-- When T=0, disp x2+PC-> PC; When T = 1, nop
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Y = CONST * 2
ex.ybus_sel <= SEL_IMM;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_S_8_1;
-- if (not T) PC = Z
ex_stall.wrpc_z <= not t_bcc;
id.incpc <= '1';
dispatch <= t_bcc;
id.if_issue <= t_bcc;
when x"1" =>
id.ifadsel <= '1';
dispatch <= '1';
id.if_issue <= '1';
delay_jump <= '1';
when others =>
end case;
elsif std_match(cond, "010001001--------") then
-- BT label [89dd]
-- When T=1, disp x2+PC-> PC; When T = 0, nop
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Y = CONST * 2
ex.ybus_sel <= SEL_IMM;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_S_8_1;
-- if (T) PC = Z
ex_stall.wrpc_z <= t_bcc;
id.incpc <= '1';
dispatch <= not t_bcc;
id.if_issue <= '1';
when x"1" =>
id.ifadsel <= '1';
id.if_issue <= '1';
when x"2" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "010001101--------") then
-- BT /S label [8Ddd]
-- When T=1, disp x2+PC-> PC; When T = 0, nop
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Y = CONST * 2
ex.ybus_sel <= SEL_IMM;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_S_8_1;
-- if (T) PC = Z
ex_stall.wrpc_z <= t_bcc;
id.incpc <= '1';
dispatch <= not t_bcc;
id.if_issue <= not t_bcc;
when x"1" =>
id.ifadsel <= '1';
dispatch <= '1';
id.if_issue <= '1';
delay_jump <= '1';
when others =>
end case;
elsif std_match(cond, "01010------------") then
-- BRA label [Addd]
-- Delayed branch, disp x 2+ PC -> PC
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Y = CONST * 2
ex.ybus_sel <= SEL_IMM;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_S_12_1;
-- PC = Z
ex_stall.wrpc_z <= '1';
id.incpc <= '1';
when x"1" =>
id.ifadsel <= '1';
dispatch <= '1';
id.if_issue <= '1';
delay_jump <= '1';
when others =>
end case;
elsif std_match(cond, "01011------------") then
-- BSR label [Bddd]
-- Delayed branching, PC -> PR, disp x 2 + PC -> PC
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Y = CONST * 2
ex.ybus_sel <= SEL_IMM;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_S_12_1;
-- PC = Z
ex_stall.wrpc_z <= '1';
-- PR = PC
ex_stall.wrpr_pc <= '1';
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10010";
id.incpc <= '1';
when x"1" =>
id.ifadsel <= '1';
dispatch <= '1';
id.if_issue <= '1';
delay_jump <= '1';
when others =>
end case;
elsif std_match(cond, "01001------------") then
-- MOV.W @(disp, PC), Rn [9ndd]
-- (disp x 2 + PC) -> sign extension -> Rn
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Y = UCONST * 2
ex.ybus_sel <= SEL_IMM;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_8_1;
-- W = MEM[Z] word
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
ex.mem_size <= WORD;
-- Rn = W
wb_stall.wrreg_w <= '1';
-- wb.regnum_w <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "011001101--------") then
-- AND.B #imm, @(R0, GBR) [CDii]
-- (R0 + GBR) & imm -> (R0 + GBR)
case op.addr(3 downto 0) is
when x"0" =>
-- X = GBR
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10000";
-- Y = R0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "00000";
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- W = MEM[Z] byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
ex.mem_size <= BYTE;
-- TEMP1 = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "10100";
when x"1" =>
-- X = GBR
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10000";
-- Y = R0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "00000";
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"2" =>
-- X = TEMP1
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10100";
-- Y = TEMP0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10011";
-- Z = X and [:u 8 0]
ex.aluiny_sel <= SEL_IMM;
ex_stall.zbus_sel <= SEL_LOGIC;
ex.logic_func <= LOGIC_AND;
imm_enum <= IMM_U_8_0;
-- MEM[Y] = Z byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
ex_stall.mem_addr_sel <= SEL_YBUS;
ex_stall.mem_wdata_sel <= SEL_ZBUS;
ex.mem_size <= BYTE;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "011001111--------") then
-- OR.B #imm, @(R0, GBR) [CFii]
-- (R0 + GBR) | imm -> (R0 + GBR)
case op.addr(3 downto 0) is
when x"0" =>
-- X = GBR
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10000";
-- Y = R0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "00000";
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- W = MEM[Z] byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
ex.mem_size <= BYTE;
-- TEMP1 = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "10100";
when x"1" =>
-- X = GBR
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10000";
-- Y = R0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "00000";
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"2" =>
-- X = TEMP1
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10100";
-- Y = TEMP0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10011";
-- Z = X or [:u 8 0]
ex.aluiny_sel <= SEL_IMM;
ex_stall.zbus_sel <= SEL_LOGIC;
ex.logic_func <= LOGIC_OR;
imm_enum <= IMM_U_8_0;
-- MEM[Y] = Z byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
ex_stall.mem_addr_sel <= SEL_YBUS;
ex_stall.mem_wdata_sel <= SEL_ZBUS;
ex.mem_size <= BYTE;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "011001100--------") then
-- TST.B #imm, @(R0, GBR) [CCii]
-- (R0 + GBR) & imm, when result is 0, 1 -> T
case op.addr(3 downto 0) is
when x"0" =>
-- X = GBR
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10000";
-- Y = R0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "00000";
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- W = MEM[Z] byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
ex.mem_size <= BYTE;
-- TEMP1 = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "10100";
when x"1" =>
when x"2" =>
-- X = TEMP1
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10100";
ex.aluiny_sel <= SEL_IMM;
-- ex.logic_sr_func <= ZERO;
ex.logic_func <= LOGIC_AND;
ex_stall.sr_sel <= SEL_LOGIC;
imm_enum <= IMM_U_8_0;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "011001110--------") then
-- XOR.B #imm, @(R0, GBR) [CEii]
-- (R0 + GBR) ^ imm -> (R0 + GBR)
case op.addr(3 downto 0) is
when x"0" =>
-- X = GBR
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10000";
-- Y = R0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "00000";
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- W = MEM[Z] byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
ex.mem_size <= BYTE;
-- TEMP1 = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "10100";
when x"1" =>
-- X = GBR
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10000";
-- Y = R0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "00000";
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"2" =>
-- X = TEMP1
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10100";
-- Y = TEMP0
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10011";
-- Z = X xor [:u 8 0]
ex.aluiny_sel <= SEL_IMM;
ex_stall.zbus_sel <= SEL_LOGIC;
-- ex.logic_func <= LOGIC_XOR;
imm_enum <= IMM_U_8_0;
-- MEM[Y] = Z byte
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
ex_stall.mem_addr_sel <= SEL_YBUS;
ex_stall.mem_wdata_sel <= SEL_ZBUS;
ex.mem_size <= BYTE;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "011001001--------") then
-- AND #imm, R0 [C9ii]
-- R0 & imm->R0
-- X = R0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "00000";
-- Y = UCONST
ex.ybus_sel <= SEL_IMM;
-- Z = X and Y
ex_stall.zbus_sel <= SEL_LOGIC;
ex.logic_func <= LOGIC_AND;
imm_enum <= IMM_U_8_0;
-- R0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "00000";
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "010001000--------") then
-- CMP /EQ #imm, R0 [88ii]
-- When R0=imm,1->T
-- X = R0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "00000";
-- Y = CONST
ex.ybus_sel <= SEL_IMM;
-- ex.logic_sr_func <= ZERO;
-- ex.logic_func <= LOGIC_XOR;
ex_stall.sr_sel <= SEL_LOGIC;
imm_enum <= IMM_S_8_0;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "011001011--------") then
-- OR #imm, R0 [CBii]
-- R0 | imm->R0
-- X = R0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "00000";
-- Y = UCONST
ex.ybus_sel <= SEL_IMM;
-- Z = X or Y
ex_stall.zbus_sel <= SEL_LOGIC;
ex.logic_func <= LOGIC_OR;
imm_enum <= IMM_U_8_0;
-- R0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "00000";
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "011001000--------") then
-- TST #imm, R0 [C8ii]
-- R0 & imm, when result is 0, 1 -> T
-- X = R0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "00000";
-- Y = UCONST
ex.ybus_sel <= SEL_IMM;
-- ex.logic_sr_func <= ZERO;
ex.logic_func <= LOGIC_AND;
ex_stall.sr_sel <= SEL_LOGIC;
imm_enum <= IMM_U_8_0;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "011001010--------") then
-- XOR #imm, R0 [CAii]
-- R0 ^ imm->R0
-- X = R0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "00000";
-- Y = UCONST
ex.ybus_sel <= SEL_IMM;
-- Z = X xor Y
ex_stall.zbus_sel <= SEL_LOGIC;
-- ex.logic_func <= LOGIC_XOR;
imm_enum <= IMM_U_8_0;
-- R0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "00000";
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "011000011--------") then
-- TRAPA #imm [C3ii]
-- PC/SR -> Stack area, (imm x 4 + VBR) -> PC
case op.addr(3 downto 0) is
when x"0" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Y = SR
ex.ybus_sel <= SEL_SR;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
when x"1" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Y = PC
ex.ybus_sel <= SEL_PC;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
when x"2" =>
-- X = UCONST * 4
ex.xbus_sel <= SEL_IMM;
-- Y = VBR
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10001";
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_8_2;
-- W = MEM[Z] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex.mem_size <= LONG;
when x"3" =>
when x"4" =>
ex_stall.zbus_sel <= SEL_WBUS;
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"5" =>
id.ifadsel <= '1';
id.if_issue <= '1';
when x"6" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "00111------------") then
-- ADD #imm, Rn [7nii]
-- Rn + imm -> Rn
-- X = Rn
-- ex.xbus_sel <= SEL_REG;
-- ex.regnum_x <= rn;
-- Y = CONST
ex.ybus_sel <= SEL_IMM;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_S_8_0;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "01110------------") then
-- MOV #imm, Rn [Enii]
-- imm -> sign extension -> Rn
-- Y = CONST
ex.ybus_sel <= SEL_IMM;
ex_stall.zbus_sel <= SEL_YBUS;
imm_enum <= IMM_S_8_0;
-- Rn = Z
ex_stall.wrreg_z <= '1';
-- ex.regnum_z <= rn;
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
elsif std_match(cond, "1-----111--------") then
-- General Illegal [-(-111)dd]
--
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Z = X - 2
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
imm_enum <= IMM_P2;
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"1" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Y = SR
ex.ybus_sel <= SEL_SR;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
when x"2" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Y = PC
ex.ybus_sel <= SEL_PC;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
when x"3" =>
-- X = UCONST * 4
ex.xbus_sel <= SEL_IMM;
-- Y = VBR
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10001";
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_8_2;
-- W = MEM[Z] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex.mem_size <= LONG;
when x"4" =>
when x"5" =>
ex_stall.zbus_sel <= SEL_WBUS;
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"6" =>
id.ifadsel <= '1';
id.if_issue <= '1';
when x"7" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "1-----110--------") then
-- Slot Illegal [-(-110)dd]
--
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Z = X + 0
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_ZERO;
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"1" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Y = SR
ex.ybus_sel <= SEL_SR;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
when x"2" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Y = PC
ex.ybus_sel <= SEL_PC;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
when x"3" =>
-- X = UCONST * 4
ex.xbus_sel <= SEL_IMM;
-- Y = VBR
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10001";
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_8_2;
-- W = MEM[Z] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex.mem_size <= LONG;
when x"4" =>
when x"5" =>
ex_stall.zbus_sel <= SEL_WBUS;
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"6" =>
id.ifadsel <= '1';
id.if_issue <= '1';
when x"7" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "1-----011--------") then
-- Reset [-(-011)dd]
--
case op.addr(3 downto 0) is
when x"0" =>
when x"1" =>
event_ack_0 <= '1';
when x"2" =>
-- Y = UCONST * 4
ex.ybus_sel <= SEL_IMM;
ex_stall.zbus_sel <= SEL_YBUS;
imm_enum <= IMM_U_8_2;
-- W = MEM[Z] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex.mem_size <= LONG;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"3" =>
-- X = TEMP0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10011";
-- Z = X + 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
-- imm_enum <= IMM_P4;
-- W = MEM[Z] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex.mem_size <= LONG;
-- R15 = W
wb_stall.wrreg_w <= '1';
wb.regnum_w <= "01111";
when x"4" =>
ex_stall.zbus_sel <= SEL_WBUS;
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"5" =>
-- X = TEMP1
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10100";
-- Y = TEMP1
-- ex.ybus_sel <= SEL_REG;
ex.regnum_y <= "10100";
-- Z = X xor Y
ex_stall.zbus_sel <= SEL_LOGIC;
-- ex.logic_func <= LOGIC_XOR;
-- VBR = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10001";
id.ifadsel <= '1';
id.if_issue <= '1';
when x"6" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "1-----000--------") then
-- Interrupt [-(-000)dd]
--
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Z = X - 2
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
imm_enum <= IMM_P2;
event_ack_0 <= '1';
ilevel_cap <= '1';
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"1" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Z = (X & FC) + 0
ex.aluinx_sel <= SEL_FC;
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_ZERO;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"2" =>
-- X = TEMP0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10011";
-- Y = SR
ex.ybus_sel <= SEL_SR;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"3" =>
-- X = TEMP0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10011";
-- Y = PC
ex.ybus_sel <= SEL_PC;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"4" =>
-- X = VBR
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10001";
-- Y = UCONST * 4
ex.ybus_sel <= SEL_IMM;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_8_2;
-- W = MEM[Z] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex.mem_size <= LONG;
when x"5" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
ex_stall.sr_sel <= SEL_INT_MASK;
-- imm_enum <= IMM_P4;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
when x"6" =>
ex_stall.zbus_sel <= SEL_WBUS;
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"7" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
id.ifadsel <= '1';
id.if_issue <= '1';
when x"8" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "1-----001--------") then
-- Error [-(-001)dd]
--
case op.addr(3 downto 0) is
when x"0" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Z = X - 2
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
imm_enum <= IMM_P2;
event_ack_0 <= '1';
ilevel_cap <= '1';
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"1" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Z = (X & FC) + 0
ex.aluinx_sel <= SEL_FC;
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_ZERO;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"2" =>
-- X = TEMP0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10011";
-- Y = SR
ex.ybus_sel <= SEL_SR;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"3" =>
-- X = TEMP0
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10011";
-- Y = PC
ex.ybus_sel <= SEL_PC;
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- MEM[Z] = Y long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '1';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex_stall.mem_wdata_sel <= SEL_YBUS;
-- ex.mem_size <= LONG;
-- TEMP0 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "10011";
when x"4" =>
-- X = VBR
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "10001";
-- Y = UCONST * 4
ex.ybus_sel <= SEL_IMM;
-- Z = X + Y
-- ex_stall.zbus_sel <= SEL_ARITH;
-- ex.arith_func <= ADD;
imm_enum <= IMM_U_8_2;
-- W = MEM[Z] long
ex_stall.ma_issue <= '1';
ex.ma_wr <= '0';
-- ex_stall.mem_addr_sel <= SEL_ZBUS;
-- ex.mem_size <= LONG;
when x"5" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
when x"6" =>
ex_stall.zbus_sel <= SEL_WBUS;
-- PC = Z
ex_stall.wrpc_z <= '1';
when x"7" =>
-- X = R15
-- ex.xbus_sel <= SEL_REG;
ex.regnum_x <= "01111";
-- Z = X - 4
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
-- imm_enum <= IMM_P4;
-- R15 = Z
ex_stall.wrreg_z <= '1';
ex.regnum_z <= "01111";
id.ifadsel <= '1';
id.if_issue <= '1';
when x"8" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
elsif std_match(cond, "1-----010--------") then
-- Break [-(-010)dd]
--
case op.addr(3 downto 0) is
when x"0" =>
when x"1" =>
-- X = PC
ex.xbus_sel <= SEL_PC;
-- Z = X - 2
ex.aluiny_sel <= SEL_IMM;
-- ex_stall.zbus_sel <= SEL_ARITH;
ex.arith_func <= SUB;
imm_enum <= IMM_P2;
-- PC = Z
ex_stall.wrpc_z <= '1';
debug <= '1';
when x"2" =>
id.ifadsel <= '1';
id.if_issue <= '1';
when x"3" =>
id.incpc <= '1';
dispatch <= '1';
id.if_issue <= '1';
when others =>
end case;
end if;
end process;
end;