From 858b1e7930a4f0f211310684481dfab8c86c8261 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 16 Oct 2019 12:05:36 +1100 Subject: [PATCH 1/6] writeback: Remove a mux leg on data_in Initialize to 0 forces the mux to have an extra leg fed with zeros. Instead initialize data_in to one of the mux inputs Signed-off-by: Benjamin Herrenschmidt --- writeback.vhdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/writeback.vhdl b/writeback.vhdl index 042ad59..ab7b6c7 100644 --- a/writeback.vhdl +++ b/writeback.vhdl @@ -95,7 +95,7 @@ begin partial_write <= '0'; sign_extend <= '0'; second_word <= '0'; - data_in <= (others => '0'); + data_in <= e_in.write_data; if e_in.write_enable = '1' then w_out.write_reg <= e_in.write_reg; From 4437487ad06515b1216810315f8b511fd27cf15c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 16 Oct 2019 12:28:19 +1100 Subject: [PATCH 2/6] execute1: Reformat No functional change Signed-off-by: Benjamin Herrenschmidt --- execute1.vhdl | 646 +++++++++++++++++++++++++------------------------- 1 file changed, 323 insertions(+), 323 deletions(-) diff --git a/execute1.vhdl b/execute1.vhdl index 702744e..002bdac 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -11,361 +11,361 @@ use work.insn_helpers.all; use work.ppc_fx_insns.all; entity execute1 is - generic ( - SIM : boolean := false + generic ( + SIM : boolean := false ); - port ( - clk : in std_logic; + port ( + clk : in std_logic; - -- asynchronous - flush_out : out std_ulogic; + -- asynchronous + flush_out : out std_ulogic; - e_in : in Decode2ToExecute1Type; + e_in : in Decode2ToExecute1Type; - -- asynchronous - f_out : out Execute1ToFetch1Type; + -- asynchronous + f_out : out Execute1ToFetch1Type; - e_out : out Execute1ToWritebackType; + e_out : out Execute1ToWritebackType; - terminate_out : out std_ulogic + terminate_out : out std_ulogic ); end entity execute1; architecture behaviour of execute1 is - type reg_type is record - --f : Execute1ToFetch1Type; - e : Execute1ToWritebackType; - end record; + type reg_type is record + --f : Execute1ToFetch1Type; + e : Execute1ToWritebackType; + end record; - signal r, rin : reg_type; + signal r, rin : reg_type; - signal ctrl: ctrl_t := (carry => '0', others => (others => '0')); - signal ctrl_tmp: 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 right_shift, rot_clear_left, rot_clear_right: std_ulogic; - signal rotator_result: std_ulogic_vector(63 downto 0); - signal rotator_carry: std_ulogic; - signal logical_result: std_ulogic_vector(63 downto 0); - signal countzero_result: std_ulogic_vector(63 downto 0); + signal right_shift, rot_clear_left, rot_clear_right: std_ulogic; + signal rotator_result: std_ulogic_vector(63 downto 0); + signal rotator_carry: std_ulogic; + signal logical_result: std_ulogic_vector(63 downto 0); + signal countzero_result: std_ulogic_vector(63 downto 0); - function decode_input_carry (carry_sel : carry_in_t; ca_in : std_ulogic) return std_ulogic is - begin - case carry_sel is - when ZERO => - return '0'; - when CA => - return ca_in; - when ONE => - return '1'; - end case; - end; + function decode_input_carry (carry_sel : carry_in_t; ca_in : std_ulogic) return std_ulogic is + begin + case carry_sel is + when ZERO => + return '0'; + when CA => + return ca_in; + when ONE => + return '1'; + end case; + end; begin - rotator_0: entity work.rotator - port map ( - rs => e_in.read_data3, - ra => e_in.read_data1, - shift => e_in.read_data2(6 downto 0), - insn => e_in.insn, - is_32bit => e_in.is_32bit, - right_shift => right_shift, - arith => e_in.is_signed, - clear_left => rot_clear_left, - clear_right => rot_clear_right, - result => rotator_result, - carry_out => rotator_carry - ); + rotator_0: entity work.rotator + port map ( + rs => e_in.read_data3, + ra => e_in.read_data1, + shift => e_in.read_data2(6 downto 0), + insn => e_in.insn, + is_32bit => e_in.is_32bit, + right_shift => right_shift, + arith => e_in.is_signed, + clear_left => rot_clear_left, + clear_right => rot_clear_right, + result => rotator_result, + carry_out => rotator_carry + ); - logical_0: entity work.logical - port map ( - rs => e_in.read_data3, - rb => e_in.read_data2, - op => e_in.insn_type, - invert_in => e_in.invert_a, - invert_out => e_in.invert_out, - result => logical_result - ); + logical_0: entity work.logical + port map ( + rs => e_in.read_data3, + rb => e_in.read_data2, + op => e_in.insn_type, + invert_in => e_in.invert_a, + invert_out => e_in.invert_out, + result => logical_result + ); - countzero_0: entity work.zero_counter - port map ( - rs => e_in.read_data3, - count_right => e_in.insn(10), - is_32bit => e_in.is_32bit, - result => countzero_result - ); + countzero_0: entity work.zero_counter + port map ( + rs => e_in.read_data3, + count_right => e_in.insn(10), + is_32bit => e_in.is_32bit, + result => countzero_result + ); - execute1_0: process(clk) - begin - if rising_edge(clk) then - r <= rin; - ctrl <= ctrl_tmp; - end if; - end process; + execute1_0: process(clk) + begin + if rising_edge(clk) then + r <= rin; + ctrl <= ctrl_tmp; + end if; + end process; - execute1_1: process(all) - variable v : reg_type; - variable a_inv : std_ulogic_vector(63 downto 0); - variable result : std_ulogic_vector(63 downto 0); - variable newcrf : std_ulogic_vector(3 downto 0); - variable result_with_carry : std_ulogic_vector(64 downto 0); - variable result_en : integer; - variable crnum : integer; - variable scrnum : integer; - variable lo, hi : integer; - variable sh, mb, me : std_ulogic_vector(5 downto 0); - 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 l : std_ulogic; - begin - result := (others => '0'); - result_with_carry := (others => '0'); - result_en := 0; - newcrf := (others => '0'); + execute1_1: process(all) + variable v : reg_type; + variable a_inv : std_ulogic_vector(63 downto 0); + variable result : std_ulogic_vector(63 downto 0); + variable newcrf : std_ulogic_vector(3 downto 0); + variable result_with_carry : std_ulogic_vector(64 downto 0); + variable result_en : integer; + variable crnum : integer; + variable scrnum : integer; + variable lo, hi : integer; + variable sh, mb, me : std_ulogic_vector(5 downto 0); + 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 l : std_ulogic; + begin + result := (others => '0'); + result_with_carry := (others => '0'); + result_en := 0; + newcrf := (others => '0'); - v := r; - v.e := Execute1ToWritebackInit; - --v.f := Execute1ToFetch1TypeInit; + v := r; + v.e := Execute1ToWritebackInit; + --v.f := Execute1ToFetch1TypeInit; - ctrl_tmp <= ctrl; - -- FIXME: run at 512MHz not core freq - ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1); + ctrl_tmp <= ctrl; + -- FIXME: run at 512MHz not core freq + ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1); - terminate_out <= '0'; - f_out <= Execute1ToFetch1TypeInit; + terminate_out <= '0'; + f_out <= Execute1ToFetch1TypeInit; - -- rotator control signals - right_shift <= '1' when e_in.insn_type = OP_SHR else '0'; - rot_clear_left <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCL else '0'; - rot_clear_right <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCR else '0'; + -- rotator control signals + right_shift <= '1' when e_in.insn_type = OP_SHR else '0'; + rot_clear_left <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCL else '0'; + rot_clear_right <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCR else '0'; - if e_in.valid = '1' then + if e_in.valid = '1' then - v.e.valid := '1'; - v.e.write_reg := e_in.write_reg; - v.e.write_len := x"8"; - v.e.sign_extend := '0'; + v.e.valid := '1'; + v.e.write_reg := e_in.write_reg; + v.e.write_len := x"8"; + v.e.sign_extend := '0'; - case_0: case e_in.insn_type is + case_0: case e_in.insn_type is - when OP_ILLEGAL => - terminate_out <= '1'; - report "illegal"; - when OP_NOP => - -- Do nothing - when OP_ADD => - if e_in.invert_a = '0' then - a_inv := e_in.read_data1; - else - a_inv := not e_in.read_data1; - end if; - result_with_carry := ppc_adde(a_inv, e_in.read_data2, decode_input_carry(e_in.input_carry, ctrl.carry)); - result := result_with_carry(63 downto 0); - if e_in.output_carry then - ctrl_tmp.carry <= result_with_carry(64); - end if; - result_en := 1; - when OP_AND | OP_OR | OP_XOR => - result := logical_result; - result_en := 1; - when OP_B => - f_out.redirect <= '1'; - if (insn_aa(e_in.insn)) then - f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2)); - else - f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); - end if; - when OP_BC => - bo := insn_bo(e_in.insn); - bi := insn_bi(e_in.insn); - if bo(4-2) = '0' then - ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1); - end if; - if ppc_bc_taken(bo, bi, e_in.cr, ctrl.ctr) = 1 then - f_out.redirect <= '1'; - if (insn_aa(e_in.insn)) then - f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2)); - else - f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); - end if; - end if; - when OP_BCREG => - -- bits 10 and 6 distinguish between bclr, bcctr and bctar - bo := insn_bo(e_in.insn); - bi := insn_bi(e_in.insn); - if bo(4-2) = '0' and e_in.insn(10) = '0' then - ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1); - end if; - if ppc_bc_taken(bo, bi, e_in.cr, ctrl.ctr) = 1 then - f_out.redirect <= '1'; - if e_in.insn(10) = '0' then - f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00"; - else - f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00"; - end if; - end if; - when OP_CMPB => - result := ppc_cmpb(e_in.read_data3, e_in.read_data2); - result_en := 1; - when OP_CMP => - bf := insn_bf(e_in.insn); - l := insn_l(e_in.insn); - v.e.write_cr_enable := '1'; - crnum := to_integer(unsigned(bf)); - v.e.write_cr_mask := num_to_fxm(crnum); - for i in 0 to 7 loop - lo := i*4; - hi := lo + 3; - v.e.write_cr_data(hi downto lo) := ppc_cmp(l, e_in.read_data1, e_in.read_data2); - end loop; - when OP_CMPL => - bf := insn_bf(e_in.insn); - l := insn_l(e_in.insn); - v.e.write_cr_enable := '1'; - crnum := to_integer(unsigned(bf)); - v.e.write_cr_mask := num_to_fxm(crnum); - for i in 0 to 7 loop - lo := i*4; - hi := lo + 3; - v.e.write_cr_data(hi downto lo) := ppc_cmpl(l, e_in.read_data1, e_in.read_data2); - end loop; - when OP_CNTZ => - result := countzero_result; - result_en := 1; - when OP_EXTS => - v.e.write_len := e_in.data_len; - v.e.sign_extend := '1'; - result := e_in.read_data3; - result_en := 1; - when OP_ISEL => - crnum := to_integer(unsigned(insn_bc(e_in.insn))); - if e_in.cr(31-crnum) = '1' then - result := e_in.read_data1; - else - result := e_in.read_data2; - 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; - when OP_MFSPR => - if std_match(e_in.insn(20 downto 11), "0100100000") then - result := ctrl.ctr; - result_en := 1; - elsif std_match(e_in.insn(20 downto 11), "0100000000") then - result := ctrl.lr; - result_en := 1; - elsif std_match(e_in.insn(20 downto 11), "0110001000") then - result := ctrl.tb; - result_en := 1; - end if; - when OP_MFCR => - if e_in.insn(20) = '0' then - -- mfcr - result := x"00000000" & e_in.cr; - else - -- mfocrf - crnum := fxm_to_num(insn_fxm(e_in.insn)); - result := (others => '0'); - for i in 0 to 7 loop - lo := (7-i)*4; - hi := lo + 3; - if crnum = i then - result(hi downto lo) := e_in.cr(hi downto lo); - end if; - end loop; - end if; - result_en := 1; - when OP_MTCRF => - v.e.write_cr_enable := '1'; - if e_in.insn(20) = '0' then - -- mtcrf - v.e.write_cr_mask := insn_fxm(e_in.insn); - else - -- mtocrf: We require one hot priority encoding here - crnum := fxm_to_num(insn_fxm(e_in.insn)); - v.e.write_cr_mask := num_to_fxm(crnum); - end if; - v.e.write_cr_data := e_in.read_data3(31 downto 0); - when OP_MTSPR => - if std_match(e_in.insn(20 downto 11), "0100100000") then - ctrl_tmp.ctr <= e_in.read_data3; - elsif std_match(e_in.insn(20 downto 11), "0100000000") then - ctrl_tmp.lr <= e_in.read_data3; - end if; - when OP_POPCNTB => - result := ppc_popcntb(e_in.read_data3); - result_en := 1; - when OP_POPCNTW => - result := ppc_popcntw(e_in.read_data3); - result_en := 1; - when OP_POPCNTD => - result := ppc_popcntd(e_in.read_data3); - result_en := 1; - when OP_PRTYD => - result := ppc_prtyd(e_in.read_data3); - result_en := 1; - when OP_PRTYW => - result := ppc_prtyw(e_in.read_data3); - result_en := 1; - when OP_RLC | OP_RLCL | OP_RLCR | OP_SHL | OP_SHR => - result := rotator_result; - if e_in.output_carry = '1' then - ctrl_tmp.carry <= rotator_carry; - end if; - result_en := 1; - when OP_SIM_CONFIG => - -- bit 0 was used to select the microwatt console, which - -- we no longer support. - if SIM = true then - result := x"0000000000000000"; - else - result := x"0000000000000000"; - end if; - result_en := 1; + when OP_ILLEGAL => + terminate_out <= '1'; + report "illegal"; + when OP_NOP => + -- Do nothing + when OP_ADD => + if e_in.invert_a = '0' then + a_inv := e_in.read_data1; + else + a_inv := not e_in.read_data1; + end if; + result_with_carry := ppc_adde(a_inv, e_in.read_data2, decode_input_carry(e_in.input_carry, ctrl.carry)); + result := result_with_carry(63 downto 0); + if e_in.output_carry then + ctrl_tmp.carry <= result_with_carry(64); + end if; + result_en := 1; + when OP_AND | OP_OR | OP_XOR => + result := logical_result; + result_en := 1; + when OP_B => + f_out.redirect <= '1'; + if (insn_aa(e_in.insn)) then + f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2)); + else + f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); + end if; + when OP_BC => + bo := insn_bo(e_in.insn); + bi := insn_bi(e_in.insn); + if bo(4-2) = '0' then + ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1); + end if; + if ppc_bc_taken(bo, bi, e_in.cr, ctrl.ctr) = 1 then + f_out.redirect <= '1'; + if (insn_aa(e_in.insn)) then + f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2)); + else + f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); + end if; + end if; + when OP_BCREG => + -- bits 10 and 6 distinguish between bclr, bcctr and bctar + bo := insn_bo(e_in.insn); + bi := insn_bi(e_in.insn); + if bo(4-2) = '0' and e_in.insn(10) = '0' then + ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1); + end if; + if ppc_bc_taken(bo, bi, e_in.cr, ctrl.ctr) = 1 then + f_out.redirect <= '1'; + if e_in.insn(10) = '0' then + f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00"; + else + f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00"; + end if; + end if; + when OP_CMPB => + result := ppc_cmpb(e_in.read_data3, e_in.read_data2); + result_en := 1; + when OP_CMP => + bf := insn_bf(e_in.insn); + l := insn_l(e_in.insn); + v.e.write_cr_enable := '1'; + crnum := to_integer(unsigned(bf)); + v.e.write_cr_mask := num_to_fxm(crnum); + for i in 0 to 7 loop + lo := i*4; + hi := lo + 3; + v.e.write_cr_data(hi downto lo) := ppc_cmp(l, e_in.read_data1, e_in.read_data2); + end loop; + when OP_CMPL => + bf := insn_bf(e_in.insn); + l := insn_l(e_in.insn); + v.e.write_cr_enable := '1'; + crnum := to_integer(unsigned(bf)); + v.e.write_cr_mask := num_to_fxm(crnum); + for i in 0 to 7 loop + lo := i*4; + hi := lo + 3; + v.e.write_cr_data(hi downto lo) := ppc_cmpl(l, e_in.read_data1, e_in.read_data2); + end loop; + when OP_CNTZ => + result := countzero_result; + result_en := 1; + when OP_EXTS => + v.e.write_len := e_in.data_len; + v.e.sign_extend := '1'; + result := e_in.read_data3; + result_en := 1; + when OP_ISEL => + crnum := to_integer(unsigned(insn_bc(e_in.insn))); + if e_in.cr(31-crnum) = '1' then + result := e_in.read_data1; + else + result := e_in.read_data2; + 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; + when OP_MFSPR => + if std_match(e_in.insn(20 downto 11), "0100100000") then + result := ctrl.ctr; + result_en := 1; + elsif std_match(e_in.insn(20 downto 11), "0100000000") then + result := ctrl.lr; + result_en := 1; + elsif std_match(e_in.insn(20 downto 11), "0110001000") then + result := ctrl.tb; + result_en := 1; + end if; + when OP_MFCR => + if e_in.insn(20) = '0' then + -- mfcr + result := x"00000000" & e_in.cr; + else + -- mfocrf + crnum := fxm_to_num(insn_fxm(e_in.insn)); + result := (others => '0'); + for i in 0 to 7 loop + lo := (7-i)*4; + hi := lo + 3; + if crnum = i then + result(hi downto lo) := e_in.cr(hi downto lo); + end if; + end loop; + end if; + result_en := 1; + when OP_MTCRF => + v.e.write_cr_enable := '1'; + if e_in.insn(20) = '0' then + -- mtcrf + v.e.write_cr_mask := insn_fxm(e_in.insn); + else + -- mtocrf: We require one hot priority encoding here + crnum := fxm_to_num(insn_fxm(e_in.insn)); + v.e.write_cr_mask := num_to_fxm(crnum); + end if; + v.e.write_cr_data := e_in.read_data3(31 downto 0); + when OP_MTSPR => + if std_match(e_in.insn(20 downto 11), "0100100000") then + ctrl_tmp.ctr <= e_in.read_data3; + elsif std_match(e_in.insn(20 downto 11), "0100000000") then + ctrl_tmp.lr <= e_in.read_data3; + end if; + when OP_POPCNTB => + result := ppc_popcntb(e_in.read_data3); + result_en := 1; + when OP_POPCNTW => + result := ppc_popcntw(e_in.read_data3); + result_en := 1; + when OP_POPCNTD => + result := ppc_popcntd(e_in.read_data3); + result_en := 1; + when OP_PRTYD => + result := ppc_prtyd(e_in.read_data3); + result_en := 1; + when OP_PRTYW => + result := ppc_prtyw(e_in.read_data3); + result_en := 1; + when OP_RLC | OP_RLCL | OP_RLCR | OP_SHL | OP_SHR => + result := rotator_result; + if e_in.output_carry = '1' then + ctrl_tmp.carry <= rotator_carry; + end if; + result_en := 1; + when OP_SIM_CONFIG => + -- bit 0 was used to select the microwatt console, which + -- we no longer support. + if SIM = true then + result := x"0000000000000000"; + else + result := x"0000000000000000"; + end if; + result_en := 1; - when OP_TDI => - -- Keep our test cases happy for now, ignore trap instructions - report "OP_TDI FIXME"; + when OP_TDI => + -- Keep our test cases happy for now, ignore trap instructions + report "OP_TDI FIXME"; - when others => - terminate_out <= '1'; - report "illegal"; - end case; + when others => + terminate_out <= '1'; + report "illegal"; + end case; - if e_in.lr = '1' then - ctrl_tmp.lr <= std_ulogic_vector(unsigned(e_in.nia) + 4); - end if; + if e_in.lr = '1' then + ctrl_tmp.lr <= std_ulogic_vector(unsigned(e_in.nia) + 4); + end if; - if result_en = 1 then - v.e.write_data := result; - v.e.write_enable := '1'; - v.e.rc := e_in.rc; - end if; - end if; + if result_en = 1 then + v.e.write_data := result; + v.e.write_enable := '1'; + v.e.rc := e_in.rc; + end if; + end if; - -- Update registers - rin <= v; + -- Update registers + rin <= v; - -- update outputs - --f_out <= r.f; - e_out <= r.e; - flush_out <= f_out.redirect; - end process; + -- update outputs + --f_out <= r.f; + e_out <= r.e; + flush_out <= f_out.redirect; + end process; end architecture behaviour; From da0bd89c431b4b69ded7fb21dc3fbecf18f5b914 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 16 Oct 2019 12:11:16 +1100 Subject: [PATCH 3/6] crhelpers: Constraint "crnum" integer This seems to save quite a few LUTs Signed-off-by: Benjamin Herrenschmidt --- crhelpers.vhdl | 11 +++++++---- execute1.vhdl | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/crhelpers.vhdl b/crhelpers.vhdl index f51110c..1e6160f 100644 --- a/crhelpers.vhdl +++ b/crhelpers.vhdl @@ -5,13 +5,16 @@ library work; use work.common.all; package crhelpers is - function fxm_to_num(fxm: std_ulogic_vector(7 downto 0)) return integer; - function num_to_fxm(num: integer) return std_ulogic_vector; + subtype crnum_t is integer range 0 to 7; + subtype crmask_t is std_ulogic_vector(7 downto 0); + + function fxm_to_num(fxm: crmask_t) return crnum_t; + function num_to_fxm(num: crnum_t) return crmask_t; end package crhelpers; package body crhelpers is - function fxm_to_num(fxm: std_ulogic_vector(7 downto 0)) return integer is + function fxm_to_num(fxm: crmask_t) return crnum_t is begin -- If multiple fields are set (undefined), match existing -- hardware by returning the first one. @@ -27,7 +30,7 @@ package body crhelpers is return 7; end; - function num_to_fxm(num: integer) return std_ulogic_vector is + function num_to_fxm(num: crnum_t) return crmask_t is begin case num is when 0 => diff --git a/execute1.vhdl b/execute1.vhdl index 002bdac..6d3a936 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -109,8 +109,8 @@ begin variable newcrf : std_ulogic_vector(3 downto 0); variable result_with_carry : std_ulogic_vector(64 downto 0); variable result_en : integer; - variable crnum : integer; - variable scrnum : integer; + variable crnum : crnum_t; + variable scrnum : crnum_t; variable lo, hi : integer; variable sh, mb, me : std_ulogic_vector(5 downto 0); variable sh32, mb32, me32 : std_ulogic_vector(4 downto 0); From bddc9327cc28526b6c10e76f3a3645bbe46cf6fb Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 16 Oct 2019 12:32:45 +1100 Subject: [PATCH 4/6] execute1: Remove mux on "write_data" and "rc" outputs Only "write_enable" needs to change, this shrinks the core a bit more Signed-off-by: Benjamin Herrenschmidt --- execute1.vhdl | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/execute1.vhdl b/execute1.vhdl index 6d3a936..3fd6eba 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -108,7 +108,7 @@ begin variable result : std_ulogic_vector(63 downto 0); variable newcrf : std_ulogic_vector(3 downto 0); variable result_with_carry : std_ulogic_vector(64 downto 0); - variable result_en : integer; + variable result_en : std_ulogic; variable crnum : crnum_t; variable scrnum : crnum_t; variable lo, hi : integer; @@ -120,7 +120,7 @@ begin begin result := (others => '0'); result_with_carry := (others => '0'); - result_en := 0; + result_en := '0'; newcrf := (others => '0'); v := r; @@ -164,10 +164,10 @@ begin if e_in.output_carry then ctrl_tmp.carry <= result_with_carry(64); end if; - result_en := 1; + result_en := '1'; when OP_AND | OP_OR | OP_XOR => result := logical_result; - result_en := 1; + result_en := '1'; when OP_B => f_out.redirect <= '1'; if (insn_aa(e_in.insn)) then @@ -206,7 +206,7 @@ begin end if; when OP_CMPB => result := ppc_cmpb(e_in.read_data3, e_in.read_data2); - result_en := 1; + result_en := '1'; when OP_CMP => bf := insn_bf(e_in.insn); l := insn_l(e_in.insn); @@ -231,12 +231,12 @@ begin end loop; when OP_CNTZ => result := countzero_result; - result_en := 1; + result_en := '1'; when OP_EXTS => v.e.write_len := e_in.data_len; v.e.sign_extend := '1'; result := e_in.read_data3; - result_en := 1; + result_en := '1'; when OP_ISEL => crnum := to_integer(unsigned(insn_bc(e_in.insn))); if e_in.cr(31-crnum) = '1' then @@ -244,7 +244,7 @@ begin else result := e_in.read_data2; end if; - result_en := 1; + result_en := '1'; when OP_MCRF => bf := insn_bf(e_in.insn); bfa := insn_bfa(e_in.insn); @@ -267,13 +267,13 @@ begin when OP_MFSPR => if std_match(e_in.insn(20 downto 11), "0100100000") then result := ctrl.ctr; - result_en := 1; + result_en := '1'; elsif std_match(e_in.insn(20 downto 11), "0100000000") then result := ctrl.lr; - result_en := 1; + result_en := '1'; elsif std_match(e_in.insn(20 downto 11), "0110001000") then result := ctrl.tb; - result_en := 1; + result_en := '1'; end if; when OP_MFCR => if e_in.insn(20) = '0' then @@ -291,7 +291,7 @@ begin end if; end loop; end if; - result_en := 1; + result_en := '1'; when OP_MTCRF => v.e.write_cr_enable := '1'; if e_in.insn(20) = '0' then @@ -311,25 +311,25 @@ begin end if; when OP_POPCNTB => result := ppc_popcntb(e_in.read_data3); - result_en := 1; + result_en := '1'; when OP_POPCNTW => result := ppc_popcntw(e_in.read_data3); - result_en := 1; + result_en := '1'; when OP_POPCNTD => result := ppc_popcntd(e_in.read_data3); - result_en := 1; + result_en := '1'; when OP_PRTYD => result := ppc_prtyd(e_in.read_data3); - result_en := 1; + result_en := '1'; when OP_PRTYW => result := ppc_prtyw(e_in.read_data3); - result_en := 1; + result_en := '1'; when OP_RLC | OP_RLCL | OP_RLCR | OP_SHL | OP_SHR => result := rotator_result; if e_in.output_carry = '1' then ctrl_tmp.carry <= rotator_carry; end if; - result_en := 1; + result_en := '1'; when OP_SIM_CONFIG => -- bit 0 was used to select the microwatt console, which -- we no longer support. @@ -338,7 +338,7 @@ begin else result := x"0000000000000000"; end if; - result_en := 1; + result_en := '1'; when OP_TDI => -- Keep our test cases happy for now, ignore trap instructions @@ -353,13 +353,12 @@ begin ctrl_tmp.lr <= std_ulogic_vector(unsigned(e_in.nia) + 4); end if; - if result_en = 1 then - v.e.write_data := result; - v.e.write_enable := '1'; - v.e.rc := e_in.rc; - end if; end if; + v.e.write_data := result; + v.e.write_enable := result_en; + v.e.rc := e_in.rc; + -- Update registers rin <= v; From 60b05ee1e58f709524f16a19cdd4afd569a9c6dc Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 16 Oct 2019 17:47:08 +1100 Subject: [PATCH 5/6] common: Reformat No code change Signed-off-by: Benjamin Herrenschmidt --- common.vhdl | 412 ++++++++++++++++++++++++++-------------------------- 1 file changed, 206 insertions(+), 206 deletions(-) diff --git a/common.vhdl b/common.vhdl index 93bd598..b353922 100644 --- a/common.vhdl +++ b/common.vhdl @@ -5,212 +5,212 @@ library work; use work.decode_types.all; package common is - type ctrl_t is record - lr: std_ulogic_vector(63 downto 0); - ctr: std_ulogic_vector(63 downto 0); - tb: std_ulogic_vector(63 downto 0); - carry: std_ulogic; - end record; - - type Fetch1ToIcacheType is record - req: std_ulogic; - stop_mark: std_ulogic; - nia: std_ulogic_vector(63 downto 0); - end record; - - type IcacheToFetch2Type is record - valid: std_ulogic; - stop_mark: std_ulogic; - nia: std_ulogic_vector(63 downto 0); - insn: std_ulogic_vector(31 downto 0); - end record; - - type Fetch2ToDecode1Type is record - valid: std_ulogic; - stop_mark : std_ulogic; - nia: std_ulogic_vector(63 downto 0); - insn: std_ulogic_vector(31 downto 0); - end record; - constant Fetch2ToDecode1Init : Fetch2ToDecode1Type := (valid => '0', stop_mark => '0', others => (others => '0')); - - type Decode1ToDecode2Type is record - valid: std_ulogic; - stop_mark : std_ulogic; - nia: std_ulogic_vector(63 downto 0); - insn: std_ulogic_vector(31 downto 0); - decode: decode_rom_t; - end record; - constant Decode1ToDecode2Init : Decode1ToDecode2Type := (valid => '0', stop_mark => '0', decode => decode_rom_init, others => (others => '0')); - - type Decode2ToExecute1Type is record - valid: std_ulogic; - insn_type: insn_type_t; - nia: std_ulogic_vector(63 downto 0); - write_reg: std_ulogic_vector(4 downto 0); - read_reg1: std_ulogic_vector(4 downto 0); - read_reg2: std_ulogic_vector(4 downto 0); - read_data1: std_ulogic_vector(63 downto 0); - read_data2: std_ulogic_vector(63 downto 0); - read_data3: std_ulogic_vector(63 downto 0); - cr: std_ulogic_vector(31 downto 0); - lr: std_ulogic; - rc: std_ulogic; - invert_a: std_ulogic; - invert_out: std_ulogic; - input_carry: carry_in_t; - output_carry: std_ulogic; - input_cr: std_ulogic; - output_cr: std_ulogic; - is_32bit: std_ulogic; - is_signed: std_ulogic; - insn: std_ulogic_vector(31 downto 0); - data_len: std_ulogic_vector(3 downto 0); - end record; - constant Decode2ToExecute1Init : Decode2ToExecute1Type := - (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', invert_a => '0', - invert_out => '0', input_carry => ZERO, output_carry => '0', input_cr => '0', output_cr => '0', - is_32bit => '0', is_signed => '0', others => (others => '0')); - - type Decode2ToMultiplyType is record - valid: std_ulogic; - insn_type: insn_type_t; - write_reg: std_ulogic_vector(4 downto 0); - data1: std_ulogic_vector(64 downto 0); - data2: std_ulogic_vector(64 downto 0); - rc: std_ulogic; - end record; - constant Decode2ToMultiplyInit : Decode2ToMultiplyType := (valid => '0', insn_type => OP_ILLEGAL, rc => '0', others => (others => '0')); - - type Decode2ToDividerType is record - valid: std_ulogic; - write_reg: std_ulogic_vector(4 downto 0); - dividend: std_ulogic_vector(63 downto 0); - divisor: std_ulogic_vector(63 downto 0); - is_signed: std_ulogic; - is_32bit: std_ulogic; - is_extended: std_ulogic; - is_modulus: std_ulogic; - rc: std_ulogic; - end record; - constant Decode2ToDividerInit: Decode2ToDividerType := (valid => '0', is_signed => '0', is_32bit => '0', is_extended => '0', is_modulus => '0', rc => '0', others => (others => '0')); - - type Decode2ToRegisterFileType is record - read1_enable : std_ulogic; - read1_reg : std_ulogic_vector(4 downto 0); - read2_enable : std_ulogic; - read2_reg : std_ulogic_vector(4 downto 0); - read3_enable : std_ulogic; - read3_reg : std_ulogic_vector(4 downto 0); - end record; - - type RegisterFileToDecode2Type is record - read1_data : std_ulogic_vector(63 downto 0); - read2_data : std_ulogic_vector(63 downto 0); - read3_data : std_ulogic_vector(63 downto 0); - end record; - - type Decode2ToCrFileType is record - read : std_ulogic; - end record; - - type CrFileToDecode2Type is record - read_cr_data : std_ulogic_vector(31 downto 0); - end record; - - type Execute1ToFetch1Type is record - redirect: std_ulogic; - redirect_nia: std_ulogic_vector(63 downto 0); - end record; - constant Execute1ToFetch1TypeInit : Execute1ToFetch1Type := (redirect => '0', others => (others => '0')); - - type Decode2ToLoadstore1Type is record - valid : std_ulogic; - load : std_ulogic; -- is this a load or store - addr1 : std_ulogic_vector(63 downto 0); - addr2 : std_ulogic_vector(63 downto 0); - data : std_ulogic_vector(63 downto 0); -- data to write, unused for read - write_reg : std_ulogic_vector(4 downto 0); -- read data goes to this register - length : std_ulogic_vector(3 downto 0); - byte_reverse : std_ulogic; - sign_extend : std_ulogic; -- do we need to sign extend? - update : std_ulogic; -- is this an update instruction? - update_reg : std_ulogic_vector(4 downto 0); -- if so, the register to update - end record; - constant Decode2ToLoadstore1Init : Decode2ToLoadstore1Type := (valid => '0', load => '0', byte_reverse => '0', sign_extend => '0', update => '0', others => (others => '0')); - - type Loadstore1ToLoadstore2Type is record - valid : std_ulogic; - load : std_ulogic; - addr : std_ulogic_vector(63 downto 0); - data : std_ulogic_vector(63 downto 0); - write_reg : std_ulogic_vector(4 downto 0); - length : std_ulogic_vector(3 downto 0); - byte_reverse : std_ulogic; - sign_extend : std_ulogic; - update : std_ulogic; - update_reg : std_ulogic_vector(4 downto 0); - end record; - - type Loadstore2ToWritebackType is record - valid : std_ulogic; - write_enable: std_ulogic; - write_reg : std_ulogic_vector(4 downto 0); - write_data : std_ulogic_vector(63 downto 0); - write_len : std_ulogic_vector(3 downto 0); - write_shift : std_ulogic_vector(2 downto 0); - sign_extend : std_ulogic; - byte_reverse : std_ulogic; - second_word : std_ulogic; - end record; - constant Loadstore2ToWritebackInit : Loadstore2ToWritebackType := (valid => '0', write_enable => '0', sign_extend => '0', byte_reverse => '0', second_word => '0', others => (others => '0')); - - type Execute1ToWritebackType is record - valid: std_ulogic; - rc : std_ulogic; - write_enable : std_ulogic; - write_reg: std_ulogic_vector(4 downto 0); - write_data: std_ulogic_vector(63 downto 0); - write_len : std_ulogic_vector(3 downto 0); - write_cr_enable : std_ulogic; - write_cr_mask : std_ulogic_vector(7 downto 0); - write_cr_data : std_ulogic_vector(31 downto 0); - sign_extend: std_ulogic; - end record; - constant Execute1ToWritebackInit : Execute1ToWritebackType := (valid => '0', rc => '0', write_enable => '0', write_cr_enable => '0', sign_extend => '0', others => (others => '0')); - - type MultiplyToWritebackType is record - valid: std_ulogic; - - write_reg_enable : std_ulogic; - write_reg_nr: std_ulogic_vector(4 downto 0); - write_reg_data: std_ulogic_vector(63 downto 0); - rc: std_ulogic; - end record; - constant MultiplyToWritebackInit : MultiplyToWritebackType := (valid => '0', write_reg_enable => '0', rc => '0', others => (others => '0')); - - type DividerToWritebackType is record - valid: std_ulogic; - - write_reg_enable : std_ulogic; - write_reg_nr: std_ulogic_vector(4 downto 0); - write_reg_data: std_ulogic_vector(63 downto 0); - rc: std_ulogic; - end record; - constant DividerToWritebackInit : DividerToWritebackType := (valid => '0', write_reg_enable => '0', rc => '0', others => (others => '0')); - - type WritebackToRegisterFileType is record - write_reg : std_ulogic_vector(4 downto 0); - write_data : std_ulogic_vector(63 downto 0); - write_enable : std_ulogic; - end record; - constant WritebackToRegisterFileInit : WritebackToRegisterFileType := (write_enable => '0', others => (others => '0')); - - type WritebackToCrFileType is record - write_cr_enable : std_ulogic; - write_cr_mask : std_ulogic_vector(7 downto 0); - write_cr_data : std_ulogic_vector(31 downto 0); - end record; - constant WritebackToCrFileInit : WritebackToCrFileType := (write_cr_enable => '0', others => (others => '0')); + type ctrl_t is record + lr: std_ulogic_vector(63 downto 0); + ctr: std_ulogic_vector(63 downto 0); + tb: std_ulogic_vector(63 downto 0); + carry: std_ulogic; + end record; + + type Fetch1ToIcacheType is record + req: std_ulogic; + stop_mark: std_ulogic; + nia: std_ulogic_vector(63 downto 0); + end record; + + type IcacheToFetch2Type is record + valid: std_ulogic; + stop_mark: std_ulogic; + nia: std_ulogic_vector(63 downto 0); + insn: std_ulogic_vector(31 downto 0); + end record; + + type Fetch2ToDecode1Type is record + valid: std_ulogic; + stop_mark : std_ulogic; + nia: std_ulogic_vector(63 downto 0); + insn: std_ulogic_vector(31 downto 0); + end record; + constant Fetch2ToDecode1Init : Fetch2ToDecode1Type := (valid => '0', stop_mark => '0', others => (others => '0')); + + type Decode1ToDecode2Type is record + valid: std_ulogic; + stop_mark : std_ulogic; + nia: std_ulogic_vector(63 downto 0); + insn: std_ulogic_vector(31 downto 0); + decode: decode_rom_t; + end record; + constant Decode1ToDecode2Init : Decode1ToDecode2Type := (valid => '0', stop_mark => '0', decode => decode_rom_init, others => (others => '0')); + + type Decode2ToExecute1Type is record + valid: std_ulogic; + insn_type: insn_type_t; + nia: std_ulogic_vector(63 downto 0); + write_reg: std_ulogic_vector(4 downto 0); + read_reg1: std_ulogic_vector(4 downto 0); + read_reg2: std_ulogic_vector(4 downto 0); + read_data1: std_ulogic_vector(63 downto 0); + read_data2: std_ulogic_vector(63 downto 0); + read_data3: std_ulogic_vector(63 downto 0); + cr: std_ulogic_vector(31 downto 0); + lr: std_ulogic; + rc: std_ulogic; + invert_a: std_ulogic; + invert_out: std_ulogic; + input_carry: carry_in_t; + output_carry: std_ulogic; + input_cr: std_ulogic; + output_cr: std_ulogic; + is_32bit: std_ulogic; + is_signed: std_ulogic; + insn: std_ulogic_vector(31 downto 0); + data_len: std_ulogic_vector(3 downto 0); + end record; + constant Decode2ToExecute1Init : Decode2ToExecute1Type := + (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', invert_a => '0', + invert_out => '0', input_carry => ZERO, output_carry => '0', input_cr => '0', output_cr => '0', + is_32bit => '0', is_signed => '0', others => (others => '0')); + + type Decode2ToMultiplyType is record + valid: std_ulogic; + insn_type: insn_type_t; + write_reg: std_ulogic_vector(4 downto 0); + data1: std_ulogic_vector(64 downto 0); + data2: std_ulogic_vector(64 downto 0); + rc: std_ulogic; + end record; + constant Decode2ToMultiplyInit : Decode2ToMultiplyType := (valid => '0', insn_type => OP_ILLEGAL, rc => '0', others => (others => '0')); + + type Decode2ToDividerType is record + valid: std_ulogic; + write_reg: std_ulogic_vector(4 downto 0); + dividend: std_ulogic_vector(63 downto 0); + divisor: std_ulogic_vector(63 downto 0); + is_signed: std_ulogic; + is_32bit: std_ulogic; + is_extended: std_ulogic; + is_modulus: std_ulogic; + rc: std_ulogic; + end record; + constant Decode2ToDividerInit: Decode2ToDividerType := (valid => '0', is_signed => '0', is_32bit => '0', is_extended => '0', is_modulus => '0', rc => '0', others => (others => '0')); + + type Decode2ToRegisterFileType is record + read1_enable : std_ulogic; + read1_reg : std_ulogic_vector(4 downto 0); + read2_enable : std_ulogic; + read2_reg : std_ulogic_vector(4 downto 0); + read3_enable : std_ulogic; + read3_reg : std_ulogic_vector(4 downto 0); + end record; + + type RegisterFileToDecode2Type is record + read1_data : std_ulogic_vector(63 downto 0); + read2_data : std_ulogic_vector(63 downto 0); + read3_data : std_ulogic_vector(63 downto 0); + end record; + + type Decode2ToCrFileType is record + read : std_ulogic; + end record; + + type CrFileToDecode2Type is record + read_cr_data : std_ulogic_vector(31 downto 0); + end record; + + type Execute1ToFetch1Type is record + redirect: std_ulogic; + redirect_nia: std_ulogic_vector(63 downto 0); + end record; + constant Execute1ToFetch1TypeInit : Execute1ToFetch1Type := (redirect => '0', others => (others => '0')); + + type Decode2ToLoadstore1Type is record + valid : std_ulogic; + load : std_ulogic; -- is this a load or store + addr1 : std_ulogic_vector(63 downto 0); + addr2 : std_ulogic_vector(63 downto 0); + data : std_ulogic_vector(63 downto 0); -- data to write, unused for read + write_reg : std_ulogic_vector(4 downto 0); -- read data goes to this register + length : std_ulogic_vector(3 downto 0); + byte_reverse : std_ulogic; + sign_extend : std_ulogic; -- do we need to sign extend? + update : std_ulogic; -- is this an update instruction? + update_reg : std_ulogic_vector(4 downto 0); -- if so, the register to update + end record; + constant Decode2ToLoadstore1Init : Decode2ToLoadstore1Type := (valid => '0', load => '0', byte_reverse => '0', sign_extend => '0', update => '0', others => (others => '0')); + + type Loadstore1ToLoadstore2Type is record + valid : std_ulogic; + load : std_ulogic; + addr : std_ulogic_vector(63 downto 0); + data : std_ulogic_vector(63 downto 0); + write_reg : std_ulogic_vector(4 downto 0); + length : std_ulogic_vector(3 downto 0); + byte_reverse : std_ulogic; + sign_extend : std_ulogic; + update : std_ulogic; + update_reg : std_ulogic_vector(4 downto 0); + end record; + + type Loadstore2ToWritebackType is record + valid : std_ulogic; + write_enable: std_ulogic; + write_reg : std_ulogic_vector(4 downto 0); + write_data : std_ulogic_vector(63 downto 0); + write_len : std_ulogic_vector(3 downto 0); + write_shift : std_ulogic_vector(2 downto 0); + sign_extend : std_ulogic; + byte_reverse : std_ulogic; + second_word : std_ulogic; + end record; + constant Loadstore2ToWritebackInit : Loadstore2ToWritebackType := (valid => '0', write_enable => '0', sign_extend => '0', byte_reverse => '0', second_word => '0', others => (others => '0')); + + type Execute1ToWritebackType is record + valid: std_ulogic; + rc : std_ulogic; + write_enable : std_ulogic; + write_reg: std_ulogic_vector(4 downto 0); + write_data: std_ulogic_vector(63 downto 0); + write_len : std_ulogic_vector(3 downto 0); + write_cr_enable : std_ulogic; + write_cr_mask : std_ulogic_vector(7 downto 0); + write_cr_data : std_ulogic_vector(31 downto 0); + sign_extend: std_ulogic; + end record; + constant Execute1ToWritebackInit : Execute1ToWritebackType := (valid => '0', rc => '0', write_enable => '0', write_cr_enable => '0', sign_extend => '0', others => (others => '0')); + + type MultiplyToWritebackType is record + valid: std_ulogic; + + write_reg_enable : std_ulogic; + write_reg_nr: std_ulogic_vector(4 downto 0); + write_reg_data: std_ulogic_vector(63 downto 0); + rc: std_ulogic; + end record; + constant MultiplyToWritebackInit : MultiplyToWritebackType := (valid => '0', write_reg_enable => '0', rc => '0', others => (others => '0')); + + type DividerToWritebackType is record + valid: std_ulogic; + + write_reg_enable : std_ulogic; + write_reg_nr: std_ulogic_vector(4 downto 0); + write_reg_data: std_ulogic_vector(63 downto 0); + rc: std_ulogic; + end record; + constant DividerToWritebackInit : DividerToWritebackType := (valid => '0', write_reg_enable => '0', rc => '0', others => (others => '0')); + + type WritebackToRegisterFileType is record + write_reg : std_ulogic_vector(4 downto 0); + write_data : std_ulogic_vector(63 downto 0); + write_enable : std_ulogic; + end record; + constant WritebackToRegisterFileInit : WritebackToRegisterFileType := (write_enable => '0', others => (others => '0')); + + type WritebackToCrFileType is record + write_cr_enable : std_ulogic; + write_cr_mask : std_ulogic_vector(7 downto 0); + write_cr_data : std_ulogic_vector(31 downto 0); + end record; + constant WritebackToCrFileInit : WritebackToCrFileType := (write_cr_enable => '0', others => (others => '0')); end common; package body common is From e67924f55e3f33ccdcd14d519fd1c949a7b79739 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 17 Oct 2019 17:16:09 +1100 Subject: [PATCH 6/6] isel takes a CR bit, not a CR field Fix a GHDL assert in isel. Signed-off-by: Anton Blanchard --- execute1.vhdl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/execute1.vhdl b/execute1.vhdl index 3fd6eba..de18a37 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -110,6 +110,7 @@ begin variable result_with_carry : std_ulogic_vector(64 downto 0); variable result_en : std_ulogic; variable crnum : crnum_t; + variable crbit : integer range 0 to 31; variable scrnum : crnum_t; variable lo, hi : integer; variable sh, mb, me : std_ulogic_vector(5 downto 0); @@ -238,8 +239,8 @@ begin result := e_in.read_data3; result_en := '1'; when OP_ISEL => - crnum := to_integer(unsigned(insn_bc(e_in.insn))); - if e_in.cr(31-crnum) = '1' then + crbit := to_integer(unsigned(insn_bc(e_in.insn))); + if e_in.cr(31-crbit) = '1' then result := e_in.read_data1; else result := e_in.read_data2;