Rework pipeline, add stall and flush signals

This adds stall and flush signals to the pipeline.

Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
pull/42/head
Anton Blanchard 5 years ago committed by Anton Blanchard
parent 3b32abcb5d
commit 92a7152370

@ -13,7 +13,6 @@ package common is
end record; end record;


type Fetch1ToFetch2Type is record type Fetch1ToFetch2Type is record
valid: std_ulogic;
nia: std_ulogic_vector(63 downto 0); nia: std_ulogic_vector(63 downto 0);
end record; end record;



@ -60,9 +60,15 @@ architecture behave of core is
signal multiply_to_writeback: MultiplyToWritebackType; signal multiply_to_writeback: MultiplyToWritebackType;


-- local signals -- local signals
signal fetch_enable: std_ulogic := '0'; signal fetch1_stall_in : std_ulogic;
signal fetch2_stall_in : std_ulogic;
signal fetch2_stall_out : std_ulogic;
signal decode1_stall_in : std_ulogic;
signal decode2_stall_out : std_ulogic;

signal flush: std_ulogic;

signal complete: std_ulogic; signal complete: std_ulogic;
signal first_fetch: std_ulogic := '0';


signal terminate: std_ulogic; signal terminate: std_ulogic;
begin begin
@ -71,19 +77,27 @@ begin


fetch1_0: entity work.fetch1 fetch1_0: entity work.fetch1
generic map (RESET_ADDRESS => (others => '0')) generic map (RESET_ADDRESS => (others => '0'))
port map (clk => clk, rst => rst, fetch_one_in => fetch_enable, port map (clk => clk, rst => rst, stall_in => fetch1_stall_in, flush_in => flush,
e_in => execute1_to_fetch1, f_out => fetch1_to_fetch2); e_in => execute1_to_fetch1, f_out => fetch1_to_fetch2);


fetch1_stall_in <= fetch2_stall_out or decode2_stall_out;

fetch2_0: entity work.fetch2 fetch2_0: entity work.fetch2
port map (clk => clk, wishbone_in => wishbone_insn_in, port map (clk => clk, rst => rst, stall_in => fetch2_stall_in,
stall_out => fetch2_stall_out, flush_in => flush, wishbone_in => wishbone_insn_in,
wishbone_out => wishbone_insn_out, f_in => fetch1_to_fetch2, wishbone_out => wishbone_insn_out, f_in => fetch1_to_fetch2,
f_out => fetch2_to_decode1); f_out => fetch2_to_decode1);


fetch2_stall_in <= decode2_stall_out;

decode1_0: entity work.decode1 decode1_0: entity work.decode1
port map (clk => clk, f_in => fetch2_to_decode1, d_out => decode1_to_decode2); port map (clk => clk, rst => rst, stall_in => decode1_stall_in, flush_in => flush, f_in => fetch2_to_decode1, d_out => decode1_to_decode2);

decode1_stall_in <= decode2_stall_out;


decode2_0: entity work.decode2 decode2_0: entity work.decode2
port map (clk => clk, d_in => decode1_to_decode2, e_out => decode2_to_execute1, port map (clk => clk, rst => rst, stall_out => decode2_stall_out, flush_in => flush,
complete_in => complete, d_in => decode1_to_decode2, e_out => decode2_to_execute1,
l_out => decode2_to_loadstore1, m_out => decode2_to_multiply, l_out => decode2_to_loadstore1, m_out => decode2_to_multiply,
r_in => register_file_to_decode2, r_out => decode2_to_register_file, r_in => register_file_to_decode2, r_out => decode2_to_register_file,
c_in => cr_file_to_decode2, c_out => decode2_to_cr_file); c_in => cr_file_to_decode2, c_out => decode2_to_cr_file);
@ -99,7 +113,7 @@ begin


execute1_0: entity work.execute1 execute1_0: entity work.execute1
generic map (SIM => SIM) generic map (SIM => SIM)
port map (clk => clk, e_in => decode2_to_execute1, f_out => execute1_to_fetch1, port map (clk => clk, flush_out => flush, e_in => decode2_to_execute1, f_out => execute1_to_fetch1,
e_out => execute1_to_execute2, terminate_out => terminate); e_out => execute1_to_execute2, terminate_out => terminate);


execute2_0: entity work.execute2 execute2_0: entity work.execute2
@ -121,21 +135,4 @@ begin
m_in => multiply_to_writeback, w_out => writeback_to_register_file, m_in => multiply_to_writeback, w_out => writeback_to_register_file,
c_out => writeback_to_cr_file, complete_out => complete); c_out => writeback_to_cr_file, complete_out => complete);


-- Only single issue until we add bypass support
single_issue_0: process(clk)
begin
if (rising_edge(clk)) then
if rst = '1' then
first_fetch <= '1';
else
if first_fetch = '1' then
fetch_enable <= '1';
first_fetch <= '0';
else
fetch_enable <= complete;
end if;
end if;
end if;
end process single_issue_0;

end behave; end behave;

@ -8,15 +8,19 @@ use work.decode_types.all;


entity decode1 is entity decode1 is
port ( port (
clk : in std_ulogic; clk : in std_ulogic;
rst : in std_ulogic;


f_in : in Fetch2ToDecode1Type; stall_in : in std_ulogic;
d_out : out Decode1ToDecode2Type flush_in : in std_ulogic;

f_in : in Fetch2ToDecode1Type;
d_out : out Decode1ToDecode2Type
); );
end entity decode1; end entity decode1;


architecture behaviour of decode1 is architecture behaviour of decode1 is
signal f : Fetch2ToDecode1Type := Fetch2ToDecode1Init; signal r, rin : Decode1ToDecode2Type;


type decode_rom_array_t is array(ppc_insn_t) of decode_rom_t; type decode_rom_array_t is array(ppc_insn_t) of decode_rom_t;


@ -230,610 +234,616 @@ begin
decode1_0: process(clk) decode1_0: process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
f <= f_in; -- Output state remains unchanged on stall, unless we are flushing
if rst = '1' or flush_in = '1' or stall_in = '0' then
r <= rin;
end if;
end if; end if;
end process; end process;


decode1_1: process(all) decode1_1: process(all)
variable v : Decode1ToDecode2Type;
variable ppc_insn: ppc_insn_t; variable ppc_insn: ppc_insn_t;
begin begin
d_out <= Decode1ToDecode2Init; v := r;

v.valid := f_in.valid;

ppc_insn := PPC_ILLEGAL; ppc_insn := PPC_ILLEGAL;


d_out.valid <= f.valid; if f_in.valid then
v.nia := f_in.nia;
v.insn := f_in.insn;


if f.valid then report "Decode insn " & to_hstring(f_in.insn) & " at " & to_hstring(f_in.nia);
d_out.nia <= f.nia;
d_out.insn <= f.insn;


