common.vhdl 17.9 KB
Newer Older
Anton Blanchard's avatar
Anton Blanchard committed
1 2
library ieee;
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
Anton Blanchard's avatar
Anton Blanchard committed
4 5 6 7 8

library work;
use work.decode_types.all;

package common is
9

10 11 12 13 14 15 16 17 18
    -- MSR bit numbers
    constant MSR_SF  : integer := (63 - 0);     -- Sixty-Four bit mode
    constant MSR_EE  : integer := (63 - 48);    -- External interrupt Enable
    constant MSR_PR  : integer := (63 - 49);    -- PRoblem state
    constant MSR_IR  : integer := (63 - 58);    -- Instruction Relocation
    constant MSR_DR  : integer := (63 - 59);    -- Data Relocation
    constant MSR_RI  : integer := (63 - 62);    -- Recoverable Interrupt
    constant MSR_LE  : integer := (63 - 63);    -- Little Endian

19 20 21 22 23
    -- SPR numbers
    subtype spr_num_t is integer range 0 to 1023;

    function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t;

24 25 26
    constant SPR_XER    : spr_num_t := 1;
    constant SPR_LR     : spr_num_t := 8;
    constant SPR_CTR    : spr_num_t := 9;
27 28
    constant SPR_DSISR  : spr_num_t := 18;
    constant SPR_DAR    : spr_num_t := 19;
29
    constant SPR_TB     : spr_num_t := 268;
30
    constant SPR_TBU    : spr_num_t := 269;
31
    constant SPR_DEC    : spr_num_t := 22;
32 33
    constant SPR_SRR0   : spr_num_t := 26;
    constant SPR_SRR1   : spr_num_t := 27;
34
    constant SPR_CFAR   : spr_num_t := 28;
35 36 37 38 39 40 41 42 43
    constant SPR_HSRR0  : spr_num_t := 314;
    constant SPR_HSRR1  : spr_num_t := 315;
    constant SPR_SPRG0  : spr_num_t := 272;
    constant SPR_SPRG1  : spr_num_t := 273;
    constant SPR_SPRG2  : spr_num_t := 274;
    constant SPR_SPRG3  : spr_num_t := 275;
    constant SPR_SPRG3U : spr_num_t := 259;
    constant SPR_HSPRG0 : spr_num_t := 304;
    constant SPR_HSPRG1 : spr_num_t := 305;
44 45
    constant SPR_PID    : spr_num_t := 48;
    constant SPR_PRTBL  : spr_num_t := 720;
46
    constant SPR_KAIVB   : spr_num_t := 850;
47

48 49 50 51 52 53
    -- GPR indices in the register file (GPR only)
    subtype gpr_index_t is std_ulogic_vector(4 downto 0);

    -- Extended GPR indice (can hold an SPR)
    subtype gspr_index_t is std_ulogic_vector(5 downto 0);

54 55 56 57 58 59 60 61
    -- Some SPRs are stored in the register file, they use the magic
    -- GPR numbers above 31.
    --
    -- The function fast_spr_num() returns the corresponding fast
    -- pseudo-GPR number for a given SPR number. The result MSB
    -- indicates if this is indeed a fast SPR. If clear, then
    -- the SPR is not stored in the GPR file.
    --
62 63 64 65 66 67 68
    function fast_spr_num(spr: spr_num_t) return gspr_index_t;

    -- Indices conversion functions
    function gspr_to_gpr(i: gspr_index_t) return gpr_index_t;
    function gpr_to_gspr(i: gpr_index_t) return gspr_index_t;
    function gpr_or_spr_to_gspr(g: gpr_index_t; s: gspr_index_t) return gspr_index_t;
    function is_fast_spr(s: gspr_index_t) return std_ulogic;
69

