Merge pull request #158 from paulusmack/excpath

Fix exception stuff so we make timing again
pull/159/head
Anton Blanchard 4 years ago committed by GitHub
commit 97e3d47a13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -263,9 +263,12 @@ package common is
write_cr_data : std_ulogic_vector(31 downto 0); write_cr_data : std_ulogic_vector(31 downto 0);
write_xerc_enable : std_ulogic; write_xerc_enable : std_ulogic;
xerc : xer_common_t; xerc : xer_common_t;
exc_write_enable : std_ulogic;
exc_write_reg : gspr_index_t;
exc_write_data : std_ulogic_vector(63 downto 0);
end record; end record;
constant Execute1ToWritebackInit : Execute1ToWritebackType := (valid => '0', rc => '0', write_enable => '0', constant Execute1ToWritebackInit : Execute1ToWritebackType := (valid => '0', rc => '0', write_enable => '0',
write_cr_enable => '0', write_cr_enable => '0', exc_write_enable => '0',
write_xerc_enable => '0', xerc => xerc_init, write_xerc_enable => '0', xerc => xerc_init,
others => (others => '0')); others => (others => '0'));



@ -42,6 +42,7 @@ architecture behaviour of decode1 is
15 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- addis 15 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- addis
28 => (ALU, OP_AND, NONE, CONST_UI, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0'), -- andi. 28 => (ALU, OP_AND, NONE, CONST_UI, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0'), -- andi.
29 => (ALU, OP_AND, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0'), -- andis. 29 => (ALU, OP_AND, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0'), -- andis.
0 => (ALU, OP_ATTN, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- attn
18 => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'), -- b 18 => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'), -- b
16 => (ALU, OP_BC, SPR, CONST_BD, NONE, SPR , '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'), -- bc 16 => (ALU, OP_BC, SPR, CONST_BD, NONE, SPR , '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'), -- bc
11 => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, '0', '1', '1', '0', ONE, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0'), -- cmpi 11 => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, '0', '1', '1', '0', ONE, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0'), -- cmpi
@ -60,6 +61,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 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 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 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 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 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 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
@ -67,8 +69,8 @@ architecture behaviour of decode1 is
36 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- stw 36 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- stw
37 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '0'), -- stwu 37 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '0'), -- stwu
8 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '1', '0', ONE, '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- subfic 8 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '1', '0', ONE, '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- subfic
2 => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tdi 2 => (ALU, OP_TRAP, RA, CONST_SI, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tdi
--PPC_TWI 3 3 => (ALU, OP_TRAP, RA, CONST_SI, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '1'), -- twi
26 => (ALU, OP_XOR, NONE, CONST_UI, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- xori 26 => (ALU, OP_XOR, NONE, CONST_UI, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- xori
27 => (ALU, OP_XOR, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- xoris 27 => (ALU, OP_XOR, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- xoris
others => illegal_inst others => illegal_inst
@ -103,7 +105,7 @@ architecture behaviour of decode1 is
-- unit internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl -- unit internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl
-- op in out A out in out len ext pipe -- op in out A out in out len ext pipe
-- mcrf; and cr logical ops -- mcrf; and cr logical ops
2#000# => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), 2#000# => (ALU, OP_CROP, NONE, NONE, NONE, NONE, '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'),
-- addpcis not implemented yet -- addpcis not implemented yet
2#001# => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), 2#001# => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'),
-- bclr, bcctr, bctar -- bclr, bcctr, bctar
@ -317,8 +319,8 @@ architecture behaviour of decode1 is
2#0011001000# => (ALU, OP_ADD, RA, NONE, NONE, RT, '0', '0', '1', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- subfze 2#0011001000# => (ALU, OP_ADD, RA, NONE, NONE, RT, '0', '0', '1', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- subfze
2#1011001000# => (ALU, OP_ADD, RA, NONE, NONE, RT, '0', '0', '1', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- subfzeo 2#1011001000# => (ALU, OP_ADD, RA, NONE, NONE, RT, '0', '0', '1', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- subfzeo
2#1001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sync 2#1001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sync
-- 2#0001000100# td 2#0001000100# => (ALU, OP_TRAP, RA, RB, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- td
2#0000000100# => (ALU, OP_TW, RA, RB, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tw 2#0000000100# => (ALU, OP_TRAP, RA, RB, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '1'), -- tw
2#0100111100# => (ALU, OP_XOR, NONE, RB, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- xor 2#0100111100# => (ALU, OP_XOR, NONE, RB, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- xor
others => illegal_inst others => illegal_inst
); );
@ -342,10 +344,7 @@ architecture behaviour of decode1 is


-- unit internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl -- unit internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl
-- op in out A out in out len ext pipe -- 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 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');
constant sim_cfg_instr : decode_rom_t := (ALU, OP_SIM_CONFIG,NONE, NONE, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1');


begin begin
decode1_0: process(clk) decode1_0: process(clk)
@ -403,15 +402,6 @@ begin
elsif std_match(f_in.insn, "01100000000000000000000000000000") then elsif std_match(f_in.insn, "01100000000000000000000000000000") then
report "PPC_nop"; report "PPC_nop";
v.decode := nop_instr; 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, "000001---------------0000000011-") then
report "PPC_SIM_CONFIG";
v.decode := sim_cfg_instr;
elsif std_match(f_in.insn, "000000---------------0100000000-") then
report "PPC_attn";
v.decode := attn_instr;


else else
v.decode := major_decode_rom_array(to_integer(majorop)); v.decode := major_decode_rom_array(to_integer(majorop));

@ -5,20 +5,19 @@ package decode_types is
type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD, type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD,
OP_ADDPCIS, OP_AND, OP_ATTN, OP_B, OP_BC, OP_BCREG, OP_ADDPCIS, OP_AND, OP_ATTN, OP_B, OP_BC, OP_BCREG,
OP_BPERM, OP_CMP, OP_CMPB, OP_CMPEQB, OP_CMPRB, OP_BPERM, OP_CMP, OP_CMPB, OP_CMPEQB, OP_CMPRB,
OP_CNTZ, OP_CRAND, OP_CNTZ, OP_CROP,
OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST,
OP_CRXOR, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST,
OP_DCBZ, OP_DIV, OP_DIVE, OP_EXTS, OP_DCBZ, OP_DIV, OP_DIVE, OP_EXTS,
OP_EXTSWSLI, OP_ICBI, OP_ICBT, OP_ISEL, OP_ISYNC, OP_EXTSWSLI, OP_ICBI, OP_ICBT, OP_ISEL, OP_ISYNC,
OP_LOAD, OP_STORE, OP_MADDHD, OP_MADDHDU, OP_MADDLD, OP_MCRF, OP_LOAD, OP_STORE, OP_MADDHD, OP_MADDHDU, OP_MADDLD,
OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFMSR, OP_MFSPR, OP_MOD, OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFMSR, OP_MFSPR, OP_MOD,
OP_MTCRF, OP_MTMSRD, OP_MTSPR, OP_MUL_L64, OP_MTCRF, OP_MTMSRD, OP_MTSPR, OP_MUL_L64,
OP_MUL_H64, OP_MUL_H32, OP_OR, OP_MUL_H64, OP_MUL_H32, OP_OR,
OP_POPCNT, OP_PRTY, OP_RFID, OP_POPCNT, OP_PRTY, OP_RFID,
OP_RLC, OP_RLCL, OP_RLCR, OP_SC, OP_SETB, OP_RLC, OP_RLCL, OP_RLCR, OP_SC, OP_SETB,
OP_SHL, OP_SHR, OP_SHL, OP_SHR,
OP_SYNC, OP_TD, OP_TDI, OP_TW, OP_SYNC, OP_TRAP,
OP_TWI, OP_XOR, OP_SIM_CONFIG OP_XOR
); );
type input_reg_a_t is (NONE, RA, RA_OR_ZERO, SPR); type input_reg_a_t is (NONE, RA, RA_OR_ZERO, SPR);
type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1, CONST_SH, CONST_SH32, SPR); type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1, CONST_SH, CONST_SH32, SPR);