report "Decode insn " & to_hstring(f.insn); if std_match(f_in.insn, "011111---------------0100001010-") then
if std_match(f.insn, "011111---------------0100001010-") then
report "PPC_add"; report "PPC_add";
ppc_insn := PPC_ADD; ppc_insn := PPC_ADD;
elsif std_match(f.insn, "011111---------------0000001010-") then elsif std_match(f_in.insn, "011111---------------0000001010-") then
report "PPC_addc"; report "PPC_addc";
ppc_insn := PPC_ADDC; ppc_insn := PPC_ADDC;
elsif std_match(f.insn, "011111---------------0010001010-") then elsif std_match(f_in.insn, "011111---------------0010001010-") then
report "PPC_adde"; report "PPC_adde";
ppc_insn := PPC_ADDE; ppc_insn := PPC_ADDE;
elsif std_match(f.insn, "011111---------------0010101010-") then elsif std_match(f_in.insn, "011111---------------0010101010-") then
report "PPC_addex"; report "PPC_addex";
ppc_insn := PPC_ADDEX; ppc_insn := PPC_ADDEX;
elsif std_match(f.insn, "001110--------------------------") then elsif std_match(f_in.insn, "001110--------------------------") then
report "PPC_addi"; report "PPC_addi";
ppc_insn := PPC_ADDI; ppc_insn := PPC_ADDI;
elsif std_match(f.insn, "001100--------------------------") then elsif std_match(f_in.insn, "001100--------------------------") then
report "PPC_addic"; report "PPC_addic";
ppc_insn := PPC_ADDIC; ppc_insn := PPC_ADDIC;
elsif std_match(f.insn, "001101--------------------------") then elsif std_match(f_in.insn, "001101--------------------------") then
report "PPC_addic."; report "PPC_addic.";
ppc_insn := PPC_ADDIC_RC; ppc_insn := PPC_ADDIC_RC;
elsif std_match(f.insn, "001111--------------------------") then elsif std_match(f_in.insn, "001111--------------------------") then
report "PPC_addis"; report "PPC_addis";
ppc_insn := PPC_ADDIS; ppc_insn := PPC_ADDIS;
elsif std_match(f.insn, "011111---------------0011101010-") then elsif std_match(f_in.insn, "011111---------------0011101010-") then
report "PPC_addme"; report "PPC_addme";
ppc_insn := PPC_ADDME; ppc_insn := PPC_ADDME;
elsif std_match(f.insn, "010011--------------------00010-") then elsif std_match(f_in.insn, "010011--------------------00010-") then
report "PPC_addpcis"; report "PPC_addpcis";
ppc_insn := PPC_ADDPCIS; ppc_insn := PPC_ADDPCIS;
elsif std_match(f.insn, "011111---------------0011001010-") then elsif std_match(f_in.insn, "011111---------------0011001010-") then
report "PPC_addze"; report "PPC_addze";
ppc_insn := PPC_ADDZE; ppc_insn := PPC_ADDZE;
elsif std_match(f.insn, "011111---------------0000011100-") then elsif std_match(f_in.insn, "011111---------------0000011100-") then
report "PPC_and"; report "PPC_and";
ppc_insn := PPC_AND; ppc_insn := PPC_AND;
elsif std_match(f.insn, "011111---------------0000111100-") then elsif std_match(f_in.insn, "011111---------------0000111100-") then
report "PPC_andc"; report "PPC_andc";
ppc_insn := PPC_ANDC; ppc_insn := PPC_ANDC;
elsif std_match(f.insn, "011100--------------------------") then elsif std_match(f_in.insn, "011100--------------------------") then
report "PPC_andi."; report "PPC_andi.";
ppc_insn := PPC_ANDI_RC; ppc_insn := PPC_ANDI_RC;
elsif std_match(f.insn, "011101--------------------------") then elsif std_match(f_in.insn, "011101--------------------------") then
report "PPC_andis."; report "PPC_andis.";
ppc_insn := PPC_ANDIS_RC; ppc_insn := PPC_ANDIS_RC;
elsif std_match(f.insn, "000000---------------0100000000-") then elsif std_match(f_in.insn, "000000---------------0100000000-") then
report "PPC_attn"; report "PPC_attn";
ppc_insn := PPC_ATTN; ppc_insn := PPC_ATTN;
elsif std_match(f.insn, "010010------------------------0-") then elsif std_match(f_in.insn, "010010------------------------0-") then
report "PPC_b"; report "PPC_b";
ppc_insn := PPC_B; ppc_insn := PPC_B;
elsif std_match(f.insn, "010010------------------------1-") then elsif std_match(f_in.insn, "010010------------------------1-") then
report "PPC_ba"; report "PPC_ba";
ppc_insn := PPC_BA; ppc_insn := PPC_BA;
elsif std_match(f.insn, "010000------------------------0-") then elsif std_match(f_in.insn, "010000------------------------0-") then
report "PPC_bc"; report "PPC_bc";
ppc_insn := PPC_BC; ppc_insn := PPC_BC;
elsif std_match(f.insn, "010000------------------------10") then elsif std_match(f_in.insn, "010000------------------------10") then
report "PPC_bca"; report "PPC_bca";
ppc_insn := PPC_BCA; ppc_insn := PPC_BCA;
elsif std_match(f.insn, "010011---------------1000010000-") then elsif std_match(f_in.insn, "010011---------------1000010000-") then
report "PPC_bcctr"; report "PPC_bcctr";
ppc_insn := PPC_BCCTR; ppc_insn := PPC_BCCTR;
elsif std_match(f.insn, "010000------------------------11") then elsif std_match(f_in.insn, "010000------------------------11") then
report "PPC_bcla"; report "PPC_bcla";
ppc_insn := PPC_BCLA; ppc_insn := PPC_BCLA;
elsif std_match(f.insn, "010011---------------0000010000-") then elsif std_match(f_in.insn, "010011---------------0000010000-") then
report "PPC_bclr"; report "PPC_bclr";
ppc_insn := PPC_BCLR; ppc_insn := PPC_BCLR;
elsif std_match(f.insn, "010011---------------1000110000-") then elsif std_match(f_in.insn, "010011---------------1000110000-") then
report "PPC_bctar"; report "PPC_bctar";
ppc_insn := PPC_BCTAR; ppc_insn := PPC_BCTAR;
elsif std_match(f.insn, "011111---------------0011111100-") then elsif std_match(f_in.insn, "011111---------------0011111100-") then
report "PPC_bperm"; report "PPC_bperm";
ppc_insn := PPC_BPERM; ppc_insn := PPC_BPERM;
elsif std_match(f.insn, "011111---------------0000000000-") then elsif std_match(f_in.insn, "011111---------------0000000000-") then
report "PPC_cmp"; report "PPC_cmp";
ppc_insn := PPC_CMP; ppc_insn := PPC_CMP;
elsif std_match(f.insn, "011111---------------0111111100-") then elsif std_match(f_in.insn, "011111---------------0111111100-") then
report "PPC_cmpb"; report "PPC_cmpb";
ppc_insn := PPC_CMPB; ppc_insn := PPC_CMPB;
elsif std_match(f.insn, "011111---------------0011100000-") then elsif std_match(f_in.insn, "011111---------------0011100000-") then
report "PPC_cmpeqb"; report "PPC_cmpeqb";
ppc_insn := PPC_CMPEQB; ppc_insn := PPC_CMPEQB;
elsif std_match(f.insn, "001011--------------------------") then elsif std_match(f_in.insn, "001011--------------------------") then
report "PPC_cmpi"; report "PPC_cmpi";
ppc_insn := PPC_CMPI; ppc_insn := PPC_CMPI;
elsif std_match(f.insn, "011111---------------0000100000-") then elsif std_match(f_in.insn, "011111---------------0000100000-") then
report "PPC_cmpl"; report "PPC_cmpl";
ppc_insn := PPC_CMPL; ppc_insn := PPC_CMPL;
elsif std_match(f.insn, "001010--------------------------") then elsif std_match(f_in.insn, "001010--------------------------") then
report "PPC_cmpli"; report "PPC_cmpli";
ppc_insn := PPC_CMPLI; ppc_insn := PPC_CMPLI;
elsif std_match(f.insn, "011111---------------0011000000-") then elsif std_match(f_in.insn, "011111---------------0011000000-") then
report "PPC_cmprb"; report "PPC_cmprb";
ppc_insn := PPC_CMPRB; ppc_insn := PPC_CMPRB;
elsif std_match(f.insn, "011111---------------0000111010-") then elsif std_match(f_in.insn, "011111---------------0000111010-") then
report "PPC_cntlzd"; report "PPC_cntlzd";
ppc_insn := PPC_CNTLZD; ppc_insn := PPC_CNTLZD;
elsif std_match(f.insn, "011111---------------0000011010-") then elsif std_match(f_in.insn, "011111---------------0000011010-") then
report "PPC_cntlzw"; report "PPC_cntlzw";
ppc_insn := PPC_CNTLZW; ppc_insn := PPC_CNTLZW;
elsif std_match(f.insn, "011111---------------1000111010-") then elsif std_match(f_in.insn, "011111---------------1000111010-") then
report "PPC_cnttzd"; report "PPC_cnttzd";
ppc_insn := PPC_CNTTZD; ppc_insn := PPC_CNTTZD;
elsif std_match(f.insn, "011111---------------1000011010-") then elsif std_match(f_in.insn, "011111---------------1000011010-") then
report "PPC_cnttzw"; report "PPC_cnttzw";
ppc_insn := PPC_CNTTZW; ppc_insn := PPC_CNTTZW;
elsif std_match(f.insn, "010011---------------0100000001-") then elsif std_match(f_in.insn, "010011---------------0100000001-") then
report "PPC_crand"; report "PPC_crand";
ppc_insn := PPC_CRAND; ppc_insn := PPC_CRAND;
elsif std_match(f.insn, "010011---------------0010000001-") then elsif std_match(f_in.insn, "010011---------------0010000001-") then
report "PPC_crandc"; report "PPC_crandc";
ppc_insn := PPC_CRANDC; ppc_insn := PPC_CRANDC;
elsif std_match(f.insn, "010011---------------0100100001-") then elsif std_match(f_in.insn, "010011---------------0100100001-") then
report "PPC_creqv"; report "PPC_creqv";
ppc_insn := PPC_CREQV; ppc_insn := PPC_CREQV;
elsif std_match(f.insn, "010011---------------0011100001-") then elsif std_match(f_in.insn, "010011---------------0011100001-") then
report "PPC_crnand"; report "PPC_crnand";
ppc_insn := PPC_CRNAND; ppc_insn := PPC_CRNAND;
elsif std_match(f.insn, "010011---------------0000100001-") then elsif std_match(f_in.insn, "010011---------------0000100001-") then
report "PPC_crnor"; report "PPC_crnor";
ppc_insn := PPC_CRNOR; ppc_insn := PPC_CRNOR;
elsif std_match(f.insn, "010011---------------0111000001-") then elsif std_match(f_in.insn, "010011---------------0111000001-") then
report "PPC_cror"; report "PPC_cror";
ppc_insn := PPC_CROR; ppc_insn := PPC_CROR;
elsif std_match(f.insn, "010011---------------0110100001-") then elsif std_match(f_in.insn, "010011---------------0110100001-") then
report "PPC_crorc"; report "PPC_crorc";
ppc_insn := PPC_CRORC; ppc_insn := PPC_CRORC;
elsif std_match(f.insn, "010011---------------0011000001-") then elsif std_match(f_in.insn, "010011---------------0011000001-") then
report "PPC_crxor"; report "PPC_crxor";
ppc_insn := PPC_CRXOR; ppc_insn := PPC_CRXOR;
elsif std_match(f.insn, "011111---------------1011110011-") then elsif std_match(f_in.insn, "011111---------------1011110011-") then
report "PPC_darn"; report "PPC_darn";
ppc_insn := PPC_DARN; ppc_insn := PPC_DARN;
elsif std_match(f.insn, "011111---------------0001010110-") then elsif std_match(f_in.insn, "011111---------------0001010110-") then
report "PPC_dcbf"; report "PPC_dcbf";
ppc_insn := PPC_DCBF; ppc_insn := PPC_DCBF;
elsif std_match(f.insn, "011111---------------0000110110-") then elsif std_match(f_in.insn, "011111---------------0000110110-") then
report "PPC_dcbst"; report "PPC_dcbst";
ppc_insn := PPC_DCBST; ppc_insn := PPC_DCBST;
elsif std_match(f.insn, "011111---------------0100010110-") then elsif std_match(f_in.insn, "011111---------------0100010110-") then
report "PPC_dcbt"; report "PPC_dcbt";
ppc_insn := PPC_DCBT; ppc_insn := PPC_DCBT;
elsif std_match(f.insn, "011111---------------0011110110-") then elsif std_match(f_in.insn, "011111---------------0011110110-") then
report "PPC_dcbtst"; report "PPC_dcbtst";
ppc_insn := PPC_DCBTST; ppc_insn := PPC_DCBTST;
elsif std_match(f.insn, "011111---------------1111110110-") then elsif std_match(f_in.insn, "011111---------------1111110110-") then
report "PPC_dcbz"; report "PPC_dcbz";
ppc_insn := PPC_DCBZ; ppc_insn := PPC_DCBZ;
elsif std_match(f.insn, "011111---------------0111101001-") then elsif std_match(f_in.insn, "011111---------------0111101001-") then
report "PPC_divd"; report "PPC_divd";
ppc_insn := PPC_DIVD; ppc_insn := PPC_DIVD;
elsif std_match(f.insn, "011111---------------0110101001-") then elsif std_match(f_in.insn, "011111---------------0110101001-") then
report "PPC_divde"; report "PPC_divde";
ppc_insn := PPC_DIVDE; ppc_insn := PPC_DIVDE;
elsif std_match(f.insn, "011111---------------0110001001-") then elsif std_match(f_in.insn, "011111---------------0110001001-") then
report "PPC_divdeu"; report "PPC_divdeu";
ppc_insn := PPC_DIVDEU; ppc_insn := PPC_DIVDEU;
elsif std_match(f.insn, "011111---------------0111001001-") then elsif std_match(f_in.insn, "011111---------------0111001001-") then
report "PPC_divdu"; report "PPC_divdu";
ppc_insn := PPC_DIVDU; ppc_insn := PPC_DIVDU;
elsif std_match(f.insn, "011111---------------0111101011-") then elsif std_match(f_in.insn, "011111---------------0111101011-") then
report "PPC_divw"; report "PPC_divw";
ppc_insn := PPC_DIVW; ppc_insn := PPC_DIVW;
elsif std_match(f.insn, "011111---------------0110101011-") then elsif std_match(f_in.insn, "011111---------------0110101011-") then
report "PPC_divwe"; report "PPC_divwe";
ppc_insn := PPC_DIVWE; ppc_insn := PPC_DIVWE;
elsif std_match(f.insn, "011111---------------0110001011-") then elsif std_match(f_in.insn, "011111---------------0110001011-") then
report "PPC_divweu"; report "PPC_divweu";
ppc_insn := PPC_DIVWEU; ppc_insn := PPC_DIVWEU;
elsif std_match(f.insn, "011111---------------0111001011-") then elsif std_match(f_in.insn, "011111---------------0111001011-") then
report "PPC_divwu"; report "PPC_divwu";
ppc_insn := PPC_DIVWU; ppc_insn := PPC_DIVWU;
elsif std_match(f.insn, "011111---------------0100011100-") then elsif std_match(f_in.insn, "011111---------------0100011100-") then
report "PPC_eqv"; report "PPC_eqv";
ppc_insn := PPC_EQV; ppc_insn := PPC_EQV;
elsif std_match(f.insn, "011111---------------1110111010-") then elsif std_match(f_in.insn, "011111---------------1110111010-") then
report "PPC_extsb"; report "PPC_extsb";
ppc_insn := PPC_EXTSB; ppc_insn := PPC_EXTSB;
elsif std_match(f.insn, "011111---------------1110011010-") then elsif std_match(f_in.insn, "011111---------------1110011010-") then
report "PPC_extsh"; report "PPC_extsh";
ppc_insn := PPC_EXTSH; ppc_insn := PPC_EXTSH;
elsif std_match(f.insn, "011111---------------1111011010-") then elsif std_match(f_in.insn, "011111---------------1111011010-") then
report "PPC_extsw"; report "PPC_extsw";
ppc_insn := PPC_EXTSW; ppc_insn := PPC_EXTSW;
elsif std_match(f.insn, "011111---------------110111101--") then elsif std_match(f_in.insn, "011111---------------110111101--") then
report "PPC_extswsli"; report "PPC_extswsli";
ppc_insn := PPC_EXTSWSLI; ppc_insn := PPC_EXTSWSLI;
elsif std_match(f.insn, "011111---------------1111010110-") then elsif std_match(f_in.insn, "011111---------------1111010110-") then
report "PPC_icbi"; report "PPC_icbi";
ppc_insn := PPC_ICBI; ppc_insn := PPC_ICBI;
elsif std_match(f.insn, "011111---------------0000010110-") then elsif std_match(f_in.insn, "011111---------------0000010110-") then
report "PPC_icbt"; report "PPC_icbt";
ppc_insn := PPC_ICBT; ppc_insn := PPC_ICBT;
elsif std_match(f.insn, "011111--------------------01111-") then elsif std_match(f_in.insn, "011111--------------------01111-") then
report "PPC_isel"; report "PPC_isel";
ppc_insn := PPC_ISEL; ppc_insn := PPC_ISEL;
elsif std_match(f.insn, "010011---------------0010010110-") then elsif std_match(f_in.insn, "010011---------------0010010110-") then
report "PPC_isync"; report "PPC_isync";
ppc_insn := PPC_ISYNC; ppc_insn := PPC_ISYNC;
elsif std_match(f.insn, "011111---------------0000110100-") then elsif std_match(f_in.insn, "011111---------------0000110100-") then
report "PPC_lbarx"; report "PPC_lbarx";
ppc_insn := PPC_LBARX; ppc_insn := PPC_LBARX;
elsif std_match(f.insn, "100010--------------------------") then elsif std_match(f_in.insn, "100010--------------------------") then
report "PPC_lbz"; report "PPC_lbz";
ppc_insn := PPC_LBZ; ppc_insn := PPC_LBZ;
elsif std_match(f.insn, "100011--------------------------") then elsif std_match(f_in.insn, "100011--------------------------") then
report "PPC_lbzu"; report "PPC_lbzu";
ppc_insn := PPC_LBZU; ppc_insn := PPC_LBZU;
elsif std_match(f.insn, "011111---------------0001110111-") then elsif std_match(f_in.insn, "011111---------------0001110111-") then
report "PPC_lbzux"; report "PPC_lbzux";
ppc_insn := PPC_LBZUX; ppc_insn := PPC_LBZUX;
elsif std_match(f.insn, "011111---------------0001010111-") then elsif std_match(f_in.insn, "011111---------------0001010111-") then
report "PPC_lbzx"; report "PPC_lbzx";
ppc_insn := PPC_LBZX; ppc_insn := PPC_LBZX;
elsif std_match(f.insn, "111010------------------------00") then elsif std_match(f_in.insn, "111010------------------------00") then
report "PPC_ld"; report "PPC_ld";
ppc_insn := PPC_LD; ppc_insn := PPC_LD;
elsif std_match(f.insn, "011111---------------0001010100-") then elsif std_match(f_in.insn, "011111---------------0001010100-") then
report "PPC_ldarx"; report "PPC_ldarx";
ppc_insn := PPC_LDARX; ppc_insn := PPC_LDARX;
elsif std_match(f.insn, "011111---------------1000010100-") then elsif std_match(f_in.insn, "011111---------------1000010100-") then
report "PPC_ldbrx"; report "PPC_ldbrx";
ppc_insn := PPC_LDBRX; ppc_insn := PPC_LDBRX;
elsif std_match(f.insn, "111010------------------------01") then elsif std_match(f_in.insn, "111010------------------------01") then
report "PPC_ldu"; report "PPC_ldu";
ppc_insn := PPC_LDU; ppc_insn := PPC_LDU;
elsif std_match(f.insn, "011111---------------0000110101-") then elsif std_match(f_in.insn, "011111---------------0000110101-") then
report "PPC_ldux"; report "PPC_ldux";
ppc_insn := PPC_LDUX; ppc_insn := PPC_LDUX;
elsif std_match(f.insn, "011111---------------0000010101-") then elsif std_match(f_in.insn, "011111---------------0000010101-") then
report "PPC_ldx"; report "PPC_ldx";
ppc_insn := PPC_LDX; ppc_insn := PPC_LDX;
elsif std_match(f.insn, "101010--------------------------") then elsif std_match(f_in.insn, "101010--------------------------") then
report "PPC_lha"; report "PPC_lha";
ppc_insn := PPC_LHA; ppc_insn := PPC_LHA;
elsif std_match(f.insn, "011111---------------0001110100-") then elsif std_match(f_in.insn, "011111---------------0001110100-") then
report "PPC_lharx"; report "PPC_lharx";
ppc_insn := PPC_LHARX; ppc_insn := PPC_LHARX;
elsif std_match(f.insn, "101011--------------------------") then elsif std_match(f_in.insn, "101011--------------------------") then
report "PPC_lhau"; report "PPC_lhau";
ppc_insn := PPC_LHAU; ppc_insn := PPC_LHAU;
elsif std_match(f.insn, "011111---------------0101110111-") then elsif std_match(f_in.insn, "011111---------------0101110111-") then
report "PPC_lhaux"; report "PPC_lhaux";
ppc_insn := PPC_LHAUX; ppc_insn := PPC_LHAUX;
elsif std_match(f.insn, "011111---------------0101010111-") then elsif std_match(f_in.insn, "011111---------------0101010111-") then
report "PPC_lhax"; report "PPC_lhax";
ppc_insn := PPC_LHAX; ppc_insn := PPC_LHAX;
elsif std_match(f.insn, "011111---------------1100010110-") then elsif std_match(f_in.insn, "011111---------------1100010110-") then
report "PPC_lhbrx"; report "PPC_lhbrx";
ppc_insn := PPC_LHBRX; ppc_insn := PPC_LHBRX;
elsif std_match(f.insn, "101000--------------------------") then elsif std_match(f_in.insn, "101000--------------------------") then
report "PPC_lhz"; report "PPC_lhz";
ppc_insn := PPC_LHZ; ppc_insn := PPC_LHZ;
elsif std_match(f.insn, "101001--------------------------") then elsif std_match(f_in.insn, "101001--------------------------") then
report "PPC_lhzu"; report "PPC_lhzu";
ppc_insn := PPC_LHZU; ppc_insn := PPC_LHZU;
elsif std_match(f.insn, "011111---------------0100110111-") then elsif std_match(f_in.insn, "011111---------------0100110111-") then
report "PPC_lhzux"; report "PPC_lhzux";
ppc_insn := PPC_LHZUX; ppc_insn := PPC_LHZUX;
elsif std_match(f.insn, "011111---------------0100010111-") then elsif std_match(f_in.insn, "011111---------------0100010111-") then
report "PPC_lhzx"; report "PPC_lhzx";
ppc_insn := PPC_LHZX; ppc_insn := PPC_LHZX;
elsif std_match(f.insn, "111010------------------------10") then elsif std_match(f_in.insn, "111010------------------------10") then
report "PPC_lwa"; report "PPC_lwa";
ppc_insn := PPC_LWA; ppc_insn := PPC_LWA;
elsif std_match(f.insn, "011111---------------0000010100-") then elsif std_match(f_in.insn, "011111---------------0000010100-") then
report "PPC_lwarx"; report "PPC_lwarx";
ppc_insn := PPC_LWARX; ppc_insn := PPC_LWARX;
elsif std_match(f.insn, "011111---------------0101110101-") then elsif std_match(f_in.insn, "011111---------------0101110101-") then
report "PPC_lwaux"; report "PPC_lwaux";
ppc_insn := PPC_LWAUX; ppc_insn := PPC_LWAUX;
elsif std_match(f.insn, "011111---------------0101010101-") then elsif std_match(f_in.insn, "011111---------------0101010101-") then
report "PPC_lwax"; report "PPC_lwax";
ppc_insn := PPC_LWAX; ppc_insn := PPC_LWAX;
elsif std_match(f.insn, "011111---------------1000010110-") then elsif std_match(f_in.insn, "011111---------------1000010110-") then
report "PPC_lwbrx"; report "PPC_lwbrx";
ppc_insn := PPC_LWBRX; ppc_insn := PPC_LWBRX;
elsif std_match(f.insn, "100000--------------------------") then elsif std_match(f_in.insn, "100000--------------------------") then
report "PPC_lwz"; report "PPC_lwz";
ppc_insn := PPC_LWZ; ppc_insn := PPC_LWZ;
elsif std_match(f.insn, "100001--------------------------") then elsif std_match(f_in.insn, "100001--------------------------") then
report "PPC_lwzu"; report "PPC_lwzu";
ppc_insn := PPC_LWZU; ppc_insn := PPC_LWZU;
elsif std_match(f.insn, "011111---------------0000110111-") then elsif std_match(f_in.insn, "011111---------------0000110111-") then
report "PPC_lwzux"; report "PPC_lwzux";
ppc_insn := PPC_LWZUX; ppc_insn := PPC_LWZUX;
elsif std_match(f.insn, "011111---------------0000010111-") then elsif std_match(f_in.insn, "011111---------------0000010111-") then
report "PPC_lwzx"; report "PPC_lwzx";
ppc_insn := PPC_LWZX; ppc_insn := PPC_LWZX;
elsif std_match(f.insn, "000100--------------------110000") then elsif std_match(f_in.insn, "000100--------------------110000") then
report "PPC_maddhd"; report "PPC_maddhd";
ppc_insn := PPC_MADDHD; ppc_insn := PPC_MADDHD;
elsif std_match(f.insn, "000100--------------------110001") then elsif std_match(f_in.insn, "000100--------------------110001") then
report "PPC_maddhdu"; report "PPC_maddhdu";
ppc_insn := PPC_MADDHDU; ppc_insn := PPC_MADDHDU;
elsif std_match(f.insn, "000100--------------------110011") then elsif std_match(f_in.insn, "000100--------------------110011") then
report "PPC_maddld"; report "PPC_maddld";
ppc_insn := PPC_MADDLD; ppc_insn := PPC_MADDLD;
elsif std_match(f.insn, "010011---------------0000000000-") then elsif std_match(f_in.insn, "010011---------------0000000000-") then
report "PPC_mcrf"; report "PPC_mcrf";
ppc_insn := PPC_MCRF; ppc_insn := PPC_MCRF;
elsif std_match(f.insn, "011111---------------1000000000-") then elsif std_match(f_in.insn, "011111---------------1000000000-") then
report "PPC_mcrxr"; report "PPC_mcrxr";
ppc_insn := PPC_MCRXR; ppc_insn := PPC_MCRXR;
elsif std_match(f.insn, "011111---------------1001000000-") then elsif std_match(f_in.insn, "011111---------------1001000000-") then
report "PPC_mcrxrx"; report "PPC_mcrxrx";
ppc_insn := PPC_MCRXRX; ppc_insn := PPC_MCRXRX;
elsif std_match(f.insn, "011111-----0---------0000010011-") then elsif std_match(f_in.insn, "011111-----0---------0000010011-") then
report "PPC_mfcr"; report "PPC_mfcr";
ppc_insn := PPC_MFCR; ppc_insn := PPC_MFCR;
elsif std_match(f.insn, "011111-----1---------0000010011-") then elsif std_match(f_in.insn, "011111-----1---------0000010011-") then
report "PPC_mfocrf"; report "PPC_mfocrf";
ppc_insn := PPC_MFOCRF; ppc_insn := PPC_MFOCRF;
-- Specific MF/MT SPR encodings first -- Specific MF/MT SPR encodings first
elsif std_match(f.insn, "011111-----01001000000101010011-") then elsif std_match(f_in.insn, "011111-----01001000000101010011-") then
report "PPC_mfctr"; report "PPC_mfctr";
ppc_insn := PPC_MFCTR; ppc_insn := PPC_MFCTR;
elsif std_match(f.insn, "011111-----01000000000101010011-") then elsif std_match(f_in.insn, "011111-----01000000000101010011-") then
report "PPC_mflr"; report "PPC_mflr";
ppc_insn := PPC_MFLR; ppc_insn := PPC_MFLR;
elsif std_match(f.insn, "011111-----01100010000101010011-") then elsif std_match(f_in.insn, "011111-----01100010000101010011-") then
report "PPC_mftb"; report "PPC_mftb";
ppc_insn := PPC_MFTB; ppc_insn := PPC_MFTB;
elsif std_match(f.insn, "011111-----01001000000111010011-") then elsif std_match(f_in.insn, "011111-----01001000000111010011-") then
report "PPC_mtctr"; report "PPC_mtctr";
ppc_insn := PPC_MTCTR; ppc_insn := PPC_MTCTR;
elsif std_match(f.insn, "011111-----01000000000111010011-") then elsif std_match(f_in.insn, "011111-----01000000000111010011-") then
report "PPC_mtlr"; report "PPC_mtlr";
ppc_insn := PPC_MTLR; ppc_insn := PPC_MTLR;
elsif std_match(f.insn, "011111---------------0101010011-") then elsif std_match(f_in.insn, "011111---------------0101010011-") then
report "PPC_mfspr"; report "PPC_mfspr";
ppc_insn := PPC_MFSPR; ppc_insn := PPC_MFSPR;
elsif std_match(f.insn, "011111---------------1100001001-") then elsif std_match(f_in.insn, "011111---------------1100001001-") then
report "PPC_modsd"; report "PPC_modsd";
ppc_insn := PPC_MODSD; ppc_insn := PPC_MODSD;
elsif std_match(f.insn, "011111---------------1100001011-") then elsif std_match(f_in.insn, "011111---------------1100001011-") then
report "PPC_modsw"; report "PPC_modsw";
ppc_insn := PPC_MODSW; ppc_insn := PPC_MODSW;
elsif std_match(f.insn, "011111---------------0100001001-") then elsif std_match(f_in.insn, "011111---------------0100001001-") then
report "PPC_modud"; report "PPC_modud";
ppc_insn := PPC_MODUD; ppc_insn := PPC_MODUD;
elsif std_match(f.insn, "011111---------------0100001011-") then elsif std_match(f_in.insn, "011111---------------0100001011-") then
report "PPC_moduw"; report "PPC_moduw";
ppc_insn := PPC_MODUW; ppc_insn := PPC_MODUW;
elsif std_match(f.insn, "011111-----0---------0010010000-") then elsif std_match(f_in.insn, "011111-----0---------0010010000-") then
report "PPC_mtcrf"; report "PPC_mtcrf";
ppc_insn := PPC_MTCRF; ppc_insn := PPC_MTCRF;
elsif std_match(f.insn, "011111-----1---------0010010000-") then elsif std_match(f_in.insn, "011111-----1---------0010010000-") then
report "PPC_mtocrf"; report "PPC_mtocrf";
ppc_insn := PPC_MTOCRF; ppc_insn := PPC_MTOCRF;
elsif std_match(f.insn, "011111---------------0111010011-") then elsif std_match(f_in.insn, "011111---------------0111010011-") then
report "PPC_mtspr"; report "PPC_mtspr";
ppc_insn := PPC_MTSPR; ppc_insn := PPC_MTSPR;
elsif std_match(f.insn, "011111----------------001001001-") then elsif std_match(f_in.insn, "011111----------------001001001-") then
report "PPC_mulhd"; report "PPC_mulhd";
ppc_insn := PPC_MULHD; ppc_insn := PPC_MULHD;
elsif std_match(f.insn, "011111----------------000001001-") then elsif std_match(f_in.insn, "011111----------------000001001-") then
report "PPC_mulhdu"; report "PPC_mulhdu";
ppc_insn := PPC_MULHDU; ppc_insn := PPC_MULHDU;
elsif std_match(f.insn, "011111----------------001001011-") then elsif std_match(f_in.insn, "011111----------------001001011-") then
report "PPC_mulhw"; report "PPC_mulhw";
ppc_insn := PPC_MULHW; ppc_insn := PPC_MULHW;
elsif std_match(f.insn, "011111----------------000001011-") then elsif std_match(f_in.insn, "011111----------------000001011-") then
report "PPC_mulhwu"; report "PPC_mulhwu";
ppc_insn := PPC_MULHWU; ppc_insn := PPC_MULHWU;
elsif std_match(f.insn, "011111---------------0011101001-") then elsif std_match(f_in.insn, "011111---------------0011101001-") then
report "PPC_mulld"; report "PPC_mulld";
ppc_insn := PPC_MULLD; ppc_insn := PPC_MULLD;
elsif std_match(f.insn, "000111--------------------------") then elsif std_match(f_in.insn, "000111--------------------------") then
report "PPC_mulli"; report "PPC_mulli";
ppc_insn := PPC_MULLI; ppc_insn := PPC_MULLI;
elsif std_match(f.insn, "011111---------------0011101011-") then elsif std_match(f_in.insn, "011111---------------0011101011-") then
report "PPC_mullw"; report "PPC_mullw";
ppc_insn := PPC_MULLW; ppc_insn := PPC_MULLW;
elsif std_match(f.insn, "011111---------------0111011100-") then elsif std_match(f_in.insn, "011111---------------0111011100-") then
report "PPC_nand"; report "PPC_nand";
ppc_insn := PPC_NAND; ppc_insn := PPC_NAND;
elsif std_match(f.insn, "011111---------------0001101000-") then elsif std_match(f_in.insn, "011111---------------0001101000-") then
report "PPC_neg"; report "PPC_neg";
ppc_insn := PPC_NEG; ppc_insn := PPC_NEG;
elsif std_match(f.insn, "011111---------------0001111100-") then elsif std_match(f_in.insn, "011111---------------0001111100-") then
report "PPC_nor"; report "PPC_nor";
ppc_insn := PPC_NOR; ppc_insn := PPC_NOR;
elsif std_match(f.insn, "011111---------------0110111100-") then elsif std_match(f_in.insn, "011111---------------0110111100-") then
report "PPC_or"; report "PPC_or";
ppc_insn := PPC_OR; ppc_insn := PPC_OR;
elsif std_match(f.insn, "011111---------------0110011100-") then elsif std_match(f_in.insn, "011111---------------0110011100-") then
report "PPC_orc"; report "PPC_orc";
ppc_insn := PPC_ORC; ppc_insn := PPC_ORC;
elsif std_match(f.insn, "011000--------------------------") then elsif std_match(f_in.insn, "011000--------------------------") then
report "PPC_ori"; report "PPC_ori";
ppc_insn := PPC_ORI; ppc_insn := PPC_ORI;
elsif std_match(f.insn, "011001--------------------------") then elsif std_match(f_in.insn, "011001--------------------------") then
report "PPC_oris"; report "PPC_oris";
ppc_insn := PPC_ORIS; ppc_insn := PPC_ORIS;
elsif std_match(f.insn, "011111---------------0001111010-") then elsif std_match(f_in.insn, "011111---------------0001111010-") then
report "PPC_popcntb"; report "PPC_popcntb";
ppc_insn := PPC_POPCNTB; ppc_insn := PPC_POPCNTB;
elsif std_match(f.insn, "011111---------------0111111010-") then elsif std_match(f_in.insn, "011111---------------0111111010-") then
report "PPC_popcntd"; report "PPC_popcntd";
ppc_insn := PPC_POPCNTD; ppc_insn := PPC_POPCNTD;
elsif std_match(f.insn, "011111---------------0101111010-") then elsif std_match(f_in.insn, "011111---------------0101111010-") then
report "PPC_popcntw"; report "PPC_popcntw";
ppc_insn := PPC_POPCNTW; ppc_insn := PPC_POPCNTW;
elsif std_match(f.insn, "011111---------------0010111010-") then elsif std_match(f_in.insn, "011111---------------0010111010-") then
report "PPC_prtyd"; report "PPC_prtyd";
ppc_insn := PPC_PRTYD; ppc_insn := PPC_PRTYD;
elsif std_match(f.insn, "011111---------------0010011010-") then elsif std_match(f_in.insn, "011111---------------0010011010-") then
report "PPC_prtyw"; report "PPC_prtyw";
ppc_insn := PPC_PRTYW; ppc_insn := PPC_PRTYW;
elsif std_match(f.insn, "011110---------------------1000-") then elsif std_match(f_in.insn, "011110---------------------1000-") then
report "PPC_rldcl"; report "PPC_rldcl";
ppc_insn := PPC_RLDCL; ppc_insn := PPC_RLDCL;
elsif std_match(f.insn, "011110---------------------1001-") then elsif std_match(f_in.insn, "011110---------------------1001-") then
report "PPC_rldcr"; report "PPC_rldcr";
ppc_insn := PPC_RLDCR; ppc_insn := PPC_RLDCR;
elsif std_match(f.insn, "011110---------------------010--") then elsif std_match(f_in.insn, "011110---------------------010--") then
report "PPC_rldic"; report "PPC_rldic";
ppc_insn := PPC_RLDIC; ppc_insn := PPC_RLDIC;
elsif std_match(f.insn, "011110---------------------000--") then elsif std_match(f_in.insn, "011110---------------------000--") then
report "PPC_rldicl"; report "PPC_rldicl";
ppc_insn := PPC_RLDICL; ppc_insn := PPC_RLDICL;
elsif std_match(f.insn, "011110---------------------001--") then elsif std_match(f_in.insn, "011110---------------------001--") then
report "PPC_rldicr"; report "PPC_rldicr";
ppc_insn := PPC_RLDICR; ppc_insn := PPC_RLDICR;
elsif std_match(f.insn, "011110---------------------011--") then elsif std_match(f_in.insn, "011110---------------------011--") then
report "PPC_rldimi"; report "PPC_rldimi";
ppc_insn := PPC_RLDIMI; ppc_insn := PPC_RLDIMI;
elsif std_match(f.insn, "010100--------------------------") then elsif std_match(f_in.insn, "010100--------------------------") then
report "PPC_rlwimi"; report "PPC_rlwimi";
ppc_insn := PPC_RLWIMI; ppc_insn := PPC_RLWIMI;
elsif std_match(f.insn, "010101--------------------------") then elsif std_match(f_in.insn, "010101--------------------------") then
report "PPC_rlwinm"; report "PPC_rlwinm";
ppc_insn := PPC_RLWINM; ppc_insn := PPC_RLWINM;
elsif std_match(f.insn, "010111--------------------------") then elsif std_match(f_in.insn, "010111--------------------------") then
report "PPC_rlwnm"; report "PPC_rlwnm";
ppc_insn := PPC_RLWNM; ppc_insn := PPC_RLWNM;
elsif std_match(f.insn, "011111---------------0010000000-") then elsif std_match(f_in.insn, "011111---------------0010000000-") then
report "PPC_setb"; report "PPC_setb";
ppc_insn := PPC_SETB; ppc_insn := PPC_SETB;
elsif std_match(f.insn, "011111---------------0000011011-") then elsif std_match(f_in.insn, "011111---------------0000011011-") then
report "PPC_sld"; report "PPC_sld";
ppc_insn := PPC_SLD; ppc_insn := PPC_SLD;
elsif std_match(f.insn, "011111---------------0000011000-") then elsif std_match(f_in.insn, "011111---------------0000011000-") then
report "PPC_slw"; report "PPC_slw";
ppc_insn := PPC_SLW; ppc_insn := PPC_SLW;
elsif std_match(f.insn, "011111---------------1100011010-") then elsif std_match(f_in.insn, "011111---------------1100011010-") then
report "PPC_srad"; report "PPC_srad";
ppc_insn := PPC_SRAD; ppc_insn := PPC_SRAD;
elsif std_match(f.insn, "011111---------------110011101--") then elsif std_match(f_in.insn, "011111---------------110011101--") then
report "PPC_sradi"; report "PPC_sradi";
ppc_insn := PPC_SRADI; ppc_insn := PPC_SRADI;
elsif std_match(f.insn, "011111---------------1100011000-") then elsif std_match(f_in.insn, "011111---------------1100011000-") then
report "PPC_sraw"; report "PPC_sraw";
ppc_insn := PPC_SRAW; ppc_insn := PPC_SRAW;
elsif std_match(f.insn, "011111---------------1100111000-") then elsif std_match(f_in.insn, "011111---------------1100111000-") then
report "PPC_srawi"; report "PPC_srawi";
ppc_insn := PPC_SRAWI; ppc_insn := PPC_SRAWI;
elsif std_match(f.insn, "011111---------------1000011011-") then elsif std_match(f_in.insn, "011111---------------1000011011-") then
report "PPC_srd"; report "PPC_srd";
ppc_insn := PPC_SRD; ppc_insn := PPC_SRD;
elsif std_match(f.insn, "011111---------------1000011000-") then elsif std_match(f_in.insn, "011111---------------1000011000-") then
report "PPC_srw"; report "PPC_srw";
ppc_insn := PPC_SRW; ppc_insn := PPC_SRW;
elsif std_match(f.insn, "100110--------------------------") then elsif std_match(f_in.insn, "100110--------------------------") then
report "PPC_stb"; report "PPC_stb";
ppc_insn := PPC_STB; ppc_insn := PPC_STB;
elsif std_match(f.insn, "011111---------------1010110110-") then elsif std_match(f_in.insn, "011111---------------1010110110-") then
report "PPC_stbcx"; report "PPC_stbcx";
ppc_insn := PPC_STBCX; ppc_insn := PPC_STBCX;
elsif std_match(f.insn, "100111--------------------------") then elsif std_match(f_in.insn, "100111--------------------------") then
report "PPC_stbu"; report "PPC_stbu";
ppc_insn := PPC_STBU; ppc_insn := PPC_STBU;
elsif std_match(f.insn, "011111---------------0011110111-") then elsif std_match(f_in.insn, "011111---------------0011110111-") then
report "PPC_stbux"; report "PPC_stbux";
ppc_insn := PPC_STBUX; ppc_insn := PPC_STBUX;
elsif std_match(f.insn, "011111---------------0011010111-") then elsif std_match(f_in.insn, "011111---------------0011010111-") then
report "PPC_stbx"; report "PPC_stbx";
ppc_insn := PPC_STBX; ppc_insn := PPC_STBX;
elsif std_match(f.insn, "111110------------------------00") then elsif std_match(f_in.insn, "111110------------------------00") then
report "PPC_std"; report "PPC_std";
ppc_insn := PPC_STD; ppc_insn := PPC_STD;
elsif std_match(f.insn, "011111---------------1010010100-") then elsif std_match(f_in.insn, "011111---------------1010010100-") then
report "PPC_stdbrx"; report "PPC_stdbrx";
ppc_insn := PPC_STDBRX; ppc_insn := PPC_STDBRX;
elsif std_match(f.insn, "011111---------------0011010110-") then elsif std_match(f_in.insn, "011111---------------0011010110-") then
report "PPC_stdcx"; report "PPC_stdcx";
ppc_insn := PPC_STDCX; ppc_insn := PPC_STDCX;
elsif std_match(f.insn, "111110------------------------01") then elsif std_match(f_in.insn, "111110------------------------01") then
report "PPC_stdu"; report "PPC_stdu";
ppc_insn := PPC_STDU; ppc_insn := PPC_STDU;
elsif std_match(f.insn, "011111---------------0010110101-") then elsif std_match(f_in.insn, "011111---------------0010110101-") then
report "PPC_stdux"; report "PPC_stdux";
ppc_insn := PPC_STDUX; ppc_insn := PPC_STDUX;
elsif std_match(f.insn, "011111---------------0010010101-") then elsif std_match(f_in.insn, "011111---------------0010010101-") then
report "PPC_stdx"; report "PPC_stdx";
ppc_insn := PPC_STDX; ppc_insn := PPC_STDX;
elsif std_match(f.insn, "101100--------------------------") then elsif std_match(f_in.insn, "101100--------------------------") then
report "PPC_sth"; report "PPC_sth";
ppc_insn := PPC_STH; ppc_insn := PPC_STH;
elsif std_match(f.insn, "011111---------------1110010110-") then elsif std_match(f_in.insn, "011111---------------1110010110-") then
report "PPC_sthbrx"; report "PPC_sthbrx";
ppc_insn := PPC_STHBRX; ppc_insn := PPC_STHBRX;
elsif std_match(f.insn, "011111---------------1011010110-") then elsif std_match(f_in.insn, "011111---------------1011010110-") then
report "PPC_sthcx"; report "PPC_sthcx";
ppc_insn := PPC_STHCX; ppc_insn := PPC_STHCX;
elsif std_match(f.insn, "101101--------------------------") then elsif std_match(f_in.insn, "101101--------------------------") then
report "PPC_sthu"; report "PPC_sthu";
ppc_insn := PPC_STHU; ppc_insn := PPC_STHU;
elsif std_match(f.insn, "011111---------------0110110111-") then elsif std_match(f_in.insn, "011111---------------0110110111-") then
report "PPC_sthux"; report "PPC_sthux";
ppc_insn := PPC_STHUX; ppc_insn := PPC_STHUX;
elsif std_match(f.insn, "011111---------------0110010111-") then elsif std_match(f_in.insn, "011111---------------0110010111-") then
report "PPC_sthx"; report "PPC_sthx";
ppc_insn := PPC_STHX; ppc_insn := PPC_STHX;
elsif std_match(f.insn, "100100--------------------------") then elsif std_match(f_in.insn, "100100--------------------------") then
report "PPC_stw"; report "PPC_stw";
ppc_insn := PPC_STW; ppc_insn := PPC_STW;
elsif std_match(f.insn, "011111---------------1010010110-") then elsif std_match(f_in.insn, "011111---------------1010010110-") then
report "PPC_stwbrx"; report "PPC_stwbrx";
ppc_insn := PPC_STWBRX; ppc_insn := PPC_STWBRX;
elsif std_match(f.insn, "011111---------------0010010110-") then elsif std_match(f_in.insn, "011111---------------0010010110-") then
report "PPC_stwcx"; report "PPC_stwcx";
ppc_insn := PPC_STWCX; ppc_insn := PPC_STWCX;
elsif std_match(f.insn, "100101--------------------------") then elsif std_match(f_in.insn, "100101--------------------------") then
report "PPC_stwu"; report "PPC_stwu";
ppc_insn := PPC_STWU; ppc_insn := PPC_STWU;
elsif std_match(f.insn, "011111---------------0010110111-") then elsif std_match(f_in.insn, "011111---------------0010110111-") then
report "PPC_stwux"; report "PPC_stwux";
ppc_insn := PPC_STWUX; ppc_insn := PPC_STWUX;
elsif std_match(f.insn, "011111---------------0010010111-") then elsif std_match(f_in.insn, "011111---------------0010010111-") then
report "PPC_stwx"; report "PPC_stwx";
ppc_insn := PPC_STWX; ppc_insn := PPC_STWX;
elsif std_match(f.insn, "011111---------------0000101000-") then elsif std_match(f_in.insn, "011111---------------0000101000-") then
report "PPC_subf"; report "PPC_subf";
ppc_insn := PPC_SUBF; ppc_insn := PPC_SUBF;
elsif std_match(f.insn, "011111---------------0000001000-") then elsif std_match(f_in.insn, "011111---------------0000001000-") then
report "PPC_subfc"; report "PPC_subfc";
ppc_insn := PPC_SUBFC; ppc_insn := PPC_SUBFC;
elsif std_match(f.insn, "011111---------------0010001000-") then elsif std_match(f_in.insn, "011111---------------0010001000-") then
report "PPC_subfe"; report "PPC_subfe";
ppc_insn := PPC_SUBFE; ppc_insn := PPC_SUBFE;
elsif std_match(f.insn, "001000--------------------------") then elsif std_match(f_in.insn, "001000--------------------------") then
report "PPC_subfic"; report "PPC_subfic";
ppc_insn := PPC_SUBFIC; ppc_insn := PPC_SUBFIC;
elsif std_match(f.insn, "011111---------------0011101000-") then elsif std_match(f_in.insn, "011111---------------0011101000-") then
report "PPC_subfme"; report "PPC_subfme";
ppc_insn := PPC_SUBFME; ppc_insn := PPC_SUBFME;
elsif std_match(f.insn, "011111---------------0011001000-") then elsif std_match(f_in.insn, "011111---------------0011001000-") then
report "PPC_subfze"; report "PPC_subfze";
ppc_insn := PPC_SUBFZE; ppc_insn := PPC_SUBFZE;
elsif std_match(f.insn, "011111---------------1001010110-") then elsif std_match(f_in.insn, "011111---------------1001010110-") then
report "PPC_sync"; report "PPC_sync";
ppc_insn := PPC_SYNC; ppc_insn := PPC_SYNC;
elsif std_match(f.insn, "011111---------------0001000100-") then elsif std_match(f_in.insn, "011111---------------0001000100-") then
report "PPC_td"; report "PPC_td";
ppc_insn := PPC_TD; ppc_insn := PPC_TD;
elsif std_match(f.insn, "000010--------------------------") then elsif std_match(f_in.insn, "000010--------------------------") then
report "PPC_tdi"; report "PPC_tdi";
ppc_insn := PPC_TDI; ppc_insn := PPC_TDI;
elsif std_match(f.insn, "011111---------------0000000100-") then elsif std_match(f_in.insn, "011111---------------0000000100-") then
report "PPC_tw"; report "PPC_tw";
ppc_insn := PPC_TW; ppc_insn := PPC_TW;
elsif std_match(f.insn, "000011--------------------------") then elsif std_match(f_in.insn, "000011--------------------------") then
report "PPC_twi"; report "PPC_twi";
ppc_insn := PPC_TWI; ppc_insn := PPC_TWI;
elsif std_match(f.insn, "011111---------------0100111100-") then elsif std_match(f_in.insn, "011111---------------0100111100-") then
report "PPC_xor"; report "PPC_xor";
ppc_insn := PPC_XOR; ppc_insn := PPC_XOR;
elsif std_match(f.insn, "011010--------------------------") then elsif std_match(f_in.insn, "011010--------------------------") then
report "PPC_xori"; report "PPC_xori";
ppc_insn := PPC_XORI; ppc_insn := PPC_XORI;
elsif std_match(f.insn, "011011--------------------------") then elsif std_match(f_in.insn, "011011--------------------------") then
report "PPC_xoris"; report "PPC_xoris";
ppc_insn := PPC_XORIS; ppc_insn := PPC_XORIS;
elsif std_match(f.insn, "000001---------------0000000000-") then elsif std_match(f_in.insn, "000001---------------0000000000-") then
report "PPC_SIM_READ"; report "PPC_SIM_READ";
ppc_insn := PPC_SIM_READ; ppc_insn := PPC_SIM_READ;
elsif std_match(f.insn, "000001---------------0000000001-") then elsif std_match(f_in.insn, "000001---------------0000000001-") then
report "PPC_SIM_POLL"; report "PPC_SIM_POLL";
ppc_insn := PPC_SIM_POLL; ppc_insn := PPC_SIM_POLL;
elsif std_match(f.insn, "000001---------------0000000010-") then elsif std_match(f_in.insn, "000001---------------0000000010-") then
report "PPC_SIM_WRITE"; report "PPC_SIM_WRITE";
ppc_insn := PPC_SIM_WRITE; ppc_insn := PPC_SIM_WRITE;
elsif std_match(f.insn, "000001---------------0000000011-") then elsif std_match(f_in.insn, "000001---------------0000000011-") then
report "PPC_SIM_CONFIG"; report "PPC_SIM_CONFIG";
ppc_insn := PPC_SIM_CONFIG; ppc_insn := PPC_SIM_CONFIG;
else else
@ -841,7 +851,21 @@ begin
ppc_insn := PPC_ILLEGAL; ppc_insn := PPC_ILLEGAL;
end if; end if;


