| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -11,157 +11,157 @@ use work.wishbone_types.all;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				-- In this cycle we read or write any data and do sign extension and update if required.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				entity loadstore2 is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					port (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						clk   : in std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    port (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        clk   : in std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						l_in  : in Loadstore1ToLoadstore2Type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						w_out : out Loadstore2ToWritebackType;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        l_in  : in Loadstore1ToLoadstore2Type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        w_out : out Loadstore2ToWritebackType;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						m_in  : in wishbone_slave_out;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						m_out : out wishbone_master_out
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        m_in  : in wishbone_slave_out;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        m_out : out wishbone_master_out
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				end loadstore2;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				architecture behave of loadstore2 is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal l_saved : Loadstore1ToLoadstore2Type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal w_tmp   : Loadstore2ToWritebackType;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal m_tmp   : wishbone_master_out;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					type state_t is (IDLE, WAITING_FOR_READ_ACK, WAITING_FOR_WRITE_ACK);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal state   : state_t := IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					function length_to_sel(length : in std_logic_vector(3 downto 0)) return std_ulogic_vector is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case length is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							when "0001" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								return "00000001";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							when "0010" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								return "00000011";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							when "0100" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								return "00001111";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							when "1000" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								return "11111111";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							when others =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								return "00000000";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end function length_to_sel;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					function wishbone_data_shift(address : in std_ulogic_vector(63 downto 0)) return natural is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return to_integer(unsigned(address(2 downto 0))) * 8;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end function wishbone_data_shift;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					function wishbone_data_sel(size : in std_logic_vector(3 downto 0); address : in std_logic_vector(63 downto 0)) return std_ulogic_vector is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return std_ulogic_vector(shift_left(unsigned(length_to_sel(size)), to_integer(unsigned(address(2 downto 0)))));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end function wishbone_data_sel;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal l_saved : Loadstore1ToLoadstore2Type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal w_tmp   : Loadstore2ToWritebackType;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal m_tmp   : wishbone_master_out;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    type state_t is (IDLE, WAITING_FOR_READ_ACK, WAITING_FOR_WRITE_ACK);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal state   : state_t := IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    function length_to_sel(length : in std_logic_vector(3 downto 0)) return std_ulogic_vector is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        case length is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when "0001" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                return "00000001";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when "0010" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                return "00000011";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when "0100" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                return "00001111";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when "1000" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                return "11111111";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when others =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                return "00000000";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end function length_to_sel;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    function wishbone_data_shift(address : in std_ulogic_vector(63 downto 0)) return natural is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return to_integer(unsigned(address(2 downto 0))) * 8;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end function wishbone_data_shift;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    function wishbone_data_sel(size : in std_logic_vector(3 downto 0); address : in std_logic_vector(63 downto 0)) return std_ulogic_vector is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return std_ulogic_vector(shift_left(unsigned(length_to_sel(size)), to_integer(unsigned(address(2 downto 0)))));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end function wishbone_data_sel;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					w_out <= w_tmp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					m_out <= m_tmp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					loadstore2_0: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						variable tmp : std_ulogic_vector(63 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						variable data : std_ulogic_vector(63 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						variable sign_extend_byte_reverse : std_ulogic_vector(1 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							tmp := (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							data := (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							w_tmp <= Loadstore2ToWritebackInit;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							l_saved <= l_saved;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							case_0: case state is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							when IDLE =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if l_in.valid = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									m_tmp <= wishbone_master_out_init;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									m_tmp.sel <= wishbone_data_sel(l_in.length, l_in.addr);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									m_tmp.adr <= l_in.addr(63 downto 3) & "000";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									m_tmp.cyc <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									m_tmp.stb <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									l_saved <= l_in;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									if l_in.load = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										m_tmp.we <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										-- Load with update instructions write two GPR destinations.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										-- We don't want the expense of two write ports, so make it
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										-- single in the pipeline and write back the update GPR now
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										-- and the load once we get the data back. We'll have to
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										-- revisit this when loads can take exceptions.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if l_in.update = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											w_tmp.write_enable <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											w_tmp.write_reg <= l_in.update_reg;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											w_tmp.write_data <= l_in.addr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										state <= WAITING_FOR_READ_ACK;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										m_tmp.we <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										data := l_in.data;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										m_tmp.dat <= std_logic_vector(shift_left(unsigned(data), wishbone_data_shift(l_in.addr)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										assert l_in.sign_extend = '0' report "sign extension doesn't make sense for stores" severity failure;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										state <= WAITING_FOR_WRITE_ACK;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							when WAITING_FOR_READ_ACK =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if m_in.ack = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									tmp := std_logic_vector(shift_right(unsigned(m_in.dat), wishbone_data_shift(l_saved.addr)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									case to_integer(unsigned(l_saved.length)) is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when 0 =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when 1 =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									        data(7 downto 0) := tmp(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when 2 =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									        data(15 downto 0) := tmp(15 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when 4 =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									        data(31 downto 0) := tmp(31 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when 8 =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									        data(63 downto 0) := tmp(63 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when others =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										assert false report "invalid length" severity failure;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									sign_extend_byte_reverse := l_saved.sign_extend & l_saved.byte_reverse;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									case sign_extend_byte_reverse is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when "10" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									    data := sign_extend(data, to_integer(unsigned(l_saved.length)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when "01" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										data := byte_reverse(data, to_integer(unsigned(l_saved.length)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when others =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									w_tmp.write_data <= data;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									-- write data to register file
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									w_tmp.valid <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									w_tmp.write_enable <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									w_tmp.write_reg <= l_saved.write_reg;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									m_tmp <= wishbone_master_out_init;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							when WAITING_FOR_WRITE_ACK =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if m_in.ack = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									w_tmp.valid <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									if l_saved.update = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										w_tmp.write_enable <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										w_tmp.write_reg <= l_saved.update_reg;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										w_tmp.write_data <= l_saved.addr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									m_tmp <= wishbone_master_out_init;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end process;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    w_out <= w_tmp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    m_out <= m_tmp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    loadstore2_0: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable tmp : std_ulogic_vector(63 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable data : std_ulogic_vector(63 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable sign_extend_byte_reverse : std_ulogic_vector(1 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            tmp := (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            data := (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            w_tmp <= Loadstore2ToWritebackInit;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            l_saved <= l_saved;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            case_0: case state is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                when IDLE =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    if l_in.valid = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        m_tmp <= wishbone_master_out_init;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        m_tmp.sel <= wishbone_data_sel(l_in.length, l_in.addr);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        m_tmp.adr <= l_in.addr(63 downto 3) & "000";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        m_tmp.cyc <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        m_tmp.stb <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        l_saved <= l_in;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        if l_in.load = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            m_tmp.we <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            -- Load with update instructions write two GPR destinations.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            -- We don't want the expense of two write ports, so make it
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            -- single in the pipeline and write back the update GPR now
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            -- and the load once we get the data back. We'll have to
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            -- revisit this when loads can take exceptions.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            if l_in.update = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                w_tmp.write_enable <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                w_tmp.write_reg <= l_in.update_reg;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                w_tmp.write_data <= l_in.addr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            state <= WAITING_FOR_READ_ACK;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            m_tmp.we <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            data := l_in.data;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            m_tmp.dat <= std_logic_vector(shift_left(unsigned(data), wishbone_data_shift(l_in.addr)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            assert l_in.sign_extend = '0' report "sign extension doesn't make sense for stores" severity failure;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            state <= WAITING_FOR_WRITE_ACK;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                when WAITING_FOR_READ_ACK =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    if m_in.ack = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        tmp := std_logic_vector(shift_right(unsigned(m_in.dat), wishbone_data_shift(l_saved.addr)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        case to_integer(unsigned(l_saved.length)) is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            when 0 =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            when 1 =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                data(7 downto 0) := tmp(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            when 2 =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                data(15 downto 0) := tmp(15 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            when 4 =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                data(31 downto 0) := tmp(31 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            when 8 =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                data(63 downto 0) := tmp(63 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            when others =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                assert false report "invalid length" severity failure;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        sign_extend_byte_reverse := l_saved.sign_extend & l_saved.byte_reverse;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        case sign_extend_byte_reverse is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            when "10" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                data := sign_extend(data, to_integer(unsigned(l_saved.length)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            when "01" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                data := byte_reverse(data, to_integer(unsigned(l_saved.length)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            when others =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        w_tmp.write_data <= data;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        -- write data to register file
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        w_tmp.valid <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        w_tmp.write_enable <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        w_tmp.write_reg <= l_saved.write_reg;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        m_tmp <= wishbone_master_out_init;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                when WAITING_FOR_WRITE_ACK =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    if m_in.ack = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        w_tmp.valid <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        if l_saved.update = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            w_tmp.write_enable <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            w_tmp.write_reg <= l_saved.update_reg;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            w_tmp.write_data <= l_saved.addr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        m_tmp <= wishbone_master_out_init;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end process;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				end;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |