Move XER low bits out of register file

Besides the overflow and status carry bits, XER has 18 bits which need
to retain the value written by mtxer (in case software wants to
emulate the move-assist instructions (lswi, lswx, stswi, stswx).
Until now these bits (and others) have been stored in the GPR file as
a "fast" SPR, but this causes complications because XER is not really
a fast SPR.

Instead, we now store these 18 bits in the 'ctrl' signal, which exists
in execute1.  This will enable us to simplify the data path in future,
and has the added bonus that with a little bit of plumbing, we can get
the full XER value printed when dumping registers at the end of a
simulation.

Therefore this changes scripts/run_test.sh to remove the greps which
exclude XER from the comparison of actual and expected register
results.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/379/head
Paul Mackerras 2 years ago
parent bdd4d04162
commit 204fedc63f

@ -114,7 +114,7 @@ package common is

-- The XER is split: the common bits (CA, OV, SO, OV32 and CA32) are
-- in the CR file as a kind of CR extension (with a separate write
-- control). The rest is stored as a fast SPR.
-- control). The rest is stored in ctrl_t (effectively in execute1).
type xer_common_t is record
ca : std_ulogic;
ca32 : std_ulogic;
@ -192,7 +192,10 @@ package common is
dec: std_ulogic_vector(63 downto 0);
msr: std_ulogic_vector(63 downto 0);
cfar: std_ulogic_vector(63 downto 0);
xer_low: std_ulogic_vector(17 downto 0);
end record;
constant ctrl_t_init : ctrl_t :=
(xer_low => 18x"0", others => (others => '0'));

type Fetch1ToIcacheType is record
req: std_ulogic;
@ -739,8 +742,6 @@ package body common is
n := 10;
when SPR_HSPRG1 =>
n := 11;
when SPR_XER =>
n := 12;
when SPR_TAR =>
n := 13;
when others =>

@ -145,7 +145,7 @@ architecture behave of core is
signal dbg_gpr_addr : gspr_index_t;
signal dbg_gpr_data : std_ulogic_vector(63 downto 0);

signal msr : std_ulogic_vector(63 downto 0);
signal ctrl_debug : ctrl_t;

-- PMU event bus
signal icache_events : IcacheEventType;
@ -333,6 +333,7 @@ begin
d_out => cr_file_to_decode2,
w_in => writeback_to_cr_file,
sim_dump => sim_cr_dump,
ctrl => ctrl_debug,
log_out => log_data(183 downto 171)
);

@ -359,7 +360,7 @@ begin
bypass_data => execute1_bypass,
bypass_cr_data => execute1_cr_bypass,
icache_inval => ex1_icache_inval,
dbg_msr_out => msr,
dbg_ctrl_out => ctrl_debug,
wb_events => writeback_events,
ls_events => loadstore_events,
dc_events => dcache_events,
@ -482,7 +483,7 @@ begin
terminate => terminate,
core_stopped => dbg_core_is_stopped,
nia => fetch1_to_icache.nia,
msr => msr,
msr => ctrl_debug.msr,
dbg_gpr_req => dbg_gpr_req,
dbg_gpr_ack => dbg_gpr_ack,
dbg_gpr_addr => dbg_gpr_addr,

@ -18,6 +18,7 @@ entity cr_file is
d_out : out CrFileToDecode2Type;

w_in : in WritebackToCrFileType;
ctrl : in ctrl_t;

-- debug
sim_dump : in std_ulogic;
@ -84,9 +85,18 @@ begin

sim_dump_test: if SIM generate
dump_cr: process(all)
variable xer : std_ulogic_vector(31 downto 0);
begin
if sim_dump = '1' then
report "CR 00000000" & to_hstring(crs);
xer := (others => '0');
xer(31) := xerc.so;
xer(30) := xerc.ov;
xer(29) := xerc.ca;
xer(19) := xerc.ov32;
xer(18) := xerc.ca32;
xer(17 downto 0) := ctrl.xer_low;
report "XER 00000000" & to_hstring(xer);
assert false report "end of test" severity failure;
end if;
end process;

@ -41,7 +41,7 @@ entity execute1 is
bypass_data : out bypass_data_t;
bypass_cr_data : out cr_bypass_data_t;

dbg_msr_out : out std_ulogic_vector(63 downto 0);
dbg_ctrl_out : out ctrl_t;

icache_inval : out std_ulogic;
terminate_out : out std_ulogic;
@ -99,8 +99,8 @@ architecture behaviour of execute1 is
signal mshort_p : std_ulogic_vector(31 downto 0) := (others => '0');

