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

Subversion Repositories mlite

[/] [mlite/] [trunk/] [vhdl/] [reg_bank.vhd] - Blame information for rev 9

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

Line No. Rev Author Line
1 2 rhoads
---------------------------------------------------------------------
2
-- TITLE: Register Bank
3
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
-- DATE CREATED: 2/2/01
5
-- FILENAME: reg_bank.vhd
6
-- PROJECT: MIPS 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
--    Implements a register bank with 32 registers that are 32-bits wide.
11
--    There are two read-ports and one write port.
12
---------------------------------------------------------------------
13
library ieee;
14
use ieee.std_logic_1164.all;
15 8 rhoads
use ieee.std_logic_unsigned.all;  --needed for conv_integer
16 2 rhoads
use work.mips_pack.all;
17
 
18
entity reg_bank is
19
   port(clk            : in  std_logic;
20
        rs_index       : in  std_logic_vector(5 downto 0);
21
        rt_index       : in  std_logic_vector(5 downto 0);
22
        rd_index       : in  std_logic_vector(5 downto 0);
23
        reg_source_out : out std_logic_vector(31 downto 0);
24
        reg_target_out : out std_logic_vector(31 downto 0);
25
        reg_dest_new   : in  std_logic_vector(31 downto 0);
26
        intr_enable    : out std_logic);
27
end; --entity reg_bank
28
 
29 9 rhoads
 
30 8 rhoads
--------------------------------------------------------------------
31
-- Change mips_cpu.vhd to use the ram_block architecture.  
32 9 rhoads
-- The ram_block architecture attempts to use TWO dual-port memories.
33
-- For a tri-port memory with one write and two read ports then
34
-- remove dual_port_ram2 so only one tri-port memory will be created.
35 8 rhoads
-- According to the Xilinx answers database record #4075 this architecture
36
-- may cause Synplify to infer a synchronous dual-port RAM using RAM16x1D.  
37
-- For Altera use either a csdpram or lpm_ram_dq.
38 9 rhoads
-- I need feedback on this section!
39 8 rhoads
--------------------------------------------------------------------
40
architecture ram_block of reg_bank is
41 9 rhoads
   signal reg_status : std_logic;
42 8 rhoads
   type ram_type is array(31 downto 0) of std_logic_vector(31 downto 0);
43 9 rhoads
   signal dual_port_ram1 : ram_type;
44
   signal dual_port_ram2 : ram_type;
45 8 rhoads
 
46 9 rhoads
   --controls access to dual-port memories
47
   signal addr_a1, addr_a2, addr_b : std_logic_vector(4 downto 0);
48
   signal data_out1, data_out2     : std_logic_vector(31 downto 0);
49
   signal write_enable             : std_logic;
50 8 rhoads
begin
51
 
52
reg_proc: process(clk, rs_index, rt_index, rd_index, reg_dest_new,
53 9 rhoads
      reg_status, data_out1, data_out2)
54 8 rhoads
begin
55 9 rhoads
   --setup for first dual-port memory
56
   if rs_index = "101110" then  --reg_epc CP0 14
57
      addr_a1 <= "00000";
58
   else
59
      addr_a1 <= rs_index(4 downto 0);
60
   end if;
61 8 rhoads
   case rs_index is
62
   when "000000" => reg_source_out <= ZERO;
63
   when "101100" => reg_source_out <= ZERO(31 downto 1) & reg_status;
64
   when "111111" => reg_source_out <= ZERO(31 downto 8) & "00110000"; --intr vector
65 9 rhoads
   when others   => reg_source_out <= data_out1;
66 8 rhoads
   end case;
67
 
68 9 rhoads
   --setup for second dual-port memory
69
   addr_a2 <= rt_index(4 downto 0);
70 8 rhoads
   case rt_index is
71
   when "000000" => reg_target_out <= ZERO;
72 9 rhoads
   when others   => reg_target_out <= data_out2;
73 8 rhoads
   end case;
74
 
75 9 rhoads
   --setup second port (write port) for both dual-port memories
76
   if rd_index /= "000000" and rd_index /= "101100" then
77
      write_enable <= '1';
78
   else
79
      write_enable <= '0';
80
   end if;
81
   if rd_index = "101110" then  --reg_epc CP0 14
82
      addr_b <= "00000";
83
   else
84
      addr_b <= rd_index(4 downto 0);
85
   end if;
86
 
87 8 rhoads
   if rising_edge(clk) then
88 9 rhoads
      if rd_index = "101100" then
89
         reg_status <= reg_dest_new(0);
90
      elsif rd_index = "101110" then  --reg_epc CP0 14
