mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-04-24 19:50:22 +00:00
Decode sc in the major opcode decode table
This decodes sc using entry 17 of the major_decode_rom_array table instead of a special case in the decode1_1 process. This means that only the major opcode (the top 6 bits) is checked at decode time. To make sure that the instruction is sc not scv, we now check bit 1 of the instruction at execute time and generate an illegal instruction interrupt if it is 0 (indicating scv). The level field of the sc instruction is now ignored. This reduces LUT consumption by 31 LUTs on the Arty A7-100. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
@@ -60,6 +60,7 @@ architecture behaviour of decode1 is
|
||||
20 => (ALU, OP_RLC, RA, CONST_SH32, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0'), -- rlwimi
|
||||
21 => (ALU, OP_RLC, NONE, CONST_SH32, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0'), -- rlwinm
|
||||
23 => (ALU, OP_RLC, NONE, RB, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0'), -- rlwnm
|
||||
17 => (ALU, OP_SC, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- sc
|
||||
38 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- stb
|
||||
39 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '0'), -- stbu
|
||||
44 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- sth
|
||||
@@ -344,7 +345,6 @@ architecture behaviour of decode1 is
|
||||
-- op in out A out in out len ext pipe
|
||||
constant attn_instr : decode_rom_t := (ALU, OP_ATTN, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1');
|
||||
constant nop_instr : decode_rom_t := (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0');
|
||||
constant sc_instr : decode_rom_t := (ALU, OP_SC, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0');
|
||||
|
||||
begin
|
||||
decode1_0: process(clk)
|
||||
@@ -402,9 +402,6 @@ begin
|
||||
elsif std_match(f_in.insn, "01100000000000000000000000000000") then
|
||||
report "PPC_nop";
|
||||
v.decode := nop_instr;
|
||||
elsif std_match(f_in.insn, "010001--------------0000000---1-") then
|
||||
report "PPC_sc";
|
||||
v.decode := sc_instr;
|
||||
elsif std_match(f_in.insn, "000000---------------0100000000-") then
|
||||
report "PPC_attn";
|
||||
v.decode := attn_instr;
|
||||
|
||||
@@ -239,6 +239,7 @@ begin
|
||||
variable exception : std_ulogic;
|
||||
variable exception_nextpc : std_ulogic;
|
||||
variable trapval : std_ulogic_vector(4 downto 0);
|
||||
variable illegal : std_ulogic;
|
||||
begin
|
||||
result := (others => '0');
|
||||
result_with_carry := (others => '0');
|
||||
@@ -388,6 +389,7 @@ begin
|
||||
|
||||
ctrl_tmp.irq_state <= WRITE_SRR0;
|
||||
exception := '0';
|
||||
illegal := '0';
|
||||
exception_nextpc := '0';
|
||||
v.e.exc_write_enable := '0';
|
||||
v.e.exc_write_reg := fast_spr_num(SPR_SRR0);
|
||||
@@ -426,22 +428,21 @@ begin
|
||||
when OP_ILLEGAL =>
|
||||
-- we need two cycles to write srr0 and 1
|
||||
-- will need more when we have to write DSISR, DAR and HIER
|
||||
exception := '1';
|
||||
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#700#, 64));
|
||||
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
|
||||
-- Since we aren't doing Hypervisor emulation assist (0xe40) we
|
||||
-- set bit 44 to indicate we have an illegal
|
||||
ctrl_tmp.srr1(63 - 44) <= '1';
|
||||
report "illegal";
|
||||
illegal := '1';
|
||||
when OP_SC =>
|
||||
-- FIXME Assume everything is SC (not SCV) for now
|
||||
-- check bit 1 of the instruction is 1 so we know this is sc;
|
||||
-- 0 would mean scv, so generate an illegal instruction interrupt
|
||||
-- we need two cycles to write srr0 and 1
|
||||
-- will need more when we have to write DSISR, DAR and HIER
|
||||
exception := '1';
|
||||
exception_nextpc := '1';
|
||||
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#C00#, 64));
|
||||
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
|
||||
report "sc";
|
||||
if e_in.insn(1) = '1' then
|
||||
exception := '1';
|
||||
exception_nextpc := '1';
|
||||
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#C00#, 64));
|
||||
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
|
||||
report "sc";
|
||||
else
|
||||
illegal := '1';
|
||||
end if;
|
||||
when OP_ATTN =>
|
||||
terminate_out <= '1';
|
||||
report "ATTN";
|
||||
@@ -836,6 +837,15 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if illegal = '1' then
|
||||
exception := '1';
|
||||
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#700#, 64));
|
||||
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
|
||||
-- Since we aren't doing Hypervisor emulation assist (0xe40) we
|
||||
-- set bit 44 to indicate we have an illegal
|
||||
ctrl_tmp.srr1(63 - 44) <= '1';
|
||||
report "illegal";
|
||||
end if;
|
||||
if exception = '1' then
|
||||
v.e.exc_write_enable := '1';
|
||||
if exception_nextpc = '1' then
|
||||
|
||||
Reference in New Issue
Block a user