d_out.decode <= decode_rom_array(ppc_insn); v.decode := decode_rom_array(ppc_insn);
end if;

if flush_in = '1' then
v.valid := '0';
end if;

if rst = '1' then
v := Decode1ToDecode2Init;
end if; end if;

-- Update registers
rin <= v;

-- Update outputs
d_out <= r;
end process; end process;
end architecture behaviour; end architecture behaviour;

@ -11,6 +11,12 @@ use work.insn_helpers.all;
entity decode2 is entity decode2 is
port ( port (
clk : in std_ulogic; clk : in std_ulogic;
rst : in std_ulogic;

complete_in : in std_ulogic;
stall_out : out std_ulogic;

flush_in: in std_ulogic;


d_in : in Decode1ToDecode2Type; d_in : in Decode1ToDecode2Type;


@ -27,7 +33,21 @@ entity decode2 is
end entity decode2; end entity decode2;


architecture behaviour of decode2 is architecture behaviour of decode2 is
signal d : Decode1ToDecode2Type; type state_type is (IDLE, WAIT_FOR_PREV_TO_COMPLETE, WAIT_FOR_CURR_TO_COMPLETE);

type reg_internal_type is record
state : state_type;
outstanding : integer;
end record;

type reg_type is record
e : Decode2ToExecute1Type;
m : Decode2ToMultiplyType;
l : Decode2ToLoadstore1Type;
end record;

signal r_int, rin_int : reg_internal_type;
signal r, rin : reg_type;


type decode_input_reg_t is record type decode_input_reg_t is record
reg_valid : std_ulogic; reg_valid : std_ulogic;
@ -168,138 +188,219 @@ begin
decode2_0: process(clk) decode2_0: process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
d <= d_in; r <= rin;
r_int <= rin_int;
end if; end if;
end process; end process;


r_out.read1_reg <= insn_ra(d.insn) when (d.decode.input_reg_a = RA) else r_out.read1_reg <= insn_ra(d_in.insn) when (d_in.decode.input_reg_a = RA) else
insn_ra(d.insn) when d.decode.input_reg_a = RA_OR_ZERO else insn_ra(d_in.insn) when d_in.decode.input_reg_a = RA_OR_ZERO else
insn_rs(d.insn) when d.decode.input_reg_a = RS else insn_rs(d_in.insn) when d_in.decode.input_reg_a = RS else
(others => '0'); (others => '0');


r_out.read2_reg <= insn_rb(d.insn) when d.decode.input_reg_b = RB else r_out.read2_reg <= insn_rb(d_in.insn) when d_in.decode.input_reg_b = RB else
insn_rs(d.insn) when d.decode.input_reg_b = RS else insn_rs(d_in.insn) when d_in.decode.input_reg_b = RS else
(others => '0'); (others => '0');


r_out.read3_reg <= insn_rs(d.insn) when d.decode.input_reg_c = RS else r_out.read3_reg <= insn_rs(d_in.insn) when d_in.decode.input_reg_c = RS else
(others => '0'); (others => '0');


c_out.read <= d.decode.input_cr; c_out.read <= d_in.decode.input_cr;


decode2_1: process(all) decode2_1: process(all)
variable v : reg_type;
variable v_int : reg_internal_type;
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);
variable decoded_reg_a : decode_input_reg_t; variable decoded_reg_a : decode_input_reg_t;
variable decoded_reg_b : decode_input_reg_t; variable decoded_reg_b : decode_input_reg_t;
variable decoded_reg_c : decode_input_reg_t; variable decoded_reg_c : decode_input_reg_t;
variable is_valid : std_ulogic;
begin begin
e_out <= Decode2ToExecute1Init; v := r;
l_out <= Decode2ToLoadStore1Init; v_int := r_int;
m_out <= Decode2ToMultiplyInit;
v.e := Decode2ToExecute1Init;
v.l := Decode2ToLoadStore1Init;
v.m := Decode2ToMultiplyInit;


mul_a := (others => '0'); mul_a := (others => '0');
mul_b := (others => '0'); mul_b := (others => '0');


--e_out.input_cr <= d.decode.input_cr; --v.e.input_cr := d_in.decode.input_cr;
--m_out.input_cr <= d.decode.input_cr; --v.m.input_cr := d_in.decode.input_cr;
--e_out.output_cr <= d.decode.output_cr; --v.e.output_cr := d_in.decode.output_cr;


decoded_reg_a := decode_input_reg_a (d.decode.input_reg_a, d.insn, r_in.read1_data); decoded_reg_a := decode_input_reg_a (d_in.decode.input_reg_a, d_in.insn, r_in.read1_data);
decoded_reg_b := decode_input_reg_b (d.decode.input_reg_b, d.insn, r_in.read2_data); decoded_reg_b := decode_input_reg_b (d_in.decode.input_reg_b, d_in.insn, r_in.read2_data);
decoded_reg_c := decode_input_reg_c (d.decode.input_reg_c, d.insn, r_in.read3_data); decoded_reg_c := decode_input_reg_c (d_in.decode.input_reg_c, d_in.insn, r_in.read3_data);


r_out.read1_enable <= decoded_reg_a.reg_valid; r_out.read1_enable <= decoded_reg_a.reg_valid;
r_out.read2_enable <= decoded_reg_b.reg_valid; r_out.read2_enable <= decoded_reg_b.reg_valid;
r_out.read3_enable <= decoded_reg_c.reg_valid; r_out.read3_enable <= decoded_reg_c.reg_valid;


case d.decode.unit is
when ALU =>
e_out.valid <= d.valid;
when LDST =>
l_out.valid <= d.valid;
when MUL =>
m_out.valid <= d.valid;
when NONE =>
e_out.valid <= d.valid;
e_out.insn_type <= OP_ILLEGAL;
end case;

-- execute unit -- execute unit
e_out.nia <= d.nia; v.e.nia := d_in.nia;
e_out.insn_type <= d.decode.insn_type; v.e.insn_type := d_in.decode.insn_type;
e_out.read_reg1 <= decoded_reg_a.reg; v.e.read_reg1 := decoded_reg_a.reg;
e_out.read_data1 <= decoded_reg_a.data; v.e.read_data1 := decoded_reg_a.data;
e_out.read_reg2 <= decoded_reg_b.reg; v.e.read_reg2 := decoded_reg_b.reg;
e_out.read_data2 <= decoded_reg_b.data; v.e.read_data2 := decoded_reg_b.data;
e_out.write_reg <= decode_output_reg(d.decode.output_reg_a, d.insn); v.e.write_reg := decode_output_reg(d_in.decode.output_reg_a, d_in.insn);
e_out.rc <= decode_rc(d.decode.rc, d.insn); v.e.rc := decode_rc(d_in.decode.rc, d_in.insn);
e_out.cr <= c_in.read_cr_data; v.e.cr := c_in.read_cr_data;
e_out.input_carry <= d.decode.input_carry; v.e.input_carry := d_in.decode.input_carry;
e_out.output_carry <= d.decode.output_carry; v.e.output_carry := d_in.decode.output_carry;
if d.decode.lr then if d_in.decode.lr then
e_out.lr <= insn_lk(d.insn); v.e.lr := insn_lk(d_in.insn);
end if; end if;
e_out.const1 <= decode_const_a(d.decode.const_a, d.insn); v.e.const1 := decode_const_a(d_in.decode.const_a, d_in.insn);
e_out.const2 <= decode_const_b(d.decode.const_b, d.insn); v.e.const2 := decode_const_b(d_in.decode.const_b, d_in.insn);
e_out.const3 <= decode_const_c(d.decode.const_c, d.insn); v.e.const3 := decode_const_c(d_in.decode.const_c, d_in.insn);


-- multiply unit -- multiply unit
m_out.nia <= d.nia; v.m.nia := d_in.nia;
m_out.insn_type <= d.decode.insn_type; v.m.insn_type := d_in.decode.insn_type;
mul_a := decoded_reg_a.data; mul_a := decoded_reg_a.data;
mul_b := decoded_reg_b.data; mul_b := decoded_reg_b.data;
m_out.write_reg <= decode_output_reg(d.decode.output_reg_a, d.insn); v.m.write_reg := decode_output_reg(d_in.decode.output_reg_a, d_in.insn);
m_out.rc <= decode_rc(d.decode.rc, d.insn); v.m.rc := decode_rc(d_in.decode.rc, d_in.insn);


if d.decode.mul_32bit = '1' then if d_in.decode.mul_32bit = '1' then
if d.decode.mul_signed = '1' then if d_in.decode.mul_signed = '1' then
m_out.data1 <= (others => mul_a(31)); v.m.data1 := (others => mul_a(31));
m_out.data1(31 downto 0) <= mul_a(31 downto 0); v.m.data1(31 downto 0) := mul_a(31 downto 0);
m_out.data2 <= (others => mul_b(31)); v.m.data2 := (others => mul_b(31));
m_out.data2(31 downto 0) <= mul_b(31 downto 0); v.m.data2(31 downto 0) := mul_b(31 downto 0);
else else
m_out.data1 <= '0' & x"00000000" & mul_a(31 downto 0); v.m.data1 := '0' & x"00000000" & mul_a(31 downto 0);
m_out.data2 <= '0' & x"00000000" & mul_b(31 downto 0); v.m.data2 := '0' & x"00000000" & mul_b(31 downto 0);
end if; end if;
else else
if d.decode.mul_signed = '1' then if d_in.decode.mul_signed = '1' then
m_out.data1 <= mul_a(63) & mul_a; v.m.data1 := mul_a(63) & mul_a;
m_out.data2 <= mul_b(63) & mul_b; v.m.data2 := mul_b(63) & mul_b;
else else
m_out.data1 <= '0' & mul_a; v.m.data1 := '0' & mul_a;
m_out.data2 <= '0' & mul_b; v.m.data2 := '0' & mul_b;
end if; end if;
end if; end if;


-- load/store unit -- load/store unit
l_out.nia <= d.nia; v.l.nia := d_in.nia;
l_out.update_reg <= decoded_reg_a.reg; v.l.update_reg := decoded_reg_a.reg;
l_out.addr1 <= decoded_reg_a.data; v.l.addr1 := decoded_reg_a.data;
l_out.addr2 <= decoded_reg_b.data; v.l.addr2 := decoded_reg_b.data;
l_out.data <= decoded_reg_c.data; v.l.data := decoded_reg_c.data;
l_out.write_reg <= decode_output_reg(d.decode.output_reg_a, d.insn); v.l.write_reg := decode_output_reg(d_in.decode.output_reg_a, d_in.insn);


if d.decode.insn_type = OP_LOAD then if d_in.decode.insn_type = OP_LOAD then
l_out.load <= '1'; v.l.load := '1';
else else
l_out.load <= '0'; v.l.load := '0';
end if; end if;


case d.decode.length is case d_in.decode.length is
when is1B => when is1B =>
l_out.length <= "0001"; v.l.length := "0001";
when is2B => when is2B =>
l_out.length <= "0010"; v.l.length := "0010";
when is4B => when is4B =>
l_out.length <= "0100"; v.l.length := "0100";
when is8B => when is8B =>
l_out.length <= "1000"; v.l.length := "1000";
when NONE => when NONE =>
l_out.length <= "0000"; v.l.length := "0000";
end case; end case;


l_out.byte_reverse <= d.decode.byte_reverse; v.l.byte_reverse := d_in.decode.byte_reverse;
l_out.sign_extend <= d.decode.sign_extend; v.l.sign_extend := d_in.decode.sign_extend;
l_out.update <= d.decode.update; v.l.update := d_in.decode.update;

-- single issue

if complete_in = '1' then
v_int.outstanding := v_int.outstanding - 1;
end if;

-- state machine to handle instructions that must be single
-- through the pipeline.
stall_out <= '0';
is_valid := d_in.valid;
case v_int.state is
when IDLE =>
if (flush_in = '0') and (d_in.valid = '1') and (d_in.decode.sgl_pipe = '1') then
if v_int.outstanding /= 0 then
v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
stall_out <= '1';
is_valid := '0';
else
-- send insn out and wait on it to complete
v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
end if;
end if;

when WAIT_FOR_PREV_TO_COMPLETE =>
if v_int.outstanding = 0 then
-- send insn out and wait on it to complete
v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
else
stall_out <= '1';
is_valid := '0';
end if;

when WAIT_FOR_CURR_TO_COMPLETE =>
if v_int.outstanding = 0 then
v_int.state := IDLE;
else
stall_out <= '1';
is_valid := '0';
end if;
end case;

v.e.valid := '0';
v.m.valid := '0';
v.l.valid := '0';
case d_in.decode.unit is
when ALU =>
v.e.valid := is_valid;
when LDST =>
v.l.valid := is_valid;
when MUL =>
v.m.valid := is_valid;
when NONE =>
v.e.valid := is_valid;
v.e.insn_type := OP_ILLEGAL;
end case;

if flush_in = '1' then
v.e.valid := '0';
v.m.valid := '0';
v.l.valid := '0';
end if;

-- track outstanding instructions
if v.e.valid = '1' or v.l.valid = '1' or v.m.valid = '1' then
v_int.outstanding := v_int.outstanding + 1;
end if;

assert r_int.outstanding <= 1 report "Outstanding bad " & integer'image(r_int.outstanding) severity failure;

if rst = '1' then
v_int.state := IDLE;
v_int.outstanding := 0;
v.e := Decode2ToExecute1Init;
v.l := Decode2ToLoadStore1Init;
v.m := Decode2ToMultiplyInit;
end if;

-- Update registers
rin <= v;
rin_int <= v_int;

-- Update outputs
e_out <= r.e;
l_out <= r.l;
m_out <= r.m;
end process; end process;
end architecture behaviour; end architecture behaviour;

@ -17,8 +17,14 @@ entity execute1 is
port ( port (
clk : in std_logic; clk : in std_logic;


-- asynchronous
flush_out : out std_ulogic;

e_in : in Decode2ToExecute1Type; e_in : in Decode2ToExecute1Type;

-- asynchronous
f_out : out Execute1ToFetch1Type; f_out : out Execute1ToFetch1Type;

e_out : out Execute1ToExecute2Type; e_out : out Execute1ToExecute2Type;


terminate_out : out std_ulogic terminate_out : out std_ulogic
@ -26,19 +32,26 @@ entity execute1 is
end entity execute1; end entity execute1;


architecture behaviour of execute1 is architecture behaviour of execute1 is
signal e: Decode2ToExecute1Type := Decode2ToExecute1Init; type reg_type is record
--f : Execute1ToFetch1Type;
e : Execute1ToExecute2Type;
end record;

signal r, rin : reg_type;

signal ctrl: ctrl_t := (carry => '0', others => (others => '0')); signal ctrl: ctrl_t := (carry => '0', others => (others => '0'));
signal ctrl_tmp: ctrl_t := (carry => '0', others => (others => '0')); signal ctrl_tmp: ctrl_t := (carry => '0', others => (others => '0'));
begin begin
execute1_0: process(clk) execute1_0: process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
e <= e_in; r <= rin;
ctrl <= ctrl_tmp; ctrl <= ctrl_tmp;
end if; end if;
end process; end process;


execute1_1: process(all) execute1_1: process(all)
variable v : reg_type;
variable result : std_ulogic_vector(63 downto 0); variable result : std_ulogic_vector(63 downto 0);
variable result_with_carry : std_ulogic_vector(64 downto 0); variable result_with_carry : std_ulogic_vector(64 downto 0);
variable result_en : integer; variable result_en : integer;
@ -49,21 +62,26 @@ begin
result_with_carry := (others => '0'); result_with_carry := (others => '0');
result_en := 0; result_en := 0;


e_out <= Execute1ToExecute2Init; v := r;
f_out <= Execute1ToFetch1TypeInit; v.e := Execute1ToExecute2Init;
--v.f := Execute1ToFetch1TypeInit;

ctrl_tmp <= ctrl; ctrl_tmp <= ctrl;
-- FIXME: run at 512MHz not core freq -- FIXME: run at 512MHz not core freq
ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1); ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1);


terminate_out <= '0'; terminate_out <= '0';
flush_out <= '0';
f_out <= Execute1ToFetch1TypeInit;

if e_in.valid = '1' then


if e.valid = '1' then v.e.valid := '1';
e_out.valid <= '1'; v.e.write_reg := e_in.write_reg;
e_out.write_reg <= e.write_reg;


report "execute " & to_hstring(e.nia); report "execute " & to_hstring(e_in.nia);


case_0: case e.insn_type is case_0: case e_in.insn_type is


when OP_ILLEGAL => when OP_ILLEGAL =>
terminate_out <= '1'; terminate_out <= '1';
@ -71,94 +89,98 @@ begin
when OP_NOP => when OP_NOP =>
-- Do nothing -- Do nothing
when OP_ADD => when OP_ADD =>
result := ppc_add(e.read_data1, e.read_data2); result := ppc_add(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_ADDC => when OP_ADDC =>
result_with_carry := ppc_adde(e.read_data1, e.read_data2, ctrl.carry and e.input_carry); result_with_carry := ppc_adde(e_in.read_data1, e_in.read_data2, ctrl.carry and e_in.input_carry);
result := result_with_carry(63 downto 0); result := result_with_carry(63 downto 0);
ctrl_tmp.carry <= result_with_carry(64) and e.output_carry; ctrl_tmp.carry <= result_with_carry(64) and e_in.output_carry;
result_en := 1; result_en := 1;
when OP_AND => when OP_AND =>
result := ppc_and(e.read_data1, e.read_data2); result := ppc_and(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_ANDC => when OP_ANDC =>
result := ppc_andc(e.read_data1, e.read_data2); result := ppc_andc(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_B => when OP_B =>
flush_out <= '1';
f_out.redirect <= '1'; f_out.redirect <= '1';
f_out.redirect_nia <= std_ulogic_vector(signed(e.nia) + signed(e.read_data2)); f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
when OP_BC => when OP_BC =>
if e.const1(4-2) = '0' then if e_in.const1(4-2) = '0' then
ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1); ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
end if; end if;
if ppc_bc_taken(e.const1(4 downto 0), e.const2(4 downto 0), e.cr, ctrl.ctr) = 1 then if ppc_bc_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr, ctrl.ctr) = 1 then
flush_out <= '1';
f_out.redirect <= '1'; f_out.redirect <= '1';
f_out.redirect_nia <= std_ulogic_vector(signed(e.nia) + signed(e.read_data2)); f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
end if; end if;
when OP_BCLR => when OP_BCLR =>
if e.const1(4-2) = '0' then if e_in.const1(4-2) = '0' then
ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1); ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
end if; end if;
if ppc_bc_taken(e.const1(4 downto 0), e.const2(4 downto 0), e.cr, ctrl.ctr) = 1 then if ppc_bc_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr, ctrl.ctr) = 1 then
flush_out <= '1';
f_out.redirect <= '1'; f_out.redirect <= '1';
f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00"; f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00";
end if; end if;
when OP_BCCTR => when OP_BCCTR =>
if ppc_bcctr_taken(e.const1(4 downto 0), e.const2(4 downto 0), e.cr) = 1 then if ppc_bcctr_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr) = 1 then
flush_out <= '1';
f_out.redirect <= '1'; f_out.redirect <= '1';
f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00"; f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00";
end if; end if;
when OP_CMPB => when OP_CMPB =>
result := ppc_cmpb(e.read_data1, e.read_data2); result := ppc_cmpb(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_CMP => when OP_CMP =>
e_out.write_cr_enable <= '1'; v.e.write_cr_enable := '1';
crnum := to_integer(unsigned(e.const1(2 downto 0))); crnum := to_integer(unsigned(e_in.const1(2 downto 0)));
e_out.write_cr_mask <= num_to_fxm(crnum); v.e.write_cr_mask := num_to_fxm(crnum);
for i in 0 to 7 loop for i in 0 to 7 loop
lo := i*4; lo := i*4;
hi := lo + 3; hi := lo + 3;
e_out.write_cr_data(hi downto lo) <= ppc_cmp(e.const2(0), e.read_data1, e.read_data2); v.e.write_cr_data(hi downto lo) := ppc_cmp(e_in.const2(0), e_in.read_data1, e_in.read_data2);
end loop; end loop;
when OP_CMPL => when OP_CMPL =>
e_out.write_cr_enable <= '1'; v.e.write_cr_enable := '1';
crnum := to_integer(unsigned(e.const1(2 downto 0))); crnum := to_integer(unsigned(e_in.const1(2 downto 0)));
e_out.write_cr_mask <= num_to_fxm(crnum); v.e.write_cr_mask := num_to_fxm(crnum);
for i in 0 to 7 loop for i in 0 to 7 loop
lo := i*4; lo := i*4;
hi := lo + 3; hi := lo + 3;
e_out.write_cr_data(hi downto lo) <= ppc_cmpl(e.const2(0), e.read_data1, e.read_data2); v.e.write_cr_data(hi downto lo) := ppc_cmpl(e_in.const2(0), e_in.read_data1, e_in.read_data2);
end loop; end loop;
when OP_CNTLZW => when OP_CNTLZW =>
result := ppc_cntlzw(e.read_data1); result := ppc_cntlzw(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_CNTTZW => when OP_CNTTZW =>
result := ppc_cnttzw(e.read_data1); result := ppc_cnttzw(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_CNTLZD => when OP_CNTLZD =>
result := ppc_cntlzd(e.read_data1); result := ppc_cntlzd(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_CNTTZD => when OP_CNTTZD =>
result := ppc_cnttzd(e.read_data1); result := ppc_cnttzd(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_EXTSB => when OP_EXTSB =>
result := ppc_extsb(e.read_data1); result := ppc_extsb(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_EXTSH => when OP_EXTSH =>
result := ppc_extsh(e.read_data1); result := ppc_extsh(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_EXTSW => when OP_EXTSW =>
result := ppc_extsw(e.read_data1); result := ppc_extsw(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_EQV => when OP_EQV =>
result := ppc_eqv(e.read_data1, e.read_data2); result := ppc_eqv(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_ISEL => when OP_ISEL =>
crnum := to_integer(unsigned(e.const1)); crnum := to_integer(unsigned(e_in.const1));
if e.cr(31-crnum) = '1' then if e_in.cr(31-crnum) = '1' then
result := e.read_data1; result := e_in.read_data1;
else else
result := e.read_data2; result := e_in.read_data2;
end if; end if;
result_en := 1; result_en := 1;
when OP_MFCTR => when OP_MFCTR =>
@ -171,133 +193,133 @@ begin
result := ctrl.tb; result := ctrl.tb;
result_en := 1; result_en := 1;
when OP_MTCTR => when OP_MTCTR =>
ctrl_tmp.ctr <= e.read_data1; ctrl_tmp.ctr <= e_in.read_data1;
when OP_MTLR => when OP_MTLR =>
ctrl_tmp.lr <= e.read_data1; ctrl_tmp.lr <= e_in.read_data1;
when OP_MFCR => when OP_MFCR =>
result := x"00000000" & e.cr; result := x"00000000" & e_in.cr;
result_en := 1; result_en := 1;
when OP_MFOCRF => when OP_MFOCRF =>
crnum := fxm_to_num(e.const1(7 downto 0)); crnum := fxm_to_num(e_in.const1(7 downto 0));
result := (others => '0'); result := (others => '0');
-- result((4*(7-crnum)+3) downto (4*(7-crnum))) := e.cr((4*(7-crnum)+3) downto (4*(7-crnum))); FIXME -- result((4*(7-crnum)+3) downto (4*(7-crnum))) := e_in.cr((4*(7-crnum)+3) downto (4*(7-crnum))); FIXME
for i in 0 to 7 loop for i in 0 to 7 loop
lo := (7-i)*4; lo := (7-i)*4;
hi := lo + 3; hi := lo + 3;
if crnum = i then if crnum = i then
result(hi downto lo) := e.cr(hi downto lo); result(hi downto lo) := e_in.cr(hi downto lo);
end if; end if;
end loop; end loop;
result_en := 1; result_en := 1;
when OP_MTCRF => when OP_MTCRF =>
e_out.write_cr_enable <= '1'; v.e.write_cr_enable := '1';
e_out.write_cr_mask <= e.const1(7 downto 0); v.e.write_cr_mask := e_in.const1(7 downto 0);
e_out.write_cr_data <= e.read_data1(31 downto 0); v.e.write_cr_data := e_in.read_data1(31 downto 0);
when OP_MTOCRF => when OP_MTOCRF =>
e_out.write_cr_enable <= '1'; v.e.write_cr_enable := '1';
-- We require one hot priority encoding here -- We require one hot priority encoding here
crnum := fxm_to_num(e.const1(7 downto 0)); crnum := fxm_to_num(e_in.const1(7 downto 0));
e_out.write_cr_mask <= num_to_fxm(crnum); v.e.write_cr_mask := num_to_fxm(crnum);
e_out.write_cr_data <= e.read_data1(31 downto 0); v.e.write_cr_data := e_in.read_data1(31 downto 0);
when OP_NAND => when OP_NAND =>
result := ppc_nand(e.read_data1, e.read_data2); result := ppc_nand(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_NEG => when OP_NEG =>
result := ppc_neg(e.read_data1); result := ppc_neg(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_NOR => when OP_NOR =>
result := ppc_nor(e.read_data1, e.read_data2); result := ppc_nor(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_OR => when OP_OR =>
result := ppc_or(e.read_data1, e.read_data2); result := ppc_or(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_ORC => when OP_ORC =>
result := ppc_orc(e.read_data1, e.read_data2); result := ppc_orc(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_POPCNTB => when OP_POPCNTB =>
result := ppc_popcntb(e.read_data1); result := ppc_popcntb(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_POPCNTW => when OP_POPCNTW =>
result := ppc_popcntw(e.read_data1); result := ppc_popcntw(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_POPCNTD => when OP_POPCNTD =>
result := ppc_popcntd(e.read_data1); result := ppc_popcntd(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_PRTYD => when OP_PRTYD =>
result := ppc_prtyd(e.read_data1); result := ppc_prtyd(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_PRTYW => when OP_PRTYW =>
result := ppc_prtyw(e.read_data1); result := ppc_prtyw(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_RLDCL => when OP_RLDCL =>
result := ppc_rldcl(e.read_data1, e.read_data2, e.const2(5 downto 0)); result := ppc_rldcl(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0));
result_en := 1; result_en := 1;
when OP_RLDCR => when OP_RLDCR =>
result := ppc_rldcr(e.read_data1, e.read_data2, e.const2(5 downto 0)); result := ppc_rldcr(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0));
result_en := 1; result_en := 1;
when OP_RLDICL => when OP_RLDICL =>
result := ppc_rldicl(e.read_data1, e.const1(5 downto 0), e.const2(5 downto 0)); result := ppc_rldicl(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0));
result_en := 1; result_en := 1;
when OP_RLDICR => when OP_RLDICR =>
result := ppc_rldicr(e.read_data1, e.const1(5 downto 0), e.const2(5 downto 0)); result := ppc_rldicr(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0));
result_en := 1; result_en := 1;
when OP_RLWNM => when OP_RLWNM =>
result := ppc_rlwnm(e.read_data1, e.read_data2, e.const2(4 downto 0), e.const3(4 downto 0)); result := ppc_rlwnm(e_in.read_data1, e_in.read_data2, e_in.const2(4 downto 0), e_in.const3(4 downto 0));
result_en := 1; result_en := 1;
when OP_RLWINM => when OP_RLWINM =>
result := ppc_rlwinm(e.read_data1, e.const1(4 downto 0), e.const2(4 downto 0), e.const3(4 downto 0)); result := ppc_rlwinm(e_in.read_data1, e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.const3(4 downto 0));
result_en := 1; result_en := 1;
when OP_RLDIC => when OP_RLDIC =>
result := ppc_rldic(e.read_data1, e.const1(5 downto 0), e.const2(5 downto 0)); result := ppc_rldic(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0));
result_en := 1; result_en := 1;
when OP_RLDIMI => when OP_RLDIMI =>
result := ppc_rldimi(e.read_data1, e.read_data2, e.const1(5 downto 0), e.const2(5 downto 0)); result := ppc_rldimi(e_in.read_data1, e_in.read_data2, e_in.const1(5 downto 0), e_in.const2(5 downto 0));
result_en := 1; result_en := 1;
when OP_RLWIMI => when OP_RLWIMI =>
result := ppc_rlwimi(e.read_data1, e.read_data2, e.const1(4 downto 0), e.const2(4 downto 0), e.const3(4 downto 0)); result := ppc_rlwimi(e_in.read_data1, e_in.read_data2, e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.const3(4 downto 0));
result_en := 1; result_en := 1;
when OP_SLD => when OP_SLD =>
result := ppc_sld(e.read_data1, e.read_data2); result := ppc_sld(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_SLW => when OP_SLW =>
result := ppc_slw(e.read_data1, e.read_data2); result := ppc_slw(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_SRAW => when OP_SRAW =>
result_with_carry := ppc_sraw(e.read_data1, e.read_data2); result_with_carry := ppc_sraw(e_in.read_data1, e_in.read_data2);
result := result_with_carry(63 downto 0); result := result_with_carry(63 downto 0);
ctrl_tmp.carry <= result_with_carry(64); ctrl_tmp.carry <= result_with_carry(64);
result_en := 1; result_en := 1;
when OP_SRAWI => when OP_SRAWI =>
result_with_carry := ppc_srawi(e.read_data1, e.const1(5 downto 0)); result_with_carry := ppc_srawi(e_in.read_data1, e_in.const1(5 downto 0));
result := result_with_carry(63 downto 0); result := result_with_carry(63 downto 0);
ctrl_tmp.carry <= result_with_carry(64); ctrl_tmp.carry <= result_with_carry(64);
result_en := 1; result_en := 1;
when OP_SRAD => when OP_SRAD =>
result_with_carry := ppc_srad(e.read_data1, e.read_data2); result_with_carry := ppc_srad(e_in.read_data1, e_in.read_data2);
result := result_with_carry(63 downto 0); result := result_with_carry(63 downto 0);
ctrl_tmp.carry <= result_with_carry(64); ctrl_tmp.carry <= result_with_carry(64);
result_en := 1; result_en := 1;
when OP_SRADI => when OP_SRADI =>
result_with_carry := ppc_sradi(e.read_data1, e.const1(5 downto 0)); result_with_carry := ppc_sradi(e_in.read_data1, e_in.const1(5 downto 0));
result := result_with_carry(63 downto 0); result := result_with_carry(63 downto 0);
ctrl_tmp.carry <= result_with_carry(64); ctrl_tmp.carry <= result_with_carry(64);
result_en := 1; result_en := 1;
when OP_SRD => when OP_SRD =>
result := ppc_srd(e.read_data1, e.read_data2); result := ppc_srd(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_SRW => when OP_SRW =>
result := ppc_srw(e.read_data1, e.read_data2); result := ppc_srw(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_SUBF => when OP_SUBF =>
result := ppc_subf(e.read_data1, e.read_data2); result := ppc_subf(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
when OP_SUBFC => when OP_SUBFC =>
result_with_carry := ppc_subfe(e.read_data1, e.read_data2, ctrl.carry or not(e.input_carry)); result_with_carry := ppc_subfe(e_in.read_data1, e_in.read_data2, ctrl.carry or not(e_in.input_carry));
result := result_with_carry(63 downto 0); result := result_with_carry(63 downto 0);
ctrl_tmp.carry <= result_with_carry(64) and e.output_carry; ctrl_tmp.carry <= result_with_carry(64) and e_in.output_carry;
result_en := 1; result_en := 1;
when OP_XOR => when OP_XOR =>
result := ppc_xor(e.read_data1, e.read_data2); result := ppc_xor(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;


-- sim console -- sim console
@ -319,7 +341,7 @@ begin
end if; end if;
when OP_SIM_WRITE => when OP_SIM_WRITE =>
if SIM = true then if SIM = true then
sim_console_write(e.read_data1); sim_console_write(e_in.read_data1);
else else
terminate_out <= '1'; terminate_out <= '1';
report "illegal"; report "illegal";
@ -338,7 +360,7 @@ begin


when OP_DIVDU => when OP_DIVDU =>
if SIM = true then if SIM = true then
result := ppc_divdu(e.read_data1, e.read_data2); result := ppc_divdu(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
else else
terminate_out <= '1'; terminate_out <= '1';
@ -346,7 +368,7 @@ begin
end if; end if;
when OP_DIVD => when OP_DIVD =>
if SIM = true then if SIM = true then
result := ppc_divd(e.read_data1, e.read_data2); result := ppc_divd(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
else else
terminate_out <= '1'; terminate_out <= '1';
@ -354,7 +376,7 @@ begin
end if; end if;
when OP_DIVWU => when OP_DIVWU =>
if SIM = true then if SIM = true then
result := ppc_divwu(e.read_data1, e.read_data2); result := ppc_divwu(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
else else
terminate_out <= '1'; terminate_out <= '1';
@ -362,7 +384,7 @@ begin
end if; end if;
when OP_DIVW => when OP_DIVW =>
if SIM = true then if SIM = true then
result := ppc_divw(e.read_data1, e.read_data2); result := ppc_divw(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;
else else
terminate_out <= '1'; terminate_out <= '1';
@ -373,15 +395,22 @@ begin
report "illegal"; report "illegal";
end case; end case;


if e.lr = '1' then if e_in.lr = '1' then
ctrl_tmp.lr <= std_ulogic_vector(unsigned(e.nia) + 4); ctrl_tmp.lr <= std_ulogic_vector(unsigned(e_in.nia) + 4);
end if; end if;


if result_en = 1 then if result_en = 1 then
e_out.write_data <= result; v.e.write_data := result;
e_out.write_enable <= '1'; v.e.write_enable := '1';
e_out.rc <= e.rc; v.e.rc := e_in.rc;
end if; end if;
end if; end if;

-- Update registers
rin <= v;

-- update outputs
--f_out <= r.f;
e_out <= r.e;
end process; end process;
end architecture behaviour; end architecture behaviour;

@ -14,7 +14,8 @@ entity fetch1 is
rst : in std_ulogic; rst : in std_ulogic;


-- Control inputs: -- Control inputs:
fetch_one_in : in std_ulogic; stall_in : in std_ulogic;
flush_in : in std_ulogic;


-- redirect from execution unit -- redirect from execution unit
e_in : in Execute1ToFetch1Type; e_in : in Execute1ToFetch1Type;
@ -25,54 +26,48 @@ entity fetch1 is
end entity fetch1; end entity fetch1;


architecture behaviour of fetch1 is architecture behaviour of fetch1 is
type reg_type is record type reg_internal_type is record
pc : std_ulogic_vector(63 downto 0); nia_next : std_ulogic_vector(63 downto 0);
fetch_one : std_ulogic;
end record; end record;

signal r_int, rin_int : reg_internal_type;
signal r : reg_type; signal r, rin : Fetch1ToFetch2Type;
signal rin : reg_type;
begin begin
regs : process(clk) regs : process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
r <= rin; r <= rin;
r_int <= rin_int;
end if; end if;
end process; end process;


comb : process(all) comb : process(all)
variable v : reg_type; variable v : Fetch1ToFetch2Type;
variable fetch_valid : std_ulogic; variable v_int : reg_internal_type;
variable fetch_nia : std_ulogic_vector(63 downto 0);
begin begin
v := r; v := r;
v_int := r_int;


fetch_valid := '0'; if stall_in = '0' then
fetch_nia := (others => '0'); v.nia := r_int.nia_next;

v_int.nia_next := std_logic_vector(unsigned(r_int.nia_next) + 4);
v.fetch_one := v.fetch_one or fetch_one_in;

if e_in.redirect = '1' then
v.pc := e_in.redirect_nia;
end if; end if;


if v.fetch_one = '1' then if e_in.redirect = '1' then
fetch_nia := v.pc; v.nia := e_in.redirect_nia;
fetch_valid := '1'; v_int.nia_next := std_logic_vector(unsigned(e_in.redirect_nia) + 4);
v.pc := std_logic_vector(unsigned(v.pc) + 4);

v.fetch_one := '0';
end if; end if;


if rst = '1' then if rst = '1' then
v.pc := RESET_ADDRESS; v.nia := RESET_ADDRESS;
v.fetch_one := '0'; v_int.nia_next := std_logic_vector(unsigned(RESET_ADDRESS) + 4);
end if; end if;


-- Update registers
rin <= v; rin <= v;
rin_int <= v_int;


f_out.valid <= fetch_valid; -- Update outputs
f_out.nia <= fetch_nia; f_out <= r;
end process; end process;


end architecture behaviour; end architecture behaviour;

@ -9,6 +9,12 @@ use work.wishbone_types.all;
entity fetch2 is entity fetch2 is
port( port(
clk : in std_ulogic; clk : in std_ulogic;
rst : in std_ulogic;

stall_in : in std_ulogic;
stall_out : out std_ulogic;

flush_in : in std_ulogic;


-- instruction memory interface -- instruction memory interface
wishbone_in : in wishbone_slave_out; wishbone_in : in wishbone_slave_out;
@ -21,50 +27,133 @@ entity fetch2 is
end entity fetch2; end entity fetch2;


architecture behaviour of fetch2 is architecture behaviour of fetch2 is
type reg_type is record type state_type is (IDLE, JUST_IDLE, WAIT_ACK, WAIT_ACK_THROWAWAY);
valid : std_ulogic;
nia : std_ulogic_vector(63 downto 0); type reg_internal_type is record
state : state_type;
nia : std_ulogic_vector(63 downto 0);
w : wishbone_master_out;
-- Trivial 64B cache
cache : std_ulogic_vector(63 downto 0);
tag : std_ulogic_vector(60 downto 0);
tag_valid : std_ulogic;
end record; end record;


signal f : Fetch1ToFetch2Type; function wishbone_fetch(nia : std_ulogic_vector(63 downto 0)) return wishbone_master_out is
signal wishbone: wishbone_slave_out; variable w : wishbone_master_out;
signal r : reg_type := (valid => '0', nia => (others => '0')); begin
signal rin : reg_type := (valid => '0', nia => (others => '0')); assert nia(2 downto 0) = "000";

w.adr := nia;
w.dat := (others => '0');
w.cyc := '1';
w.stb := '1';
w.sel := "11111111";
w.we := '0';

return w;
end;

signal r, rin : Fetch2ToDecode1Type;
signal r_int, rin_int : reg_internal_type;
begin begin
regs : process(clk) regs : process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
wishbone <= wishbone_in; -- Output state remains unchanged on stall, unless we are flushing
f <= f_in; if rst = '1' or flush_in = '1' or stall_in = '0' then
r <= rin; r <= rin;
end if;
r_int <= rin_int;
end if; end if;
end process; end process;


comb : process(all) comb : process(all)
variable v : reg_type; variable v : Fetch2ToDecode1Type;
variable v_int : reg_internal_type;
begin begin
v := r; v := r;
v_int := r_int;

v.valid := '0';
v.nia := f_in.nia;

case v_int.state is
when IDLE | JUST_IDLE =>
v_int.state := IDLE;

if (v_int.tag_valid = '1') and (v_int.tag = f_in.nia(63 downto 3)) then
v.valid := '1';
if f_in.nia(2) = '0' then
v.insn := v_int.cache(31 downto 0);
else
v.insn := v_int.cache(63 downto 32);
end if;
else
v_int.state := WAIT_ACK;
v_int.nia := f_in.nia;
v_int.w := wishbone_fetch(f_in.nia(63 downto 3) & "000");
end if;


if f.valid = '1' then when WAIT_ACK =>
v.valid := '1'; if wishbone_in.ack = '1' then
v.nia := f.nia; v_int.state := IDLE;
v_int.w := wishbone_master_out_init;
v_int.cache := wishbone_in.dat;
v_int.tag := v_int.nia(63 downto 3);
v_int.tag_valid := '1';

v.valid := '1';
if v_int.nia(2) = '0' then
v.insn := v_int.cache(31 downto 0);
else
v.insn := v_int.cache(63 downto 32);
end if;
end if;

when WAIT_ACK_THROWAWAY =>
if wishbone_in.ack = '1' then
-- Should we put the returned data in the cache? We went to the
-- trouble of fetching it and it might be useful in the future

v_int.w := wishbone_master_out_init;

-- We need to stall fetch1 for one more cycle, so transition through JUST_IDLE
v_int.state := JUST_IDLE;
end if;
end case;

stall_out <= '0';
if v_int.state /= IDLE then
stall_out <= '1';
end if; end if;


if v.valid = '1' and wishbone.ack = '1' then if flush_in = '1' then
v.valid := '0'; v.valid := '0';

-- Throw away in flight data
if v_int.state = WAIT_ACK then
v_int.state := WAIT_ACK_THROWAWAY;
end if;
end if; end if;


rin <= v; if rst = '1' then
v := Fetch2ToDecode1Init;


wishbone_out.adr <= v.nia(63 downto 3) & "000"; v_int.state := IDLE;
wishbone_out.dat <= (others => '0'); v_int.nia := (others => '0');
wishbone_out.cyc <= v.valid; v_int.w := wishbone_master_out_init;
wishbone_out.stb <= v.valid; v_int.cache := (others => '0');
wishbone_out.sel <= "00001111" when v.nia(2) = '0' else "11110000"; v_int.tag := (others => '0');
wishbone_out.we <= '0'; v_int.tag_valid := '0';
end if;

-- Update registers
rin_int <= v_int;
rin <= v;


f_out.valid <= wishbone.ack; -- Update outputs
f_out.nia <= v.nia; f_out <= r;
f_out.insn <= wishbone.dat(31 downto 0) when v.nia(2) = '0' else wishbone.dat(63 downto 32); wishbone_out <= r_int.w;
end process; end process;
end architecture behaviour; end architecture behaviour;

Loading…
Cancel
Save