91
         reg_status <= '0';           --disable interrupts
92
      end if;
93 8 rhoads
   end if;
94
 
95
   intr_enable <= reg_status;
96 9 rhoads
end process;
97 8 rhoads
 
98 9 rhoads
 
99
ram_proc: process(clk, addr_a1, addr_a2, addr_b, reg_dest_new,
100
      write_enable, dual_port_ram1, dual_port_ram2)
101
begin
102
   -- Simulate two dual-port RAMs
103
   data_out1 <= dual_port_ram1(conv_integer(addr_a1));
104
   data_out2 <= dual_port_ram2(conv_integer(addr_a2));
105
   if rising_edge(clk) then
106
      if write_enable = '1' then
107
         dual_port_ram1(conv_integer(addr_b)) <= reg_dest_new;
108
         dual_port_ram2(conv_integer(addr_b)) <= reg_dest_new;
109
      end if;
110
   end if;
111
 
112
 
113
   -- Simulate one tri-port RAM
114
   -- Remember to comment out dual_port_ram2
115
--   data_out1 <= dual_port_ram1(conv_integer(addr_a1));
116
--   data_out2 <= dual_port_ram1(conv_integer(addr_a2));
117
--   if rising_edge(clk) then
118
--      if write_enable = '1' then
119
--         dual_port_ram1(conv_integer(addr_b)) <= reg_dest_new;
120
--      end if;
121
--   end if;
122
 
123
 
124
   -- Generic Two-Port Synchronous RAM
125
   -- generic_tpram can be obtained from:
126
   -- http://www.opencores.org/cvsweb.shtml/generic_memories/
127
   -- Supports ASICs (Artisan, Avant, and Virage) and Xilinx FPGA
128
   -- Remember to comment out dual_port_ram1 and dual_port_ram2
129
--   bank1 : generic_tpram port map (
130
--      clk_a  => clk,
131
--      rst_a  => '0',
132
--      ce_a   => '1',
133
--      we_a   => '0',
134
--      oe_a   => '1',
135
--      addr_a => addr_a1,
136
--      di_a   => ZERO,
137
--      do_a   => data_out1,
138
--
139
--      clk_b  => clk,
140
--      rst_b  => '0',
141
--      ce_b   => '1',
142
--      we_b   => write_enable,
143
--      oe_b   => '0',
144
--      addr_b => addr_b,
145
--      di_a   => reg_dest_new);
146
--
147
--   bank2 : generic_tpram port map (
148
--      clk_a  => clk,
149
--      rst_a  => '0',
150
--      ce_a   => '1',
151
--      we_a   => '0',
152
--      oe_a   => '1',
153
--      addr_a => addr_a2,
154
--      di_a   => ZERO,
155
--      do_a   => data_out2,
156
--
157
--      clk_b  => clk,
158
--      rst_b  => '0',
159
--      ce_b   => '1',
160
--      we_b   => write_enable,
161
--      oe_b   => '0',
162
--      addr_b => addr_b,
163
--      di_a   => reg_dest_new);
164
 
165
 
166
   -- Xilinx mode using four 16x16 banks
167
   -- Remember to comment out dual_port_ram1 and dual_port_ram2
168
--   bank1_high: ramb4_s16_s16 port map (
169
--      clka  => clk,
170
--      rsta  => sig_false,
171
--      addra => addr_a1,
172
--      dia   => ZERO(31 downto 16),
173
--      ena   => sig_true,
174
--      wea   => sig_false,
175
--      doa   => data_out1(31 downto 16),
176
--
177
--      clkb  => clk,
178
--      rstb  => sig_false,
179
--      addrb => addr_b,
180
--      dib   => reg_dest_new(31 downto 16),
181
--      enb   => sig_true,
182
--      web   => write_enable);
183
--
184
--   bank1_low: ramb4_s16_s16 port map (
185
--      clka  => clk,
186
--      rsta  => sig_false,
187
--      addra => addr_a1,
188
--      dia   => ZERO(15 downto 0),
189
--      ena   => sig_true,
190
--      wea   => sig_false,
191
--      doa   => data_out1(15 downto 0),
192
--
193
--      clkb  => clk,
194
--      rstb  => sig_false,
195
--      addrb => addr_b,
196
--      dib   => reg_dest_new(15 downto 0),
197
--      enb   => sig_true,
198
--      web   => write_enable);
199
--
200
--   bank2_high: ramb4_s16_s16 port map (
201
--      clka  => clk,
202
--      rsta  => sig_false,
203
--      addra => addr_a2,
204
--      dia   => ZERO(31 downto 16),
205
--      ena   => sig_true,
206
--      wea   => sig_false,
207
--      doa   => data_out2(31 downto 16),
208
--
209
--      clkb  => clk,
210
--      rstb  => sig_false,
211
--      addrb => addr_b,
212
--      dib   => reg_dest_new(31 downto 16),
213
--      enb   => sig_true,
214
--      web   => write_enable);
215
--
216
--   bank2_low: ramb4_s16_s16 port map (
217
--      clka  => clk,
218
--      rsta  => sig_false,
219
--      addra => addr_a2,
220
--      dia   => ZERO(15 downto 0),
221
--      ena   => sig_true,
222
--      wea   => sig_false,
223
--      doa   => data_out2(15 downto 0),
224
--
225
--      clkb  => clk,
226
--      rstb  => sig_false,
227
--      addrb => addr_b,
228
--      dib   => reg_dest_new(15 downto 0),
229
--      enb   => sig_true,
230
--      web   => write_enable);
231
 