@ -237,6 +237,9 @@ begin
variable lv : Execute1ToLoadstore1Type; variable lv : Execute1ToLoadstore1Type;
variable irq_valid : std_ulogic; variable irq_valid : std_ulogic;
variable exception : std_ulogic; variable exception : std_ulogic;
variable exception_nextpc : std_ulogic;
variable trapval : std_ulogic_vector(4 downto 0);
variable illegal : std_ulogic;
begin begin
result := (others => '0'); result := (others => '0');
result_with_carry := (others => '0'); result_with_carry := (others => '0');
@ -386,24 +389,30 @@ begin


ctrl_tmp.irq_state <= WRITE_SRR0; ctrl_tmp.irq_state <= WRITE_SRR0;
exception := '0'; exception := '0';
illegal := '0';
exception_nextpc := '0';
v.e.exc_write_enable := '0';
v.e.exc_write_reg := fast_spr_num(SPR_SRR0);
v.e.exc_write_data := e_in.nia;


if ctrl.irq_state = WRITE_SRR1 then if ctrl.irq_state = WRITE_SRR1 then
v.e.write_reg := fast_spr_num(SPR_SRR1); v.e.exc_write_reg := fast_spr_num(SPR_SRR1);
result := ctrl.srr1; v.e.exc_write_data := ctrl.srr1;
result_en := '1'; v.e.exc_write_enable := '1';
ctrl_tmp.msr(63 - 48) <= '0'; -- clear EE ctrl_tmp.msr(63 - 48) <= '0'; -- clear EE
f_out.redirect <= '1'; f_out.redirect <= '1';
f_out.redirect_nia <= ctrl.irq_nia; f_out.redirect_nia <= ctrl.irq_nia;
v.e.valid := '1'; v.e.valid := e_in.valid;
report "Writing SRR1: " & to_hstring(ctrl.srr1); report "Writing SRR1: " & to_hstring(ctrl.srr1);


