OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

[/] [plasma/] [trunk/] [vhdl/] [mem_ctrl.vhd] - Blame information for rev 406

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.