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.
		
		
		
		
		
			
		
			
				
	
	
		
			124 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			VHDL
		
	
			
		
		
	
	
			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;
 |