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

Subversion Repositories pavr

[/] [pavr/] [trunk/] [src/] [pavr_register_file.vhd] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 doru
-- <File header>
2
-- Project
3
--    pAVR (pipelined AVR) is an 8 bit RISC controller, compatible with Atmel's
4
--    AVR core, but about 3x faster in terms of both clock frequency and MIPS.
5
--    The increase in speed comes from a relatively deep pipeline. The original
6
--    AVR core has only two pipeline stages (fetch and execute), while pAVR has
7
--    6 pipeline stages:
8
--       1. PM    (read Program Memory)
9
--       2. INSTR (load Instruction)
10
--       3. RFRD  (decode Instruction and read Register File)
11
--       4. OPS   (load Operands)
12
--       5. ALU   (execute ALU opcode or access Unified Memory)
13
--       6. RFWR  (write Register File)
14
-- Version
15
--    0.32
16
-- Date
17
--    2002 August 07
18
-- Author
19
--    Doru Cuturela, doruu@yahoo.com
20
-- License
21
--    This program is free software; you can redistribute it and/or modify
22
--    it under the terms of the GNU General Public License as published by
23
--    the Free Software Foundation; either version 2 of the License, or
24
--    (at your option) any later version.
25
--    This program is distributed in the hope that it will be useful,
26
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
27
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28
--    GNU General Public License for more details.
29
--    You should have received a copy of the GNU General Public License
30
--    along with this program; if not, write to the Free Software
31
--    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
32
-- </File header>
33
 
34
 
35
 
36
-- <File info>
37
-- This defines pAVR's Register File.
38
-- The Register File has 3 ports: 2 for reading and 1 for writing. All these
39
--    access all 32 locations in the register file. Apart from these 3 ports,
40
--    there are 3 special ports that access 16 bit pointer registers X, Y, Z, for
41
--    both reading and writing. The pointer registers are mapped on the register
42
--    file, at addresses 26-27 (pointer register X), 28-29 (Y) and 30-31 (Z).
43
-- Physically, the register file consists of a memory-like entity with 26 8 bit
44
--    locations, and 3 16 bit registers. Together, these form the 32 locations
45
--    of the register file. The physical separation of locations <26 and >=26 is
46
--    is invisible from outside.
47
-- Writing on the write port and on every pointer register port can be done
48
--    in parallel. However, if writing at the same time a location via the write
49
--    port and one of the pointer registers, writing via pointer register port
50
--    has priority.
51
-- </File info>
52
 
53
 
54
 
55
-- <File body>
56
library work;
57
use work.std_util.all;
58
use work.pavr_util.all;
59
use work.pavr_constants.all;
60
library IEEE;
61
use IEEE.std_logic_1164.all;
62
 
63
 
64
 
65
entity pavr_rf is
66
   port(
67
      pavr_rf_clk:     in std_logic;
68
      pavr_rf_res:     in std_logic;
69
      pavr_rf_syncres: in std_logic;
70
 
71
      -- Read port 1
72
      pavr_rf_rd1_addr: in  std_logic_vector(4 downto 0);
73
      pavr_rf_rd1_rd:   in  std_logic;
74
      pavr_rf_rd1_do:   out std_logic_vector(7 downto 0);
75
 
76
      -- Read port 2
77
      pavr_rf_rd2_addr: in  std_logic_vector(4 downto 0);
78
      pavr_rf_rd2_rd:   in  std_logic;
79
      pavr_rf_rd2_do:   out std_logic_vector(7 downto 0);
80
 
81
      -- Write port
82
      pavr_rf_wr_addr: in std_logic_vector(4 downto 0);
83
      pavr_rf_wr_wr:   in std_logic;
84
      pavr_rf_wr_di:   in std_logic_vector(7 downto 0);
85
 
86
      -- Pointer registers
87
      pavr_rf_x:    out std_logic_vector(15 downto 0);
88
      pavr_rf_x_wr: in  std_logic;
89
      pavr_rf_x_di: in  std_logic_vector(15 downto 0);
90
 
91
      pavr_rf_y:    out std_logic_vector(15 downto 0);
92
      pavr_rf_y_wr: in  std_logic;
93
      pavr_rf_y_di: in  std_logic_vector(15 downto 0);
94
 
95
      pavr_rf_z:    out std_logic_vector(15 downto 0);
96
      pavr_rf_z_wr: in  std_logic;
97
      pavr_rf_z_di: in  std_logic_vector(15 downto 0)
98
   );
99
end;
100
 
101
 
102
 
