memu.vhd 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. use work.mem_pkg.all;
  5. use work.core_pkg.all;
  6. use work.op_pkg.all;
  7. entity memu is
  8. port (
  9. -- to mem
  10. op : in memu_op_type;
  11. A : in data_type;
  12. W : in data_type;
  13. R : out data_type := (others => '0');
  14. B : out std_logic := '0';
  15. XL : out std_logic := '0';
  16. XS : out std_logic := '0';
  17. -- to memory controller
  18. D : in mem_in_type;
  19. M : out mem_out_type := MEM_OUT_NOP
  20. );
  21. end entity;
  22. architecture rtl of memu is
  23. type word_arr is array(0 to 3) of std_logic_vector(7 downto 0);
  24. -- write pipeline bytes
  25. alias W_0 : std_logic_vector(7 downto 0) is W(7 downto 0);
  26. alias W_1 : std_logic_vector(7 downto 0) is W(15 downto 8);
  27. alias W_2 : std_logic_vector(7 downto 0) is W(23 downto 16);
  28. alias W_3 : std_logic_vector(7 downto 0) is W(31 downto 24);
  29. signal W_arr : word_arr;
  30. -- read pipeline bytes
  31. alias R_0 : std_logic_vector(7 downto 0) is R(7 downto 0);
  32. alias R_1 : std_logic_vector(7 downto 0) is R(15 downto 8);
  33. alias R_2 : std_logic_vector(7 downto 0) is R(23 downto 16);
  34. alias R_3 : std_logic_vector(7 downto 0) is R(31 downto 24);
  35. signal R_arr : word_arr;
  36. -- write mem bytes
  37. alias MW_0 : std_logic_vector(7 downto 0) is M.wrdata(7 downto 0);
  38. alias MW_1 : std_logic_vector(7 downto 0) is M.wrdata(15 downto 8);
  39. alias MW_2 : std_logic_vector(7 downto 0) is M.wrdata(23 downto 16);
  40. alias MW_3 : std_logic_vector(7 downto 0) is M.wrdata(31 downto 24);
  41. signal MW_arr : word_arr;
  42. -- read mem bytes
  43. alias DR_0 : std_logic_vector(7 downto 0) is D.rddata(7 downto 0);
  44. alias DR_1 : std_logic_vector(7 downto 0) is D.rddata(15 downto 8);
  45. alias DR_2 : std_logic_vector(7 downto 0) is D.rddata(23 downto 16);
  46. alias DR_3 : std_logic_vector(7 downto 0) is D.rddata(31 downto 24);
  47. signal DR_arr : word_arr;
  48. -- adress alias
  49. alias A_byte : std_logic_vector(1 downto 0) is A(1 downto 0);
  50. -- signals
  51. -- signal exep_l, exep_s : std_logic;
  52. begin
  53. -- concurrent
  54. XL <= '1' when (op.memread = '1' and (
  55. ((op.memtype = MEM_H or op.memtype = MEM_HU) and A_byte(0) = '1') or -- cant access uneven half word
  56. ((op.memtype = MEM_W and A_byte /= "00") -- cant access word if not full
  57. )))
  58. else '0';
  59. XS <= '1' when (op.memwrite = '1' and (
  60. ((op.memtype = MEM_H or op.memtype = MEM_HU) and A_byte(0) = '1') or -- cant write uneven half word
  61. ((op.memtype = MEM_W and A_byte /= "00") -- cant write word if not full
  62. )))
  63. else '0';
  64. M.address <= A(15 downto 2);
  65. W_arr <= (W_0, W_1, W_2, W_3);
  66. R_0 <= R_arr(0);
  67. R_1 <= R_arr(1);
  68. R_2 <= R_arr(2);
  69. R_3 <= R_arr(3);
  70. MW_0 <= MW_arr(0);
  71. MW_1 <= MW_arr(1);
  72. MW_2 <= MW_arr(2);
  73. MW_3 <= MW_arr(3);
  74. DR_arr <= (DR_0, DR_1, DR_2, DR_3);
  75. M.address <= A(15 downto 2);
  76. -- memop
  77. M.rd <= op.memread when XL = '0' else '0';
  78. M.wr <= op.memwrite when XS = '0' else '0';
  79. B <= (op.memread and not XL) or D.busy;
  80. -- synchronous
  81. translation : process(all) -- very confuse but looks cool right :3
  82. begin
  83. case op.memtype is
  84. when MEM_B =>
  85. R_arr <= (0 => DR_arr(to_integer(unsigned(not A_byte))), others => (others => DR_arr(to_integer(unsigned(not A_byte)))(7)));
  86. MW_arr <= (others => (others => '-'));
  87. MW_arr(to_integer(unsigned(not A_byte))) <= W_arr(0);
  88. M.byteena <= (others => '0');
  89. M.byteena(to_integer(unsigned(not A_byte))) <= '1';
  90. when MEM_BU =>
  91. R_arr <= (0 => DR_arr(to_integer(unsigned(not A_byte))), others => (others => '0'));
  92. MW_arr <= (others => (others => '-'));
  93. MW_arr(to_integer(unsigned(not A_byte))) <= W_arr(0);
  94. M.byteena <= (others => '0');
  95. M.byteena(to_integer(unsigned(not A_byte))) <= '1';
  96. when MEM_H =>
  97. if A_byte(1) = '0' then
  98. R_arr <= (0 => DR_arr(3), 1 => DR_arr(2), others => (others => DR_arr(2)(7)));
  99. MW_arr <= (3 => W_arr(0), 2 => W_arr(1), others => (others => '-'));
  100. M.byteena <= "1100";
  101. else
  102. R_arr <= (0 => DR_arr(1), 1 => DR_arr(0), others => (others => DR_arr(0)(7)));
  103. MW_arr <= (1 => W_arr(0), 0 => W_arr(1), others => (others => '-'));
  104. M.byteena <= "0011";
  105. end if;
  106. when MEM_HU =>
  107. if A_byte(1) = '0' then
  108. R_arr <= (0 => DR_arr(3), 1 => DR_arr(2), others => (others => '0'));
  109. MW_arr <= (3 => W_arr(0), 2 => W_arr(1), others => (others => '-'));
  110. M.byteena <= "1100";
  111. else
  112. R_arr <= (0 => DR_arr(1), 1 => DR_arr(0), others => (others => '0'));
  113. MW_arr <= (1 => W_arr(0), 0 => W_arr(1), others => (others => '-'));
  114. M.byteena <= "0011";
  115. end if;
  116. when MEM_W =>
  117. R_arr <= (0 => DR_arr(3), 1 => DR_arr(2), 2 => DR_arr(1), 3 => DR_arr(0));
  118. MW_arr <= (0 => W_arr(3), 1 => W_arr(2), 2 => W_arr(1), 3 => W_arr(0));
  119. M.byteena <= "1111";
  120. end case;
  121. end process;
  122. end architecture;