70 71 72 73 74 75 76 77 78 79 80 81
    -- The XER is split: the common bits (CA, OV, SO, OV32 and CA32) are
    -- in the CR file as a kind of CR extension (with a separate write
    -- control). The rest is stored as a fast SPR.
    type xer_common_t is record
	ca : std_ulogic;
	ca32 : std_ulogic;
	ov : std_ulogic;
	ov32 : std_ulogic;
	so : std_ulogic;
    end record;
    constant xerc_init : xer_common_t := (others => '0');

82 83
    type irq_state_t is (WRITE_SRR0, WRITE_SRR1);

Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
84 85 86 87 88 89 90 91 92 93
    -- For now, fixed 16 sources, make this either a parametric
    -- package of some sort or an unconstrainted array.
    type ics_to_icp_t is record
        -- Level interrupts only, ICS just keeps prsenting the
        -- highest priority interrupt. Once handling edge, something
        -- smarter involving handshake & reject support will be needed
        src : std_ulogic_vector(3 downto 0);
        pri : std_ulogic_vector(7 downto 0);
    end record;

94
    -- This needs to die...
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
95 96
    type ctrl_t is record
	tb: std_ulogic_vector(63 downto 0);
97 98
	dec: std_ulogic_vector(63 downto 0);
	msr: std_ulogic_vector(63 downto 0);
99
        cfar: std_ulogic_vector(63 downto 0);
100 101
	-- Kestrel arch interrupt vector base: location of the interrupt vector table for kestrel
	kaivb: std_ulogic_vector(61 downto 13);
102 103
	irq_state : irq_state_t;
	srr1: std_ulogic_vector(63 downto 0);
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
104 105 106 107
    end record;

    type Fetch1ToIcacheType is record
	req: std_ulogic;
Paul Mackerras's avatar
Paul Mackerras committed
108 109
        virt_mode : std_ulogic;
        priv_mode : std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
110
	stop_mark: std_ulogic;
111
        sequential: std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
112 113 114
	nia: std_ulogic_vector(63 downto 0);
    end record;

115
    type IcacheToDecode1Type is record
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
116 117
	valid: std_ulogic;
	stop_mark: std_ulogic;
Paul Mackerras's avatar
Paul Mackerras committed
118
        fetch_failed: std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
119 120 121 122 123 124 125 126 127
	nia: std_ulogic_vector(63 downto 0);
	insn: std_ulogic_vector(31 downto 0);
    end record;

    type Decode1ToDecode2Type is record
	valid: std_ulogic;
	stop_mark : std_ulogic;
	nia: std_ulogic_vector(63 downto 0);
	insn: std_ulogic_vector(31 downto 0);
128 129
	ispr1: gspr_index_t; -- (G)SPR used for branch condition (CTR) or mfspr
	ispr2: gspr_index_t; -- (G)SPR used for branch target (CTR, LR, TAR)
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
130
	decode: decode_rom_t;
131 132 133 134 135 136 137 138 139
        br_pred: std_ulogic; -- Branch was predicted to be taken
    end record;
    constant Decode1ToDecode2Init : Decode1ToDecode2Type :=
        (valid => '0', stop_mark => '0', nia => (others => '0'), insn => (others => '0'),
         ispr1 => (others => '0'), ispr2 => (others => '0'), decode => decode_rom_init, br_pred => '0');

    type Decode1ToFetch1Type is record
        redirect     : std_ulogic;
        redirect_nia : std_ulogic_vector(63 downto 0);
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
140 141 142 143
    end record;

    type Decode2ToExecute1Type is record
	valid: std_ulogic;
144
        unit : unit_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
145 146
	insn_type: insn_type_t;
	nia: std_ulogic_vector(63 downto 0);
147 148 149
	write_reg: gspr_index_t;
	read_reg1: gspr_index_t;
	read_reg2: gspr_index_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
150 151 152
	read_data1: std_ulogic_vector(63 downto 0);
	read_data2: std_ulogic_vector(63 downto 0);
	read_data3: std_ulogic_vector(63 downto 0);
153 154 155
        bypass_data1: std_ulogic;
        bypass_data2: std_ulogic;
        bypass_data3: std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
