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
-- 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)
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;
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');
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);
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";
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