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

Subversion Repositories rv01_riscv_core

[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_arith_pkg.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 madsilicon
-----------------------------------------------------------------
2
--                                                             --
3
-----------------------------------------------------------------
4
--                                                             --
5
-- Copyright (C) 2015 Stefano Tonello                          --
6
--                                                             --
7
-- This source file may be used and distributed without        --
8
-- restriction provided that this copyright statement is not   --
9
-- removed from the file and that any derivative work contains --
10
-- the original copyright notice and the associated disclaimer.--
11
--                                                             --
12
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY         --
13
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   --
14
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   --
15
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      --
16
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         --
17
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    --
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   --
19
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        --
20
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  --
21
-- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  --
22
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  --
23
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         --
24
-- POSSIBILITY OF SUCH DAMAGE.                                 --
25
--                                                             --
26
-----------------------------------------------------------------
27
 
28
---------------------------------------------------------------
29
-- Arithmetic operations macros and shifting functions
30
---------------------------------------------------------------
31
 
32
library IEEE;
33
use IEEE.std_logic_1164.all;
34
use IEEE.numeric_std.all;
35
 
36
library WORK;
37
use WORK.RV01_CONSTS_PKG.all;
38
use WORK.RV01_TYPES_PKG.all;
39
use WORK.RV01_FUNCS_PKG.all;
40
 
41
package RV01_ARITH_PKG is
42
 
43
  ----------------------------------------------------
44
  -- ALU operation types
45
  ----------------------------------------------------
46
 
47
  -- addition operation type
48
  type ADD_CTRL is (
49
    AC_ADD,
50
    AC_SUB,
51
    AC_SLT,
52
    AC_NIL
53
  );
54
 
55
  -- multiplication operation type
56
  type MUL_CTRL is (
57
    MC_MUL,
58
    MC_MULH,
59
    MC_MULHSU,
60
    MC_MULHU,
61
    MC_NIL
62
  );
63
 
64
  -- division operation type
65
  type DIV_CTRL is (
66
    DC_DIV,
67
    DC_DIVU,
68
    DC_REM,
69
    DC_REMU,
70
    DC_NIL
71
  );
72
 
73
  -- shifting operation type
74
  type SHF_CTRL is (
75
    SC_SHL,
76
    SC_SHR,
77
    SC_NIL
78
  );
79
 
80
  -- logic (boolean) operation type
81
  type LOG_CTRL is (
82
    LC_AND,
83
    LC_OR,
84
    LC_XOR,
85
    LC_LUI,
86
    LC_NIL
87
  );
88
 
89
  ----------------------------------------------------
90
  -- shifting functions
91
  ----------------------------------------------------
92
 
93
  -- 32-bit left shift
94
  function shift_left32(SI : SDWORD_T;SHFT : SHORT_SHIFT_T) return SDWORD_T;
95
 
96
  -- 32-bit arithmetic right shift
97
  function shift_right32(SI : SDWORD_T;SHFT : SHORT_SHIFT_T) return SDWORD_T;
98
 
99
  -- 32-bit logical right shift
100
  function shift_right32(SI : SDWORDU_T;SHFT : SHORT_SHIFT_T) return SDWORDU_T;
101
 
102
  -- 64-bit left shift
103
  function shift_left64(SI : LDWORD_T;SHFT : LONG_SHIFT_T) return LDWORD_T;
104
 
105
  -- 64-bit arithmetic right shift
106
  function shift_right64(SI : LDWORD_T;SHFT : LONG_SHIFT_T) return LDWORD_T;
107
 
108
  ----------------------------------------------------
109
  -- Wrap-up sum
110
  ----------------------------------------------------
111
 
112
  function wrap_sum(A,B : unsigned(SDLEN-1 downto 0)) return unsigned;
113
 
114
  ----------------------------------------------------
115
  -- Sign-extension
116
  ----------------------------------------------------
117
 
118
  function EXTS32(V : std_logic_vector) return signed;
119
 
120
  function EXTS64(V : std_logic_vector) return signed;
121
 
122
 
123
end RV01_ARITH_PKG;
124
 
125
package body RV01_ARITH_PKG is
126
 
127
  ----------------------------------------------------
128
  -- shifting functions
129
  ----------------------------------------------------
130
 
131
  function shift_left32(SI : SDWORD_T;SHFT : SHORT_SHIFT_T) return SDWORD_T is
132
    variable SO : SDWORD_T;
133
  begin
134
    case SHFT is
135
      when  0 => SO := shift_left(SI, 0);
136
      when  1 => SO := shift_left(SI, 1);
137
      when  2 => SO := shift_left(SI, 2);
138
      when  3 => SO := shift_left(SI, 3);
139
      when  4 => SO := shift_left(SI, 4);
140
      when  5 => SO := shift_left(SI, 5);
141
      when  6 => SO := shift_left(SI, 6);
142
      when  7 => SO := shift_left(SI, 7);
143
      when  8 => SO := shift_left(SI, 8);
144
      when  9 => SO := shift_left(SI, 9);
145
      when 10 => SO := shift_left(SI,10);
146
      when 11 => SO := shift_left(SI,11);
147
      when 12 => SO := shift_left(SI,12);
148
      when 13 => SO := shift_left(SI,13);
149
      when 14 => SO := shift_left(SI,14);
150
      when 15 => SO := shift_left(SI,15);
151
      when 16 => SO := shift_left(SI,16);
152
      when 17 => SO := shift_left(SI,17);
153
      when 18 => SO := shift_left(SI,18);
154
      when 19 => SO := shift_left(SI,19);
155
      when 20 => SO := shift_left(SI,20);
156
      when 21 => SO := shift_left(SI,21);
157
      when 22 => SO := shift_left(SI,22);
158
      when 23 => SO := shift_left(SI,23);
159
      when 24 => SO := shift_left(SI,24);
160
      when 25 => SO := shift_left(SI,25);
161
      when 26 => SO := shift_left(SI,26);
162
      when 27 => SO := shift_left(SI,27);
163
      when 28 => SO := shift_left(SI,28);
164
      when 29 => SO := shift_left(SI,29);
165
      when 30 => SO := shift_left(SI,30);
166
      when others => SO := shift_left(SI,31);
167
    end case;
168
    return(SO);
169
  end function;
170
 
171
  function shift_right32(SI : SDWORD_T;SHFT : SHORT_SHIFT_T) return SDWORD_T is
172
    variable SO : SDWORD_T;
173
  begin
174
    case SHFT is
175
      when  0 => SO := shift_right(SI, 0);
176
      when  1 => SO := shift_right(SI, 1);
177
      when  2 => SO := shift_right(SI, 2);
178
      when  3 => SO := shift_right(SI, 3);
179
      when  4 => SO := shift_right(SI, 4);
180
      when  5 => SO := shift_right(SI, 5);
181
      when  6 => SO := shift_right(SI, 6);
182
      when  7 => SO := shift_right(SI, 7);
183
      when  8 => SO := shift_right(SI, 8);
184
      when  9 => SO := shift_right(SI, 9);
185
      when 10 => SO := shift_right(SI,10);
186
      when 11 => SO := shift_right(SI,11);
187
      when 12 => SO := shift_right(SI,12);
188
      when 13 => SO := shift_right(SI,13);
189
      when 14 => SO := shift_right(SI,14);
190
      when 15 => SO := shift_right(SI,15);
191
      when 16 => SO := shift_right(SI,16);
192
      when 17 => SO := shift_right(SI,17);
193
      when 18 => SO := shift_right(SI,18);
194
      when 19 => SO := shift_right(SI,19);
195
      when 20 => SO := shift_right(SI,20);
196
      when 21 => SO := shift_right(SI,21);
197
      when 22 => SO := shift_right(SI,22);
198
      when 23 => SO := shift_right(SI,23);
199
      when 24 => SO := shift_right(SI,24);
200
      when 25 => SO := shift_right(SI,25);
201
      when 26 => SO := shift_right(SI,26);
202
      when 27 => SO := shift_right(SI,27);
203
      when 28 => SO := shift_right(SI,28);
204
      when 29 => SO := shift_right(SI,29);
205
      when 30 => SO := shift_right(SI,30);
206
      when others => SO := shift_right(SI,31);
207
    end case;
208
    return(SO);
209
  end function;
210
 
211
  function shift_right32(SI : SDWORDU_T;SHFT : SHORT_SHIFT_T) return SDWORDU_T is
212
    variable SO : SDWORDU_T;
213
  begin
214
    case SHFT is
215
      when  0 => SO := shift_right(SI, 0);
216
      when  1 => SO := shift_right(SI, 1);
217
      when  2 => SO := shift_right(SI, 2);
218
      when  3 => SO := shift_right(SI, 3);
219
      when  4 => SO := shift_right(SI, 4);
220
      when  5 => SO := shift_right(SI, 5);
221
      when  6 => SO := shift_right(SI, 6);
222
      when  7 => SO := shift_right(SI, 7);
223
      when  8 => SO := shift_right(SI, 8);
224
      when  9 => SO := shift_right(SI, 9);
225
      when 10 => SO := shift_right(SI,10);
226
      when 11 => SO := shift_right(SI,11);
227
      when 12 => SO := shift_right(SI,12);
228
      when 13 => SO := shift_right(SI,13);
229
      when 14 => SO := shift_right(SI,14);
230
      when 15 => SO := shift_right(SI,15);
231
      when 16 => SO := shift_right(SI,16);
232
      when 17 => SO := shift_right(SI,17);
233
      when 18 => SO := shift_right(SI,18);
234
      when 19 => SO := shift_right(SI,19);
235
      when 20 => SO := shift_right(SI,20);
236
      when 21 => SO := shift_right(SI,21);
237
      when 22 => SO := shift_right(SI,22);
238
      when 23 => SO := shift_right(SI,23);
239
      when 24 => SO := shift_right(SI,24);
240
      when 25 => SO := shift_right(SI,25);
241
      when 26 => SO := shift_right(SI,26);
242
      when 27 => SO := shift_right(SI,27);
243
      when 28 => SO := shift_right(SI,28);
244
      when 29 => SO := shift_right(SI,29);
245
      when 30 => SO := shift_right(SI,30);
246
      when others => SO := shift_right(SI,31);
247
    end case;
248
    return(SO);
249
  end function;
250
 
251
  function shift_left64(SI : LDWORD_T;SHFT : LONG_SHIFT_T) return LDWORD_T is
252
    variable SO : LDWORD_T;
253
  begin
254
    case SHFT is
255
      when  0 => SO := shift_left(SI, 0);
256
      when  1 => SO := shift_left(SI, 1);
257
      when  2 => SO := shift_left(SI, 2);
258
      when  3 => SO := shift_left(SI, 3);
259
      when  4 => SO := shift_left(SI, 4);
260
      when  5 => SO := shift_left(SI, 5);
261
      when  6 => SO := shift_left(SI, 6);
262
      when  7 => SO := shift_left(SI, 7);
263
      when  8 => SO := shift_left(SI, 8);
264
      when  9 => SO := shift_left(SI, 9);
265
      when 10 => SO := shift_left(SI,10);
266
      when 11 => SO := shift_left(SI,11);
267
      when 12 => SO := shift_left(SI,12);
268
      when 13 => SO := shift_left(SI,13);
269
      when 14 => SO := shift_left(SI,14);
270
      when 15 => SO := shift_left(SI,15);
271
      when 16 => SO := shift_left(SI,16);
272
      when 17 => SO := shift_left(SI,17);
273
      when 18 => SO := shift_left(SI,18);
274
      when 19 => SO := shift_left(SI,19);
275
      when 20 => SO := shift_left(SI,20);
276
      when 21 => SO := shift_left(SI,21);
277
      when 22 => SO := shift_left(SI,22);
278
      when 23 => SO := shift_left(SI,23);
279
      when 24 => SO := shift_left(SI,24);
280
      when 25 => SO := shift_left(SI,25);
281
      when 26 => SO := shift_left(SI,26);
282
      when 27 => SO := shift_left(SI,27);
283
      when 28 => SO := shift_left(SI,28);
284
      when 29 => SO := shift_left(SI,29);
285
      when 30 => SO := shift_left(SI,30);
286
      when 31 => SO := shift_left(SI,31);
287
      when 32 => SO := shift_left(SI,32);
288
      when 33 => SO := shift_left(SI,33);
289
      when 34 => SO := shift_left(SI,34);
290
      when 35 => SO := shift_left(SI,35);
291
      when 36 => SO := shift_left(SI,36);
292
      when 37 => SO := shift_left(SI,37);
293
      when 38 => SO := shift_left(SI,38);
294
      when 39 => SO := shift_left(SI,39);
295
      when 40 => SO := shift_left(SI,40);
296
      when 41 => SO := shift_left(SI,41);
297
      when 42 => SO := shift_left(SI,42);
298
      when 43 => SO := shift_left(SI,43);
299
      when 44 => SO := shift_left(SI,44);
300
      when 45 => SO := shift_left(SI,45);
301
      when 46 => SO := shift_left(SI,46);
302
      when 47 => SO := shift_left(SI,47);
303
      when 48 => SO := shift_left(SI,48);
304
      when 49 => SO := shift_left(SI,49);
305
      when 50 => SO := shift_left(SI,50);
306
      when 51 => SO := shift_left(SI,51);
307
      when 52 => SO := shift_left(SI,52);
308
      when 53 => SO := shift_left(SI,53);
309
      when 54 => SO := shift_left(SI,54);
310
      when 55 => SO := shift_left(SI,55);
311
      when 56 => SO := shift_left(SI,56);
312
      when 57 => SO := shift_left(SI,57);
313
      when 58 => SO := shift_left(SI,58);
314
      when 59 => SO := shift_left(SI,59);
315
      when 60 => SO := shift_left(SI,60);
316
      when 61 => SO := shift_left(SI,61);
317
      when 62 => SO := shift_left(SI,62);
318
      when others => SO := shift_left(SI,63);
319
    end case;
320
    return(SO);
321
  end function;
322
 
323
  function shift_right64(SI : LDWORD_T;SHFT : LONG_SHIFT_T) return LDWORD_T is
324
    variable SO : LDWORD_T;
325
  begin
326
    case SHFT is
327
      when  0 => SO := shift_right(SI, 0);
328
      when  1 => SO := shift_right(SI, 1);
329
      when  2 => SO := shift_right(SI, 2);
330
      when  3 => SO := shift_right(SI, 3);
331
      when  4 => SO := shift_right(SI, 4);
332
      when  5 => SO := shift_right(SI, 5);
333
      when  6 => SO := shift_right(SI, 6);
334
      when  7 => SO := shift_right(SI, 7);
335
      when  8 => SO := shift_right(SI, 8);
336
      when  9 => SO := shift_right(SI, 9);
337
      when 10 => SO := shift_right(SI,10);
338
      when 11 => SO := shift_right(SI,11);
339
      when 12 => SO := shift_right(SI,12);
340
      when 13 => SO := shift_right(SI,13);
341
      when 14 => SO := shift_right(SI,14);
342
      when 15 => SO := shift_right(SI,15);
343
      when 16 => SO := shift_right(SI,16);
344
      when 17 => SO := shift_right(SI,17);
345
      when 18 => SO := shift_right(SI,18);
346
      when 19 => SO := shift_right(SI,19);
347
      when 20 => SO := shift_right(SI,20);
348
      when 21 => SO := shift_right(SI,21);
349
      when 22 => SO := shift_right(SI,22);
350
      when 23 => SO := shift_right(SI,23);
351
      when 24 => SO := shift_right(SI,24);
352
      when 25 => SO := shift_right(SI,25);
353
      when 26 => SO := shift_right(SI,26);
354
      when 27 => SO := shift_right(SI,27);
355
      when 28 => SO := shift_right(SI,28);
356
      when 29 => SO := shift_right(SI,29);
357
      when 30 => SO := shift_right(SI,30);
358
      when 31 => SO := shift_right(SI,31);
359
      when 32 => SO := shift_right(SI,32);
360
      when 33 => SO := shift_right(SI,33);
361
      when 34 => SO := shift_right(SI,34);
362
      when 35 => SO := shift_right(SI,35);
363
      when 36 => SO := shift_right(SI,36);
364
      when 37 => SO := shift_right(SI,37);
365
      when 38 => SO := shift_right(SI,38);
366
      when 39 => SO := shift_right(SI,39);
367
      when 40 => SO := shift_right(SI,40);
368
      when 41 => SO := shift_right(SI,41);
369
      when 42 => SO := shift_right(SI,42);
370
      when 43 => SO := shift_right(SI,43);
371
      when 44 => SO := shift_right(SI,44);
372
      when 45 => SO := shift_right(SI,45);
373
      when 46 => SO := shift_right(SI,46);
374
      when 47 => SO := shift_right(SI,47);
375
      when 48 => SO := shift_right(SI,48);
376
      when 49 => SO := shift_right(SI,49);
377
      when 50 => SO := shift_right(SI,50);
378
      when 51 => SO := shift_right(SI,51);
379
      when 52 => SO := shift_right(SI,52);
380
      when 53 => SO := shift_right(SI,53);
381
      when 54 => SO := shift_right(SI,54);
382
      when 55 => SO := shift_right(SI,55);
383
      when 56 => SO := shift_right(SI,56);
384
      when 57 => SO := shift_right(SI,57);
385
      when 58 => SO := shift_right(SI,58);
386
      when 59 => SO := shift_right(SI,59);
387
      when 60 => SO := shift_right(SI,60);
388
      when 61 => SO := shift_right(SI,61);
389
      when 62 => SO := shift_right(SI,62);
390
      when others => SO := shift_right(SI,63);
391
    end case;
392
    return(SO);
393
  end function;
394
 
395
  ----------------------------------------------------
396
  -- Wrap-up sum
397
  ----------------------------------------------------
398
 
399
  function wrap_sum(A,B : unsigned(SDLEN-1 downto 0)) return unsigned is
400
    variable TMP : unsigned(SDLEN downto 0);
401
  begin
402
    -- A is an unsigned value and thus is zero-extended
403
    -- B has to be instead treated as a signed value and thus is sign-extended
404
    TMP := ('0' & A) + (B(SDLEN-1) & B);
405
    -- result is TMP with MSb removed (wrap-up)
406
    return(TMP(SDLEN-1 downto 0));
407
  end function;
408
 
409
  ----------------------------------------------------
410
  -- Sign-extension
411
  ----------------------------------------------------
412
 
413
  function EXTS32(V : std_logic_vector) return signed is
414
    variable S : signed(SDLEN-1 downto 0);
415
  begin
416
    S(V'HIGH downto 0) := to_signed(V);
417
    S(SDLEN-1 downto V'HIGH+1) := (others => V(V'HIGH));
418
    return(S);
419
  end function;
420
 
421
  function EXTS64(V : std_logic_vector) return signed is
422
    variable S : signed(LDLEN-1 downto 0);
423
  begin
424
    S(V'HIGH downto 0) := to_signed(V);
425
    S(LDLEN-1 downto V'HIGH+1) := (others => V(V'HIGH));
426
    return(S);
427
  end function;
428
 
429
end RV01_ARITH_PKG;

powered by: WebSVN 2.1.0

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