156
	cr: std_ulogic_vector(31 downto 0);
157
        bypass_cr : std_ulogic;
158
	xerc: xer_common_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
159 160
	lr: std_ulogic;
	rc: std_ulogic;
161
	oe: std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
162 163 164 165 166 167 168 169 170 171
	invert_a: std_ulogic;
	invert_out: std_ulogic;
	input_carry: carry_in_t;
	output_carry: std_ulogic;
	input_cr: std_ulogic;
	output_cr: std_ulogic;
	is_32bit: std_ulogic;
	is_signed: std_ulogic;
	insn: std_ulogic_vector(31 downto 0);
	data_len: std_ulogic_vector(3 downto 0);
172 173 174
	byte_reverse : std_ulogic;
	sign_extend : std_ulogic;			-- do we need to sign extend?
	update : std_ulogic;				-- is this an update instruction?
175
        reserve : std_ulogic;                           -- set for larx/stcx
176
        br_pred : std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
177 178
    end record;
    constant Decode2ToExecute1Init : Decode2ToExecute1Type :=
179
	(valid => '0', unit => NONE, insn_type => OP_ILLEGAL, bypass_data1 => '0', bypass_data2 => '0', bypass_data3 => '0',
180
         bypass_cr => '0', lr => '0', rc => '0', oe => '0', invert_a => '0',
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
181
	 invert_out => '0', input_carry => ZERO, output_carry => '0', input_cr => '0', output_cr => '0',
182
	 is_32bit => '0', is_signed => '0', xerc => xerc_init, reserve => '0', br_pred => '0',
183
         byte_reverse => '0', sign_extend => '0', update => '0', nia => (others => '0'), read_data1 => (others => '0'), read_data2 => (others => '0'), read_data3 => (others => '0'), cr => (others => '0'), insn => (others => '0'), data_len => (others => '0'), others => (others => '0'));
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
184

185
    type Execute1ToMultiplyType is record
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
186
	valid: std_ulogic;
187 188
	data1: std_ulogic_vector(63 downto 0);
	data2: std_ulogic_vector(63 downto 0);
189
	is_32bit: std_ulogic;
190
        neg_result: std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
191
    end record;
192 193
    constant Execute1ToMultiplyInit : Execute1ToMultiplyType := (valid => '0',
								 is_32bit => '0', neg_result => '0',
194
								 others => (others => '0'));
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
195

196
    type Execute1ToDividerType is record
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
197 198 199 200 201 202 203
	valid: std_ulogic;
	dividend: std_ulogic_vector(63 downto 0);
	divisor: std_ulogic_vector(63 downto 0);
	is_signed: std_ulogic;
	is_32bit: std_ulogic;
	is_extended: std_ulogic;
	is_modulus: std_ulogic;
204
        neg_result: std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
205
    end record;
206 207 208
    constant Execute1ToDividerInit: Execute1ToDividerType := (valid => '0', is_signed => '0', is_32bit => '0',
                                                              is_extended => '0', is_modulus => '0',
                                                              neg_result => '0', others => (others => '0'));
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
209 210 211

    type Decode2ToRegisterFileType is record
	read1_enable : std_ulogic;
212
	read1_reg : gspr_index_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
213
	read2_enable : std_ulogic;
214
	read2_reg : gspr_index_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
215
	read3_enable : std_ulogic;
216
	read3_reg : gpr_index_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
217 218 219 220 221 222 223 224 225 226 227 228 229 230
    end record;

    type RegisterFileToDecode2Type is record
	read1_data : std_ulogic_vector(63 downto 0);
	read2_data : std_ulogic_vector(63 downto 0);
	read3_data : std_ulogic_vector(63 downto 0);
    end record;

    type Decode2ToCrFileType is record
	read : std_ulogic;
    end record;

    type CrFileToDecode2Type is record
	read_cr_data   : std_ulogic_vector(31 downto 0);
231
	read_xerc_data : xer_common_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
232 233 234 235
    end record;

    type Execute1ToFetch1Type is record
	redirect: std_ulogic;
