execute1: Rework data paths for mfspr and mtspr

Data being written to an SPR by mtspr now comes in to execute2 via
ex1.write_spr_data (renamed from ex1.ramspr_odd_data) rather than
ex1.e.write_data.  This eliminates the need for the main result mux in
execute1 to be able to pass the c_in value through.  For mfspr, the
no-op behaviour is obtained by selecting ex1.write_spr_data as
spr_result in execute2.  We already had ex1.write_spr_data being set
from c_in, so no new logic is required there.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/445/head
Paul Mackerras 2 months ago
parent fc3ff2d340
commit 8f6c727309

@ -262,7 +262,7 @@ architecture behaviour of decode1 is
INSN_mfcr => (ALU, NONE, OP_MFCR, NONE, IMM, NONE, NONE, RT, MSC, "101", '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE),
INSN_mffs => (FPU, FPU, OP_FP_MISC, NONE, FRB, NONE, NONE, FRT, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE),
INSN_mfmsr => (ALU, NONE, OP_MFMSR, NONE, IMM, NONE, NONE, RT, MSC, "100", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '1', NONE),
INSN_mfspr => (ALU, NONE, OP_MFSPR, NONE, IMM, NONE, RS, RT, LOG, "111", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE),
INSN_mfspr => (ALU, NONE, OP_MFSPR, NONE, IMM, NONE, RS, RT, SPR, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE),
INSN_modsd => (DVU, NONE, OP_MOD, RA, RB, NONE, NONE, RT, ADD, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE),
INSN_modsw => (DVU, NONE, OP_MOD, RA, RB, NONE, NONE, RT, ADD, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', NONE, '0', '0', '0', NONE),
INSN_modud => (DVU, NONE, OP_MOD, RA, RB, NONE, NONE, RT, ADD, "101", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE),
@ -273,7 +273,7 @@ architecture behaviour of decode1 is
INSN_mtfsfi => (FPU, FPU, OP_FP_MISC, NONE, IMM, NONE, NONE, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE),
INSN_mtmsr => (ALU, NONE, OP_MTMSRD, NONE, IMM, NONE, RS, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '1', '0', NONE),
INSN_mtmsrd => (ALU, NONE, OP_MTMSRD, NONE, IMM, NONE, RS, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', '0', NONE),
INSN_mtspr => (ALU, NONE, OP_MTSPR, NONE, IMM, NONE, RS, NONE, LOG, "111", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE),
INSN_mtspr => (ALU, NONE, OP_MTSPR, NONE, IMM, NONE, RS, NONE, ADD, "000", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE),
INSN_mulhd => (ALU, NONE, OP_MUL_H64, RA, RB, NONE, NONE, RT, ADD, "010", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', '0', NONE),
INSN_mulhdu => (ALU, NONE, OP_MUL_H64, RA, RB, NONE, NONE, RT, ADD, "010", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', '0', NONE),
INSN_mulhw => (ALU, NONE, OP_MUL_H32, RA, RB, NONE, NONE, RT, ADD, "001", '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '0', '0', NONE),

@ -614,11 +614,6 @@ begin
v.e.br_pred := d_in.br_pred;
v.e.result_sel := d_in.decode.result;
v.e.sub_select := d_in.decode.subresult;
if op = OP_MFSPR then
if d_in.ram_spr.valid = '1' then
v.e.result_sel := SPR; -- ramspr_result
end if;
end if;
v.e.privileged := d_in.decode.privileged;
if (op = OP_MFSPR or op = OP_MTSPR) and d_in.insn(20) = '1' then
v.e.privileged := '1';

@ -102,6 +102,7 @@ architecture behaviour of execute1 is
scv_trap : std_ulogic;
write_tbl : std_ulogic;
write_tbu : std_ulogic;
noop_spr_read : std_ulogic;
end record;
constant side_effect_init : side_effect_type := (others => '0');

@ -125,13 +126,13 @@ architecture behaviour of execute1 is
fp_intr : std_ulogic;
res2_sel : std_ulogic_vector(1 downto 0);
bypass_valid : std_ulogic;
ramspr_odd_data : std_ulogic_vector(63 downto 0);
spr_write_data : std_ulogic_vector(63 downto 0);
ic : std_ulogic_vector(3 downto 0);
end record;
constant actions_type_init : actions_type :=
(e => Execute1ToWritebackInit, se => side_effect_init,
new_msr => (others => '0'), res2_sel => "00",
ramspr_odd_data => 64x"0", ic => x"0", others => '0');
spr_write_data => 64x"0", ic => x"0", others => '0');

type reg_stage1_type is record
e : Execute1ToWritebackType;
@ -164,7 +165,7 @@ architecture behaviour of execute1 is
xerc : xer_common_t;
xerc_valid : std_ulogic;
ramspr_wraddr : ramspr_index;
ramspr_odd_data : std_ulogic_vector(63 downto 0);
spr_write_data : std_ulogic_vector(63 downto 0);
ic : std_ulogic_vector(3 downto 0);
prefixed : std_ulogic;
insn : std_ulogic_vector(31 downto 0);
@ -184,7 +185,7 @@ architecture behaviour of execute1 is
taken_branch_event => '0', br_mispredict => '0',
msr => 64x"0",
xerc => xerc_init, xerc_valid => '0',
ramspr_wraddr => (others => '0'), ramspr_odd_data => 64x"0",
ramspr_wraddr => (others => '0'), spr_write_data => 64x"0",
ic => x"0",
prefixed => '0', insn => 32x"0", prefix => 26x"0");

@ -595,13 +596,13 @@ begin
thi := timebase(63 downto 32);
carry := '0';
if stage2_stall = '0' and ex1.se.write_tbl = '1' then
tlo := ex1.e.write_data(31 downto 0);
tlo := ex1.spr_write_data(31 downto 0);
elsif tb_ctrl.freeze = '0' then
tlo := std_ulogic_vector(unsigned(tlo) + 1);
carry := tb_carry;
end if;
if stage2_stall = '0' and ex1.se.write_tbu = '1' then
thi := ex1.e.write_data(31 downto 0);
thi := ex1.spr_write_data(31 downto 0);
else
thi := std_ulogic_vector(unsigned(thi) + carry);
end if;
@ -640,7 +641,7 @@ begin
x_to_pmu.addr <= l_in.ea_for_pmu;
x_to_pmu.addr_v <= l_in.ea_valid;
x_to_pmu.spr_num <= ex1.pmu_spr_num;
x_to_pmu.spr_val <= ex1.e.write_data;
x_to_pmu.spr_val <= ex1.spr_write_data;
x_to_pmu.run <= ctrl.run;
x_to_pmu.trace <= pmu_trace;

@ -704,14 +705,14 @@ begin
if ex1.lr_from_next = '1' then
ramspr_even_data := next_nia;
else
ramspr_even_data := ex1.e.write_data;
ramspr_even_data := ex1.spr_write_data;
end if;
if interrupt_in.intr = '1' then
even_wr_data := ex2.e.last_nia;
odd_wr_data := intr_srr1(ctrl.msr, interrupt_in.srr1);
else
even_wr_data := ramspr_even_data;
odd_wr_data := ex1.ramspr_odd_data;
odd_wr_data := ex1.spr_write_data;
end if;
ramspr_wr_addr <= wr_addr;
ramspr_even_wr_data <= even_wr_data;
@ -728,7 +729,7 @@ begin
ramspr_even <= even_rd_data;
end if;
if ex1.se.ramspr_write_odd = '1' and e_in.ramspr_odd_rdaddr = ex1.ramspr_wraddr then
ramspr_odd <= ex1.ramspr_odd_data;
ramspr_odd <= ex1.spr_write_data;
else
ramspr_odd <= odd_rd_data;
end if;
@ -1211,9 +1212,9 @@ begin

v.se.ramspr_write_even := e_in.ramspr_write_even;
v.se.ramspr_write_odd := e_in.ramspr_write_odd;
v.ramspr_odd_data := c_in;
v.spr_write_data := c_in;
if e_in.dec_ctr = '1' then
v.ramspr_odd_data := std_ulogic_vector(unsigned(ramspr_odd) - 1);
v.spr_write_data := std_ulogic_vector(unsigned(ramspr_odd) - 1);
end if;

-- Note the difference between v.exception and v.trap:
@ -1391,16 +1392,17 @@ begin
when OP_DARN =>
when OP_MFMSR =>
when OP_MFSPR =>
if e_in.spr_is_ram = '1' or e_in.spr_select.noop = '1' then
if e_in.spr_is_ram = '1' then
if e_in.valid = '1' and not is_X(e_in.insn) then
report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
"=" & to_hstring(alu_result);
end if;
elsif e_in.spr_select.valid = '1' then
elsif e_in.spr_select.valid = '1' and e_in.spr_select.wonly = '0' then
if e_in.valid = '1' and not is_X(e_in.insn) then
report "MFSPR to slow SPR " & integer'image(decode_spr_num(e_in.insn));
end if;
slow_op := '1';
v.se.noop_spr_read := e_in.spr_select.noop;
if e_in.spr_select.ispmu = '0' then
case e_in.spr_select.sel is
when SPRSEL_LOGR =>
@ -1420,6 +1422,8 @@ begin
report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
" invalid";
end if;
slow_op := '1';
v.se.noop_spr_read := '1';
if ex1.msr(MSR_PR) = '1' then
illegal := '1';
end if;
@ -1676,7 +1680,7 @@ begin
v.se := side_effect_init;
v.ramspr_wraddr := e_in.ramspr_wraddr;
v.lr_from_next := e_in.lr;
v.ramspr_odd_data := actions.ramspr_odd_data;
v.spr_write_data := actions.spr_write_data;
v.ic := actions.ic;
v.prefixed := e_in.prefixed;
v.insn := e_in.insn;
@ -2060,7 +2064,9 @@ begin
else
rcresult := countbits_result;
end if;
if ex1.res2_sel(0) = '0' then
if ex1.se.noop_spr_read = '1' then
sprres := ex1.spr_write_data;
elsif ex1.res2_sel(0) = '0' then
sprres := spr_result;
else
sprres := pmu_to_x.spr_val;
@ -2104,40 +2110,40 @@ begin
ctrl_tmp.msr <= ex1.msr;
end if;
if ex1.se.write_xerlow = '1' then
ctrl_tmp.xer_low <= ex1.e.write_data(17 downto 0);
ctrl_tmp.xer_low <= ex1.spr_write_data(17 downto 0);
end if;
if ex1.se.write_dec = '1' then
ctrl_tmp.dec <= ex1.e.write_data;
ctrl_tmp.dec <= ex1.spr_write_data;
end if;
if ex1.se.write_cfar = '1' then
ctrl_tmp.cfar <= ex1.e.write_data;
ctrl_tmp.cfar <= ex1.spr_write_data;
elsif ex1.se.set_cfar = '1' then
ctrl_tmp.cfar <= ex1.e.last_nia;
end if;
if ex1.se.write_loga = '1' then
v.log_addr_spr := ex1.e.write_data(31 downto 0);
v.log_addr_spr := ex1.spr_write_data(31 downto 0);
elsif ex1.se.inc_loga = '1' then
v.log_addr_spr := std_ulogic_vector(unsigned(ex2.log_addr_spr) + 1);
end if;
x_to_pmu.mtspr <= ex1.se.write_pmuspr;
if ex1.se.write_fscr = '1' then
ctrl_tmp.fscr_ic <= ex1.e.write_data(59 downto 56);
ctrl_tmp.fscr_pref <= ex1.e.write_data(FSCR_PREFIX);
ctrl_tmp.fscr_scv <= ex1.e.write_data(FSCR_SCV);
ctrl_tmp.fscr_tar <= ex1.e.write_data(FSCR_TAR);
ctrl_tmp.fscr_dscr <= ex1.e.write_data(FSCR_DSCR);
ctrl_tmp.fscr_ic <= ex1.spr_write_data(59 downto 56);
ctrl_tmp.fscr_pref <= ex1.spr_write_data(FSCR_PREFIX);
ctrl_tmp.fscr_scv <= ex1.spr_write_data(FSCR_SCV);
ctrl_tmp.fscr_tar <= ex1.spr_write_data(FSCR_TAR);
ctrl_tmp.fscr_dscr <= ex1.spr_write_data(FSCR_DSCR);
elsif ex1.se.write_ic = '1' then
ctrl_tmp.fscr_ic <= ex1.ic;
end if;
if ex1.se.write_lpcr = '1' then
ctrl_tmp.lpcr_hail <= ex1.e.write_data(LPCR_HAIL);
ctrl_tmp.lpcr_ld <= ex1.e.write_data(LPCR_LD);
ctrl_tmp.lpcr_heic <= ex1.e.write_data(LPCR_HEIC);
ctrl_tmp.lpcr_lpes <= ex1.e.write_data(LPCR_LPES);
ctrl_tmp.lpcr_hvice <= ex1.e.write_data(LPCR_HVICE);
ctrl_tmp.lpcr_hail <= ex1.spr_write_data(LPCR_HAIL);
ctrl_tmp.lpcr_ld <= ex1.spr_write_data(LPCR_LD);
ctrl_tmp.lpcr_heic <= ex1.spr_write_data(LPCR_HEIC);
ctrl_tmp.lpcr_lpes <= ex1.spr_write_data(LPCR_LPES);
ctrl_tmp.lpcr_hvice <= ex1.spr_write_data(LPCR_HVICE);
end if;
if ex1.se.write_heir = '1' then
ctrl_tmp.heir <= ex1.e.write_data;
ctrl_tmp.heir <= ex1.spr_write_data;
elsif ex1.se.set_heir = '1' then
ctrl_tmp.heir(31 downto 0) <= ex1.insn;
if ex1.prefixed = '1' then
@ -2148,13 +2154,13 @@ begin
end if;
end if;
if ex1.se.write_ctrl = '1' then
ctrl_tmp.run <= ex1.e.write_data(0);
ctrl_tmp.run <= ex1.spr_write_data(0);
end if;
if ex1.se.write_dscr = '1' then
ctrl_tmp.dscr <= ex1.e.write_data(24 downto 0);
ctrl_tmp.dscr <= ex1.spr_write_data(24 downto 0);
end if;
if ex1.se.write_ciabr = '1' then
ctrl_tmp.ciabr <= ex1.e.write_data;
ctrl_tmp.ciabr <= ex1.spr_write_data;
end if;
if ex1.se.enter_wait = '1' then
ctrl_tmp.wait_state <= '1';

@ -171,8 +171,7 @@ begin
end if;
tmp(7 downto 0) := rs(7 downto 0);
when others =>
-- e.g. OP_MFSPR
tmp := rs;
tmp := (others => '0');
end case;

result <= tmp;

Loading…
Cancel
Save