diff --git a/common.vhdl b/common.vhdl index 3e9da69..44198b0 100644 --- a/common.vhdl +++ b/common.vhdl @@ -1,10 +1,21 @@ library ieee; use ieee.std_logic_1164.all; +use ieee.numeric_std.all; library work; use work.decode_types.all; package common is + + -- SPR numbers + subtype spr_num_t is integer range 0 to 1023; + + function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t; + + constant SPR_LR : spr_num_t := 8; + constant SPR_CTR : spr_num_t := 9; + constant SPR_TB : spr_num_t := 268; + type ctrl_t is record lr: std_ulogic_vector(63 downto 0); ctr: std_ulogic_vector(63 downto 0); @@ -216,4 +227,8 @@ package common is end common; package body common is + function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t is + begin + return to_integer(unsigned(insn(15 downto 11) & insn(20 downto 16))); + end; end common; diff --git a/execute1.vhdl b/execute1.vhdl index 6632783..862c631 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -269,16 +269,17 @@ begin 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 + case decode_spr_num(e_in.insn) is + when SPR_CTR => result := ctrl.ctr; - result_en := '1'; - elsif std_match(e_in.insn(20 downto 11), "0100000000") then + when SPR_LR => result := ctrl.lr; - result_en := '1'; - elsif std_match(e_in.insn(20 downto 11), "0110001000") then + when SPR_TB => result := ctrl.tb; - result_en := '1'; - end if; + when others => + result := (others => '0'); + end case; + result_en := '1'; when OP_MFCR => if e_in.insn(20) = '0' then -- mfcr @@ -308,11 +309,13 @@ begin 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 + case decode_spr_num(e_in.insn) is + when SPR_CTR => ctrl_tmp.ctr <= e_in.read_data3; - elsif std_match(e_in.insn(20 downto 11), "0100000000") then + when SPR_LR => ctrl_tmp.lr <= e_in.read_data3; - end if; + when others => + end case; when OP_POPCNTB => result := ppc_popcntb(e_in.read_data3); result_en := '1';