mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
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>
120 lines
3.4 KiB
VHDL
120 lines
3.4 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
library work;
|
|
use work.common.all;
|
|
|
|
entity cr_file is
|
|
generic (
|
|
SIM : boolean := false;
|
|
-- Non-zero to enable log data collection
|
|
LOG_LENGTH : natural := 0
|
|
);
|
|
port(
|
|
clk : in std_logic;
|
|
|
|
d_in : in Decode2ToCrFileType;
|
|
d_out : out CrFileToDecode2Type;
|
|
|
|
w_in : in WritebackToCrFileType;
|
|
ctrl : in ctrl_t;
|
|
|
|
-- debug
|
|
sim_dump : in std_ulogic;
|
|
|
|
log_out : out std_ulogic_vector(12 downto 0)
|
|
);
|
|
end entity cr_file;
|
|
|
|
architecture behaviour of cr_file is
|
|
signal crs : std_ulogic_vector(31 downto 0) := (others => '0');
|
|
signal crs_updated : std_ulogic_vector(31 downto 0);
|
|
signal xerc : xer_common_t := xerc_init;
|
|
signal xerc_updated : xer_common_t;
|
|
begin
|
|
cr_create_0: process(all)
|
|
variable hi, lo : integer := 0;
|
|
variable cr_tmp : std_ulogic_vector(31 downto 0) := (others => '0');
|
|
begin
|
|
cr_tmp := crs;
|
|
|
|
for i in 0 to 7 loop
|
|
if w_in.write_cr_mask(i) = '1' then
|
|
lo := i*4;
|
|
hi := lo + 3;
|
|
cr_tmp(hi downto lo) := w_in.write_cr_data(hi downto lo);
|
|
end if;
|
|
end loop;
|
|
|
|
crs_updated <= cr_tmp;
|
|
|
|
if w_in.write_xerc_enable = '1' then
|
|
xerc_updated <= w_in.write_xerc_data;
|
|
else
|
|
xerc_updated <= xerc;
|
|
end if;
|
|
|
|
end process;
|
|
|
|
-- synchronous writes
|
|
cr_write_0: process(clk)
|
|
begin
|
|
if rising_edge(clk) then
|
|
if w_in.write_cr_enable = '1' then
|
|
report "Writing " & to_hstring(w_in.write_cr_data) & " to CR mask " & to_hstring(w_in.write_cr_mask);
|
|
crs <= crs_updated;
|
|
end if;
|
|
if w_in.write_xerc_enable = '1' then
|
|
report "Writing XERC";
|
|
xerc <= xerc_updated;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- asynchronous reads
|
|
cr_read_0: process(all)
|
|
begin
|
|
-- just return the entire CR to make mfcrf easier for now
|
|
if d_in.read = '1' then
|
|
report "Reading CR " & to_hstring(crs_updated);
|
|
end if;
|
|
d_out.read_cr_data <= crs_updated;
|
|
d_out.read_xerc_data <= xerc_updated;
|
|
end process;
|
|
|
|
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;
|
|
end generate;
|
|
|
|
cf_log: if LOG_LENGTH > 0 generate
|
|
signal log_data : std_ulogic_vector(12 downto 0);
|
|
begin
|
|
cr_log: process(clk)
|
|
begin
|
|
if rising_edge(clk) then
|
|
log_data <= w_in.write_cr_enable &
|
|
w_in.write_cr_data(31 downto 28) &
|
|
w_in.write_cr_mask;
|
|
end if;
|
|
end process;
|
|
log_out <= log_data;
|
|
end generate;
|
|
|
|
end architecture behaviour;
|