@ -44,6 +44,8 @@ architecture behaviour of decode1 is
signal decode_rom_addr : insn_code;
signal decode_rom_addr : insn_code;
signal decode : decode_rom_t;
signal decode : decode_rom_t;
signal double : std_ulogic;
type prefix_state_t is record
type prefix_state_t is record
prefixed : std_ulogic;
prefixed : std_ulogic;
prefix : std_ulogic_vector(25 downto 0);
prefix : std_ulogic_vector(25 downto 0);
@ -485,6 +487,8 @@ architecture behaviour of decode1 is
end;
end;
begin
begin
double <= not r.second when (r.valid = '1' and decode.repeat /= NONE) else '0';
decode1_0: process(clk)
decode1_0: process(clk)
begin
begin
if rising_edge(clk) then
if rising_edge(clk) then
@ -497,10 +501,14 @@ begin
fetch_failed <= '0';
fetch_failed <= '0';
pr <= prefix_state_init;
pr <= prefix_state_init;
elsif stall_in = '0' then
elsif stall_in = '0' then
r <= rin;
if double = '0' then
fetch_failed <= f_in.fetch_failed;
r <= rin;
if f_in.valid = '1' then
fetch_failed <= f_in.fetch_failed;
pr <= pr_in;
if f_in.valid = '1' then
pr <= pr_in;
end if;
else
r.second <= '1';
end if;
end if;
end if;
end if;
if rst = '1' then
if rst = '1' then
@ -511,12 +519,12 @@ begin
end if;
end if;
end process;
end process;
busy_out <= stall_in;
busy_out <= stall_in or double;
decode1_rom: process(clk)
decode1_rom: process(clk)
begin
begin
if rising_edge(clk) then
if rising_edge(clk) then
if stall_in = '0' then
if stall_in = '0' and double = '0' then
decode <= decode_rom(decode_rom_addr);
decode <= decode_rom(decode_rom_addr);
end if;
end if;
end if;
end if;
@ -646,33 +654,43 @@ begin
-- Work out GPR/FPR read addresses
-- Work out GPR/FPR read addresses
-- Note that for prefixed instructions we are working this out based
-- Note that for prefixed instructions we are working this out based
-- only on the suffix.
-- only on the suffix.
maybe_rb := '0';
if double = '0' then
vr.reg_1_addr := '0' & insn_ra(f_in.insn);
maybe_rb := '0';
vr.reg_2_addr := '0' & insn_rb(f_in.insn);
vr.reg_1_addr := '0' & insn_ra(f_in.insn);
vr.reg_3_addr := '0' & insn_rs(f_in.insn);
vr.reg_2_addr := '0' & insn_rb(f_in.insn);
if icode >= INSN_first_rb then
vr.reg_3_addr := '0' & insn_rs(f_in.insn);
maybe_rb := '1';
if icode >= INSN_first_rb then
if icode < INSN_first_frs then
maybe_rb := '1';
if icode >= INSN_first_rc then
if icode < INSN_first_frs then
vr.reg_3_addr := '0' & insn_rcreg(f_in.insn);
if icode >= INSN_first_rc then
end if;
vr.reg_3_addr := '0' & insn_rcreg(f_in.insn);
else
end if;
-- access FRS operand
else
vr.reg_3_addr(5) := '1';
-- access FRS operand
if icode >= INSN_first_frab then
vr.reg_3_addr(5) := '1';
-- access FRA and/or FRB operands
if icode >= INSN_first_frab then
vr.reg_1_addr(5) := '1';
-- access FRA and/or FRB operands
vr.reg_2_addr(5) := '1';
vr.reg_1_addr(5) := '1';
end if;
vr.reg_2_addr(5) := '1';
if icode >= INSN_first_frabc then
end if;
-- access FRC operand
if icode >= INSN_first_frabc then
vr.reg_3_addr := '1' & insn_rcreg(f_in.insn);
-- access FRC operand
vr.reg_3_addr := '1' & insn_rcreg(f_in.insn);
end if;
end if;
end if;
end if;
end if;
vr.read_1_enable := f_in.valid;
vr.read_2_enable := f_in.valid and maybe_rb;
vr.read_3_enable := f_in.valid;
else
-- second instance of a doubled instruction
vr.reg_1_addr := r.reg_a;
vr.reg_2_addr := r.reg_b;
vr.reg_3_addr := r.reg_c;
vr.read_1_enable := '0'; -- (not actually used)
vr.read_2_enable := '0';
vr.read_3_enable := '1'; -- (not actually used)
end if;
end if;
vr.read_1_enable := f_in.valid;
vr.read_2_enable := f_in.valid and maybe_rb;
vr.read_3_enable := f_in.valid;
v.reg_a := vr.reg_1_addr;
v.reg_a := vr.reg_1_addr;
v.reg_b := vr.reg_2_addr;
v.reg_b := vr.reg_2_addr;