-- GPR indices in the register file (GPR only)
subtype gpr_index_t is std_ulogic_vector(4 downto 0);
- -- Extended GPR index (can hold an SPR or a FPR)
- subtype gspr_index_t is std_ulogic_vector(6 downto 0);
+ -- Extended GPR index (can hold a GPR or a FPR)
+ subtype gspr_index_t is std_ulogic_vector(5 downto 0);
-- FPR indices
subtype fpr_index_t is std_ulogic_vector(4 downto 0);
- -- Some SPRs are stored in the register file, they use the magic
- -- GPR numbers above 31.
+ -- FPRs are stored in the register file, using GSPR
+ -- numbers from 32 to 63.
--
- -- 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.
- --
- -- FPRs are also stored in the register file, using GSPR
- -- numbers from 64 to 95.
- --
- 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;
function fpr_to_gspr(f: fpr_index_t) return gspr_index_t;
-- The XER is split: the common bits (CA, OV, SO, OV32 and CA32) are
stop_mark : std_ulogic;
nia: std_ulogic_vector(63 downto 0);
insn: std_ulogic_vector(31 downto 0);
- 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)
- ispro: gspr_index_t; -- (G)SPR written with LR or CTR
decode: decode_rom_t;
br_pred: std_ulogic; -- Branch was predicted to be taken
big_endian: std_ulogic;
end record;
constant Decode1ToDecode2Init : Decode1ToDecode2Type :=
(valid => '0', stop_mark => '0', nia => (others => '0'), insn => (others => '0'),
- ispr1 => (others => '0'), ispr2 => (others => '0'), ispro => (others => '0'),
decode => decode_rom_init, br_pred => '0', big_endian => '0',
spr_info => spr_id_init, ram_spr => ram_spr_info_init);
begin
return to_integer(unsigned(insn(15 downto 11) & insn(20 downto 16)));
end;
- function fast_spr_num(spr: spr_num_t) return gspr_index_t is
- begin
- return "0000000";
- end;
function gspr_to_gpr(i: gspr_index_t) return gpr_index_t is
begin
function gpr_to_gspr(i: gpr_index_t) return gspr_index_t is
begin
- return "00" & 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);
+ return "0" & i;
end;
function fpr_to_gspr(f: fpr_index_t) return gspr_index_t is
begin
- return "10" & f;
+ return "1" & f;
end;
function tag_match(tag1 : instr_tag_t; tag2 : instr_tag_t) return boolean is
-- addpcis
2#001# => (ALU, NONE, OP_ADD, CIA, CONST_DXHI4, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE),
-- bclr, bcctr, bctar
- 2#100# => (ALU, NONE, OP_BCREG, NONE, NONE, NONE, SPR, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', NONE),
+ 2#100# => (ALU, NONE, OP_BCREG, NONE, NONE, NONE, NONE, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', NONE),
-- isync
2#111# => (ALU, NONE, OP_ISYNC, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE),
-- rfid
2#1001000000# => (ALU, NONE, OP_MCRXRX, NONE, NONE, NONE, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- mcrxrx
2#0000010011# => (ALU, NONE, OP_MFCR, NONE, NONE, NONE, RT, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- mfcr/mfocrf
2#0001010011# => (ALU, NONE, OP_MFMSR, NONE, NONE, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', NONE), -- mfmsr
- 2#0101010011# => (ALU, NONE, OP_MFSPR, SPR, NONE, RS, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- mfspr
+ 2#0101010011# => (ALU, NONE, OP_MFSPR, NONE, NONE, RS, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- mfspr
2#0100001001# => (DVU, NONE, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- modud
2#0100001011# => (DVU, NONE, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '0', NONE), -- moduw
2#1100001001# => (DVU, NONE, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', NONE), -- modsd
2#0010010000# => (ALU, NONE, OP_MTCRF, NONE, NONE, RS, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- mtcrf/mtocrf
2#0010010010# => (ALU, NONE, OP_MTMSRD, NONE, NONE, RS, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '0', NONE), -- mtmsr
2#0010110010# => (ALU, NONE, OP_MTMSRD, NONE, NONE, RS, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- mtmsrd # ignore top bits and d
- 2#0111010011# => (ALU, NONE, OP_MTSPR, NONE, NONE, RS, SPR, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- mtspr
+ 2#0111010011# => (ALU, NONE, OP_MTSPR, NONE, NONE, RS, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- mtspr
2#0001001001# => (ALU, NONE, OP_MUL_H64, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0', NONE), -- mulhd
2#0000001001# => (ALU, NONE, OP_MUL_H64, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0', NONE), -- mulhdu
2#0001001011# => (ALU, NONE, OP_MUL_H32, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '0', NONE), -- mulhw
-- major opcode 31, lots of things
v.decode := decode_op_31_array(to_integer(unsigned(f_in.insn(10 downto 1))));
- -- Work out ispr1/ispro independent of v.decode since they seem to be critical path
- v.ispr1 := fast_spr_num(sprn);
- v.ispro := fast_spr_num(sprn);
-
if std_match(f_in.insn(10 downto 1), "01-1010011") then
-- mfspr or mtspr
-- Make mtspr to slow SPRs single issue
constant decode_output_reg_init : decode_output_reg_t := ('0', (others => '0'));
function decode_input_reg_a (t : input_reg_a_t; insn_in : std_ulogic_vector(31 downto 0);
- ispr : gspr_index_t;
instr_addr : std_ulogic_vector(63 downto 0))
return decode_input_reg_t is
begin
if t = RA or (t = RA_OR_ZERO and insn_ra(insn_in) /= "00000") then
return ('1', gpr_to_gspr(insn_ra(insn_in)), (others => '0'));
- elsif t = SPR then
- -- ISPR must be either a valid fast SPR number or all 0 for a slow SPR.
- -- If it's all 0, we don't treat it as a dependency as slow SPRs
- -- operations are single issue.
- --
- assert is_fast_spr(ispr) = '1' or ispr = "0000000"
- report "Decode A says SPR but ISPR is invalid:" &
- to_hstring(ispr) severity failure;
- return (is_fast_spr(ispr), ispr, (others => '0'));
elsif t = CIA then
return ('0', (others => '0'), instr_addr);
elsif HAS_FPU and t = FRA then
end if;
end;
- function decode_input_reg_b (t : input_reg_b_t; insn_in : std_ulogic_vector(31 downto 0);
- ispr : gspr_index_t) return decode_input_reg_t is
+ function decode_input_reg_b (t : input_reg_b_t; insn_in : std_ulogic_vector(31 downto 0))
+ return decode_input_reg_t is
variable ret : decode_input_reg_t;
begin
case t is
ret := ('0', (others => '0'), x"00000000000000" & "00" & insn_in(1) & insn_in(15 downto 11));
when CONST_SH32 =>
ret := ('0', (others => '0'), x"00000000000000" & "000" & insn_in(15 downto 11));
- when SPR =>
- -- ISPR must be either a valid fast SPR number or all 0 for a slow SPR.
- -- If it's all 0, we don't treat it as a dependency as slow SPRs
- -- operations are single issue.
- assert is_fast_spr(ispr) = '1' or ispr = "0000000"
- report "Decode B says SPR but ISPR is invalid:" &
- to_hstring(ispr) severity failure;
- ret := (is_fast_spr(ispr), ispr, (others => '0'));
when NONE =>
ret := ('0', (others => '0'), (others => '0'));
end case;
end case;
end;
- function decode_output_reg (t : output_reg_a_t; insn_in : std_ulogic_vector(31 downto 0);
- ispr : gspr_index_t) return decode_output_reg_t is
+ function decode_output_reg (t : output_reg_a_t; insn_in : std_ulogic_vector(31 downto 0))
+ return decode_output_reg_t is
begin
case t is
when RT =>
if HAS_FPU then
return ('1', fpr_to_gspr(insn_frt(insn_in)));
else
- return ('0', "0000000");
+ return ('0', "000000");
end if;
- when SPR =>
- -- ISPR must be either a valid fast SPR number or all 0 for a slow SPR.
- -- If it's all 0, we don't treat it as a dependency as slow SPRs
- -- operations are single issue.
- assert is_fast_spr(ispr) = '1' or ispr = "0000000"
- report "Decode B says SPR but ISPR is invalid:" &
- to_hstring(ispr) severity failure;
- return (is_fast_spr(ispr), ispr);
when NONE =>
- return ('0', "0000000");
+ return ('0', "000000");
end case;
end;
decoded_reg_c <= decode_input_reg_init;
decoded_reg_o <= decode_output_reg_init;
if d_in.valid = '1' then
- decoded_reg_a <= decode_input_reg_a (d_in.decode.input_reg_a, d_in.insn, d_in.ispr1, d_in.nia);
- decoded_reg_b <= decode_input_reg_b (d_in.decode.input_reg_b, d_in.insn, d_in.ispr2);
+ decoded_reg_a <= decode_input_reg_a (d_in.decode.input_reg_a, d_in.insn, d_in.nia);
+ decoded_reg_b <= decode_input_reg_b (d_in.decode.input_reg_b, d_in.insn);
decoded_reg_c <= decode_input_reg_c (d_in.decode.input_reg_c, d_in.insn);
- decoded_reg_o <= decode_output_reg (d_in.decode.output_reg_a, d_in.insn, d_in.ispro);
+ decoded_reg_o <= decode_output_reg (d_in.decode.output_reg_a, d_in.insn);
end if;
r_out.read1_enable <= decoded_reg_a.reg_valid;
v.e.result_sel := result_select(op);
v.e.sub_select := subresult_select(op);
if op = OP_MFSPR then
- if is_fast_spr(d_in.ispr1) = '1' then
- v.e.result_sel := "000"; -- adder_result, effectively a_in
- elsif d_in.ram_spr.valid = '1' then
+ if d_in.ram_spr.valid = '1' then
v.e.result_sel := "101"; -- ramspr_result
elsif d_in.spr_info.valid = '0' then
-- Privileged mfspr to invalid/unimplemented SPR numbers