You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
microwatt/cr_file.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;