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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [arm/] [libs/] [armldst.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
use IEEE.std_logic_unsigned.conv_integer;
4
use IEEE.std_logic_arith.conv_unsigned;
5
use work.int.all;
6
use work.memdef.all;
7
use work.armpctrl.all;
8
use work.armpmodel.all;
9
use work.armdecode.all;
10
use work.gendc_lib.all;
11
 
12
-- PREFIX: als_xxx
13
package armldst is
14
 
15
constant ALS_REGLIST_SZ : integer := 16;
16
constant ALS_REGLIST_U  : integer := 15;
17
constant ALS_REGLIST_D  : integer := 0;
18
constant ALS_REGLIST_pc : integer := 15;
19
constant ALS_REGLIST_ZERO : std_logic_vector(ALS_REGLIST_SZ-1 downto 0):= "0000000000000000";
20
 
21
 
22
-------------------------------------------------------------------------------
23
-- single load / store
24
 
25
-- Init size and signed for LDSTAM
26
procedure als_LDSTAM_init_size(
27
  insn : in std_logic_vector(31 downto 0);
28
  pctrl : inout apc_pctrl
29
);
30
 
31
-- Init size and signed for LSV4AM
32
procedure als_LSV4AM_init_size(
33
  insn : in std_logic_vector(31 downto 0);
34
  pctrl : inout apc_pctrl
35
);
36
 
37
-- Init address calc exop
38
procedure als_LDSTAMxLSV4AM_init_addsub(
39
  insn : in std_logic_vector(31 downto 0);
40
  pctrl : inout apc_pctrl
41
);
42
 
43
-------------------------------------------------------------------------------
44
-- multiple load / store
45
 
46
-- Count leading zeros
47
function als_getnextpos (
48
  insn    : in std_logic_vector(31 downto 0);
49
  reglist : in std_logic_vector(APM_REGLIST_SZ-1 downto 0)
50
) return std_logic_vector;
51
 
52
-- get inc/decrement offsets
53
procedure als_offsets (
54
  insn : in std_logic_vector(31 downto 0);
55
  startoff  : inout std_logic_vector(31 downto 0);
56
  endoff    : inout std_logic_vector(31 downto 0);
57
  incval    : inout std_logic_vector(31 downto 0)
58
);
59
 
60
-------------------------------------------------------------------------------
61
 
62
end armldst;
63
 
64
package body armldst is
65
 
66
procedure als_LDSTAM_init_size(
67
  insn : in std_logic_vector(31 downto 0);
68
  pctrl : inout apc_pctrl
69
) is
70
begin
71
  -- unsigned byte / word
72
  if insn(ADE_LDSTAM_UBYTE) = '1' then
73
    pctrl.me.meop_param.size  := lmd_byte;
74
    pctrl.me.meop_param.signed := '0';
75
  else
76
    pctrl.me.meop_param.size  := lmd_word;
77
    pctrl.me.meop_param.signed := '1';
78
  end if;
79
end;
80
 
81
procedure als_LSV4AM_init_size(
82
  insn : in std_logic_vector(31 downto 0);
83
  pctrl : inout apc_pctrl
84
) is
85
begin
86
  if insn(ADE_LSV4AM_SIGNED) = '1' then
87
    pctrl.me.meop_param.signed := '1';
88
  else
89
    pctrl.me.meop_param.signed := '0';
90
  end if;
91
 
92
  if insn(ADE_LSV4AM_HALF) = '1' then
93
    pctrl.me.meop_param.size  := lmd_half;
94
  else
95
    pctrl.me.meop_param.size  := lmd_byte;
96
  end if;
97
end;
98
 
99
procedure als_LDSTAMxLSV4AM_init_addsub(
100
  insn : in std_logic_vector(31 downto 0);
101
  pctrl : inout apc_pctrl
102
) is
103
begin
104
  if insn(ADE_LDSTAMxLSV4AM_ADD) = '1' then
105
    pctrl.ex.exop_aluop := ADE_OP_ADD;
106
  else
107
    pctrl.ex.exop_aluop := ADE_OP_SUB;
108
  end if;
109
end;
110
 
111
function als_getnextpos (
112
  insn    : in std_logic_vector(31 downto 0);
113
  reglist : in std_logic_vector(APM_REGLIST_SZ-1 downto 0)
114
) return std_logic_vector is
115
  variable part03_00   : std_logic_vector(3 downto 0);
116
  variable part07_04   : std_logic_vector(3 downto 0);
117
  variable part11_08   : std_logic_vector(3 downto 0);
118
  variable part15_12   : std_logic_vector(3 downto 0);
119
  variable part03_00ui : integer;
120
  variable part03_00di : integer;
121
  variable part07_04ui : integer;
122
  variable part07_04di : integer;
123
  variable part11_08ui : integer;
124
  variable part11_08di : integer;
125
  variable part15_12ui : integer;
126
  variable part15_12di : integer;
127
  variable src4        : std_logic_vector(3 downto 0);
128
  variable src4ui        : integer;
129
  variable src4di        : integer;
130
  variable srcu        : std_logic_vector(1 downto 0);
131
  variable srcd        : std_logic_vector(1 downto 0);
132
  variable posu        : std_logic_vector(3 downto 0);
133
  variable posd        : std_logic_vector(3 downto 0);
134
  variable i           : integer;
135
begin
136
  part03_00 := reglist( 3 downto  0);
137
  part07_04 := reglist( 7 downto  4);
138
  part11_08 := reglist(11 downto  8);
139
  part15_12 := reglist(15 downto 12);
140
 
141
  -- priority 0-3
142
  part03_00ui := 0;
143
L1u:  for i in 0 to 3 loop
144
    if part03_00(i) = '1' then
145
      part03_00ui := i;
146
      exit L1u;
147
    end if;
148
  end loop;
149
  part03_00di := 3;
150
L1d:  for i in 3 downto 0 loop
151
    if part03_00(i) = '1' then
152
      part03_00di := i;
153
      exit L1d;
154
    end if;
155
  end loop;
156
 
157
  -- priority 4-7
158
  part07_04ui := 0;
159
L2u:  for i in 0 to 3 loop
160
    if part07_04(i) = '1' then
161
      part07_04ui := i;
162
      exit L2u;
163
    end if;
164
  end loop;
165
  part07_04di := 3;
166
L2d:  for i in 3 downto 0 loop
167
    if part07_04(i) = '1' then
168
      part07_04di := i;
169
      exit L2d;
170
    end if;
171
  end loop;
172
 
173
  -- priority 8-11
174
  part11_08ui := 0;
175
L3u:  for i in 0 to 3 loop
176
    if part11_08(i) = '1' then
177
      part11_08ui := i;
178
      exit L3u;
179
    end if;
180
  end loop;
181
  part11_08di := 3;
182
L3d:  for i in 3 downto 0 loop
183
    if part11_08(i) = '1' then
184
      part11_08di := i;
185
      exit L3d;
186
    end if;
187
  end loop;
188
 
189
  -- priority 12-15
190
  part15_12ui := 0;
191
L4u:  for i in 0 to 3 loop
192
    if part15_12(i) = '1' then
193
      part15_12ui := i;
194
      exit L4u;
195
    end if;
196
  end loop;
197
  part15_12di := 0;
198
L4d:  for i in 3 downto 0 loop
199
    if part15_12(i) = '1' then
200
      part15_12di := i;
201
      exit L4d;
202
    end if;
203
  end loop;
204
 
205
  src4 := (others => '0');
206
  if part03_00 /= "0000" then
207
    src4(0) := '1';
208
  end if;
209
  if part07_04 /= "0000" then
210
    src4(1) := '1';
211
  end if;
212
  if part11_08 /= "0000" then
213
    src4(2) := '1';
214
  end if;
215
  if part15_12 /= "0000" then
216
    src4(3) := '1';
217
  end if;
218
 
219
  -- priority upper blocks
220
  src4ui := 0;
221
S4u:  for i in 0 to 3 loop
222
    if src4(i) = '1' then
223
      src4ui := i;
224
      exit S4u;
225
    end if;
226
  end loop;
227
  src4di := 3;
228
S4d:  for i in 3 downto 0 loop
229
    if src4(i) = '1' then
230
      src4di := i;
231
      exit S4d;
232
    end if;
233
  end loop;
234
 
235
  srcu := std_logic_vector(conv_unsigned(src4ui, 2));
236
  srcd := std_logic_vector(conv_unsigned(src4di, 2));
237
 
238
  posu(3 downto 2) := srcu;
239
  case srcu is
240
    when "11" => posu(1 downto 0) := std_logic_vector(conv_unsigned(part15_12ui, 2));
241
    when "10" => posu(1 downto 0) := std_logic_vector(conv_unsigned(part11_08ui, 2));
242
    when "01" => posu(1 downto 0) := std_logic_vector(conv_unsigned(part07_04ui, 2));
243
    when "00" => posu(1 downto 0) := std_logic_vector(conv_unsigned(part03_00ui, 2));
244
    when others => null;
245
  end case;
246
  posd(3 downto 2) := srcd;
247
  case srcd is
248
    when "11" => posd(1 downto 0) := std_logic_vector(conv_unsigned(part15_12di, 2));
249
    when "10" => posd(1 downto 0) := std_logic_vector(conv_unsigned(part11_08di, 2));
250
    when "01" => posd(1 downto 0) := std_logic_vector(conv_unsigned(part07_04di, 2));
251
    when "00" => posd(1 downto 0) := std_logic_vector(conv_unsigned(part03_00di, 2));
252
    when others => null;
253
  end case;
254
 
255
  if insn(ADE_UID_U) = '1' then
256
    return posu; -- Increment regorder [0-15]
257
  else
258
    return posd; -- Decrement regorder [15-0]
259
  end if;
260
 
261
  return posu;
262
end;
263
 
264
procedure als_offsets (
265
  insn : in std_logic_vector(31 downto 0);
266
  startoff  : inout std_logic_vector(31 downto 0);
267
  endoff    : inout std_logic_vector(31 downto 0);
268
  incval    : inout std_logic_vector(31 downto 0)
269
) is
270
variable mode : std_logic_vector(1 downto 0);
271
variable regnum_mul4 : std_logic_vector(31 downto 0);
272
begin
273
  mode := insn(ADE_PAB_U)&insn(ADE_UID_U);
274
 
275
  startoff := (others => '0');
276
  endoff   := (others => '0');
277
  incval   := (others => '0');
278
 
279
  -- LRM/STM: Increment after  (regorder [0-15],start:+0,end(onwb):+4) :ldmia|stmia <rn>,{<reglist>}
280
  -- LRM/STM: Increment before (regorder [0-15],start:+4,end(onwb):+0) :ldmib|stmib <rn>,{<reglist>}
281
  -- LRM/STM: Decrement after  (regorder [15-0],start:-0,end(onwb):-4) :ldmda|stmda <rn>,{<reglist>}
282
  -- LRM/STM: Decrement before (regorder [15-0],start:-4,end(onwb):-0) :ldmdb|stmdb <rn>,{<reglist>}
283
  case mode is
284
    when "01" => incval := LIN_FOUR   ; startoff := (others=> '0'); endoff := LIN_FOUR;       -- increment after
285
    when "11" => incval := LIN_FOUR   ; startoff := LIN_FOUR      ; endoff := (others=> '0'); -- increment before
286
    when "00" => incval := LIN_MINFOUR; startoff := (others=> '0'); endoff := LIN_MINFOUR;    -- decrement after
287
    when "10" => incval := LIN_MINFOUR; startoff := LIN_MINFOUR   ; endoff := (others=> '0'); -- decrement before
288
    when others =>
289
  end case;
290
 
291
end;
292
 
293
 
294
end armldst;

powered by: WebSVN 2.1.0

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