Root/plasma/logic/mem_ctrl.vhd

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---------------------------------------------------------------------
13library ieee;
14use ieee.std_logic_1164.all;
15use work.mlite_pack.all;
16
17entity mem_ctrl is
18   port(clk : in std_logic;
19        reset_in : in std_logic;
20        pause_in : in std_logic;
21        nullify_op : in std_logic;
22        address_pc : in std_logic_vector(31 downto 2);
23        opcode_out : out std_logic_vector(31 downto 0);
24
25        address_in : in std_logic_vector(31 downto 0);
26        mem_source : in mem_source_type;
27        data_write : in std_logic_vector(31 downto 0);
28        data_read : out std_logic_vector(31 downto 0);
29        pause_out : out std_logic;
30        
31        address_next : out std_logic_vector(31 downto 2);
32        byte_we_next : out std_logic_vector(3 downto 0);
33
34        address : out std_logic_vector(31 downto 2);
35        byte_we : out std_logic_vector(3 downto 0);
36        data_w : out std_logic_vector(31 downto 0);
37        data_r : in std_logic_vector(31 downto 0));
38end; --entity mem_ctrl
39
40architecture logic of mem_ctrl is
41   --"00" = big_endian; "11" = little_endian
42   constant ENDIAN_MODE : std_logic_vector(1 downto 0) := "00";
43   signal opcode_reg : std_logic_vector(31 downto 0);
44   signal next_opcode_reg : std_logic_vector(31 downto 0);
45   signal address_reg : std_logic_vector(31 downto 2);
46   signal byte_we_reg : std_logic_vector(3 downto 0);
47
48   signal mem_state_reg : std_logic;
49   constant STATE_ADDR : std_logic := '0';
50   constant STATE_ACCESS : std_logic := '1';
51
52begin
53
54mem_proc: process(clk, reset_in, pause_in, nullify_op,
55                  address_pc, address_in, mem_source, data_write,
56                  data_r, opcode_reg, next_opcode_reg, mem_state_reg,
57                  address_reg, byte_we_reg)
58   variable address_var : std_logic_vector(31 downto 2);
59   variable data_read_var : std_logic_vector(31 downto 0);
60   variable data_write_var : std_logic_vector(31 downto 0);
61   variable opcode_next : std_logic_vector(31 downto 0);
62   variable byte_we_var : std_logic_vector(3 downto 0);
63   variable mem_state_next : std_logic;
64   variable pause_var : std_logic;
65   variable bits : std_logic_vector(1 downto 0);
66begin
67   byte_we_var := "0000";
68   pause_var := '0';
69   data_read_var := ZERO;
70   data_write_var := ZERO;
71   mem_state_next := mem_state_reg;
72   opcode_next := opcode_reg;
73
74   case mem_source is
75   when MEM_READ32 =>
76      data_read_var := data_r;
77
78   when MEM_READ16 | MEM_READ16S =>
79      if address_in(1) = ENDIAN_MODE(1) then
80         data_read_var(15 downto 0) := data_r(31 downto 16);
81      else
82         data_read_var(15 downto 0) := data_r(15 downto 0);
83      end if;
84      if mem_source = MEM_READ16 or data_read_var(15) = '0' then
85         data_read_var(31 downto 16) := ZERO(31 downto 16);
86      else
87         data_read_var(31 downto 16) := ONES(31 downto 16);
88      end if;
89
90   when MEM_READ8 | MEM_READ8S =>
91      bits := address_in(1 downto 0) xor ENDIAN_MODE;
92      case bits is
93      when "00" => data_read_var(7 downto 0) := data_r(31 downto 24);
94      when "01" => data_read_var(7 downto 0) := data_r(23 downto 16);
95      when "10" => data_read_var(7 downto 0) := data_r(15 downto 8);
96      when others => data_read_var(7 downto 0) := data_r(7 downto 0);
97      end case;
98      if mem_source = MEM_READ8 or data_read_var(7) = '0' then
99         data_read_var(31 downto 8) := ZERO(31 downto 8);
100      else
101         data_read_var(31 downto 8) := ONES(31 downto 8);
102      end if;
103
104   when MEM_WRITE32 =>
105      data_write_var := data_write;
106      byte_we_var := "1111";
107
108   when MEM_WRITE16 =>
109      data_write_var := data_write(15 downto 0) & data_write(15 downto 0);
110      if address_in(1) = ENDIAN_MODE(1) then
111         byte_we_var := "1100";
112      else
113         byte_we_var := "0011";
114      end if;
115
116   when MEM_WRITE8 =>
117      data_write_var := data_write(7 downto 0) & data_write(7 downto 0) &
118                  data_write(7 downto 0) & data_write(7 downto 0);
119      bits := address_in(1 downto 0) xor ENDIAN_MODE;
120      case bits is
121      when "00" =>
122         byte_we_var := "1000";
123      when "01" =>
124         byte_we_var := "0100";
125      when "10" =>
126         byte_we_var := "0010";
127      when others =>
128         byte_we_var := "0001";
129      end case;
130
131   when others =>
132   end case;
133
134   if mem_source = MEM_FETCH then --opcode fetch
135      address_var := address_pc;
136      opcode_next := data_r;
137      mem_state_next := STATE_ADDR;
138   else
139      if mem_state_reg = STATE_ADDR then
140         if pause_in = '0' then
141            address_var := address_in(31 downto 2);
142            mem_state_next := STATE_ACCESS;
143            pause_var := '1';
144         else
145            address_var := address_pc;
146            byte_we_var := "0000";
147         end if;
148      else --STATE_ACCESS
149         if pause_in = '0' then
150            address_var := address_pc;
151            opcode_next := next_opcode_reg;
152            mem_state_next := STATE_ADDR;
153            byte_we_var := "0000";
154         else
155            address_var := address_in(31 downto 2);
156            byte_we_var := "0000";
157         end if;
158      end if;
159   end if;
160
161   if nullify_op = '1' and pause_in = '0' then
162      opcode_next := ZERO; --NOP after beql
163   end if;
164
165   if reset_in = '1' then
166      mem_state_reg <= STATE_ADDR;
167      opcode_reg <= ZERO;
168      next_opcode_reg <= ZERO;
169      address_reg <= ZERO(31 downto 2);
170      byte_we_reg <= "0000";
171   elsif rising_edge(clk) then
172      if pause_in = '0' then
173         address_reg <= address_var;
174         byte_we_reg <= byte_we_var;
175         mem_state_reg <= mem_state_next;
176         opcode_reg <= opcode_next;
177         if mem_state_reg = STATE_ADDR then
178            next_opcode_reg <= data_r;
179         end if;
180      end if;
181   end if;
182
183   opcode_out <= opcode_reg;
184   data_read <= data_read_var;
185   pause_out <= pause_var;
186
187   address_next <= address_var;
188   byte_we_next <= byte_we_var;
189
190   address <= address_reg;
191   byte_we <= byte_we_reg;
192   data_w <= data_write_var;
193
194end process; --data_proc
195
196end; --architecture logic
197

Archive Download this file

Branches:
master



interactive