Rework decode2
authorAnton Blanchard <anton@linux.ibm.com>
Tue, 3 Sep 2019 02:44:03 +0000 (12:44 +1000)
committerAnton Blanchard <anton@ozlabs.org>
Tue, 3 Sep 2019 06:47:54 +0000 (16:47 +1000)
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 <anton@linux.ibm.com>
Makefile
common.vhdl
decode2.vhdl
insn_helpers.vhdl [new file with mode: 0644]
microwatt.core

index 9dce002f1f7039bc66617066c0b840780d803c3c..b4ec01e6cb4d76dcacd156030b0fb1d9548c76e5 100644 (file)
--- 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
index a1f3f7a14199ac9d7b997e204442a742335c06cd..7455bf34ab25e3a16716a9409d8f549bd9152f8f 100644 (file)
@@ -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;
index 1205f762fa67c5a7fed7dd37d67745ffc7d42e4c..bb25230aa6eaf95dc9960a95ad11b1855e9ee4ed 100644 (file)
@@ -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 (file)
index 0000000..09d3b98
--- /dev/null
@@ -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;
index 0285e36f03d28c47bdca4fa4cbdd71bdbcb7a3be..1838667d3dfb93763e28a41c52a544140c8e3b44 100644 (file)
@@ -25,6 +25,7 @@ filesets:
       - multiply.vhdl
       - writeback.vhdl
       - wishbone_arbiter.vhdl
+      - insn_helpers.vhdl
       - core.vhdl
     file_type : vhdlSource-2008