mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
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>
This commit is contained in:
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,
|
||||
|
||||
10
cr_file.vhdl
10
cr_file.vhdl
@ -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…
x
Reference in New Issue
Block a user