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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [arm/] [libs/] [armshiefter.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tarookumic
library ieee;
2
use ieee.std_logic_1164.all;
3
 
4
-- PREFIX: ash_xxx
5
package armshiefter is
6
 
7
-- Addressing modes:
8
-- DAta PRocessing Addressing Modes      : DAPRAM
9
-- LoaD/STore Addressing Modes           : LDSTAM
10
-- Load/Store misc (V4) Addressing Modes : LSV4AM
11
 
12
-- Share shiefter for DAPRAM  and LDSTAM addressing modes
13
-- operands:
14
--                               data1  data2   value   shieftval
15
-- ade_styp_immrot(DAPRAM):        -      -      imm      imm 
16
-- ade_styp_simm(DAPRAM+LDSTAM):   -     use    data2     imm
17
-- ade_styp_sreg(DAPRAM):         use    use    data1    data2
18
-- ade_styp_none:                  -     use    data2      0
19
 
20
type ash_styp is (
21
  ash_styp_none,  -- no shieft
22
  ash_styp_immrot,-- DAPRAM: OP2 immidiate rotated
23
  ash_styp_simm,  -- DAPRAM: OP2 shieft with imm, LDSTAM: addr v1 reg (adm_LDSTAM_reg) 
24
  ash_styp_sreg   -- DAPRAM: OP2 shieft with reg  
25
);
26
 
27
type ash_sdir is (
28
  ash_sdir_snone,    -- no shieft
29
  ash_sdir_slsl,     -- LSL #: logical shieft left 
30
  ash_sdir_slsr,     -- LSR #: logical shieft righ
31
  ash_sdir_sasr,     -- ASR #: arithmetic shieft left
32
  ash_sdir_sror,     -- ROR #: rotate 
33
  ash_sdir_srrx      -- RRX #: rotate 1 with carry
34
);
35
 
36
-- Shiefter of rsstg
37
procedure aas_shieft(
38
  insn  : in std_logic_vector(31 downto 0);
39
  dir   : in ash_sdir;
40
  typ   : in ash_styp;
41
  data1 : in std_logic_vector(31 downto 0);
42
  data2 : in std_logic_vector(31 downto 0);
43
  carry : in std_logic;
44
  shieftout      : out std_logic_vector(31 downto 0);
45
  shieftcarryout : out std_logic
46
);
47
 
48
end armshiefter;
49
 
50
package body armshiefter is
51
 
52
constant ASH_DAPRAMxLDSTAM_IMMROT_U : integer := 11; -- imm rot amount
53
constant ASH_DAPRAMxLDSTAM_IMMROT_D : integer := 8;
54
constant ASH_DAPRAMxLDSTAM_IMM_U    : integer := 7;  -- imm const
55
constant ASH_DAPRAMxLDSTAM_IMM_D    : integer := 0;
56
constant ASH_DAPRAMxLDSTAM_SIMM_U   : integer := 11; -- shieft immidiate amount
57
constant ASH_DAPRAMxLDSTAM_SIMM_D   : integer := 7;
58
 
59
type shift_src is (shiftin_00,shiftin_32,shiftin_33,shiftin_prev);
60
 
61
procedure aas_shieft(
62
  insn  : in std_logic_vector(31 downto 0);
63
  dir   : in ash_sdir;
64
  typ   : in ash_styp;
65
  data1 : in std_logic_vector(31 downto 0);
66
  data2 : in std_logic_vector(31 downto 0);
67
  carry : in std_logic;
68
  shieftout      : out std_logic_vector(31 downto 0);
69
  shieftcarryout : out std_logic
70
) is
71
variable op1 : std_logic_vector(31 downto 0);
72
variable op2 : std_logic_vector(4 downto 0);
73
variable shiftin : std_logic_vector(64 downto 0);
74
variable carryout : std_logic;
75
variable carryoutsrc : shift_src;
76
begin
77
 
78
  carryoutsrc := shiftin_prev;
79
  carryout := carry;
80
 
81
  op1 := data1;
82
  op2 := (others => '0');
83
  shiftin := (others => '0');
84
  shiftin(32 downto 1) := data1;
85
 
86
  --                                       data1  data2   value   shieftval
87
  -- adm_DAPRAMxLDSTAM_DAPRAM_immrot:        -      -      imm      imm 
88
  -- adm_DAPRAMxLDSTAM_DAPRAMxLDSTAM_simm:   -     use    data2     imm
89
  -- adm_DAPRAMxLDSTAM_DAPRAM_sreg:         use    use    data1    data2
90
  -- adm_DAPRAMxLDSTAM_DAPRAM_none:          -     use    data2      0
91
 
92
  case typ is
93
    when ash_styp_immrot  => -- (special msr case also)
94
 
95
      --  64  63               33  32 31          1  0
96
      -- +---+---+---------------+===+=============+---+
97
      -- |           op1         |       op1       | 0 |
98
      -- +---+---+---------------+ccc+=============+---+
99
      --         |    op1            |                   <<  1 (>>1) 
100
      --                      |       op1       |        << 31 (>>31)
101
 
102
      op1 := (others => '0');
103
      op1(7 downto 0) := insn(ASH_DAPRAMxLDSTAM_IMM_U downto ASH_DAPRAMxLDSTAM_IMM_D);
104
 
105
      shiftin := (others => '0');
106
      shiftin(32 downto 1) := op1;
107
      shiftin(64 downto 33) := op1;
108
      op2 := insn(ASH_DAPRAMxLDSTAM_IMMROT_U downto ASH_DAPRAMxLDSTAM_IMMROT_D) & "0";
109
 
110
      carryoutsrc := shiftin_32;
111
 
112
      if op2 = "00000" then -- == 0
113
        carryoutsrc := shiftin_prev;
114
        carryout := carry;
115
      end if;
116
 
117
    when ash_styp_simm =>
118
 
119
      shiftin := (others => '0');
120
      shiftin(32 downto 1) := data2;
121
 
122
      case dir  is
123
        when ash_sdir_slsl =>
124
 
125
          --$(del)
126
          --if shift_imm == 0 then /* Register Operand */
127
          --  shifter_operand = Rm
128
          --  shifter_carry_out = C Flag
129
          --else /* shift_imm > 0 */
130
          --  shifter_operand = Rm Logical_Shift_Left shift_imm
131
          --  shifter_carry_out = Rm[32 - shift_imm]
132
          --$(/del)
133
 
134
          --  64  63               33  32 31          1  0
135
          -- +---+---+---------------+===+=============+---+
136
          -- | c |           op1         |    000      | 0 |
137
          -- +---+---+------------ccc+===+=============+---+
138
          --       c |    op1            |                   << 31 (>>0)
139
          --                       c |       op1       |     << 0 (>>31)
140
 
141
          shiftin := (others => '0');
142
          shiftin(64) := carry;
143
          shiftin(63 downto 32) := data2;
144
          op2 := not insn(ASH_DAPRAMxLDSTAM_SIMM_U downto ASH_DAPRAMxLDSTAM_SIMM_D);
145
 
146
          carryoutsrc := shiftin_33;
147
 
148
        when ash_sdir_slsr =>
149
 
150
          --$(del)
151
          --if shift_imm == 0 then
152
          --  shifter_operand = 0
153
          --  shifter_carry_out = Rm[31]
154
          --else /* shift_imm > 0 */
155
          --  shifter_operand = Rm Logical_Shift_Right shift_imm
156
          --  shifter_carry_out = Rm[shift_imm - 1]
157
          --$(/del)
158
 
159
          --  64  63               33  32 31          1  0
160
          -- +---+---+---------------+===+=============+---+
161
          -- | 0 | 0 |    000        |        op1      | c |
162
          -- +---+---+---------------+===+=============+ccc+
163
          --                         |     op1         |     >> 0
164
          --                                       |op1|     >> 31 
165
 
166
          shiftin := (others => '0');
167
          shiftin(0) := carry;
168
          shiftin(32 downto 1) := data2;
169
          op2 := insn(ASH_DAPRAMxLDSTAM_SIMM_U downto ASH_DAPRAMxLDSTAM_SIMM_D);
170
 
171
          carryoutsrc := shiftin_00;
172
 
173
        when ash_sdir_sasr =>
174
          --$(del)
175
          --if shift_imm == 0 then
176
          --  if Rm[31] == 0 then
177
          --    shifter_operand = 0
178
          --    shifter_carry_out = Rm[31]
179
          --  else /* Rm[31] == 1 */
180
          --    shifter_operand = 0xFFFFFFFF
181
          --    shifter_carry_out = Rm[31]
182
          --else /* shift_imm > 0 */
183
          --  shifter_operand = Rm Arithmetic_Shift_Right <shift_imm>
184
          --  shifter_carry_out = Rm[shift_imm - 1]
185
          --$(/del)
186
 
187
          --  64  63               33  32 31          1  0
188
          -- +---+---+---------------+===+=============+---+
189
          -- | s | s |    sss        |        op1      | c |
190
          -- +---+---+---------------+===+=============+ccc+
191
          --                           s |    op1      |     >> 1
192
          --                                  sss  |op1|     >> 31 
193
          --                                  000      | 0   >> 0 (s=0)
194
          --                                  111      | 1   >> 0 (s=1)
195
          if data2(31) = '1' then
196
            shiftin(64 downto 33) := (others => '1');
197
          else
198
            shiftin(64 downto 33) := (others => '0');
199
          end if;
200
          shiftin(0) := carry;
201
          shiftin(32 downto 1) := data2;
202
          op2 := insn(ASH_DAPRAMxLDSTAM_SIMM_U downto ASH_DAPRAMxLDSTAM_SIMM_D);
203
 
204
          if op2 = "00000" then
205
            if data2(31) = '1' then
206
              shiftin(32 downto 0) := (others => '1');
207
            else
208
              shiftin(32 downto 0) := (others => '0');
209
            end if;
210
          end if;
211
 
212
          carryoutsrc := shiftin_00;
213
 
214
        when ash_sdir_sror =>
215
 
216
          --$(del)
217
          --if shift_imm == 0 then
218
          --  ash_sdir_srrx case
219
          --else /* shift_imm > 0 */
220
          --  shifter_operand = Rm Rotate_Right shift_imm
221
          --  shifter_carry_out = Rm[shift_imm - 1]
222
          --$(/del)
223
 
224
          --  64  63               33  32 31          1  0
225
          -- +---+---+---------------+===+=============+---+
226
          -- |           op1         |       op1       | 0 |
227
          -- +---+---+---------------+ccc+=============+---+
228
          --         |    op1            |                   <<  1 (>>1) 
229
          --                      |       op1       |        << 31 (>>31)
230
 
231
          shiftin := (others => '0');
232
          shiftin(64 downto 33) := data2;
233
          shiftin(32 downto 1) := data2;
234
          op2 := insn(ASH_DAPRAMxLDSTAM_SIMM_U downto ASH_DAPRAMxLDSTAM_SIMM_D);
235
 
236
          carryoutsrc := shiftin_32;
237
 
238
        when ash_sdir_srrx =>
239
 
240
          --$(del)
241
          --shifter_operand = (C Flag Logical_Shift_Left 31) OR (Rm Logical_Shift_Right 1)
242
          --shifter_carry_out = Rm[0]
243
          --$(/del)
244
 
245
          --  64  63               33  32 31          1  0
246
          -- +---+---+---------------+===+=============+---+
247
          -- |           000         | c |    op1-1        |
248
          -- +---+---+---------------+===+=============+ccc+
249
          --                                                 : rrx 
250
 
251
          shiftin(31 downto 0) := data2;
252
          shiftin(32) := carry;
253
          op2 := (others => '0');
254
 
255
          carryoutsrc := shiftin_00;
256
 
257
        when ash_sdir_snone =>
258
          op2 := (others => '0');
259
        when others => null;
260
      end case;
261
 
262
 
263
 
264
    when ash_styp_sreg =>
265
 
266
      shiftin := (others => '0');
267
      shiftin(32 downto 1) := data1;
268
 
269
      case dir  is
270
        when ash_sdir_slsl =>
271
 
272
          --$(del)
273
          --if Rs[7:0] == 0 then
274
          --  shifter_operand = Rm
275
          --  shifter_carry_out = C Flag
276
          --else if Rs[7:0] < 32 then
277
          --  shifter_operand = Rm Logical_Shift_Left Rs[7:0]
278
          --  shifter_carry_out = Rm[32 - Rs[7:0]]
279
          --else if Rs[7:0] == 32 then
280
          --  shifter_operand = 0
281
          --  shifter_carry_out = Rm[0]
282
          --else /* Rs[7:0] > 32 */
283
          --  shifter_operand = 0
284
          --  shifter_carry_out = 0
285
          --$(/del)
286
 
287
          --  64  63               33  32 31          1  0
288
          -- +---+---+---------------+===+=============+---+
289
          -- | c |           op1         |    000      | 0 |
290
          -- +---+---+------------ccc+===+=============+---+
291
          --       c |    op1            |                   << 31 (>>0)
292
          --                       c |       op1       |     << 0 (>>31)
293
 
294
          shiftin := (others => '0');
295
          shiftin(64) := carry;
296
          shiftin(63 downto 32) := data1;
297
          op2 := not data2(4 downto 0);
298
 
299
          carryoutsrc := shiftin_33;
300
 
301
          if not (data2(7 downto 5) = "000") then -- >= 32
302
            shiftin := (others => '0');
303
            if data2(7 downto 0) = "00100000" then  -- == 32
304
              carryoutsrc := shiftin_prev;
305
              carryout := data1(0);
306
            end if;
307
          end if;
308
 
309
        when ash_sdir_slsr =>
310
 
311
          --$(del)
312
          --if Rs[7:0] == 0 then
313
          --  shifter_operand = Rm
314
          --  shifter_carry_out = C Flag
315
          --else if Rs[7:0] < 32 then
316
          --  shifter_operand = Rm Logical_Shift_Right Rs[7:0]
317
          --  shifter_carry_out = Rm[Rs[7:0] - 1]
318
          --else if Rs[7:0] == 32 then
319
          --  shifter_operand = 0
320
          --  shifter_carry_out = Rm[31]
321
          --else /* Rs[7:0] > 32 */
322
          --  shifter_operand = 0
323
          --  shifter_carry_out = 0
324
          --$(/del)
325
 
326
          --  64  63               33  32 31          1  0
327
          -- +---+---+---------------+===+=============+---+
328
          -- | 0 | 0 |    000        |        op1      | c |
329
          -- +---+---+---------------+===+=============+ccc+
330
          --                         |     op1         |     >> 0
331
          --                                       |op1|     >> 31 
332
 
333
          shiftin := (others => '0');
334
          shiftin(0) := carry;
335
          shiftin(32 downto 1) := data1;
336
          op2 := data2(4 downto 0);
337
 
338
          carryoutsrc := shiftin_00;
339
 
340
          if not (data2(7 downto 5) = "000") then -- >= 32
341
            shiftin := (others => '0');
342
            if data2(7 downto 0) = "00100000" then  -- == 32
343
              carryoutsrc := shiftin_prev;
344
              carryout := data1(31);
345
            end if;
346
          end if;
347
 
348
        when ash_sdir_sasr =>
349
          --$(del)
350
          --if Rs[7:0] == 0 then
351
          --  shifter_operand = Rm
352
          --  shifter_carry_out = C Flag
353
          --else if Rs[7:0] < 32 then
354
          --  shifter_operand = Rm Arithmetic_Shift_Right Rs[7:0]
355
          --  shifter_carry_out = Rm[Rs[7:0] - 1]
356
          --else /* Rs[7:0] >= 32 */
357
          --  if Rm[31] == 0 then
358
          --    shifter_operand = 0
359
          --    shifter_carry_out = Rm[31]
360
          --  else /* Rm[31] == 1 */
361
          --    shifter_operand = 0xFFFFFFFF
362
          --    shifter_carry_out = Rm[31]
363
          --$(/del)
364
 
365
          --  64  63               33  32 31          1  0
366
          -- +---+---+---------------+===+=============+---+
367
          -- | s | s |    sss        |        op1      | c |
368
          -- +---+---+---------------+===+=============+ccc+
369
          --                           s |    op1      |     >> 1
370
          --                                  sss  |op1|     >> 31 
371
          --                                  000      | 0   >> 0 (s=0)
372
          --                                  111      | 1   >> 0 (s=1)
373
          if data1(31) = '1' then
374
            shiftin(64 downto 33) := (others => '1');
375
          else
376
            shiftin(64 downto 33) := (others => '0');
377
          end if;
378
          shiftin(0) := carry;
379
          shiftin(32 downto 1) := data1;
380
          op2 := data2(4 downto 0);
381
 
382
          if not (data2(7 downto 5) = "000") then -- >= 32
383
            if data1(31) = '1' then
384
              shiftin(32 downto 0) := (others => '1');
385
            else
386
              shiftin(32 downto 0) := (others => '0');
387
            end if;
388
          end if;
389
 
390
          carryoutsrc := shiftin_00;
391
 
392
        when ash_sdir_sror =>
393
 
394
          --$(del)
395
          --if Rs[7:0] == 0 then
396
          --  shifter_operand = Rm
397
          --  shifter_carry_out = C Flag
398
          --else if Rs[4:0] == 0 then
399
          --  shifter_operand = Rm 
400
          --  shifter_carry_out = Rm[31]
401
          --else /* Rs[4:0] > 0 */
402
          --  shifter_operand = Rm Rotate_Right Rs[4:0]
403
          --  shifter_carry_out = Rm[Rs[4:0] - 1]
404
          --$(/del)
405
 
406
          --  64  63               33  32 31          1  0
407
          -- +---+---+---------------+===+=============+---+
408
          -- |           op1         |       op1       | 0 |
409
          -- +---+---+---------------+ccc+=============+---+
410
          --         |    op1            |                   <<  1 (>>1) 
411
          --                      |       op1       |        << 31 (>>31)
412
 
413
          shiftin := (others => '0');
414
          shiftin(64 downto 33) := data1;
415
          shiftin(32 downto 1) := data1;
416
          op2 := data2(4 downto 0);
417
 
418
          carryoutsrc := shiftin_32;
419
 
420
          if data2(7 downto 0) = "00000000" then -- == 0
421
            carryoutsrc := shiftin_prev;
422
            carryout := carry;
423
          end if;
424
 
425
        when ash_sdir_srrx =>
426
 
427
          --$(del)
428
          --shifter_operand = (C Flag Logical_Shift_Left 31) OR (Rm Logical_Shift_Right 1)
429
          --shifter_carry_out = Rm[0]
430
          --$(/del)
431
 
432
          --  64  63               33  32 31          1  0
433
          -- +---+---+---------------+===+=============+---+
434
          -- |           000         | c |    op1-1        |
435
          -- +---+---+---------------+===+=============+ccc+
436
          --                                                 : rrx
437
 
438
          op2 := (others => '0');
439
          shiftin(31 downto 0) := carry & shiftin(31 downto 1);
440
 
441
        when ash_sdir_snone =>
442
        when others => null;
443
      end case;
444
 
445
    when ash_styp_none =>
446
 
447
      shiftin := (others => '0');
448
      shiftin(32 downto 1) := data2;
449
 
450
    when others =>
451
  end case;
452
 
453
  -- shifter
454
  if op2 (4) = '1' then
455
    shiftin(48 downto 0) := shiftin(64 downto 16);
456
  end if;
457
  if op2 (3) = '1' then
458
    shiftin(40 downto 0) := shiftin(48 downto 8);
459
  end if;
460
  if op2 (2) = '1' then
461
    shiftin(36 downto 0) := shiftin(40 downto 4);
462
  end if;
463
  if op2 (1) = '1' then
464
    shiftin(34 downto 0) := shiftin(36 downto 2);
465
  end if;
466
  if op2 (0) = '1' then
467
    shiftin(32 downto 0) := shiftin(33 downto 1);
468
  end if;
469
 
470
  -- carry out select
471
  case carryoutsrc is
472
    when shiftin_00   => carryout := shiftin(0);
473
    when shiftin_33   => carryout := shiftin(33);
474
    when shiftin_32   => carryout := shiftin(32);
475
    when shiftin_prev =>
476
    when others => null;
477
  end case;
478
 
479
  shieftout := shiftin(32 downto 1);
480
  shieftcarryout := carryout;
481
 
482
end;
483
 
484
end armshiefter;

powered by: WebSVN 2.1.0

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