You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
3.3 KiB
VHDL
103 lines
3.3 KiB
VHDL
-- Implements instructions that involve sorting bits,
|
|
-- that is, cfuged, pextd and pdepd.
|
|
--
|
|
-- cfuged: Sort the bits in the mask in RB into 0s at the left, 1s at the right
|
|
-- and move the bits in RS in the same fashion to give the result
|
|
-- pextd: Like cfuged but the only use the bits of RS where the
|
|
-- corresponding bit in RB is 1
|
|
-- pdepd: Inverse of pextd; take the low-order bits of RS and spread them out
|
|
-- to the bit positions which have a 1 in RB
|
|
|
|
-- NB opc is bits 7-6 of the instruction:
|
|
-- 00 = pdepd, 01 = pextd, 10 = cfuged
|
|
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
library work;
|
|
use work.helpers.all;
|
|
|
|
entity bit_sorter is
|
|
port (
|
|
clk : in std_ulogic;
|
|
rst : in std_ulogic;
|
|
rs : in std_ulogic_vector(63 downto 0);
|
|
rb : in std_ulogic_vector(63 downto 0);
|
|
go : in std_ulogic;
|
|
opc : in std_ulogic_vector(1 downto 0);
|
|
done : out std_ulogic;
|
|
result : out std_ulogic_vector(63 downto 0)
|
|
);
|
|
end entity bit_sorter;
|
|
|
|
architecture behaviour of bit_sorter is
|
|
|
|
signal val : std_ulogic_vector(63 downto 0);
|
|
signal st : std_ulogic;
|
|
signal sd : std_ulogic;
|
|
signal opr : std_ulogic_vector(1 downto 0);
|
|
signal bc : unsigned(5 downto 0);
|
|
signal jl : unsigned(5 downto 0);
|
|
signal jr : unsigned(5 downto 0);
|
|
signal sr_ml : std_ulogic_vector(63 downto 0);
|
|
signal sr_mr : std_ulogic_vector(63 downto 0);
|
|
signal sr_vl : std_ulogic_vector(63 downto 0);
|
|
signal sr_vr : std_ulogic_vector(63 downto 0);
|
|
|
|
begin
|
|
bsort_r: process(clk)
|
|
begin
|
|
if rising_edge(clk) then
|
|
sd <= '0';
|
|
if rst = '1' then
|
|
st <= '0';
|
|
opr <= "00";
|
|
val <= (others => '0');
|
|
elsif go = '1' then
|
|
st <= '1';
|
|
sr_ml <= rb;
|
|
sr_mr <= rb;
|
|
sr_vl <= rs;
|
|
sr_vr <= rs;
|
|
opr <= opc;
|
|
val <= (others => '0');
|
|
bc <= to_unsigned(0, 6);
|
|
jl <= to_unsigned(63, 6);
|
|
jr <= to_unsigned(0, 6);
|
|
elsif st = '1' then
|
|
if bc = 6x"3f" then
|
|
st <= '0';
|
|
sd <= '1';
|
|
end if;
|
|
bc <= bc + 1;
|
|
if sr_ml(63) = '0' and opr(1) = '1' then
|
|
-- cfuged
|
|
val(to_integer(jl)) <= sr_vl(63);
|
|
jl <= jl - 1;
|
|
end if;
|
|
if sr_mr(0) = '1' then
|
|
if opr = "00" then
|
|
-- pdepd
|
|
val(to_integer(bc)) <= sr_vr(0);
|
|
else
|
|
-- cfuged or pextd
|
|
val(to_integer(jr)) <= sr_vr(0);
|
|
end if;
|
|
jr <= jr + 1;
|
|
end if;
|
|
sr_vl <= sr_vl(62 downto 0) & '0';
|
|
if opr /= "00" or sr_mr(0) = '1' then
|
|
sr_vr <= '0' & sr_vr(63 downto 1);
|
|
end if;
|
|
sr_ml <= sr_ml(62 downto 0) & '0';
|
|
sr_mr <= '0' & sr_mr(63 downto 1);
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
done <= sd;
|
|
result <= val;
|
|
|
|
end behaviour;
|