|
|
@ -108,9 +108,10 @@ begin
|
|
|
|
variable result : std_ulogic_vector(63 downto 0);
|
|
|
|
variable result : std_ulogic_vector(63 downto 0);
|
|
|
|
variable newcrf : std_ulogic_vector(3 downto 0);
|
|
|
|
variable newcrf : std_ulogic_vector(3 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 : std_ulogic;
|
|
|
|
variable crnum : integer;
|
|
|
|
variable crnum : crnum_t;
|
|
|
|
variable scrnum : integer;
|
|
|
|
variable crbit : integer range 0 to 31;
|
|
|
|
|
|
|
|
variable scrnum : crnum_t;
|
|
|
|
variable lo, hi : integer;
|
|
|
|
variable lo, hi : integer;
|
|
|
|
variable sh, mb, me : std_ulogic_vector(5 downto 0);
|
|
|
|
variable sh, mb, me : std_ulogic_vector(5 downto 0);
|
|
|
|
variable sh32, mb32, me32 : std_ulogic_vector(4 downto 0);
|
|
|
|
variable sh32, mb32, me32 : std_ulogic_vector(4 downto 0);
|
|
|
@ -120,7 +121,7 @@ begin
|
|
|
|
begin
|
|
|
|
begin
|
|
|
|
result := (others => '0');
|
|
|
|
result := (others => '0');
|
|
|
|
result_with_carry := (others => '0');
|
|
|
|
result_with_carry := (others => '0');
|
|
|
|
result_en := 0;
|
|
|
|
result_en := '0';
|
|
|
|
newcrf := (others => '0');
|
|
|
|
newcrf := (others => '0');
|
|
|
|
|
|
|
|
|
|
|
|
v := r;
|
|
|
|
v := r;
|
|
|
@ -164,10 +165,10 @@ begin
|
|
|
|
if e_in.output_carry then
|
|
|
|
if e_in.output_carry then
|
|
|
|
ctrl_tmp.carry <= result_with_carry(64);
|
|
|
|
ctrl_tmp.carry <= result_with_carry(64);
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_AND | OP_OR | OP_XOR =>
|
|
|
|
when OP_AND | OP_OR | OP_XOR =>
|
|
|
|
result := logical_result;
|
|
|
|
result := logical_result;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_B =>
|
|
|
|
when OP_B =>
|
|
|
|
f_out.redirect <= '1';
|
|
|
|
f_out.redirect <= '1';
|
|
|
|
if (insn_aa(e_in.insn)) then
|
|
|
|
if (insn_aa(e_in.insn)) then
|
|
|
@ -206,7 +207,7 @@ begin
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
when OP_CMPB =>
|
|
|
|
when OP_CMPB =>
|
|
|
|
result := ppc_cmpb(e_in.read_data3, e_in.read_data2);
|
|
|
|
result := ppc_cmpb(e_in.read_data3, e_in.read_data2);
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_CMP =>
|
|
|
|
when OP_CMP =>
|
|
|
|
bf := insn_bf(e_in.insn);
|
|
|
|
bf := insn_bf(e_in.insn);
|
|
|
|
l := insn_l(e_in.insn);
|
|
|
|
l := insn_l(e_in.insn);
|
|
|
@ -231,20 +232,20 @@ begin
|
|
|
|
end loop;
|
|
|
|
end loop;
|
|
|
|
when OP_CNTZ =>
|
|
|
|
when OP_CNTZ =>
|
|
|
|
result := countzero_result;
|
|
|
|
result := countzero_result;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_EXTS =>
|
|
|
|
when OP_EXTS =>
|
|
|
|
v.e.write_len := e_in.data_len;
|
|
|
|
v.e.write_len := e_in.data_len;
|
|
|
|
v.e.sign_extend := '1';
|
|
|
|
v.e.sign_extend := '1';
|
|
|
|
result := e_in.read_data3;
|
|
|
|
result := e_in.read_data3;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_ISEL =>
|
|
|
|
when OP_ISEL =>
|
|
|
|
crnum := to_integer(unsigned(insn_bc(e_in.insn)));
|
|
|
|
crbit := to_integer(unsigned(insn_bc(e_in.insn)));
|
|
|
|
if e_in.cr(31-crnum) = '1' then
|
|
|
|
if e_in.cr(31-crbit) = '1' then
|
|
|
|
result := e_in.read_data1;
|
|
|
|
result := e_in.read_data1;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
result := e_in.read_data2;
|
|
|
|
result := e_in.read_data2;
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_MCRF =>
|
|
|
|
when OP_MCRF =>
|
|
|
|
bf := insn_bf(e_in.insn);
|
|
|
|
bf := insn_bf(e_in.insn);
|
|
|
|
bfa := insn_bfa(e_in.insn);
|
|
|
|
bfa := insn_bfa(e_in.insn);
|
|
|
@ -267,13 +268,13 @@ begin
|
|
|
|
when OP_MFSPR =>
|
|
|
|
when OP_MFSPR =>
|
|
|
|
if std_match(e_in.insn(20 downto 11), "0100100000") then
|
|
|
|
if std_match(e_in.insn(20 downto 11), "0100100000") then
|
|
|
|
result := ctrl.ctr;
|
|
|
|
result := ctrl.ctr;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
elsif std_match(e_in.insn(20 downto 11), "0100000000") then
|
|
|
|
elsif std_match(e_in.insn(20 downto 11), "0100000000") then
|
|
|
|
result := ctrl.lr;
|
|
|
|
result := ctrl.lr;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
elsif std_match(e_in.insn(20 downto 11), "0110001000") then
|
|
|
|
elsif std_match(e_in.insn(20 downto 11), "0110001000") then
|
|
|
|
result := ctrl.tb;
|
|
|
|
result := ctrl.tb;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
when OP_MFCR =>
|
|
|
|
when OP_MFCR =>
|
|
|
|
if e_in.insn(20) = '0' then
|
|
|
|
if e_in.insn(20) = '0' then
|
|
|
@ -291,7 +292,7 @@ begin
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
end loop;
|
|
|
|
end loop;
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_MTCRF =>
|
|
|
|
when OP_MTCRF =>
|
|
|
|
v.e.write_cr_enable := '1';
|
|
|
|
v.e.write_cr_enable := '1';
|
|
|
|
if e_in.insn(20) = '0' then
|
|
|
|
if e_in.insn(20) = '0' then
|
|
|
@ -311,25 +312,25 @@ begin
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
when OP_POPCNTB =>
|
|
|
|
when OP_POPCNTB =>
|
|
|
|
result := ppc_popcntb(e_in.read_data3);
|
|
|
|
result := ppc_popcntb(e_in.read_data3);
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_POPCNTW =>
|
|
|
|
when OP_POPCNTW =>
|
|
|
|
result := ppc_popcntw(e_in.read_data3);
|
|
|
|
result := ppc_popcntw(e_in.read_data3);
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_POPCNTD =>
|
|
|
|
when OP_POPCNTD =>
|
|
|
|
result := ppc_popcntd(e_in.read_data3);
|
|
|
|
result := ppc_popcntd(e_in.read_data3);
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_PRTYD =>
|
|
|
|
when OP_PRTYD =>
|
|
|
|
result := ppc_prtyd(e_in.read_data3);
|
|
|
|
result := ppc_prtyd(e_in.read_data3);
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_PRTYW =>
|
|
|
|
when OP_PRTYW =>
|
|
|
|
result := ppc_prtyw(e_in.read_data3);
|
|
|
|
result := ppc_prtyw(e_in.read_data3);
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_RLC | OP_RLCL | OP_RLCR | OP_SHL | OP_SHR =>
|
|
|
|
when OP_RLC | OP_RLCL | OP_RLCR | OP_SHL | OP_SHR =>
|
|
|
|
result := rotator_result;
|
|
|
|
result := rotator_result;
|
|
|
|
if e_in.output_carry = '1' then
|
|
|
|
if e_in.output_carry = '1' then
|
|
|
|
ctrl_tmp.carry <= rotator_carry;
|
|
|
|
ctrl_tmp.carry <= rotator_carry;
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
when OP_SIM_CONFIG =>
|
|
|
|
when OP_SIM_CONFIG =>
|
|
|
|
-- bit 0 was used to select the microwatt console, which
|
|
|
|
-- bit 0 was used to select the microwatt console, which
|
|
|
|
-- we no longer support.
|
|
|
|
-- we no longer support.
|
|
|
@ -338,7 +339,7 @@ begin
|
|
|
|
else
|
|
|
|
else
|
|
|
|
result := x"0000000000000000";
|
|
|
|
result := x"0000000000000000";
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
result_en := 1;
|
|
|
|
result_en := '1';
|
|
|
|
|
|
|
|
|
|
|
|
when OP_TDI =>
|
|
|
|
when OP_TDI =>
|
|
|
|
-- Keep our test cases happy for now, ignore trap instructions
|
|
|
|
-- Keep our test cases happy for now, ignore trap instructions
|
|
|
@ -353,12 +354,11 @@ begin
|
|
|
|
ctrl_tmp.lr <= std_ulogic_vector(unsigned(e_in.nia) + 4);
|
|
|
|
ctrl_tmp.lr <= std_ulogic_vector(unsigned(e_in.nia) + 4);
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
|
|
if result_en = 1 then
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
|
|
v.e.write_data := result;
|
|
|
|
v.e.write_data := result;
|
|
|
|
v.e.write_enable := '1';
|
|
|
|
v.e.write_enable := result_en;
|
|
|
|
v.e.rc := e_in.rc;
|
|
|
|
v.e.rc := e_in.rc;
|
|
|
|
end if;
|
|
|
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Update registers
|
|
|
|
-- Update registers
|
|
|
|
rin <= v;
|
|
|
|
rin <= v;
|
|
|
|