-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathbitsort.vhdl
147 lines (135 loc) · 4.89 KB
/
bitsort.vhdl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
-- Implements instructions that involve sorting bits,
-- that is, cfuged, pextd and pdepd.
-- Also does bperm, which is somewhat different.
--
-- 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
-- bperm: Select 8 arbitrary bits
-- 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;
do_bperm : in std_ulogic;
bperm_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);
signal is_bperm : std_ulogic;
signal bpc : unsigned(2 downto 0);
signal bp_done : std_ulogic;
signal bperm_res : std_ulogic_vector(7 downto 0);
signal rs_sr : std_ulogic_vector(63 downto 0);
signal rb_bp : 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;
-- bit permutation
bperm_res(7) <= rb_bp(to_integer(unsigned(not rs_sr(5 downto 0)))) when not is_X(rs_sr)
else 'X';
bperm_r: process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
is_bperm <= '0';
bp_done <= '0';
bperm_res(6 downto 0) <= (others => '0');
bpc <= to_unsigned(0, 3);
elsif do_bperm = '1' then
is_bperm <= '1';
bp_done <= '0';
bperm_res(6 downto 0) <= (others => '0');
bpc <= to_unsigned(0, 3);
rs_sr <= rs;
rb_bp <= rb;
elsif bp_done = '1' then
is_bperm <= '0';
bp_done <= '0';
elsif is_bperm = '1' then
bperm_res(6 downto 0) <= bperm_res(7 downto 1);
rs_sr <= x"00" & rs_sr(63 downto 8);
if bpc = "110" then
bp_done <= '1';
end if;
bpc <= bpc + 1;
end if;
end if;
end process;
done <= sd;
bperm_done <= bp_done;
result <= val when is_bperm = '0' else (56x"0" & bperm_res);
end behaviour;