regfile.vhd 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. use ieee.std_logic_misc.all;
  5. use work.core_pkg.all;
  6. entity regfile is
  7. port (
  8. clk : in std_logic;
  9. res_n : in std_logic;
  10. stall : in std_logic;
  11. rdaddr1, rdaddr2 : in reg_adr_type;
  12. rddata1, rddata2 : out data_type;
  13. wraddr : in reg_adr_type;
  14. wrdata : in data_type;
  15. regwrite : in std_logic
  16. );
  17. end entity;
  18. architecture rtl of regfile is
  19. type data_arr is array(0 to 2**REG_BITS-1) of data_type;
  20. signal reg : data_arr := (others => (others => '0'));
  21. signal rdaddr1_cur : reg_adr_type := (others => '0');
  22. signal rdaddr2_cur : reg_adr_type := (others => '0');
  23. begin
  24. sync : process(all)
  25. begin
  26. if res_n = '0' then
  27. reg <= (others => (others => '0'));
  28. rdaddr1_cur <= (others => '0');
  29. rdaddr2_cur <= (others => '0');
  30. elsif rising_edge(clk) then
  31. if stall = '0' then
  32. rdaddr1_cur <= rdaddr1;
  33. rdaddr2_cur <= rdaddr2;
  34. if regwrite = '1' and or_reduce(wraddr) = '1'then
  35. reg(to_integer(unsigned(wraddr))) <= wrdata;
  36. end if;
  37. end if;
  38. end if;
  39. end process;
  40. read_control : process(all)
  41. begin
  42. rddata1 <= reg(to_integer(unsigned(rdaddr1_cur)));
  43. rddata2 <= reg(to_integer(unsigned(rdaddr2_cur)));
  44. if regwrite = '1' and unsigned(wraddr) >= unsigned(ZERO_REG) and stall = '0' then -- >= comparison saves some fmax (quartus is witchcraft)
  45. if rdaddr1_cur = wraddr then
  46. rddata1 <= wrdata;
  47. end if;
  48. if rdaddr2_cur = wraddr then
  49. rddata2 <= wrdata;
  50. end if;
  51. end if;
  52. end process;
  53. end architecture;