From 5e140298a57812ac58fe01b020da828d4bd6ce07 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 3 Sep 2019 12:44:03 +1000 Subject: [PATCH] Rework decode2 The decode2 stage was spaghetti code and needed cleaning up. Create a series of functions to pull fields from a ppc instruction and also a series of helpers to extract values for the execution units. As suggested by Paul, we should pass all signals to the execution units and only set the valid signal conditionally, which should use less resources. Signed-off-by: Anton Blanchard --- Makefile | 5 +- common.vhdl | 6 +- decode2.vhdl | 385 ++++++++++++++++++++++------------------------ insn_helpers.vhdl | 163 ++++++++++++++++++++ microwatt.core | 1 + 5 files changed, 349 insertions(+), 211 deletions(-) create mode 100644 insn_helpers.vhdl diff --git a/Makefile b/Makefile index 9dce002..b4ec01e 100644 --- a/Makefile +++ b/Makefile @@ -17,19 +17,18 @@ core.o: common.o wishbone_types.o fetch1.o fetch2.o decode1.o decode2.o register cr_file.o: common.o crhelpers.o: common.o decode1.o: common.o decode_types.o -decode2.o: decode_types.o common.o helpers.o +decode2.o: decode_types.o common.o helpers.o insn_helpers.o decode_types.o: execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o sim_console.o execute2.o: common.o crhelpers.o ppc_fx_insns.o fetch1.o: common.o fetch2.o: common.o wishbone_types.o -fetch_tb.o: common.o wishbone_types.o fetch.o glibc_random_helpers.o: glibc_random.o: glibc_random_helpers.o helpers.o: +insn_helpers.o: loadstore1.o: common.o loadstore2.o: common.o helpers.o wishbone_types.o -loadstore_tb.o: common.o simple_ram_types.o simple_ram.o loadstore1.o loadstore2.o multiply_tb.o: common.o glibc_random.o ppc_fx_insns.o multiply.o multiply.o: common.o decode_types.o ppc_fx_insns.o crhelpers.o ppc_fx_insns.o: helpers.o diff --git a/common.vhdl b/common.vhdl index a1f3f7a..7455bf3 100644 --- a/common.vhdl +++ b/common.vhdl @@ -41,9 +41,9 @@ package common is read_reg2: std_ulogic_vector(4 downto 0); read_data1: std_ulogic_vector(63 downto 0); read_data2: std_ulogic_vector(63 downto 0); - const1: std_ulogic_vector(23 downto 0); - const2: std_ulogic_vector(6 downto 0); - const3: std_ulogic_vector(6 downto 0); + const1: std_ulogic_vector(7 downto 0); + const2: std_ulogic_vector(5 downto 0); + const3: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); lr: std_ulogic; rc: std_ulogic; diff --git a/decode2.vhdl b/decode2.vhdl index 1205f76..bb25230 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -6,6 +6,7 @@ library work; use work.decode_types.all; use work.common.all; use work.helpers.all; +use work.insn_helpers.all; entity decode2 is port ( @@ -28,38 +29,141 @@ end entity decode2; architecture behaviour of decode2 is signal d : Decode1ToDecode2Type; - alias insn_rs : std_ulogic_vector(4 downto 0) is d.insn(25 downto 21); - alias insn_rt : std_ulogic_vector(4 downto 0) is d.insn(25 downto 21); - alias insn_ra : std_ulogic_vector(4 downto 0) is d.insn(20 downto 16); - alias insn_rb : std_ulogic_vector(4 downto 0) is d.insn(15 downto 11); - alias insn_si : std_ulogic_vector(15 downto 0) is d.insn(15 downto 0); - alias insn_ui : std_ulogic_vector(15 downto 0) is d.insn(15 downto 0); - alias insn_l : std_ulogic is d.insn(21); - alias insn_sh32 : std_ulogic_vector(4 downto 0) is d.insn(15 downto 11); - alias insn_mb32 : std_ulogic_vector(4 downto 0) is d.insn(10 downto 6); - alias insn_me32 : std_ulogic_vector(4 downto 0) is d.insn(5 downto 1); - alias insn_li : std_ulogic_vector(23 downto 0) is d.insn(25 downto 2); - alias insn_lk : std_ulogic is d.insn(0); - alias insn_rc : std_ulogic is d.insn(0); - alias insn_bd : std_ulogic_vector(13 downto 0) is d.insn(15 downto 2); - alias insn_bf : std_ulogic_vector(2 downto 0) is d.insn(25 downto 23); - alias insn_fxm : std_ulogic_vector(7 downto 0) is d.insn(19 downto 12); - alias insn_bo : std_ulogic_vector(4 downto 0) is d.insn(25 downto 21); - alias insn_bi : std_ulogic_vector(4 downto 0) is d.insn(20 downto 16); - alias insn_bh : std_ulogic_vector(1 downto 0) is d.insn(12 downto 11); - alias insn_d : std_ulogic_vector(15 downto 0) is d.insn(15 downto 0); - alias insn_ds : std_ulogic_vector(13 downto 0) is d.insn(15 downto 2); - alias insn_to : std_ulogic_vector(4 downto 0) is d.insn(25 downto 21); - alias insn_bc : std_ulogic_vector(4 downto 0) is d.insn(10 downto 6); - - -- can't use an alias for these - signal insn_sh : std_ulogic_vector(5 downto 0); - signal insn_me : std_ulogic_vector(5 downto 0); - signal insn_mb : std_ulogic_vector(5 downto 0); + type decode_input_reg_t is record + reg_valid : std_ulogic; + reg : std_ulogic_vector(4 downto 0); + data : std_ulogic_vector(63 downto 0); + end record; + + function decode_input_reg_a (t : input_reg_a_t; insn_in : std_ulogic_vector(31 downto 0); + reg_data : std_ulogic_vector(63 downto 0)) return decode_input_reg_t is + begin + case t is + when RA => + return ('1', insn_ra(insn_in), reg_data); + when RA_OR_ZERO => + return ('1', insn_ra(insn_in), ra_or_zero(reg_data, insn_ra(insn_in))); + when RS => + return ('1', insn_rs(insn_in), reg_data); + when NONE => + return ('0', (others => '0'), (others => '0')); + end case; + end; + + function decode_input_reg_b (t : input_reg_b_t; insn_in : std_ulogic_vector(31 downto 0); + reg_data : std_ulogic_vector(63 downto 0)) return decode_input_reg_t is + begin + case t is + when RB => + return ('1', insn_rb(insn_in), reg_data); + when RS => + return ('1', insn_rs(insn_in), reg_data); + when CONST_UI => + return ('0', (others => '0'), std_ulogic_vector(resize(unsigned(insn_ui(insn_in)), 64))); + when CONST_SI => + return ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_si(insn_in)), 64))); + when CONST_SI_HI => + return ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_si(insn_in)) & x"0000", 64))); + when CONST_UI_HI => + return ('0', (others => '0'), std_ulogic_vector(resize(unsigned(insn_si(insn_in)) & x"0000", 64))); + when CONST_LI => + return ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_li(insn_in)) & "00", 64))); + when CONST_BD => + return ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_bd(insn_in)) & "00", 64))); + when CONST_DS => + return ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_ds(insn_in)) & "00", 64))); + when NONE => + return ('0', (others => '0'), (others => '0')); + end case; + end; + + function decode_input_reg_c (t : input_reg_c_t; insn_in : std_ulogic_vector(31 downto 0); + reg_data : std_ulogic_vector(63 downto 0)) return decode_input_reg_t is + begin + case t is + when RS => + return ('1', insn_rs(insn_in), reg_data); + when NONE => + return ('0', (others => '0'), (others => '0')); + end case; + end; + + function decode_output_reg (t : output_reg_a_t; insn_in : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is + begin + case t is + when RT => + return insn_rt(insn_in); + when RA => + return insn_ra(insn_in); + when NONE => + return "00000"; + end case; + end; + + function decode_const_a (t : constant_a_t; insn_in : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is + begin + case t is + when SH => + return "00" & insn_sh(insn_in); + when SH32 => + return "000" & insn_sh32(insn_in); + when FXM => + return insn_fxm(insn_in); + when BO => + return "000" & insn_bo(insn_in); + when BF => + return "00000" & insn_bf(insn_in); + when TOO => + return "000" & insn_to(insn_in); + when BC => + return "000" & insn_bc(insn_in); + when NONE => + return "00000000"; + end case; + end; + + function decode_const_b (t : constant_b_t; insn_in : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is + begin + case t is + when MB => + return insn_mb(insn_in); + when ME => + return insn_me(insn_in); + when MB32 => + return "0" & insn_mb32(insn_in); + when BI => + return "0" & insn_bi(insn_in); + when L => + return "00000" & insn_l(insn_in); + when NONE => + return "000000"; + end case; + end; + + function decode_const_c (t : constant_c_t; insn_in : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is + begin + case t is + when ME32 => + return insn_me32(insn_in); + when BH => + return "000" & insn_bh(insn_in); + when NONE => + return "00000"; + end case; + end; + + function decode_rc (t : rc_t; insn_in : std_ulogic_vector(31 downto 0)) return std_ulogic is + begin + case t is + when RC => + return insn_rc(insn_in); + when ONE => + return '1'; + when NONE => + return '0'; + end case; + end; begin - insn_sh <= d.insn(1) & d.insn(15 downto 11); - insn_me <= d.insn(5) & d.insn(10 downto 6); - insn_mb <= d.insn(5) & d.insn(10 downto 6); decode2_0: process(clk) begin @@ -68,21 +172,24 @@ begin end if; end process; - r_out.read1_reg <= insn_ra when (d.decode.input_reg_a = RA) else - insn_ra when d.decode.input_reg_a = RA_OR_ZERO else - insn_rs when d.decode.input_reg_a = RS else + r_out.read1_reg <= insn_ra(d.insn) when (d.decode.input_reg_a = RA) else + insn_ra(d.insn) when d.decode.input_reg_a = RA_OR_ZERO else + insn_rs(d.insn) when d.decode.input_reg_a = RS else (others => '0'); - r_out.read2_reg <= insn_rb when d.decode.input_reg_b = RB else - insn_rs when d.decode.input_reg_b = RS else + r_out.read2_reg <= insn_rb(d.insn) when d.decode.input_reg_b = RB else + insn_rs(d.insn) when d.decode.input_reg_b = RS else (others => '0'); - r_out.read3_reg <= insn_rs when d.decode.input_reg_c = RS else + r_out.read3_reg <= insn_rs(d.insn) when d.decode.input_reg_c = RS else (others => '0'); decode2_1: process(all) variable mul_a : std_ulogic_vector(63 downto 0); variable mul_b : std_ulogic_vector(63 downto 0); + variable decoded_reg_a : decode_input_reg_t; + variable decoded_reg_b : decode_input_reg_t; + variable decoded_reg_c : decode_input_reg_t; begin e_out <= Decode2ToExecute1Init; l_out <= Decode2ToLoadStore1Init; @@ -91,122 +198,52 @@ begin mul_a := (others => '0'); mul_b := (others => '0'); - e_out.nia <= d.nia; - l_out.nia <= d.nia; - m_out.nia <= d.nia; - --e_out.input_cr <= d.decode.input_cr; --m_out.input_cr <= d.decode.input_cr; --e_out.output_cr <= d.decode.output_cr; - e_out.cr <= c_in.read_cr_data; - - e_out.input_carry <= d.decode.input_carry; - e_out.output_carry <= d.decode.output_carry; - - if d.decode.lr then - e_out.lr <= insn_lk; - end if; - - -- XXX This is getting too complicated. Use variables and assign to each unit later + decoded_reg_a := decode_input_reg_a (d.decode.input_reg_a, d.insn, r_in.read1_data); + decoded_reg_b := decode_input_reg_b (d.decode.input_reg_b, d.insn, r_in.read2_data); + decoded_reg_c := decode_input_reg_c (d.decode.input_reg_c, d.insn, r_in.read3_data); case d.decode.unit is when ALU => - e_out.insn_type <= d.decode.insn_type; e_out.valid <= d.valid; when LDST => l_out.valid <= d.valid; when MUL => - m_out.insn_type <= d.decode.insn_type; m_out.valid <= d.valid; when NONE => - e_out.insn_type <= OP_ILLEGAL; e_out.valid <= d.valid; + e_out.insn_type <= OP_ILLEGAL; end case; - -- required for bypassing - case d.decode.input_reg_a is - when RA => - e_out.read_reg1 <= insn_ra; - l_out.update_reg <= insn_ra; - when RA_OR_ZERO => - e_out.read_reg1 <= insn_ra; - l_out.update_reg <= insn_ra; - when RS => - e_out.read_reg1 <= insn_rs; - when NONE => - e_out.read_reg1 <= (others => '0'); - l_out.update_reg <= (others => '0'); - end case; - - -- required for bypassing - case d.decode.input_reg_b is - when RB => - e_out.read_reg2 <= insn_rb; - when RS => - e_out.read_reg2 <= insn_rs; - when others => - e_out.read_reg2 <= (others => '0'); - end case; - - -- required for bypassing - --case d.decode.input_reg_c is - --when RS => - --e_out.read_reg3 <= insn_rs; - --when NONE => - --e_out.read_reg3 <= (others => '0'); - --end case; - - case d.decode.input_reg_a is - when RA => - e_out.read_data1 <= r_in.read1_data; - mul_a := r_in.read1_data; - l_out.addr1 <= r_in.read1_data; - when RA_OR_ZERO => - e_out.read_data1 <= ra_or_zero(r_in.read1_data, insn_ra); - l_out.addr1 <= ra_or_zero(r_in.read1_data, insn_ra); - when RS => - e_out.read_data1 <= r_in.read1_data; - when NONE => - e_out.read_data1 <= (others => '0'); - mul_a := (others => '0'); - end case; - - case d.decode.input_reg_b is - when RB => - e_out.read_data2 <= r_in.read2_data; - mul_b := r_in.read2_data; - l_out.addr2 <= r_in.read2_data; - when RS => - e_out.read_data2 <= r_in.read2_data; - when CONST_UI => - e_out.read_data2 <= std_ulogic_vector(resize(unsigned(insn_ui), 64)); - when CONST_SI => - e_out.read_data2 <= std_ulogic_vector(resize(signed(insn_si), 64)); - l_out.addr2 <= std_ulogic_vector(resize(signed(insn_si), 64)); - mul_b := std_ulogic_vector(resize(signed(insn_si), 64)); - when CONST_SI_HI => - e_out.read_data2 <= std_ulogic_vector(resize(signed(insn_si) & x"0000", 64)); - when CONST_UI_HI => - e_out.read_data2 <= std_ulogic_vector(resize(unsigned(insn_si) & x"0000", 64)); - when CONST_LI => - e_out.read_data2 <= std_ulogic_vector(resize(signed(insn_li) & "00", 64)); - when CONST_BD => - e_out.read_data2 <= std_ulogic_vector(resize(signed(insn_bd) & "00", 64)); - when CONST_DS => - l_out.addr2 <= std_ulogic_vector(resize(signed(insn_ds) & "00", 64)); - when NONE => - e_out.read_data2 <= (others => '0'); - l_out.addr2 <= (others => '0'); - mul_b := (others => '0'); - end case; + -- execute unit + e_out.nia <= d.nia; + e_out.insn_type <= d.decode.insn_type; + e_out.read_reg1 <= decoded_reg_a.reg; + e_out.read_data1 <= decoded_reg_a.data; + e_out.read_reg2 <= decoded_reg_b.reg; + e_out.read_data2 <= decoded_reg_b.data; + e_out.write_reg <= decode_output_reg(d.decode.output_reg_a, d.insn); + e_out.rc <= decode_rc(d.decode.rc, d.insn); + e_out.cr <= c_in.read_cr_data; + e_out.input_carry <= d.decode.input_carry; + e_out.output_carry <= d.decode.output_carry; + if d.decode.lr then + e_out.lr <= insn_lk(d.insn); + end if; + e_out.const1 <= decode_const_a(d.decode.const_a, d.insn); + e_out.const2 <= decode_const_b(d.decode.const_b, d.insn); + e_out.const3 <= decode_const_c(d.decode.const_c, d.insn); - case d.decode.input_reg_c is - when RS => - l_out.data <= r_in.read3_data; - when NONE => - l_out.data <= (others => '0'); - end case; + -- multiply unit + m_out.nia <= d.nia; + m_out.insn_type <= d.decode.insn_type; + mul_a := decoded_reg_a.data; + mul_b := decoded_reg_b.data; + m_out.write_reg <= decode_output_reg(d.decode.output_reg_a, d.insn); + m_out.rc <= decode_rc(d.decode.rc, d.insn); if d.decode.mul_32bit = '1' then if d.decode.mul_signed = '1' then @@ -228,76 +265,14 @@ begin end if; end if; - case d.decode.const_a is - when SH => - e_out.const1(insn_sh'range) <= insn_sh; - when SH32 => - e_out.const1(insn_sh32'range) <= insn_sh32; - when FXM => - e_out.const1(insn_fxm'range) <= insn_fxm; - when BO => - e_out.const1(insn_bo'range)<= insn_bo; - when BF => - e_out.const1(insn_bf'range)<= insn_bf; - when TOO => - e_out.const1(insn_to'range)<= insn_to; - when BC => - e_out.const1(insn_bc'range)<= insn_bc; - when NONE => - e_out.const1 <= (others => '0'); - end case; - - case d.decode.const_b is - when MB => - e_out.const2(insn_mb'range) <= insn_mb; - when ME => - e_out.const2(insn_me'range) <= insn_me; - when MB32 => - e_out.const2(insn_mb32'range) <= insn_mb32; - when BI => - e_out.const2(insn_bi'range) <= insn_bi; - when L => - e_out.const2(0) <= insn_l; - when NONE => - e_out.const2 <= (others => '0'); - end case; - - case d.decode.const_c is - when ME32 => - e_out.const3(insn_me32'range) <= insn_me32; - when BH => - e_out.const3(insn_bh'range) <= insn_bh; - when NONE => - e_out.const3 <= (others => '0'); - end case; - - case d.decode.output_reg_a is - when RT => - e_out.write_reg <= insn_rt; - l_out.write_reg <= insn_rt; - m_out.write_reg <= insn_rt; - when RA => - e_out.write_reg <= insn_ra; - l_out.write_reg <= insn_ra; - when NONE => - e_out.write_reg <= (others => '0'); - l_out.write_reg <= (others => '0'); - m_out.write_reg <= (others => '0'); - end case; - - case d.decode.rc is - when RC => - e_out.rc <= insn_rc; - m_out.rc <= insn_rc; - when ONE => - e_out.rc <= '1'; - m_out.rc <= '1'; - when NONE => - e_out.rc <= '0'; - m_out.rc <= '0'; - end case; + -- load/store unit + l_out.nia <= d.nia; + l_out.update_reg <= decoded_reg_a.reg; + l_out.addr1 <= decoded_reg_a.data; + l_out.addr2 <= decoded_reg_b.data; + l_out.data <= decoded_reg_c.data; + l_out.write_reg <= decode_output_reg(d.decode.output_reg_a, d.insn); - -- load/store specific signals if d.decode.insn_type = OP_LOAD then l_out.load <= '1'; else diff --git a/insn_helpers.vhdl b/insn_helpers.vhdl new file mode 100644 index 0000000..09d3b98 --- /dev/null +++ b/insn_helpers.vhdl @@ -0,0 +1,163 @@ +library ieee; +use ieee.std_logic_1164.all; + +package insn_helpers is + function insn_rs (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_rt (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_ra (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_rb (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_si (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_ui (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_l (insn_in : std_ulogic_vector) return std_ulogic; + function insn_sh32 (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_mb32 (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_me32 (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_li (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_lk (insn_in : std_ulogic_vector) return std_ulogic; + function insn_rc (insn_in : std_ulogic_vector) return std_ulogic; + 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_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; + function insn_bh (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_d (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_ds (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_to (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_bc (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_sh (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_me (insn_in : std_ulogic_vector) return std_ulogic_vector; + function insn_mb (insn_in : std_ulogic_vector) return std_ulogic_vector; +end package insn_helpers; + +package body insn_helpers is + function insn_rs (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(25 downto 21); + end; + + function insn_rt (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(25 downto 21); + end; + + function insn_ra (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(20 downto 16); + end; + + function insn_rb (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(15 downto 11); + end; + + function insn_si (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(15 downto 0); + end; + + function insn_ui (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(15 downto 0); + end; + + function insn_l (insn_in : std_ulogic_vector) return std_ulogic is + begin + return insn_in(21); + end; + + function insn_sh32 (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(15 downto 11); + end; + + function insn_mb32 (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(10 downto 6); + end; + + function insn_me32 (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(5 downto 1); + end; + + function insn_li (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(25 downto 2); + end; + + function insn_lk (insn_in : std_ulogic_vector) return std_ulogic is + begin + return insn_in(0); + end; + + function insn_rc (insn_in : std_ulogic_vector) return std_ulogic is + begin + return insn_in(0); + end; + + function insn_bd (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(15 downto 2); + end; + + function insn_bf (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(25 downto 23); + end; + + function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(19 downto 12); + end; + + function insn_bo (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(25 downto 21); + end; + + function insn_bi (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(20 downto 16); + end; + + function insn_bh (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(12 downto 11); + end; + + function insn_d (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(15 downto 0); + end; + + function insn_ds (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(15 downto 2); + end; + + function insn_to (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(25 downto 21); + end; + + function insn_bc (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(10 downto 6); + end; + + function insn_sh (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(1) & insn_in(15 downto 11); + end; + + function insn_me (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(5) & insn_in(10 downto 6); + end; + + function insn_mb (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(5) & insn_in(10 downto 6); + end; +end package body insn_helpers; diff --git a/microwatt.core b/microwatt.core index 0285e36..1838667 100644 --- a/microwatt.core +++ b/microwatt.core @@ -25,6 +25,7 @@ filesets: - multiply.vhdl - writeback.vhdl - wishbone_arbiter.vhdl + - insn_helpers.vhdl - core.vhdl file_type : vhdlSource-2008 -- 2.30.2