library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; use work.mbl_pkg.all; use work.lx_rocon_pkg.all; -- 32x32b General Puprose Registers for Tumbl Core -- Uses 3 BRAMs entity lx_rocon_gprf_abd is port ( clk_i : in std_logic; rst_i : in std_logic; clken_i : in std_logic; gprf_finish_wrb_mem_i : in std_logic; -- ID2GPRF_i : in ID2GPRF_Type; MEM_WRB_i : in WRB_Type; GPRF2EX_o : out GPRF2EX_Type ); end entity lx_rocon_gprf_abd; architecture rtl of lx_rocon_gprf_abd is signal rdix_rA_s : std_logic_vector(4 downto 0); signal rdix_rB_s : std_logic_vector(4 downto 0); signal rdix_rD_s : std_logic_vector(4 downto 0); signal wre_rD_s : std_logic; signal ena_rA_s : std_logic; signal ena_rB_s : std_logic; signal ena_rD_s : std_logic; signal clken_s : std_logic; signal wthru_rA_r : std_logic; signal rA_DOA_s : std_logic_vector(31 downto 0); signal rA_DOB_s : std_logic_vector(31 downto 0); signal wthru_rB_r : std_logic; signal rB_DOA_s : std_logic_vector(31 downto 0); signal rB_DOB_s : std_logic_vector(31 downto 0); signal wthru_rD_r : std_logic; signal rD_DOA_s : std_logic_vector(31 downto 0); signal rD_DOB_s : std_logic_vector(31 downto 0); begin -- writeback if WRB_EX or WRB_MEM, but not when r0 involved wre_rD_s <= '1' when ((MEM_WRB_i.wrb_Action /= NO_WRB) and (MEM_WRB_i.wrix_rD /= "00000")) else '0'; -- ports A should remain unchanged when clken_i is low, while also -- reading from the same address as will be written to should be disabled -- (setup for writeThru of data_rD) ena_rA_s <= '1' when rst_i = '1' else clken_i when ((ID2GPRF_i.rdix_rA /= MEM_WRB_i.wrix_rD)) else '0'; ena_rB_s <= '1' when rst_i = '1' else clken_i when ((ID2GPRF_i.rdix_rB /= MEM_WRB_i.wrix_rD)) else '0'; ena_rD_s <= '1' when rst_i = '1' else clken_i when ((ID2GPRF_i.rdix_rD /= MEM_WRB_i.wrix_rD)) else '0'; -- make sure reset does it's job (writes 0 to R0 and resets the ports) clken_s <= rst_i or clken_i; rdix_rA_s <= (others => '0') when rst_i = '1' else ID2GPRF_i.rdix_rA; rdix_rB_s <= (others => '0') when rst_i = '1' else ID2GPRF_i.rdix_rB; rdix_rD_s <= (others => '0') when rst_i = '1' else ID2GPRF_i.rdix_rD; GPRF2EX_o.data_rA <= rA_DOA_s when (wthru_rA_r = '0') else rA_DOB_s; GPRF2EX_o.data_rB <= rB_DOA_s when (wthru_rB_r = '0') else rB_DOB_s; GPRF2EX_o.data_rD <= rD_DOA_s when (wthru_rD_r = '0') else rD_DOB_s; -- also for rD ??? I_rA: xilinx_dualport_bram generic map ( byte_width => 32, we_width => 1, address_width => 5, port_a_type => WRITE_FIRST, port_b_type => WRITE_FIRST ) port map ( clka => clk_i, rsta => rst_i, ena => ena_rA_s, wea(0) => rst_i, addra => rdix_rA_s, dina => C_32_ZEROS, douta => rA_DOA_s, -- Write-back clkb => clk_i, rstb => rst_i, enb => clken_s, web(0) => wre_rD_s, addrb => MEM_WRB_i.wrix_rD, dinb => MEM_WRB_i.data_rD, doutb => rA_DOB_s ); I_rB: xilinx_dualport_bram generic map ( byte_width => 32, we_width => 1, address_width => 5, port_a_type => WRITE_FIRST, port_b_type => WRITE_FIRST ) port map ( clka => clk_i, rsta => rst_i, ena => ena_rB_s, wea(0) => rst_i, addra => rdix_rB_s, dina => C_32_ZEROS, douta => rB_DOA_s, -- Write-back clkb => clk_i, rstb => rst_i, enb => clken_s, web(0) => wre_rD_s, addrb => MEM_WRB_i.wrix_rD, dinb => MEM_WRB_i.data_rD, doutb => rB_DOB_s ); I_rD: xilinx_dualport_bram generic map ( byte_width => 32, we_width => 1, address_width => 5, port_a_type => WRITE_FIRST, port_b_type => WRITE_FIRST ) port map ( clka => clk_i, rsta => rst_i, ena => ena_rD_s, wea(0) => rst_i, addra => rdix_rD_s, dina => C_32_ZEROS, douta => rD_DOA_s, -- Write-back clkb => clk_i, rstb => rst_i, enb => clken_s, web(0) => wre_rD_s, addrb => MEM_WRB_i.wrix_rD, dinb => MEM_WRB_i.data_rD, doutb => rD_DOB_s ); p_regd: process begin wait until clk_i'event and clk_i = '1'; if (clken_i = '1') then wthru_rA_r <= not ena_rA_s and not gprf_finish_wrb_mem_i; wthru_rB_r <= not ena_rB_s and not gprf_finish_wrb_mem_i; wthru_rD_r <= not ena_rD_s and not gprf_finish_wrb_mem_i; end if; end process; end architecture rtl;