Rework CR file and add forwarding

Handle the CR as a single field with per nibble enables. Forward any
writes in the same cycle.

If this proves to be an issue for timing, we may want to revisit
this in the future. For now, it keeps things simple.

Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
nia-debug
Anton Blanchard 5 years ago committed by Anton Blanchard
parent 7c2a2b7414
commit 9fbaea6f08

@ -79,14 +79,11 @@ package common is
end record; end record;


type Decode2ToCrFileType is record type Decode2ToCrFileType is record
read_cr_nr_1 : integer; read : std_ulogic;
read_cr_nr_2 : integer;
end record; end record;


type CrFileToDecode2Type is record type CrFileToDecode2Type is record
read_cr_data : std_ulogic_vector(31 downto 0); read_cr_data : std_ulogic_vector(31 downto 0);
read_cr_data_1 : std_ulogic_vector(3 downto 0);
read_cr_data_2 : std_ulogic_vector(3 downto 0);
end record; end record;


type Execute1ToFetch1Type is record type Execute1ToFetch1Type is record

@ -18,48 +18,43 @@ end entity cr_file;


architecture behaviour of cr_file is architecture behaviour of cr_file is
signal crs : std_ulogic_vector(31 downto 0) := (others => '0'); signal crs : std_ulogic_vector(31 downto 0) := (others => '0');
signal crs_updated : std_ulogic_vector(31 downto 0) := (others => '0');
begin begin
-- synchronous writes cr_create_0: process(all)
cr_write_0: process(clk)
variable hi, lo : integer := 0; variable hi, lo : integer := 0;
begin begin
if rising_edge(clk) then
if w_in.write_cr_enable = '1' then
report "Writing " & to_hstring(w_in.write_cr_data) & " to CR mask " & to_hstring(w_in.write_cr_mask);

for i in 0 to 7 loop for i in 0 to 7 loop
if w_in.write_cr_mask(i) = '1' then if w_in.write_cr_mask(i) = '1' then
lo := i*4; lo := i*4;
hi := lo + 3; hi := lo + 3;
crs(hi downto lo) <= w_in.write_cr_data(hi downto lo); crs_updated(hi downto lo) <= w_in.write_cr_data(hi downto lo);
end if; end if;
end loop; end loop;
end process;

-- synchronous writes
cr_write_0: process(clk)
begin
if rising_edge(clk) then
if w_in.write_cr_enable = '1' then
report "Writing " & to_hstring(w_in.write_cr_data) & " to CR mask " & to_hstring(w_in.write_cr_mask);
crs <= crs_updated;
end if; end if;
end if; end if;
end process cr_write_0; end process;


-- asynchronous reads -- asynchronous reads
cr_read_0: process(all) cr_read_0: process(all)
variable hi, lo : integer := 0; variable hi, lo : integer := 0;
begin begin
--lo := (7-d_in.read_cr_nr_1)*4; -- just return the entire CR to make mfcrf easier for now
--hi := lo + 3; if d_in.read = '1' then

report "Reading CR " & to_hstring(crs_updated);
--report "read " & integer'image(d_in.read_cr_nr_1) & " from CR " & to_hstring(crs(hi downto lo)); end if;
--d_out.read_cr_data_1 <= crs(hi downto lo); if w_in.write_cr_enable then

d_out.read_cr_data <= crs_updated;
-- Also return the entire CR to make mfcrf easier for now else
report "read CR " & to_hstring(crs);
d_out.read_cr_data <= crs; d_out.read_cr_data <= crs;

end if;
-- -- Forward any written data end process;
-- if w_in.write_cr_enable = '1' then
-- if d_in.read_cr_nr_1 = w_in.write_cr_nr then
-- d_out.read_cr_data_1 <= w_in.write_cr_data;
-- end if;
-- if d_in.read_cr_nr_2 = w_in.write_cr_nr then
-- d_out.read_cr_data_2 <= w_in.write_cr_data;
-- end if;
-- end if;
end process cr_read_0;
end architecture behaviour; end architecture behaviour;