Paul Mackerras's avatar
Paul Mackerras committed
236 237
        virt_mode: std_ulogic;
        priv_mode: std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
238 239
	redirect_nia: std_ulogic_vector(63 downto 0);
    end record;
240 241
    constant Execute1ToFetch1Init : Execute1ToFetch1Type := (redirect => '0', virt_mode => '0',
                                                             priv_mode => '0', others => (others => '0'));
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
242

243
    type Execute1ToLoadstore1Type is record
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
244
	valid : std_ulogic;
Paul Mackerras's avatar
Paul Mackerras committed
245
        op : insn_type_t;                               -- what ld/st or m[tf]spr or TLB op to do
Paul Mackerras's avatar
Paul Mackerras committed
246
        nia : std_ulogic_vector(63 downto 0);
247
        insn : std_ulogic_vector(31 downto 0);
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
248 249 250
	addr1 : std_ulogic_vector(63 downto 0);
	addr2 : std_ulogic_vector(63 downto 0);
	data : std_ulogic_vector(63 downto 0);		-- data to write, unused for read
251
	write_reg : gpr_index_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
252
	length : std_ulogic_vector(3 downto 0);
253
        ci : std_ulogic;                                -- cache-inhibited load/store
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
254 255 256
	byte_reverse : std_ulogic;
	sign_extend : std_ulogic;			-- do we need to sign extend?
	update : std_ulogic;				-- is this an update instruction?
257
	update_reg : gpr_index_t;                      	-- if so, the register to update
258
	xerc : xer_common_t;
259 260
        reserve : std_ulogic;                           -- set for larx/stcx.
        rc : std_ulogic;                                -- set for stcx.
Paul Mackerras's avatar
Paul Mackerras committed
261
        virt_mode : std_ulogic;                         -- do translation through TLB
262
        priv_mode : std_ulogic;                         -- privileged mode (MSR[PR] = 0)
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
263
    end record;
264
    constant Execute1ToLoadstore1Init : Execute1ToLoadstore1Type := (valid => '0', op => OP_ILLEGAL, ci => '0', byte_reverse => '0',
265
                                                                     sign_extend => '0', update => '0', xerc => xerc_init,
266
                                                                     reserve => '0', rc => '0', virt_mode => '0', priv_mode => '0',
267 268
                                                                     nia => (others => '0'), insn => (others => '0'),
                                                                     addr1 => (others => '0'), addr2 => (others => '0'), data => (others => '0'), length => (others => '0'),
269
                                                                     others => (others => '0'));
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
270

271
    type Loadstore1ToExecute1Type is record
272
        busy : std_ulogic;
273
        exception : std_ulogic;
274 275 276 277
        invalid : std_ulogic;
        perm_error : std_ulogic;
        rc_error : std_ulogic;
        badtree : std_ulogic;
278
        segment_fault : std_ulogic;
Paul Mackerras's avatar
Paul Mackerras committed
279
        instr_fault : std_ulogic;
280 281
    end record;

Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
282
    type Loadstore1ToDcacheType is record
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
283
	valid : std_ulogic;
Paul Mackerras's avatar
Paul Mackerras committed
284
	load : std_ulogic;				-- is this a load
285
        dcbz : std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
286
	nc : std_ulogic;
287
        reserve : std_ulogic;
Paul Mackerras's avatar
Paul Mackerras committed
288
        virt_mode : std_ulogic;
289
        priv_mode : std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
290 291
	addr : std_ulogic_vector(63 downto 0);
	data : std_ulogic_vector(63 downto 0);
292 293 294 295 296 297 298 299
        byte_sel : std_ulogic_vector(7 downto 0);
    end record;

    type DcacheToLoadstore1Type is record
	valid : std_ulogic;
	data : std_ulogic_vector(63 downto 0);
        store_done : std_ulogic;
        error : std_ulogic;
300
        cache_paradox : std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
301 302
    end record;

