mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
Implement CRNOR and friends
Signed-off-by: Tom Vijlbrief <tvijlbrief@gmail.com>
This commit is contained in:
parent
1a826f077b
commit
c05441bf47
18
decode1.vhdl
18
decode1.vhdl
@ -84,14 +84,14 @@ architecture behaviour of decode1 is
|
||||
2#1000010000# => '1', -- bcctr
|
||||
2#0000010000# => '1', -- bclr
|
||||
2#1000110000# => '0', -- bctar
|
||||
2#0100000001# => '0', -- crand
|
||||
2#0010000001# => '0', -- crandc
|
||||
2#0100100001# => '0', -- creqv
|
||||
2#0011100001# => '0', -- crnand
|
||||
2#0000100001# => '0', -- crnor
|
||||
2#0111000001# => '0', -- cror
|
||||
2#0011000001# => '0', -- crorc
|
||||
2#0110100001# => '0', -- crxor
|
||||
2#0100000001# => '1', -- crand
|
||||
2#0010000001# => '1', -- crandc
|
||||
2#0100100001# => '1', -- creqv
|
||||
2#0011100001# => '1', -- crnand
|
||||
2#0000100001# => '1', -- crnor
|
||||
2#0111000001# => '1', -- cror
|
||||
2#0110100001# => '1', -- crorc
|
||||
2#0011000001# => '1', -- crxor
|
||||
2#0010010110# => '1', -- isync
|
||||
2#0000000000# => '1', -- mcrf
|
||||
others => '0'
|
||||
@ -101,7 +101,7 @@ architecture behaviour of decode1 is
|
||||
constant decode_op_19_array : op_19_subop_array_t := (
|
||||
-- unit internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl
|
||||
-- op in out A out in out len ext pipe
|
||||
-- mcrf; cr logical ops not implemented yet
|
||||
-- mcrf; and cr logical ops
|
||||
2#000# => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'),
|
||||
-- addpcis not implemented yet
|
||||
2#001# => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'),
|
||||
|
||||
@ -152,6 +152,10 @@ begin
|
||||
variable sh32, mb32, me32 : std_ulogic_vector(4 downto 0);
|
||||
variable bo, bi : std_ulogic_vector(4 downto 0);
|
||||
variable bf, bfa : std_ulogic_vector(2 downto 0);
|
||||
variable cr_op : std_ulogic_vector(9 downto 0);
|
||||
variable bt, ba, bb : std_ulogic_vector(4 downto 0);
|
||||
variable btnum, banum, bbnum : integer range 0 to 31;
|
||||
variable crresult : std_ulogic;
|
||||
variable l : std_ulogic;
|
||||
variable next_nia : std_ulogic_vector(63 downto 0);
|
||||
variable carry_32, carry_64 : std_ulogic;
|
||||
@ -335,24 +339,64 @@ begin
|
||||
end if;
|
||||
result_en := '1';
|
||||
when OP_MCRF =>
|
||||
bf := insn_bf(e_in.insn);
|
||||
bfa := insn_bfa(e_in.insn);
|
||||
v.e.write_cr_enable := '1';
|
||||
crnum := to_integer(unsigned(bf));
|
||||
scrnum := to_integer(unsigned(bfa));
|
||||
v.e.write_cr_mask := num_to_fxm(crnum);
|
||||
for i in 0 to 7 loop
|
||||
lo := (7-i)*4;
|
||||
hi := lo + 3;
|
||||
if i = scrnum then
|
||||
newcrf := e_in.cr(hi downto lo);
|
||||
end if;
|
||||
end loop;
|
||||
for i in 0 to 7 loop
|
||||
lo := i*4;
|
||||
hi := lo + 3;
|
||||
v.e.write_cr_data(hi downto lo) := newcrf;
|
||||
end loop;
|
||||
cr_op := insn_cr(e_in.insn);
|
||||
report "CR OP " & to_hstring(cr_op);
|
||||
if cr_op(0) = '0' then -- MCRF
|
||||
bf := insn_bf(e_in.insn);
|
||||
bfa := insn_bfa(e_in.insn);
|
||||
v.e.write_cr_enable := '1';
|
||||
crnum := to_integer(unsigned(bf));
|
||||
scrnum := to_integer(unsigned(bfa));
|
||||
v.e.write_cr_mask := num_to_fxm(crnum);
|
||||
for i in 0 to 7 loop
|
||||
lo := (7-i)*4;
|
||||
hi := lo + 3;
|
||||
if i = scrnum then
|
||||
newcrf := e_in.cr(hi downto lo);
|
||||
end if;
|
||||
end loop;
|
||||
for i in 0 to 7 loop
|
||||
lo := i*4;
|
||||
hi := lo + 3;
|
||||
v.e.write_cr_data(hi downto lo) := newcrf;
|
||||
end loop;
|
||||
else
|
||||
v.e.write_cr_enable := '1';
|
||||
bt := insn_bt(e_in.insn);
|
||||
ba := insn_ba(e_in.insn);
|
||||
bb := insn_bb(e_in.insn);
|
||||
btnum := 31 - to_integer(unsigned(bt));
|
||||
banum := 31 - to_integer(unsigned(ba));
|
||||
bbnum := 31 - to_integer(unsigned(bb));
|
||||
case cr_op(8 downto 5) is
|
||||
when "1001" => -- CREQV
|
||||
crresult := not(e_in.cr(banum) xor e_in.cr(bbnum));
|
||||
when "0111" => -- CRNAND
|
||||
crresult := not(e_in.cr(banum) and e_in.cr(bbnum));
|
||||
when "0100" => -- CRANDC
|
||||
crresult := (e_in.cr(banum) and not e_in.cr(bbnum));
|
||||
when "1000" => -- CRAND
|
||||
crresult := (e_in.cr(banum) and e_in.cr(bbnum));
|
||||
when "0001" => -- CRNOR
|
||||
crresult := not(e_in.cr(banum) or e_in.cr(bbnum));
|
||||
when "1101" => -- CRORC
|
||||
crresult := (e_in.cr(banum) or not e_in.cr(bbnum));
|
||||
when "0110" => -- CRXOR
|
||||
crresult := (e_in.cr(banum) xor e_in.cr(bbnum));
|
||||
when "1110" => -- CROR
|
||||
crresult := (e_in.cr(banum) or e_in.cr(bbnum));
|
||||
when others =>
|
||||
report "BAD CR?";
|
||||
end case;
|
||||
v.e.write_cr_mask := num_to_fxm((31-btnum) / 4);
|
||||
for i in 0 to 31 loop
|
||||
if i = btnum then
|
||||
v.e.write_cr_data(i) := crresult;
|
||||
else
|
||||
v.e.write_cr_data(i) := e_in.cr(i);
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
when OP_MFSPR =>
|
||||
if is_fast_spr(e_in.read_reg1) then
|
||||
result := e_in.read_data1;
|
||||
|
||||
@ -20,6 +20,10 @@ package insn_helpers is
|
||||
function insn_bd (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||
function insn_bf (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||
function insn_bfa (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||
function insn_cr (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||
function insn_bt (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||
function insn_ba (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||
function insn_bb (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||
function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||
function insn_bo (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||
function insn_bi (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||
@ -124,6 +128,26 @@ package body insn_helpers is
|
||||
return insn_in(20 downto 18);
|
||||
end;
|
||||
|
||||
function insn_cr (insn_in : std_ulogic_vector) return std_ulogic_vector is
|
||||
begin
|
||||
return insn_in(10 downto 1);
|
||||
end;
|
||||
|
||||
function insn_bb (insn_in : std_ulogic_vector) return std_ulogic_vector is
|
||||
begin
|
||||
return insn_in(15 downto 11);
|
||||
end;
|
||||
|
||||
function insn_ba (insn_in : std_ulogic_vector) return std_ulogic_vector is
|
||||
begin
|
||||
return insn_in(20 downto 16);
|
||||
end;
|
||||
|
||||
function insn_bt (insn_in : std_ulogic_vector) return std_ulogic_vector is
|
||||
begin
|
||||
return insn_in(25 downto 21);
|
||||
end;
|
||||
|
||||
function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector is
|
||||
begin
|
||||
return insn_in(19 downto 12);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user