232 8 rhoads
end process;
233
 
234
end; --architecture ram_block
235
 
236
--------------------------------------------------------------------
237
 
238 2 rhoads
architecture logic of reg_bank is
239
   signal reg31, reg01, reg02, reg03 : std_logic_vector(31 downto 0);
240
   --For Altera simulations, comment out reg04 through reg30
241
   signal reg04, reg05, reg06, reg07 : std_logic_vector(31 downto 0);
242
   signal reg08, reg09, reg10, reg11 : std_logic_vector(31 downto 0);
243
   signal reg12, reg13, reg14, reg15 : std_logic_vector(31 downto 0);
244
   signal reg16, reg17, reg18, reg19 : std_logic_vector(31 downto 0);
245
   signal reg20, reg21, reg22, reg23 : std_logic_vector(31 downto 0);
246
   signal reg24, reg25, reg26, reg27 : std_logic_vector(31 downto 0);
247
   signal reg28, reg29, reg30        : std_logic_vector(31 downto 0);
248
   signal reg_epc                    : std_logic_vector(31 downto 0);
249
   signal reg_status                 : std_logic;
250
begin
251
 
252
reg_proc: process(clk, rs_index, rt_index, rd_index, reg_dest_new,
253
   reg31, reg01, reg02, reg03, reg04, reg05, reg06, reg07,
254
   reg08, reg09, reg10, reg11, reg12, reg13, reg14, reg15,
255
   reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23,
256
   reg24, reg25, reg26, reg27, reg28, reg29, reg30,
257
   reg_epc, reg_status)
258
begin
259
   case rs_index is
260
   when "000000" => reg_source_out <= ZERO;
261
   when "000001" => reg_source_out <= reg01;
262
   when "000010" => reg_source_out <= reg02;
263
   when "000011" => reg_source_out <= reg03;
264
   when "000100" => reg_source_out <= reg04;
265
   when "000101" => reg_source_out <= reg05;
266
   when "000110" => reg_source_out <= reg06;
267
   when "000111" => reg_source_out <= reg07;
268
   when "001000" => reg_source_out <= reg08;
269
   when "001001" => reg_source_out <= reg09;
270
   when "001010" => reg_source_out <= reg10;
271
   when "001011" => reg_source_out <= reg11;
272
   when "001100" => reg_source_out <= reg12;
273
   when "001101" => reg_source_out <= reg13;
274
   when "001110" => reg_source_out <= reg14;
275
   when "001111" => reg_source_out <= reg15;
276
   when "010000" => reg_source_out <= reg16;
277
   when "010001" => reg_source_out <= reg17;
278
   when "010010" => reg_source_out <= reg18;
279
   when "010011" => reg_source_out <= reg19;
280
   when "010100" => reg_source_out <= reg20;
281
   when "010101" => reg_source_out <= reg21;
282
   when "010110" => reg_source_out <= reg22;
283
   when "010111" => reg_source_out <= reg23;
284
   when "011000" => reg_source_out <= reg24;
285
   when "011001" => reg_source_out <= reg25;
286
   when "011010" => reg_source_out <= reg26;
287
   when "011011" => reg_source_out <= reg27;
288
   when "011100" => reg_source_out <= reg28;
289
   when "011101" => reg_source_out <= reg29;
290
   when "011110" => reg_source_out <= reg30;
291
   when "011111" => reg_source_out <= reg31;
292
   when "101100" => reg_source_out <= ZERO(31 downto 1) & reg_status;
293
   when "101110" => reg_source_out <= reg_epc;     --CP0 14
