You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 line
6.4KB

  1. ---------------------------------------------------------------------
  2. -- TITLE: Memory Controller
  3. -- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
  4. -- DATE CREATED: 1/31/01
  5. -- FILENAME: mem_ctrl.vhd
  6. -- PROJECT: Plasma CPU core
  7. -- COPYRIGHT: Software placed into the public domain by the author.
  8. -- Software 'as is' without warranty. Author liable for nothing.
  9. -- DESCRIPTION:
  10. -- Memory controller for the Plasma CPU.
  11. -- Supports Big or Little Endian mode.
  12. ---------------------------------------------------------------------
  13. library ieee;
  14. use ieee.std_logic_1164.all;
  15. use work.mlite_pack.all;
  16. entity mem_ctrl is
  17. port(clk : in std_logic;
  18. reset_in : in std_logic;
  19. pause_in : in std_logic;
  20. nullify_op : in std_logic;
  21. address_pc : in std_logic_vector(31 downto 2);
  22. opcode_out : out std_logic_vector(31 downto 0);
  23. address_in : in std_logic_vector(31 downto 0);
  24. mem_source : in mem_source_type;
  25. data_write : in std_logic_vector(31 downto 0);
  26. data_read : out std_logic_vector(31 downto 0);
  27. pause_out : out std_logic;
  28. address_next : out std_logic_vector(31 downto 2);
  29. byte_we_next : out std_logic_vector(3 downto 0);
  30. address : out std_logic_vector(31 downto 2);
  31. byte_we : out std_logic_vector(3 downto 0);
  32. data_w : out std_logic_vector(31 downto 0);
  33. data_r : in std_logic_vector(31 downto 0));
  34. end; --entity mem_ctrl
  35. architecture logic of mem_ctrl is
  36. --"00" = big_endian; "11" = little_endian
  37. constant ENDIAN_MODE : std_logic_vector(1 downto 0) := "00";
  38. signal opcode_reg : std_logic_vector(31 downto 0);
  39. signal next_opcode_reg : std_logic_vector(31 downto 0);
  40. signal address_reg : std_logic_vector(31 downto 2);
  41. signal byte_we_reg : std_logic_vector(3 downto 0);
  42. signal mem_state_reg : std_logic;
  43. constant STATE_ADDR : std_logic := '0';
  44. constant STATE_ACCESS : std_logic := '1';
  45. begin
  46. mem_proc: process(clk, reset_in, pause_in, nullify_op,
  47. address_pc, address_in, mem_source, data_write,
  48. data_r, opcode_reg, next_opcode_reg, mem_state_reg,
  49. address_reg, byte_we_reg)
  50. variable address_var : std_logic_vector(31 downto 2);
  51. variable data_read_var : std_logic_vector(31 downto 0);
  52. variable data_write_var : std_logic_vector(31 downto 0);
  53. variable opcode_next : std_logic_vector(31 downto 0);
  54. variable byte_we_var : std_logic_vector(3 downto 0);
  55. variable mem_state_next : std_logic;
  56. variable pause_var : std_logic;
  57. variable bits : std_logic_vector(1 downto 0);
  58. begin
  59. byte_we_var := "0000";
  60. pause_var := '0';
  61. data_read_var := ZERO;
  62. data_write_var := ZERO;
  63. mem_state_next := mem_state_reg;
  64. opcode_next := opcode_reg;
  65. case mem_source is
  66. when MEM_READ32 =>
  67. data_read_var := data_r;
  68. when MEM_READ16 | MEM_READ16S =>
  69. if address_in(1) = ENDIAN_MODE(1) then
  70. data_read_var(15 downto 0) := data_r(31 downto 16);
  71. else
  72. data_read_var(15 downto 0) := data_r(15 downto 0);
  73. end if;
  74. if mem_source = MEM_READ16 or data_read_var(15) = '0' then
  75. data_read_var(31 downto 16) := ZERO(31 downto 16);
  76. else
  77. data_read_var(31 downto 16) := ONES(31 downto 16);
  78. end if;
  79. when MEM_READ8 | MEM_READ8S =>
  80. bits := address_in(1 downto 0) xor ENDIAN_MODE;
  81. case bits is
  82. when "00" => data_read_var(7 downto 0) := data_r(31 downto 24);
  83. when "01" => data_read_var(7 downto 0) := data_r(23 downto 16);
  84. when "10" => data_read_var(7 downto 0) := data_r(15 downto 8);
  85. when others => data_read_var(7 downto 0) := data_r(7 downto 0);
  86. end case;
  87. if mem_source = MEM_READ8 or data_read_var(7) = '0' then
  88. data_read_var(31 downto 8) := ZERO(31 downto 8);
  89. else
  90. data_read_var(31 downto 8) := ONES(31 downto 8);
  91. end if;
  92. when MEM_WRITE32 =>
  93. data_write_var := data_write;
  94. byte_we_var := "1111";
  95. when MEM_WRITE16 =>
  96. data_write_var := data_write(15 downto 0) & data_write(15 downto 0);
  97. if address_in(1) = ENDIAN_MODE(1) then
  98. byte_we_var := "1100";
  99. else
  100. byte_we_var := "0011";
  101. end if;
  102. when MEM_WRITE8 =>
  103. data_write_var := data_write(7 downto 0) & data_write(7 downto 0) &
  104. data_write(7 downto 0) & data_write(7 downto 0);
  105. bits := address_in(1 downto 0) xor ENDIAN_MODE;
  106. case bits is
  107. when "00" =>
  108. byte_we_var := "1000";
  109. when "01" =>
  110. byte_we_var := "0100";
  111. when "10" =>
  112. byte_we_var := "0010";
  113. when others =>
  114. byte_we_var := "0001";
  115. end case;
  116. when others =>
  117. end case;
  118. if mem_source = MEM_FETCH then --opcode fetch
  119. address_var := address_pc;
  120. opcode_next := data_r;
  121. mem_state_next := STATE_ADDR;
  122. else
  123. if mem_state_reg = STATE_ADDR then
  124. if pause_in = '0' then
  125. address_var := address_in(31 downto 2);
  126. mem_state_next := STATE_ACCESS;
  127. pause_var := '1';
  128. else
  129. address_var := address_pc;
  130. byte_we_var := "0000";
  131. end if;
  132. else --STATE_ACCESS
  133. if pause_in = '0' then
  134. address_var := address_pc;
  135. opcode_next := next_opcode_reg;
  136. mem_state_next := STATE_ADDR;
  137. byte_we_var := "0000";
  138. else
  139. address_var := address_in(31 downto 2);
  140. byte_we_var := "0000";
  141. end if;
  142. end if;
  143. end if;
  144. if nullify_op = '1' and pause_in = '0' then
  145. opcode_next := ZERO; --NOP after beql
  146. end if;
  147. if reset_in = '1' then
  148. mem_state_reg <= STATE_ADDR;
  149. opcode_reg <= ZERO;
  150. next_opcode_reg <= ZERO;
  151. address_reg <= ZERO(31 downto 2);
  152. byte_we_reg <= "0000";
  153. elsif rising_edge(clk) then
  154. if pause_in = '0' then
  155. address_reg <= address_var;
  156. byte_we_reg <= byte_we_var;
  157. mem_state_reg <= mem_state_next;
  158. opcode_reg <= opcode_next;
  159. if mem_state_reg = STATE_ADDR then
  160. next_opcode_reg <= data_r;
  161. end if;
  162. end if;
  163. end if;
  164. opcode_out <= opcode_reg;
  165. data_read <= data_read_var;
  166. pause_out <= pause_var;
  167. address_next <= address_var;
  168. byte_we_next <= byte_we_var;
  169. address <= address_reg;
  170. byte_we <= byte_we_reg;
  171. data_w <= data_write_var;
  172. end process; --data_proc
  173. end; --architecture logic