303 304 305
    type Loadstore1ToMmuType is record
        valid : std_ulogic;
        tlbie : std_ulogic;
306
        slbia : std_ulogic;
307
        mtspr : std_ulogic;
Paul Mackerras's avatar
Paul Mackerras committed
308
        iside : std_ulogic;
309 310
        load  : std_ulogic;
        priv  : std_ulogic;
311
        sprn  : std_ulogic_vector(9 downto 0);
312 313 314 315 316
        addr  : std_ulogic_vector(63 downto 0);
        rs    : std_ulogic_vector(63 downto 0);
    end record;

    type MmuToLoadstore1Type is record
317 318 319 320 321 322 323
        done       : std_ulogic;
        invalid    : std_ulogic;
        badtree    : std_ulogic;
        segerr     : std_ulogic;
        perm_error : std_ulogic;
        rc_error   : std_ulogic;
        sprval     : std_ulogic_vector(63 downto 0);
324 325 326 327 328
    end record;

    type MmuToDcacheType is record
        valid : std_ulogic;
        tlbie : std_ulogic;
329
        doall : std_ulogic;
330
        tlbld : std_ulogic;
331 332 333 334 335 336 337
        addr  : std_ulogic_vector(63 downto 0);
        pte   : std_ulogic_vector(63 downto 0);
    end record;

    type DcacheToMmuType is record
        stall : std_ulogic;
        done  : std_ulogic;
338 339
        err   : std_ulogic;
        data  : std_ulogic_vector(63 downto 0);
340 341
    end record;

Paul Mackerras's avatar
Paul Mackerras committed
342 343 344
    type MmuToIcacheType is record
        tlbld : std_ulogic;
        tlbie : std_ulogic;
345
        doall : std_ulogic;
Paul Mackerras's avatar
Paul Mackerras committed
346 347 348 349
        addr  : std_ulogic_vector(63 downto 0);
        pte   : std_ulogic_vector(63 downto 0);
    end record;

350
    type Loadstore1ToWritebackType is record
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
351 352
	valid : std_ulogic;
	write_enable: std_ulogic;
353
	write_reg : gpr_index_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
354
	write_data : std_ulogic_vector(63 downto 0);
355
	xerc : xer_common_t;
356 357
        rc : std_ulogic;
        store_done : std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
358
    end record;
359
    constant Loadstore1ToWritebackInit : Loadstore1ToWritebackType := (valid => '0', write_enable => '0', xerc => xerc_init,
360
                                                                       rc => '0', store_done => '0', write_data => (others => '0'), others => (others => '0'));
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
361 362 363 364 365

    type Execute1ToWritebackType is record
	valid: std_ulogic;
	rc : std_ulogic;
	write_enable : std_ulogic;
366
	write_reg: gspr_index_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
367 368 369 370
	write_data: std_ulogic_vector(63 downto 0);
	write_cr_enable : std_ulogic;
	write_cr_mask : std_ulogic_vector(7 downto 0);
	write_cr_data : std_ulogic_vector(31 downto 0);
371 372
	write_xerc_enable : std_ulogic;
	xerc : xer_common_t;
373 374 375
        exc_write_enable : std_ulogic;
        exc_write_reg : gspr_index_t;
        exc_write_data : std_ulogic_vector(63 downto 0);
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
376
    end record;
377
    constant Execute1ToWritebackInit : Execute1ToWritebackType := (valid => '0', rc => '0', write_enable => '0',
378
								   write_cr_enable => '0', exc_write_enable => '0',
379
								   write_xerc_enable => '0', xerc => xerc_init,
380 381 382
                                   write_data => (others => '0'), write_cr_mask => (others => '0'),
                                   write_cr_data => (others => '0'), write_reg => (others => '0'),
                                   exc_write_reg => (others => '0'), exc_write_data => (others => '0'));
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
383

384
    type MultiplyToExecute1Type is record
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
385
	valid: std_ulogic;
386
	result: std_ulogic_vector(127 downto 0);