294 6 rhoads
   when "111111" => reg_source_out <= ZERO(31 downto 8) & "00110000"; --intr vector
295 2 rhoads
   when others =>   reg_source_out <= ZERO;
296
   end case;
297
 
298
   case rt_index is
299
   when "000000" => reg_target_out <= ZERO;
300
   when "000001" => reg_target_out <= reg01;
301
   when "000010" => reg_target_out <= reg02;
302
   when "000011" => reg_target_out <= reg03;
303
   when "000100" => reg_target_out <= reg04;
304
   when "000101" => reg_target_out <= reg05;
305
   when "000110" => reg_target_out <= reg06;
306
   when "000111" => reg_target_out <= reg07;
307
   when "001000" => reg_target_out <= reg08;
308
   when "001001" => reg_target_out <= reg09;
309
   when "001010" => reg_target_out <= reg10;
310
   when "001011" => reg_target_out <= reg11;
311
   when "001100" => reg_target_out <= reg12;
312
   when "001101" => reg_target_out <= reg13;
313
   when "001110" => reg_target_out <= reg14;
314
   when "001111" => reg_target_out <= reg15;
315
   when "010000" => reg_target_out <= reg16;
316
   when "010001" => reg_target_out <= reg17;
317
   when "010010" => reg_target_out <= reg18;
318
   when "010011" => reg_target_out <= reg19;
319
   when "010100" => reg_target_out <= reg20;
320
   when "010101" => reg_target_out <= reg21;
321
   when "010110" => reg_target_out <= reg22;
322
   when "010111" => reg_target_out <= reg23;
323
   when "011000" => reg_target_out <= reg24;
324
   when "011001" => reg_target_out <= reg25;
325
   when "011010" => reg_target_out <= reg26;
326
   when "011011" => reg_target_out <= reg27;
327
   when "011100" => reg_target_out <= reg28;
328
   when "011101" => reg_target_out <= reg29;
329
   when "011110" => reg_target_out <= reg30;
330
   when "011111" => reg_target_out <= reg31;
331
   when others =>   reg_target_out <= ZERO;
332
   end case;
333
 
334
   if rising_edge(clk) then
335 8 rhoads
--      assert reg_dest_new'last_event >= 100 ps
336 2 rhoads
--         report "Reg_dest timing error";
337
      case rd_index is
338
      when "000001" => reg01 <= reg_dest_new;
339
      when "000010" => reg02 <= reg_dest_new;
340
      when "000011" => reg03 <= reg_dest_new;
341
      when "000100" => reg04 <= reg_dest_new;
342
      when "000101" => reg05 <= reg_dest_new;
343
      when "000110" => reg06 <= reg_dest_new;
344
      when "000111" => reg07 <= reg_dest_new;
345
      when "001000" => reg08 <= reg_dest_new;
346
      when "001001" => reg09 <= reg_dest_new;
347
      when "001010" => reg10 <= reg_dest_new;
348
      when "001011" => reg11 <= reg_dest_new;
349
      when "001100" => reg12 <= reg_dest_new;
350
      when "001101" => reg13 <= reg_dest_new;
351
      when "001110" => reg14 <= reg_dest_new;
352
      when "001111" => reg15 <= reg_dest_new;
353
      when "010000" => reg16 <= reg_dest_new;
354
      when "010001" => reg17 <= reg_dest_new;
355
      when "010010" => reg18 <= reg_dest_new;
356
      when "010011" => reg19 <= reg_dest_new;
357
      when "010100" => reg20 <= reg_dest_new;
358
      when "010101" => reg21 <= reg_dest_new;
359
      when "010110" => reg22 <= reg_dest_new;
360
      when "010111" => reg23 <= reg_dest_new;
361
      when "011000" => reg24 <= reg_dest_new;
362
      when "011001" => reg25 <= reg_dest_new;
363
      when "011010" => reg26 <= reg_dest_new;
364
      when "011011" => reg27 <= reg_dest_new;
365
      when "011100" => reg28 <= reg_dest_new;
366
      when "011101" => reg29 <= reg_dest_new;
367
      when "011110" => reg30 <= reg_dest_new;
368
      when "011111" => reg31 <= reg_dest_new;
369
      when "101100" => reg_status <= reg_dest_new(0);
370
      when "101110" => reg_epc <= reg_dest_new;  --CP0 14
371
                       reg_status <= '0';        --disable interrupts
372
      when others =>
373
      end case;
374
   end if;
375
   intr_enable <= reg_status;
376
end process;
377
 
378
end; --architecture logic
379
 
380 8 rhoads
 

powered by: WebSVN 2.1.0

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