elsif irq_valid = '1' then elsif irq_valid = '1' then
-- we need two cycles to write srr0 and 1 -- we need two cycles to write srr0 and 1
-- will need more when we have to write DSISR, DAR and HIER -- will need more when we have to write DSISR, DAR and HIER
exception := '1'; -- Don't deliver the interrupt until we have a valid instruction
-- coming in, so we have a valid NIA to put in SRR0.
exception := e_in.valid;
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#900#, 64)); ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#900#, 64));
ctrl_tmp.srr1 <= msr_copy(ctrl.msr); ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
result := e_in.nia;


elsif e_in.valid = '1' then elsif e_in.valid = '1' then


@ -419,29 +428,33 @@ begin
when OP_ILLEGAL => when OP_ILLEGAL =>
-- we need two cycles to write srr0 and 1 -- we need two cycles to write srr0 and 1
-- will need more when we have to write DSISR, DAR and HIER -- will need more when we have to write DSISR, DAR and HIER
exception := '1'; illegal := '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';
result := e_in.nia;
report "illegal";
when OP_SC => 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 -- we need two cycles to write srr0 and 1
-- will need more when we have to write DSISR, DAR and HIER -- will need more when we have to write DSISR, DAR and HIER
exception := '1'; if e_in.insn(1) = '1' then
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#C00#, 64)); exception := '1';
ctrl_tmp.srr1 <= msr_copy(ctrl.msr); exception_nextpc := '1';
result := std_logic_vector(unsigned(e_in.nia) + 4); ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#C00#, 64));
report "sc"; ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
report "sc";
else
illegal := '1';
end if;
when OP_ATTN => when OP_ATTN =>
terminate_out <= '1'; -- check bits 1-10 of the instruction to make sure it's attn
report "ATTN"; -- if not then it is illegal
if e_in.insn(10 downto 1) = "0100000000" then
terminate_out <= '1';
report "ATTN";
else
illegal := '1';
end if;
when OP_NOP => when OP_NOP =>
-- Do nothing -- Do nothing
when OP_ADD | OP_CMP => when OP_ADD | OP_CMP | OP_TRAP =>
if e_in.invert_a = '0' then if e_in.invert_a = '0' then
a_inv := a_in; a_inv := a_in;
else else
@ -463,18 +476,18 @@ begin
end if; end if;
result_en := '1'; result_en := '1';
else else
-- CMP and CMPL instructions -- trap, CMP and CMPL instructions
-- Note, we have done RB - RA, not RA - RB -- Note, we have done RB - RA, not RA - RB
bf := insn_bf(e_in.insn); if e_in.insn_type = OP_CMP then
l := insn_l(e_in.insn); l := insn_l(e_in.insn);
v.e.write_cr_enable := '1'; else
crnum := to_integer(unsigned(bf)); l := not e_in.is_32bit;
v.e.write_cr_mask := num_to_fxm(crnum); end if;
zerolo := not (or (a_in(31 downto 0) xor b_in(31 downto 0))); zerolo := not (or (a_in(31 downto 0) xor b_in(31 downto 0)));
zerohi := not (or (a_in(63 downto 32) xor b_in(63 downto 32))); zerohi := not (or (a_in(63 downto 32) xor b_in(63 downto 32)));
if zerolo = '1' and (l = '0' or zerohi = '1') then if zerolo = '1' and (l = '0' or zerohi = '1') then
-- values are equal -- values are equal
newcrf := "001" & v.e.xerc.so; trapval := "00100";
else else
if l = '1' then if l = '1' then
-- 64-bit comparison -- 64-bit comparison
@ -489,19 +502,41 @@ begin
-- Subtraction might overflow, but -- Subtraction might overflow, but
-- comparison is clear from MSB difference. -- comparison is clear from MSB difference.
-- for signed, 0 is greater; for unsigned, 1 is greater -- for signed, 0 is greater; for unsigned, 1 is greater
a_lt := msb_a xnor e_in.is_signed; trapval := msb_a & msb_b & '0' & msb_b & msb_a;
else else
-- Subtraction cannot overflow since MSBs are equal. -- Subtraction cannot overflow since MSBs are equal.
-- carry = 1 indicates RA is smaller (signed or unsigned) -- carry = 1 indicates RA is smaller (signed or unsigned)
a_lt := (not l and carry_32) or (l and carry_64); a_lt := (not l and carry_32) or (l and carry_64);
trapval := a_lt & not a_lt & '0' & a_lt & not a_lt;
end if;
end if;
if e_in.insn_type = OP_CMP then
if e_in.is_signed = '1' then
newcrf := trapval(4 downto 2) & v.e.xerc.so;
else
newcrf := trapval(1 downto 0) & trapval(2) & v.e.xerc.so;
end if;
bf := insn_bf(e_in.insn);
crnum := to_integer(unsigned(bf));
v.e.write_cr_enable := '1';
v.e.write_cr_mask := num_to_fxm(crnum);
for i in 0 to 7 loop
lo := i*4;
hi := lo + 3;
v.e.write_cr_data(hi downto lo) := newcrf;
end loop;
else
-- trap instructions (tw, twi, td, tdi)
if or (trapval and insn_to(e_in.insn)) = '1' then
-- generate trap-type program interrupt
exception := '1';
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#700#, 64));
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
-- set bit 46 to say trap occurred
ctrl_tmp.srr1(63 - 46) <= '1';
report "trap";
end if; end if;
newcrf := a_lt & not a_lt & '0' & v.e.xerc.so;
end if; end if;
for i in 0 to 7 loop
lo := i*4;
hi := lo + 3;
v.e.write_cr_data(hi downto lo) := newcrf;
end loop;
end if; end if;
when OP_AND | OP_OR | OP_XOR => when OP_AND | OP_OR | OP_XOR =>
result := logical_result; result := logical_result;
@ -578,7 +613,7 @@ begin
result := b_in; result := b_in;
end if; end if;
result_en := '1'; result_en := '1';
when OP_MCRF => when OP_CROP =>
cr_op := insn_cr(e_in.insn); cr_op := insn_cr(e_in.insn);
report "CR OP " & to_hstring(cr_op); report "CR OP " & to_hstring(cr_op);
if cr_op(0) = '0' then -- MCRF if cr_op(0) = '0' then -- MCRF
@ -715,15 +750,6 @@ begin
set_carry(v.e, rotator_carry, rotator_carry); set_carry(v.e, rotator_carry, rotator_carry);
end if; end if;
result_en := '1'; result_en := '1';
when OP_SIM_CONFIG =>
-- bit 0 was used to select the microwatt console, which
-- we no longer support.
result := x"0000000000000000";
result_en := '1';

when OP_TDI =>
-- Keep our test cases happy for now, ignore trap instructions
report "OP_TDI FIXME";


when OP_ISYNC => when OP_ISYNC =>
f_out.redirect <= '1'; f_out.redirect <= '1';
@ -817,14 +843,22 @@ begin
end if; end if;
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 if exception = '1' then
v.e.write_reg := fast_spr_num(SPR_SRR0); v.e.exc_write_enable := '1';
if e_in.valid = '1' then if exception_nextpc = '1' then
result_en := '1'; v.e.exc_write_data := next_nia;
ctrl_tmp.irq_state <= WRITE_SRR1; end if;
stall_out <= '1'; ctrl_tmp.irq_state <= WRITE_SRR1;
v.e.valid := '0'; v.e.valid := '1';
end if;
end if; end if;


v.e.write_data := result; v.e.write_data := result;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save