mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-29 04:51:16 +00:00
Implement CRNOR and friends
Signed-off-by: Tom Vijlbrief <tvijlbrief@gmail.com>
This commit is contained in:
18
decode1.vhdl
18
decode1.vhdl
@@ -84,14 +84,14 @@ architecture behaviour of decode1 is
|
|||||||
2#1000010000# => '1', -- bcctr
|
2#1000010000# => '1', -- bcctr
|
||||||
2#0000010000# => '1', -- bclr
|
2#0000010000# => '1', -- bclr
|
||||||
2#1000110000# => '0', -- bctar
|
2#1000110000# => '0', -- bctar
|
||||||
2#0100000001# => '0', -- crand
|
2#0100000001# => '1', -- crand
|
||||||
2#0010000001# => '0', -- crandc
|
2#0010000001# => '1', -- crandc
|
||||||
2#0100100001# => '0', -- creqv
|
2#0100100001# => '1', -- creqv
|
||||||
2#0011100001# => '0', -- crnand
|
2#0011100001# => '1', -- crnand
|
||||||
2#0000100001# => '0', -- crnor
|
2#0000100001# => '1', -- crnor
|
||||||
2#0111000001# => '0', -- cror
|
2#0111000001# => '1', -- cror
|
||||||
2#0011000001# => '0', -- crorc
|
2#0110100001# => '1', -- crorc
|
||||||
2#0110100001# => '0', -- crxor
|
2#0011000001# => '1', -- crxor
|
||||||
2#0010010110# => '1', -- isync
|
2#0010010110# => '1', -- isync
|
||||||
2#0000000000# => '1', -- mcrf
|
2#0000000000# => '1', -- mcrf
|
||||||
others => '0'
|
others => '0'
|
||||||
@@ -101,7 +101,7 @@ architecture behaviour of decode1 is
|
|||||||
constant decode_op_19_array : op_19_subop_array_t := (
|
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
|
-- 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
|
-- 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'),
|
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
|
-- 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'),
|
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 sh32, mb32, me32 : std_ulogic_vector(4 downto 0);
|
||||||
variable bo, bi : 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 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 l : std_ulogic;
|
||||||
variable next_nia : std_ulogic_vector(63 downto 0);
|
variable next_nia : std_ulogic_vector(63 downto 0);
|
||||||
variable carry_32, carry_64 : std_ulogic;
|
variable carry_32, carry_64 : std_ulogic;
|
||||||
@@ -335,24 +339,64 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
result_en := '1';
|
result_en := '1';
|
||||||
when OP_MCRF =>
|
when OP_MCRF =>
|
||||||
bf := insn_bf(e_in.insn);
|
cr_op := insn_cr(e_in.insn);
|
||||||
bfa := insn_bfa(e_in.insn);
|
report "CR OP " & to_hstring(cr_op);
|
||||||
v.e.write_cr_enable := '1';
|
if cr_op(0) = '0' then -- MCRF
|
||||||
crnum := to_integer(unsigned(bf));
|
bf := insn_bf(e_in.insn);
|
||||||
scrnum := to_integer(unsigned(bfa));
|
bfa := insn_bfa(e_in.insn);
|
||||||
v.e.write_cr_mask := num_to_fxm(crnum);
|
v.e.write_cr_enable := '1';
|
||||||
for i in 0 to 7 loop
|
crnum := to_integer(unsigned(bf));
|
||||||
lo := (7-i)*4;
|
scrnum := to_integer(unsigned(bfa));
|
||||||
hi := lo + 3;
|
v.e.write_cr_mask := num_to_fxm(crnum);
|
||||||
if i = scrnum then
|
for i in 0 to 7 loop
|
||||||
newcrf := e_in.cr(hi downto lo);
|
lo := (7-i)*4;
|
||||||
end if;
|
hi := lo + 3;
|
||||||
end loop;
|
if i = scrnum then
|
||||||
for i in 0 to 7 loop
|
newcrf := e_in.cr(hi downto lo);
|
||||||
lo := i*4;
|
end if;
|
||||||
hi := lo + 3;
|
end loop;
|
||||||
v.e.write_cr_data(hi downto lo) := newcrf;
|
for i in 0 to 7 loop
|
||||||
end 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 =>
|
when OP_MFSPR =>
|
||||||
if is_fast_spr(e_in.read_reg1) then
|
if is_fast_spr(e_in.read_reg1) then
|
||||||
result := e_in.read_data1;
|
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_bd (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||||
function insn_bf (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_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_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector;
|
||||||
function insn_bo (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;
|
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);
|
return insn_in(20 downto 18);
|
||||||
end;
|
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
|
function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector is
|
||||||
begin
|
begin
|
||||||
return insn_in(19 downto 12);
|
return insn_in(19 downto 12);
|
||||||
|
|||||||
Reference in New Issue
Block a user