@ -43,19 +43,19 @@ architecture behaviour of decode1 is
PPC_ATTN => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), PPC_ATTN => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'),
PPC_B => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'), PPC_B => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'),
--PPC_BA --PPC_BA
PPC_BC => (ALU, OP_BC, NONE, CONST_BD, NONE, NONE, BO, BI, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'), PPC_BC => (ALU, OP_BC, NONE, CONST_BD, NONE, NONE, BO, BI, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'),
--PPC_BCA --PPC_BCA
PPC_BCCTR => (ALU, OP_BCCTR, NONE, NONE, NONE, NONE, BO, BI, BH, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'), PPC_BCCTR => (ALU, OP_BCCTR, NONE, NONE, NONE, NONE, BO, BI, BH, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'),
--PPC_BCLA --PPC_BCLA
PPC_BCLR => (ALU, OP_BCLR, NONE, NONE, NONE, NONE, BO, BI, BH, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'), PPC_BCLR => (ALU, OP_BCLR, NONE, NONE, NONE, NONE, BO, BI, BH, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'),
--PPC_BCTAR --PPC_BCTAR
--PPC_BPERM --PPC_BPERM
PPC_CMP => (ALU, OP_CMP, RA, RB, NONE, NONE, BF, L, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), PPC_CMP => (ALU, OP_CMP, RA, RB, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'),
PPC_CMPB => (ALU, OP_CMPB, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), PPC_CMPB => (ALU, OP_CMPB, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'),
--PPC_CMPEQB --PPC_CMPEQB
PPC_CMPI => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, BF, L, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), PPC_CMPI => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'),
PPC_CMPL => (ALU, OP_CMPL, RA, RB, NONE, NONE, BF, L, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), PPC_CMPL => (ALU, OP_CMPL, RA, RB, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'),
PPC_CMPLI => (ALU, OP_CMPL, RA, CONST_UI, NONE, NONE, BF, L, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), PPC_CMPLI => (ALU, OP_CMPL, RA, CONST_UI, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'),
--PPC_CMPRB --PPC_CMPRB
PPC_CNTLZD => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), PPC_CNTLZD => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'),
PPC_CNTLZW => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), PPC_CNTLZW => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'),
@ -90,7 +90,7 @@ architecture behaviour of decode1 is
--PPC_EXTSWSLI --PPC_EXTSWSLI
--PPC_ICBI --PPC_ICBI
PPC_ICBT => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), PPC_ICBT => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'),
PPC_ISEL => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), PPC_ISEL => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'),
PPC_ISYNC => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), PPC_ISYNC => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'),
PPC_LBARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0'), PPC_LBARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0'),
--CONST_LI matches CONST_SI, so reuse it --CONST_LI matches CONST_SI, so reuse it

@ -184,6 +184,8 @@ begin
r_out.read3_reg <= insn_rs(d.insn) when d.decode.input_reg_c = RS else r_out.read3_reg <= insn_rs(d.insn) when d.decode.input_reg_c = RS else
(others => '0'); (others => '0');


c_out.read <= d.decode.input_cr;

decode2_1: process(all) decode2_1: process(all)
variable mul_a : std_ulogic_vector(63 downto 0); variable mul_a : std_ulogic_vector(63 downto 0);
variable mul_b : std_ulogic_vector(63 downto 0); variable mul_b : std_ulogic_vector(63 downto 0);

@ -56,7 +56,6 @@ begin
end if; end if;


if e.write_cr_enable = '1' then if e.write_cr_enable = '1' then
report "Writing CR ";
c_tmp.write_cr_enable <= '1'; c_tmp.write_cr_enable <= '1';
c_tmp.write_cr_mask <= e.write_cr_mask; c_tmp.write_cr_mask <= e.write_cr_mask;
c_tmp.write_cr_data <= e.write_cr_data; c_tmp.write_cr_data <= e.write_cr_data;
@ -81,7 +80,6 @@ begin
w_tmp.write_data <= m.write_reg_data; w_tmp.write_data <= m.write_reg_data;
end if; end if;
if m.write_cr_enable = '1' then if m.write_cr_enable = '1' then
report "Writing CR ";
c_tmp.write_cr_enable <= '1'; c_tmp.write_cr_enable <= '1';
c_tmp.write_cr_mask <= m.write_cr_mask; c_tmp.write_cr_mask <= m.write_cr_mask;
c_tmp.write_cr_data <= m.write_cr_data; c_tmp.write_cr_data <= m.write_cr_data;

Loading…
Cancel
Save