103
architecture pavr_rf_arch of pavr_rf is
104
 
105
   signal pavr_rf_x_int: std_logic_vector(15 downto 0);
106
   signal pavr_rf_y_int: std_logic_vector(15 downto 0);
107
   signal pavr_rf_z_int: std_logic_vector(15 downto 0);
108
 
109
   type t_pavr_rf_data_array is array (0 to 25) of std_logic_vector(7 downto 0);
110
   signal pavr_rf_data_array: t_pavr_rf_data_array;
111
 
112
begin
113
 
114
   -- Read port 1
115
   process
116
      variable is_x, is_y, is_z: std_logic;
117
      variable tv: std_logic_vector(2 downto 0);
118
   begin
119
      tv := int_to_std_logic_vector(0, 3);
120
 
121
      wait until ((pavr_rf_clk'event) and (pavr_rf_clk = '1'));
122
 
123
      if (pavr_rf_rd1_addr(4 downto 1) = "1101") then
124
         is_x := '1';
125
      else
126
         is_x := '0';
127
      end if;
128
 
129
      if (pavr_rf_rd1_addr(4 downto 1) = "1110") then
130
         is_y := '1';
131
      else
132
         is_y := '0';
133
      end if;
134
 
135
      if (pavr_rf_rd1_addr(4 downto 1) = "1111") then
136
         is_z := '1';
137
      else
138
         is_z := '0';
139
      end if;
140
 
141
      if (pavr_rf_rd1_rd = '1') then
142
         tv := is_x & is_y & is_z;
143
         case tv is
144
            when "000" =>
145
               pavr_rf_rd1_do <= pavr_rf_data_array(std_logic_vector_to_nat(pavr_rf_rd1_addr));
146
            when "100" =>
147
               if (pavr_rf_rd1_addr(0) = '0') then
148
                  pavr_rf_rd1_do <= pavr_rf_x_int(7 downto 0);
149
               else
150
                  pavr_rf_rd1_do <= pavr_rf_x_int(15 downto 8);
151
               end if;
152
            when "010" =>
153
               if (pavr_rf_rd1_addr(0) = '0') then
154
                  pavr_rf_rd1_do <= pavr_rf_y_int(7 downto 0);
155
               else
156
                  pavr_rf_rd1_do <= pavr_rf_y_int(15 downto 8);
157
               end if;
158
            when others =>
159
               if (pavr_rf_rd1_addr(0) = '0') then
160
                  pavr_rf_rd1_do <= pavr_rf_z_int(7 downto 0);
161
               else
162
                  pavr_rf_rd1_do <= pavr_rf_z_int(15 downto 8);
163
               end if;
164
         end case;
165
      end if;
166
   end process;
167
 
168
 
169
 
170
   -- Read port 2
171
   process
172
      variable is_x, is_y, is_z: std_logic;
173
      variable tv: std_logic_vector(2 downto 0);
174
   begin
175
      tv := int_to_std_logic_vector(0, 3);
176
 
177
      wait until ((pavr_rf_clk'event) and (pavr_rf_clk = '1'));
178
 
179
      if (pavr_rf_rd2_addr(4 downto 1) = "1101") then
180
         is_x := '1';
181
      else
182
         is_x := '0';
183
      end if;
184
 
185
      if (pavr_rf_rd2_addr(4 downto 1) = "1110") then
186
         is_y := '1';
187
      else
188
         is_y := '0';
189
      end if;
190
 
191
      if (pavr_rf_rd2_addr(4 downto 1) = "1111") then
192
         is_z := '1';
193
      else
194
         is_z := '0';
195
      end if;
196
 
197
      if (pavr_rf_rd2_rd = '1') then
198
         tv := is_x & is_y & is_z;
199
         case tv is
200
            when "000" =>
201
               pavr_rf_rd2_do <= pavr_rf_data_array(std_logic_vector_to_nat(pavr_rf_rd2_addr));
202
            when "100" =>
203
               if (pavr_rf_rd2_addr(0) = '0') then
204
                  pavr_rf_rd2_do <= pavr_rf_x_int(7 downto 0);
205
               else
206
                  pavr_rf_rd2_do <= pavr_rf_x_int(15 downto 8);
207
               end if;
208
            when "010" =>
209
               if (pavr_rf_rd2_addr(0) = '0') then
210
                  pavr_rf_rd2_do <= pavr_rf_y_int(7 downto 0);
211
               else
212
                  pavr_rf_rd2_do <= pavr_rf_y_int(15 downto 8);
213
               end if;
214
            when others =>
215
               if (pavr_rf_rd2_addr(0) = '0') then
216
                  pavr_rf_rd2_do <= pavr_rf_z_int(7 downto 0);
217
               else
218
                  pavr_rf_rd2_do <= pavr_rf_z_int(15 downto 8);
219
               end if;
220
         end case;
221
      end if;
222
   end process;
223
 
224
 
225
 
226
   -- Write port and pointer registers
227
   process(pavr_rf_clk, pavr_rf_res, pavr_rf_syncres,
228
           pavr_rf_wr_addr, pavr_rf_wr_wr, pavr_rf_wr_di, pavr_rf_x_wr, pavr_rf_y_wr, pavr_rf_z_wr,
229
           pavr_rf_x_di, pavr_rf_y_di, pavr_rf_z_di)
230
      variable is_x, is_y, is_z: std_logic;
231
      variable tv: std_logic_vector(2 downto 0);
232
   begin
233
      tv := int_to_std_logic_vector(0, 3);
234
 
235
      if (pavr_rf_wr_addr(4 downto 1) = "1101") then
236
         is_x := '1';
237
      else
238
         is_x := '0';
239
      end if;
240
 
241
      if (pavr_rf_wr_addr(4 downto 1) = "1110") then
242
         is_y := '1';
243
      else
244
         is_y := '0';
245
      end if;
246
 
247
      if (pavr_rf_wr_addr(4 downto 1) = "1111") then
248
         is_z := '1';
249
      else
250
         is_z := '0';
251
      end if;
252
 
253
      if (pavr_rf_res = '1') then
254
         -- Asynchronous reset
255
         pavr_rf_x_int <= int_to_std_logic_vector(0, 16);
256
         pavr_rf_y_int <= int_to_std_logic_vector(0, 16);
257
         pavr_rf_z_int <= int_to_std_logic_vector(0, 16);
258
      elsif ((pavr_rf_clk'event) and (pavr_rf_clk = '1')) then
259
 
260
         -- Write port
261
         if (pavr_rf_wr_wr = '1') then
262
            tv := is_x & is_y & is_z;
263
            case tv is
264
               when "000" =>
265
                  pavr_rf_data_array(std_logic_vector_to_nat(pavr_rf_wr_addr)) <= pavr_rf_wr_di;
266
               when "100" =>
267
                  if (pavr_rf_wr_addr(0) = '0') then
268
                     pavr_rf_x_int(7 downto 0) <= pavr_rf_wr_di;
269
                  else
270
                     pavr_rf_x_int(15 downto 8) <= pavr_rf_wr_di;
271
                  end if;
272
               when "010" =>
273
                  if (pavr_rf_wr_addr(0) = '0') then
274
                     pavr_rf_y_int(7 downto 0) <= pavr_rf_wr_di;
275
                  else
276
                     pavr_rf_y_int(15 downto 8) <= pavr_rf_wr_di;
277
                  end if;
278
               when others =>
279
                  if (pavr_rf_wr_addr(0) = '0') then
280
                     pavr_rf_z_int(7 downto 0) <= pavr_rf_wr_di;
281
                  else
282
                     pavr_rf_z_int(15 downto 8) <= pavr_rf_wr_di;
283
                  end if;
284
            end case;
285
         end if;
286
 
287
         -- Write pointer registers. Possibly overwrite the above write.
288
         if (pavr_rf_x_wr = '1') then
289
            pavr_rf_x_int <= pavr_rf_x_di;
290
         end if;
291
         if (pavr_rf_y_wr = '1') then
292
            pavr_rf_y_int <= pavr_rf_y_di;
293
         end if;
294
         if (pavr_rf_z_wr = '1') then
295
            pavr_rf_z_int <= pavr_rf_z_di;
296
         end if;
297
 
298
         if (pavr_rf_syncres = '1') then
299
            -- Synchronous reset
300
            pavr_rf_x_int <= int_to_std_logic_vector(0, 16);
301
            pavr_rf_y_int <= int_to_std_logic_vector(0, 16);
302
            pavr_rf_z_int <= int_to_std_logic_vector(0, 16);
303
         end if;
304
      end if;
305
   end process;
306
 
307
 
308
 
309
   -- Zero-level assignments
310
   pavr_rf_x <= pavr_rf_x_int;
311
   pavr_rf_y <= pavr_rf_y_int;
312
   pavr_rf_z <= pavr_rf_z_int;
313
 
314
end;
315
-- </File body>

powered by: WebSVN 2.1.0

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