diff --git a/lib/CPUs/MIPS/src/core/mips_shifter.vhd b/lib/CPUs/MIPS/src/core/mips_shifter.vhd index cff2c7d..34036a2 100644 --- a/lib/CPUs/MIPS/src/core/mips_shifter.vhd +++ b/lib/CPUs/MIPS/src/core/mips_shifter.vhd @@ -49,7 +49,21 @@ architecture Behavioral of shifter is signal sa_rnd : unsigned (4 downto 0); signal fill : std_logic; + type fill_mask_rom_t is array (0 to 2*data_width-1) of unsigned(data_width-1 downto 0); -------------------------------------------------------------------------- +function gen_fill_mask_rom(data_width : natural) return fill_mask_rom_t is + variable result : fill_mask_rom_t; + begin + for i in 0 to data_width-1 loop + result(i) := (data_width-1-i downto 0 => '0') & (i-1 downto 0 => '1'); + end loop; + for i in 0 to data_width-1 loop + result(data_width+i) := (i-1 downto 0 => '1') & (data_width-1-i downto 0 => '0'); + end loop; + return result; + +end gen_fill_mask_rom; + function rot_stage(x : unsigned; en : std_logic; stage_num : natural) return unsigned is variable result : unsigned(x'range); constant sa : natural := 2**stage_num; @@ -63,52 +77,39 @@ function rot_stage(x : unsigned; en : std_logic; stage_num : natural) return uns end rot_stage; -function rot_fill(x : unsigned; fill : std_logic; shift_right : std_logic; sa : natural) return unsigned is - variable result : unsigned(x'range) := (others => '0'); - variable j : integer; - begin - - if shift_right = '0' then - for i in 0 to x'left loop - if i >= sa then - result(i) := x(i); - else - result(i) := fill; - end if; - end loop; - else - j := x'left; - for i in 0 to x'left loop - if i < sa then - result(j) := fill; - else - result(j) := x(j); - end if; - j := j - 1; - end loop; - end if; - return result; + constant fill_mask_rom : fill_mask_rom_t := gen_fill_mask_rom(data_width); + signal fill_mask : unsigned(data_width-1 downto 0); + signal fill_mask_addr : unsigned(5 downto 0); + signal dout_filled : unsigned (data_width-1 downto 0); -end rot_fill; - -------------------------------------------------------------------------- begin - rot_data(0) <= din; - + rot_data(0) <= din; + gen_rotate_right: for stage in 0 to 4 generate begin rot_data(stage+1) <= rot_stage(rot_data(stage), sa_rnd(stage), stage); end generate; - sa_rnd <= shift_ctrl.shamt_rnd; - fill <= shift_ctrl.shift_arith and din(data_width-1); - dout <= rot_fill(rot_data(5), fill, shift_ctrl.shift_right, to_integer(shift_ctrl.shamt_nrm)) after 5 ns; --- dout <= rot_data(5); - - + sa_rnd <= shift_ctrl.shamt_rnd; + fill <= shift_ctrl.shift_arith and din(data_width-1); + fill_mask_addr <= shift_ctrl.shift_right & shift_ctrl.shamt_nrm; + fill_mask <= fill_mask_rom(to_integer(fill_mask_addr)); +proc_fill_neu: + process(fill_mask, fill, rot_data(5)) + begin + if fill = '1' then + dout_filled <= rot_data(5) or fill_mask; + else + dout_filled <= rot_data(5) and not fill_mask; + end if; + end process; + + dout <= dout_filled after 5 ns; + -------------------------------------------------------------------------- end Behavioral;