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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [arm/] [libs/] [armpmodel.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: apm_xxx
5
package armpmodel is
6
 
7
-------------------------------------------------------------------------------
8
 
9
-- Processor Modes
10
constant APM_USR : std_logic_vector(4 downto 0) := "10000";        -- 1oooo
11
constant APM_SYS : std_logic_vector(4 downto 0) := "11111";        -- 11111
12
constant APM_SVC : std_logic_vector(4 downto 0) := "10011";        -- 1oo11
13
constant APM_ABT : std_logic_vector(4 downto 0) := "10111";        -- 1o111
14
constant APM_UND : std_logic_vector(4 downto 0) := "11011";        -- 11o11
15
constant APM_IRQ : std_logic_vector(4 downto 0) := "10010";        -- 1oo1o
16
constant APM_FIQ : std_logic_vector(4 downto 0) := "10001";        -- 1ooo1
17
 
18
-- check weather privileged mode
19
function apm_is_privmode (
20
  mode : std_logic_vector(4 downto 0)
21
) return boolean;
22
 
23
-------------------------------------------------------------------------------
24
 
25
-- Trap types
26
type apm_trap is (
27
  apm_trap_reset,   -- reset
28
  apm_trap_undef,   -- undefined (EXSTG)
29
  apm_trap_swi,     -- software interrupt (DRSTG)
30
  apm_trap_prefch,  -- prefetch error (IMSTG)
31
  apm_trap_dabort,  -- data abort error (MESTG)
32
  apm_trap_irq,     -- interrupt
33
  apm_trap_fiq      -- fast interrupt
34
);
35
 
36
-- Trap jump vectors
37
constant APM_RESET_VEC  : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
38
constant APM_UNDEF_VEC  : std_logic_vector(31 downto 0) := "00000000000000000000000000000100";
39
constant APM_SWI_VEC    : std_logic_vector(31 downto 0) := "00000000000000000000000000001000";
40
constant APM_PREFCH_VEC : std_logic_vector(31 downto 0) := "00000000000000000000000000001100";
41
constant APM_DABORT_VEC : std_logic_vector(31 downto 0) := "00000000000000000000000000010000";
42
constant APM_IRQ_VEC    : std_logic_vector(31 downto 0) := "00000000000000000000000000011000";
43
constant APM_FIQ_VEC    : std_logic_vector(31 downto 0) := "00000000000000000000000000011100";
44
 
45
-- Trap ctrl
46
type apm_trapctrl is record
47
  traptype : apm_trap;
48
  trap     : std_logic;
49
end record;
50
 
51
-------------------------------------------------------------------------------
52
 
53
-- Current Program Status Register (CPSR)
54
-- +---+---+---+---+---+------------+---+---+---+------+
55
-- | n | z | c | v | q |   dnm(raz) | i | f | t | mode |
56
-- +---+---+---+---+---+------------+---+---+---+------+
57
-- exstg controlled part of CPSR
58
type apm_excpsr is record
59
   n      : std_logic;                  -- negative
60
   z      : std_logic;                  -- zero
61
   c      : std_logic;                  -- carry
62
   v      : std_logic;                  -- overflow
63
   -- extensions
64
   -- fext   : std_logic_vector(3 downto 0);  -- cpsr(27:24)
65
   -- xext   : std_logic_vector(7 downto 0);  -- cpsr(15:8)
66
   -- sext   : std_logic_vector(7 downto 0);  -- cpsr(23:16)
67
end record;
68
-- wrstg controlled part of CPSR
69
type apm_wrcpsr is record
70
   i      : std_logic;                  -- [7] irq
71
   f      : std_logic;                  -- [6] fiq
72
   t      : std_logic;                  -- [5] thumb
73
   mode   : std_logic_vector(4 downto 0);
74
-- pragma translate_off
75
--   dbgmode  : aba_atyp_dbgpmode;       -- readable pmode for dbg
76
-- pragma translate_on
77
end record;
78
-- complete CPSR
79
type apm_cpsr is record
80
   ex : apm_excpsr;
81
   wr : apm_wrcpsr;
82
end record;
83
 
84
-- Banked SPSR
85
type apm_spsr is record
86
    svc_spsr : apm_cpsr;
87
    abt_spsr : apm_cpsr;
88
    und_spsr : apm_cpsr;
89
    irq_spsr : apm_cpsr;
90
    fiq_spsr : apm_cpsr;
91
end record;
92
 
93
-- convert from stdlogic to spm_cpsr
94
function apm_stdtocpsr (
95
  data : std_logic_vector
96
) return apm_cpsr;
97
 
98
-- convert from spm_cpsr to stdlogic
99
function apm_cpsrtostd (
100
  cpsr : apm_cpsr
101
) return std_logic_vector;
102
 
103
-- assemble new cpsr for msr cmd
104
function apm_msr (
105
  insn : std_logic_vector(31 downto 0);
106
  newcpsr : apm_cpsr;
107
  oldcpsr : apm_cpsr
108
) return apm_cpsr;
109
 
110
constant APM_MSR_C : integer := 16;
111
constant APM_MSR_X : integer := 17;
112
constant APM_MSR_S : integer := 18;
113
constant APM_MSR_F : integer := 19;
114
 
115
-------------------------------------------------------------------------------
116
 
117
constant APM_RREAL_U : integer := 4; -- banked register range
118
constant APM_RREAL_D : integer := 0;
119
constant APM_REG_U : integer := 3;   -- logical register range
120
constant APM_REG_D : integer := 0;
121
constant APM_REG_LINK   : std_logic_vector(3 downto 0) := "1110";   -- link register
122
constant APM_REG_PC     : std_logic_vector(3 downto 0) := "1111";   -- programm counter
123
constant APM_RREAL_PC : std_logic_vector(4 downto 0) := "01111";  -- banked program counter
124
 
125
constant APM_REGLIST_SZ : integer := 16;
126
constant APM_REGLIST_pc : integer := 15;
127
 
128
-------------------------------------------------------------------------------
129
 
130
-- map to banked register of <mode>
131
function apm_bankreg(
132
  mode : in std_logic_vector(4 downto 0);
133
  addr : in std_logic_vector
134
) return std_logic_vector;
135
 
136
-- retrieve the banked spsr for <mode> 
137
function apm_bankspsr(
138
  mode : in  std_logic_vector(4 downto 0);
139
  spsr : in  apm_spsr
140
) return apm_cpsr;
141
 
142
-- set bank spsr
143
procedure apm_setspsr(
144
  mode : in  std_logic_vector(4 downto 0);
145
  spsr : inout  apm_spsr;
146
  cpsr : in  apm_cpsr
147
);
148
 
149
-- check weather <mode> has a spsr
150
function apm_is_hasspsr (
151
  mode : std_logic_vector(4 downto 0)
152
) return boolean;
153
 
154
end armpmodel;
155
 
156
package body armpmodel is
157
 
158
-------------------------------------------------------------------------------
159
 
160
function apm_is_privmode (
161
  mode : std_logic_vector(4 downto 0)
162
) return boolean is
163
  variable tmp : boolean;
164
begin
165
  tmp := true;
166
  if mode = APM_USR then
167
    tmp := false;
168
  end if;
169
  return tmp;
170
end;
171
 
172
-------------------------------------------------------------------------------
173
 
174
constant APM_N_C : integer := 31;
175
constant APM_Z_C : integer := 30;
176
constant APM_C_C : integer := 29;
177
constant APM_V_C : integer := 28;
178
constant APM_Q_C : integer := 27;
179
 
180
constant APM_I_C : integer := 7;
181
constant APM_F_C : integer := 6;
182
constant APM_T_C : integer := 5;
183
constant APM_MODE_U : integer := 4;
184
constant APM_MODE_D : integer := 0;
185
 
186
-- extensions
187
-- constant APM_FEXT_U : integer := 27;
188
-- constant APM_FEXT_D : integer := 24;
189
-- constant APM_XEXT_U : integer := 15;
190
-- constant APM_XEXT_D : integer := 8;
191
-- constant APM_SEXT_U : integer := 23;
192
-- constant APM_SEXT_D : integer := 16;
193
 
194
function apm_stdtocpsr (
195
  data : std_logic_vector
196
) return apm_cpsr is
197
  variable tmp : apm_cpsr;
198
begin
199
 
200
  tmp.ex.n := data(APM_N_C);
201
  tmp.ex.z := data(APM_Z_C);
202
  tmp.ex.c := data(APM_C_C);
203
  tmp.ex.v := data(APM_V_C);
204
 
205
  tmp.wr.i := data(APM_I_C);
206
  tmp.wr.f := data(APM_F_C);
207
  tmp.wr.t := data(APM_T_C);
208
  tmp.wr.mode := data(APM_MODE_U downto APM_MODE_D);
209
 
210
  -- extensions
211
  -- tmp.fext := data(ACP_FEXT_U downto ACP_FEXT_D);
212
  -- tmp.xext := data(ACP_XEXT_U downto ACP_XEXT_D);
213
  -- tmp.sext := data(ACP_SEXT_U downto ACP_SEXT_D);
214
 
215
  return tmp;
216
end;
217
 
218
function apm_cpsrtostd (
219
  cpsr : apm_cpsr
220
) return std_logic_vector is
221
  variable tmp : std_logic_vector(31 downto 0);
222
begin
223
  tmp := (others => '0');
224
 
225
  tmp(APM_N_C) := cpsr.ex.n;
226
  tmp(APM_Z_C) := cpsr.ex.z;
227
  tmp(APM_C_C) := cpsr.ex.c;
228
  tmp(APM_V_C) := cpsr.ex.v;
229
  tmp(APM_Q_C) := '0';
230
 
231
  tmp(APM_I_C) := cpsr.wr.i;
232
  tmp(APM_F_C) := cpsr.wr.f;
233
  tmp(APM_T_C) := cpsr.wr.t;
234
 
235
  tmp(APM_MODE_U downto APM_MODE_D) := cpsr.wr.mode;
236
 
237
  -- extensions
238
  -- tmp(ACP_FEXT_U downto ACP_FEXT_D) := cpsr.fext;
239
  -- tmp(ACP_XEXT_U downto ACP_XEXT_D) := cpsr.xext;
240
  -- tmp(ACP_SEXT_U downto ACP_SEXT_D) := cpsr.sext;
241
 
242
  return tmp;
243
end;
244
 
245
function apm_msr (
246
  insn : std_logic_vector(31 downto 0);
247
  newcpsr : apm_cpsr;
248
  oldcpsr : apm_cpsr
249
) return apm_cpsr is
250
  variable tmp : apm_cpsr;
251
begin
252
  tmp := oldcpsr;
253
 
254
  -- +---+---+---+---+---+------------+---+---+---+------+
255
  -- | n | z | c | v | q |   dnm(raz) | i | f | t | mode |
256
  -- +---+---+---+---+---+------------+---+---+---+------+
257
 
258
  -- $(del)
259
  -- if opcode[25] == 1
260
  --   operand = 8_bit_immediate Rotate_Right (rotate_imm * 2)
261
  -- else /* opcode[25] == 0 */
262
  --   operand = Rm
263
  --
264
  -- if R == 0 then
265
  --   if field_mask[0] == 1 and InAPrivilegedMode() then
266
  --   CPSR[7:0] = operand[7:0]
267
  --   if field_mask[1] == 1 and InAPrivilegedMode() then
268
  --   CPSR[15:8] = operand[15:8]
269
  --   if field_mask[2] == 1 and InAPrivilegedMode() then
270
  --   CPSR[23:16] = operand[23:16]
271
  --   if field_mask[3] == 1 then
272
  --   CPSR[31:24] = operand[31:24]
273
  -- else /* R == 1 */
274
  --   if field_mask[0] == 1 and CurrentModeHasSPSR() then
275
  --   SPSR[7:0] = operand[7:0]
276
  --   if field_mask[1] == 1 and CurrentModeHasSPSR() then
277
  --   SPSR[15:8] = operand[15:8]
278
  --   if field_mask[2] == 1 and CurrentModeHasSPSR() then
279
  --   SPSR[23:16] = operand[23:16]
280
  --   if field_mask[3] == 1 and CurrentModeHasSPSR() then
281
  --   SPSR[31:24] = operand[31:24]
282
  -- $(/del)
283
 
284
 
285
  if insn(APM_MSR_C) = '1' then
286
    tmp.wr.i := newcpsr.wr.i;
287
    tmp.wr.f := newcpsr.wr.f;
288
    tmp.wr.t := newcpsr.wr.t;
289
    tmp.wr.mode := newcpsr.wr.mode;
290
  end if;
291
  if insn(APM_MSR_X) = '1' then
292
    -- extensions
293
    -- tmp.xext := newcpsr.xext;
294
  end if;
295
  if insn(APM_MSR_S) = '1' then
296
    -- extensions
297
    -- tmp.sext := newcpsr.sext;
298
  end if;
299
  if insn(APM_MSR_F) = '1' then
300
    tmp.ex.n := newcpsr.ex.n;
301
    tmp.ex.z := newcpsr.ex.z;
302
    tmp.ex.c := newcpsr.ex.c;
303
    tmp.ex.v := newcpsr.ex.v;
304
    -- extensions
305
    -- tmp.ex.fext := newcpsr.fext;
306
  end if;
307
 
308
  return tmp;
309
end;
310
 
311
-------------------------------------------------------------------------------
312
 
313
-- banked register mapping:
314
-- 
315
--          USR     SYS     SVC     ABT     UND     IRQ     FIQ  
316
--       +-------+-------+-------+-------+-------+-------+-------+
317
--R0-R7  |      
318
--       +-------+---------------------------------------+-------+
319
--R8-R12 |                                                R16-R20
320
--       +-------+---------------------------------------+-------+
321
--R13    |                   R24    R26     R28    R30      R21 
322
--       +-------+---------------------------------------+-------+
323
--R14    |                   R25    R27     R29    R31      R22
324
--       +-------+---------------------------------------+-------+
325
 
326
function apm_bankreg(
327
  mode : in std_logic_vector(4 downto 0);
328
  addr : in std_logic_vector
329
) return std_logic_vector is
330
variable tmp  : std_logic_vector(addr'high+1 downto 0);  -- +1: return is 5bits
331
variable bank : std_logic_vector(addr'high+1 downto 0);
332
begin
333
  tmp := "0"&addr(addr'high downto 0);
334
  bank := "0"&addr(addr'high downto 0);
335
  case mode is
336
    when APM_USR =>
337
    when APM_SYS =>
338
    when APM_SVC =>
339
      bank := "1100" & not addr(0);
340
    when APM_ABT =>
341
      bank := "1101" & not addr(0);
342
    when APM_UND =>
343
      bank := "1110" & not addr(0);
344
    when APM_FIQ =>
345
      if addr(3) = '1' then
346
        bank(4 downto 3) := "10";
347
        tmp(4 downto 3) := "10";
348
      end if;
349
    when APM_IRQ =>
350
      bank := "1111" & not addr(0);
351
    when others =>
352
  end case;
353
  case addr(3 downto 0) is
354
    when "1101"|"1110" => tmp := bank;
355
    when others =>
356
  end case;
357
  return tmp;
358
end;
359
 
360
procedure apm_setspsr(
361
  mode : in  std_logic_vector(4 downto 0);
362
  spsr : inout  apm_spsr;
363
  cpsr : in  apm_cpsr
364
) is
365
begin
366
  case mode is
367
    when APM_SVC =>
368
      spsr.svc_SPSR := cpsr;
369
    when APM_ABT =>
370
      spsr.abt_SPSR := cpsr;
371
    when APM_UND =>
372
      spsr.und_SPSR := cpsr;
373
    when APM_IRQ =>
374
      spsr.irq_SPSR := cpsr;
375
    when APM_FIQ =>
376
      spsr.fiq_SPSR := cpsr;
377
    when others =>
378
  end case;
379
end;
380
 
381
function apm_bankspsr(
382
  mode : in  std_logic_vector(4 downto 0);
383
  spsr : in  apm_spsr
384
) return apm_cpsr is
385
variable tmp : apm_cpsr;
386
begin
387
  tmp := spsr.svc_spsr;
388
  case mode is
389
    when APM_SVC =>
390
      tmp := spsr.svc_spsr;
391
    when APM_ABT =>
392
      tmp := spsr.abt_spsr;
393
    when APM_UND =>
394
      tmp := spsr.und_spsr;
395
    when APM_IRQ =>
396
      tmp := spsr.irq_spsr;
397
    when APM_FIQ =>
398
      tmp := spsr.fiq_spsr;
399
    when others =>
400
  end case;
401
  return tmp;
402
end;
403
 
404
function apm_is_hasspsr (
405
  mode : std_logic_vector(4 downto 0)
406
) return boolean is
407
  variable tmp : boolean;
408
begin
409
  tmp := true;
410
  if mode = APM_USR or
411
     mode = APM_SYS then
412
    tmp := false;
413
  end if;
414
  return tmp;
415
end;
416
 
417
end armpmodel;

powered by: WebSVN 2.1.0

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