signal valid_in : std_ulogic;
signal ctrl: ctrl_t;
signal ctrl_tmp: ctrl_t;
signal ctrl: ctrl_t := ctrl_t_init;
signal ctrl_tmp: ctrl_t := ctrl_t_init;
signal right_shift, rot_clear_left, rot_clear_right: std_ulogic;
signal rot_sign_ext: std_ulogic;
signal rotator_result: std_ulogic_vector(63 downto 0);
@ -249,6 +249,13 @@ architecture behaviour of execute1 is
return x(n - 1) = '1';
end;

function assemble_xer(xerc: xer_common_t; xer_low: std_ulogic_vector)
return std_ulogic_vector is
begin
return 32x"0" & xerc.so & xerc.ov & xerc.ca & "000000000" &
xerc.ov32 & xerc.ca32 & xer_low(17 downto 0);
end;

-- Tell vivado to keep the hierarchy for the random module so that the
-- net names in the xdc file match.
attribute keep_hierarchy : string;
@ -336,7 +343,7 @@ begin
);
end generate;

dbg_msr_out <= ctrl.msr;
dbg_ctrl_out <= ctrl;
log_rd_addr <= r.log_addr_spr;

a_in <= e_in.read_data1;
@ -402,9 +409,7 @@ begin
if rising_edge(clk) then
if rst = '1' then
r <= reg_type_init;
ctrl.tb <= (others => '0');
ctrl.dec <= (others => '0');
ctrl.cfar <= (others => '0');
ctrl <= ctrl_t_init;
ctrl.msr <= (MSR_SF => '1', MSR_LE => '1', others => '0');
else
r <= rin;
@ -1043,19 +1048,11 @@ begin
"=" & to_hstring(a_in);
if is_fast_spr(e_in.read_reg1) = '1' then
spr_val := a_in;
if decode_spr_num(e_in.insn) = SPR_XER then
-- bits 0:31 and 35:43 are treated as reserved and return 0s when read using mfxer
spr_val(63 downto 32) := (others => '0');
spr_val(63-32) := xerc_in.so;
spr_val(63-33) := xerc_in.ov;
spr_val(63-34) := xerc_in.ca;
spr_val(63-35 downto 63-43) := "000000000";
spr_val(63-44) := xerc_in.ov32;
spr_val(63-45) := xerc_in.ca32;
end if;
else
spr_val := c_in;
case decode_spr_num(e_in.insn) is
when SPR_XER =>
spr_val := assemble_xer(xerc_in, ctrl.xer_low);
when SPR_TB =>
spr_val := ctrl.tb;
when SPR_TBU =>
@ -1118,17 +1115,16 @@ begin
when OP_MTSPR =>
report "MTSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
"=" & to_hstring(c_in);
if is_fast_spr(e_in.write_reg) then
if decode_spr_num(e_in.insn) = SPR_XER then
if is_fast_spr(e_in.write_reg) = '0' then
-- slow spr
case decode_spr_num(e_in.insn) is
when SPR_XER =>
v.e.xerc.so := c_in(63-32);
v.e.xerc.ov := c_in(63-33);
v.e.xerc.ca := c_in(63-34);
v.e.xerc.ov32 := c_in(63-44);
v.e.xerc.ca32 := c_in(63-45);
end if;
else
-- slow spr
case decode_spr_num(e_in.insn) is
ctrl_tmp.xer_low <= c_in(17 downto 0);
when SPR_DEC =>
ctrl_tmp.dec <= c_in;
when 724 => -- LOG_ADDR SPR

@ -143,7 +143,6 @@ begin

report "LR " & to_hstring(registers(to_integer(unsigned(fast_spr_num(SPR_LR)))));
report "CTR " & to_hstring(registers(to_integer(unsigned(fast_spr_num(SPR_CTR)))));
report "XER " & to_hstring(registers(to_integer(unsigned(fast_spr_num(SPR_XER)))));
sim_dump_done <= '1';
else
sim_dump_done <= '0';

@ -21,9 +21,9 @@ cd $TMPDIR

cp ${MICROWATT_DIR}/tests/${TEST}.bin main_ram.bin

${MICROWATT_DIR}/core_tb | sed 's/.*: //' | egrep '^(GPR[0-9]|LR |CTR |XER |CR [0-9])' | sort | grep -v GPR31 | grep -v XER > test.out || true
${MICROWATT_DIR}/core_tb | sed 's/.*: //' | egrep '^(GPR[0-9]|LR |CTR |XER |CR [0-9])' | sort | grep -v GPR31 > test.out || true

grep -v "^$" ${MICROWATT_DIR}/tests/${TEST}.out | sort | grep -v GPR31 | grep -v XER > exp.out
grep -v "^$" ${MICROWATT_DIR}/tests/${TEST}.out | sort | grep -v GPR31 > exp.out

cp test.out /tmp
cp exp.out /tmp

Loading…
Cancel
Save