387
        overflow : std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
388
    end record;
389
    constant MultiplyToExecute1Init : MultiplyToExecute1Type := (valid => '0', overflow => '0',
390
								 others => (others => '0'));
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
391

392
    type DividerToExecute1Type is record
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
393 394
	valid: std_ulogic;
	write_reg_data: std_ulogic_vector(63 downto 0);
395
        overflow : std_ulogic;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
396
    end record;
397
    constant DividerToExecute1Init : DividerToExecute1Type := (valid => '0', overflow => '0',
398
                                                               others => (others => '0'));
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
399 400

    type WritebackToRegisterFileType is record
401
	write_reg : gspr_index_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
402 403 404
	write_data : std_ulogic_vector(63 downto 0);
	write_enable : std_ulogic;
    end record;
405
    constant WritebackToRegisterFileInit : WritebackToRegisterFileType := (write_enable => '0', write_data => (others => '0'), others => (others => '0'));
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
406 407 408 409 410

    type WritebackToCrFileType is record
	write_cr_enable : std_ulogic;
	write_cr_mask : std_ulogic_vector(7 downto 0);
	write_cr_data : std_ulogic_vector(31 downto 0);
411 412
	write_xerc_enable : std_ulogic;
	write_xerc_data : xer_common_t;
Benjamin Herrenschmidt's avatar
Benjamin Herrenschmidt committed
413
    end record;
414 415
    constant WritebackToCrFileInit : WritebackToCrFileType := (write_cr_enable => '0', write_xerc_enable => '0',
							       write_xerc_data => xerc_init,
416 417
							       write_cr_mask => (others => '0'),
							       write_cr_data => (others => '0'));
Michael Neuling's avatar
Michael Neuling committed
418

Anton Blanchard's avatar
Anton Blanchard committed
419 420 421
end common;

package body common is
422 423 424 425
    function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t is
    begin
	return to_integer(unsigned(insn(15 downto 11) & insn(20 downto 16)));
    end;
426
    function fast_spr_num(spr: spr_num_t) return gspr_index_t is
427
       variable n : integer range 0 to 31;
428 429 430 431
       -- tmp variable introduced as workaround for VCS compilation
       -- simulation was failing with subtype constraint mismatch error
       -- see GitHub PR #173
       variable tmp : std_ulogic_vector(4 downto 0);
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
    begin
       case spr is
       when SPR_LR =>
           n := 0;
       when SPR_CTR =>
           n:= 1;
       when SPR_SRR0 =>
           n := 2;
       when SPR_SRR1 =>
           n := 3;
       when SPR_HSRR0 =>
           n := 4;
       when SPR_HSRR1 =>
           n := 5;
       when SPR_SPRG0 =>
           n := 6;
       when SPR_SPRG1 =>
           n := 7;
       when SPR_SPRG2 =>
           n := 8;
       when SPR_SPRG3 | SPR_SPRG3U =>
           n := 9;
       when SPR_HSPRG0 =>
           n := 10;
       when SPR_HSPRG1 =>
           n := 11;
       when SPR_XER =>
           n := 12;
       when others =>
461
           n := 0;
462 463
           return "000000";
       end case;
464 465
       tmp := std_ulogic_vector(to_unsigned(n, 5));
       return "1" & tmp;
466
    end;
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490

    function gspr_to_gpr(i: gspr_index_t) return gpr_index_t is
    begin
	return i(4 downto 0);
    end;

    function gpr_to_gspr(i: gpr_index_t) return gspr_index_t is
    begin
	return "0" & i;
    end;

    function gpr_or_spr_to_gspr(g: gpr_index_t; s: gspr_index_t) return gspr_index_t is
    begin
	if s(5) = '1' then
	    return s;
	else
	    return gpr_to_gspr(g);
	end if;
    end;

    function is_fast_spr(s: gspr_index_t) return std_ulogic is
    begin
	return s(5);
    end;
Anton Blanchard's avatar
Anton Blanchard committed
491
end common;