1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-01-11 23:43:15 +00:00
Paul Mackerras 813e2317bf execute1: Restructure to separate out execution of side effects
We now have a record that represents the actions taken in executing an
instruction, and a process that computes that for the incoming
instruction.  We no longer have 'current' or 'r.cur_instr', instead
things like the destination register are put into r.e in the first
cycle of an instruction and not reinitialized in subsequent busy
cycles.

For mfspr and mtspr, we now decode "slow" SPR numbers (those SPRs that
are not stored in the register file) to a new "spr_selector" record
in decode1 (excluding those in the loadstore unit).  With this, the
result for mfspr is determined in the data path.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
2022-07-22 12:10:06 +10:00

124 lines
3.7 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 SO=" & std_ulogic'image(xerc_updated.so) &
" OV=" & std_ulogic'image(xerc_updated.ov) &
" CA=" & std_ulogic'image(xerc_updated.ca) &
" OV32=" & std_ulogic'image(xerc_updated.ov32) &
" CA32=" & std_ulogic'image(xerc_updated.ca32);
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;