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;