1 |
2 |
djah |
library ieee;
|
2 |
|
|
use ieee.std_logic_1164.all;
|
3 |
|
|
use ieee.numeric_std.all;
|
4 |
|
|
|
5 |
|
|
|
6 |
|
|
entity square_root is
|
7 |
|
|
generic(
|
8 |
|
|
WIDTH : positive := 32
|
9 |
|
|
);
|
10 |
|
|
port(
|
11 |
|
|
clk : in std_logic;
|
12 |
|
|
res : in std_logic;
|
13 |
|
|
ARG : in unsigned (WIDTH - 1 downto 0);
|
14 |
|
|
Z : out unsigned (WIDTH - 1 downto 0)
|
15 |
|
|
);
|
16 |
|
|
end entity square_root;
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
architecture rtl of square_root is
|
20 |
|
|
|
21 |
|
|
constant SQRT_LUT_K : positive := 8;
|
22 |
|
|
constant SQRT_LUT_N : positive := 128; --2^(K-1)
|
23 |
|
|
constant SQRT_ITER : positive := 3;
|
24 |
|
|
|
25 |
|
|
type sqrt_table is array (natural range <>) of unsigned (WIDTH-1 downto 0);
|
26 |
|
|
type pipe is array (natural range <>) of unsigned (WIDTH - 1 downto 0);
|
27 |
|
|
|
28 |
|
|
constant SQRT_TABLE_1 : sqrt_table(0 to SQRT_LUT_N -1) := (
|
29 |
|
|
x"B504F334", x"B44F9363", x"B39C5088", x"B2EB2034",
|
30 |
|
|
x"B23BF845", x"B18ECED9", x"B0E39A54", x"B03A5158",
|
31 |
|
|
x"AF92EAC8", x"AEED5DC0", x"AE49A198", x"ADA7ADE2",
|
32 |
|
|
x"AD077A62", x"AC68FF15", x"ABCC3428", x"AB3111FD",
|
33 |
|
|
x"AA979122", x"A9FFAA55", x"A9695681", x"A8D48EBE",
|
34 |
|
|
x"A8414C4B", x"A7AF8892", x"A71F3D24", x"A69063BA",
|
35 |
|
|
x"A602F631", x"A576EE88", x"A4EC46E7", x"A462F992",
|
36 |
|
|
x"A3DB00F1", x"A354578E", x"A2CEF80E", x"A24ADD38",
|
37 |
|
|
x"A1C801EF", x"A1466132", x"A0C5F61D", x"A046BBE7",
|
38 |
|
|
x"9FC8ADE0", x"9F4BC775", x"9ED00428", x"9E555F96",
|
39 |
|
|
x"9DDBD571", x"9D636184", x"9CEBFFB1", x"9C75ABED",
|
40 |
|
|
x"9C006245", x"9B8C1ED8", x"9B18DDDC", x"9AA69B99",
|
41 |
|
|
x"9A355468", x"99C504B9", x"9955A90B", x"98E73DF0",
|
42 |
|
|
x"9879C009", x"980D2C0B", x"97A17EB9", x"9736B4E7",
|
43 |
|
|
x"96CCCB78", x"9663BF5F", x"95FB8D9D", x"95943342",
|
44 |
|
|
x"952DAD6B", x"94C7F945", x"94631407", x"93FEFAF9",
|
45 |
|
|
x"939BAB6C", x"933922C1", x"92D75E64", x"92765BCB",
|
46 |
|
|
x"9216187A", x"91B69200", x"9157C5F6", x"90F9B200",
|
47 |
|
|
x"909C53CF", x"903FA91C", x"8FE3AFAB", x"8F886548",
|
48 |
|
|
x"8F2DC7CC", x"8ED3D518", x"8E7A8B16", x"8E21E7B8",
|
49 |
|
|
x"8DC9E8FC", x"8D728CE5", x"8D1BD182", x"8CC5B4E8",
|
50 |
|
|
x"8C703534", x"8C1B508D", x"8BC70521", x"8B735123",
|
51 |
|
|
x"8B2032D2", x"8ACDA871", x"8A7BB04A", x"8A2A48B2",
|
52 |
|
|
x"89D97000", x"89892494", x"893964D5", x"88EA2F2F",
|
53 |
|
|
x"889B8216", x"884D5C04", x"87FFBB77", x"87B29EF6",
|
54 |
|
|
x"8766050B", x"8719EC47", x"86CE5342", x"86833897",
|
55 |
|
|
x"86389AE8", x"85EE78DC", x"85A4D11E", x"855BA261",
|
56 |
|
|
x"8512EB59", x"84CAAAC3", x"8482DF5D", x"843B87ED",
|
57 |
|
|
x"83F4A33B", x"83AE3016", x"83682D4F", x"832299BD",
|
58 |
|
|
x"82DD743A", x"8298BBA6", x"82546EE5", x"82108CDC",
|
59 |
|
|
x"81CD1478", x"818A04A6", x"81475C5C", x"81051A8E",
|
60 |
|
|
x"80C33E38", x"8081C657", x"8040B1ED", x"80000000"
|
61 |
|
|
);
|
62 |
|
|
|
63 |
|
|
|
64 |
|
|
constant SQRT_TABLE_2 : sqrt_table(0 to SQRT_LUT_N -1) := (
|
65 |
|
|
x"FFFFFFFF", x"FE000000", x"FC07F020", x"FA17A17A",
|
66 |
|
|
x"F82EE698", x"F64D9365", x"F4737D1D", x"F2A07A45",
|
67 |
|
|
x"F0D4629B", x"EF0F0F0F", x"ED5059B2", x"EB981DAE",
|
68 |
|
|
x"E9E63740", x"E83A83A8", x"E694E122", x"E4F52EE0",
|
69 |
|
|
x"E35B4CFB", x"E1C71C72", x"E0387F1E", x"DEAF57AC",
|
70 |
|
|
x"DD2B8994", x"DBACF915", x"DA338B2B", x"D8BF258C",
|
71 |
|
|
x"D74FAE9F", x"D5E50D79", x"D47F29D4", x"D31DEC0D",
|
72 |
|
|
x"D1C13D1C", x"D0690690", x"CF15328C", x"CDC5ABBF",
|
73 |
|
|
x"CC7A5D62", x"CB333333", x"C9F01971", x"C8B0FCD7",
|
74 |
|
|
x"C775CA9A", x"C63E7064", x"C50ADC51", x"C3DAFCEA",
|
75 |
|
|
x"C2AEC126", x"C1861862", x"C060F25E", x"BF3F3F3F",
|
76 |
|
|
x"BE20EF88", x"BD05F418", x"BBEE3E26", x"BAD9BF44",
|
77 |
|
|
x"B9C86953", x"B8BA2E8C", x"B7AF0172", x"B6A6D4DB",
|
78 |
|
|
x"B5A19BE3", x"B49F49F5", x"B39FD2BE", x"B2A32A33",
|
79 |
|
|
x"B1A9448C", x"B0B21643", x"AFBD9411", x"AECBB2ED",
|
80 |
|
|
x"ADDC680B", x"ACEFA8DA", x"AC056B01", x"AB1DA461",
|
81 |
|
|
x"AA384B0F", x"A9555555", x"A874B9B3", x"A7966ED8",
|
82 |
|
|
x"A6BA6BA7", x"A5E0A72F", x"A50918B1", x"A433B799",
|
83 |
|
|
x"A3607B7F", x"A28F5C29", x"A1C05183", x"A0F353A5",
|
84 |
|
|
x"A0285ACC", x"9F5F5F5F", x"9E9859EA", x"9DD3431B",
|
85 |
|
|
x"9D1013CA", x"9C4EC4EC", x"9B8F4F9E", x"9AD1AD1B",
|
86 |
|
|
x"9A15D6C0", x"995BC60A", x"98A37495", x"97ECDC1D",
|
87 |
|
|
x"9737F679", x"9684BDA1", x"95D32BA6", x"95233AB7",
|
88 |
|
|
x"9474E51D", x"93C8253D", x"931CF593", x"927350B9",
|
89 |
|
|
x"91CB315D", x"91249249", x"907F6E5D", x"8FDBC091",
|
90 |
|
|
x"8F3983F2", x"8E98B3A6", x"8DF94AE6", x"8D5B4502",
|
91 |
|
|
x"8CBE9D5E", x"8C234F73", x"8B8956CC", x"8AF0AF0B",
|
92 |
|
|
x"8A5953E1", x"89C34116", x"892E727F", x"889AE409",
|
93 |
|
|
x"880891AC", x"87777777", x"86E79187", x"8658DC08",
|
94 |
|
|
x"85CB533A", x"853EF369", x"84B3B8F2", x"8429A043",
|
95 |
|
|
x"83A0A5D4", x"8318C632", x"8291FDF2", x"820C49BA",
|
96 |
|
|
x"8187A63F", x"81041041", x"8081848E", x"80000000"
|
97 |
|
|
);
|
98 |
|
|
|
99 |
|
|
|
100 |
|
|
constant one_and_half : unsigned(WIDTH-1 downto 0) := x"C0000000";--"11000000000000000000000000000000";
|
101 |
|
|
|
102 |
|
|
signal n : pipe(0 to SQRT_ITER);
|
103 |
|
|
signal n_next : pipe(0 to SQRT_ITER);
|
104 |
|
|
signal d : pipe(0 to SQRT_ITER);
|
105 |
|
|
signal d_next : pipe(0 to SQRT_ITER);
|
106 |
|
|
signal r : pipe(0 to SQRT_ITER);
|
107 |
|
|
signal r_next : pipe(0 to SQRT_ITER);
|
108 |
|
|
signal rsqr : pipe(0 to SQRT_ITER);
|
109 |
|
|
signal rsqr_next : pipe(0 to SQRT_ITER);
|
110 |
|
|
|
111 |
|
|
begin
|
112 |
|
|
|
113 |
|
|
-- pipe stages
|
114 |
|
|
|
115 |
|
|
process(clk) is
|
116 |
|
|
begin
|
117 |
|
|
if rising_edge(clk) then
|
118 |
|
|
for i in 0 to SQRT_ITER loop
|
119 |
|
|
if (res = '0') then
|
120 |
|
|
n(i) <= (others => '0');
|
121 |
|
|
d(i) <= (others => '0');
|
122 |
|
|
r(i) <= (others => '0');
|
123 |
|
|
rsqr(i) <= (others => '0');
|
124 |
|
|
else
|
125 |
|
|
n(i) <= n_next(i);
|
126 |
|
|
d(i) <= d_next(i);
|
127 |
|
|
r(i) <= r_next(i);
|
128 |
|
|
rsqr(i) <= rsqr_next(i);
|
129 |
|
|
end if;
|
130 |
|
|
end loop;
|
131 |
|
|
end if;
|
132 |
|
|
end process;
|
133 |
|
|
|
134 |
|
|
-- process inputs for the next stage
|
135 |
|
|
|
136 |
|
|
process(d,r,rsqr,n,ARG) is
|
137 |
|
|
variable n_extended : unsigned(2*WIDTH-1 downto 0);
|
138 |
|
|
variable d_extended : unsigned(2*WIDTH-1 downto 0);
|
139 |
|
|
variable r_next_tmp : unsigned(WIDTH-1 downto 0);
|
140 |
|
|
variable d_shift : unsigned(WIDTH-1 downto 0);
|
141 |
|
|
variable rsqr_extended : unsigned(2*WIDTH-1 downto 0);
|
142 |
|
|
|
143 |
|
|
variable index_vec : unsigned(SQRT_LUT_K-2 downto 0);
|
144 |
|
|
variable index : integer;
|
145 |
|
|
|
146 |
|
|
begin
|
147 |
|
|
n_next(0) <= ARG;
|
148 |
|
|
d_next(0) <= ARG;
|
149 |
|
|
|
150 |
|
|
index_vec := ARG(WIDTH - 3 downto WIDTH - SQRT_LUT_K - 1);
|
151 |
|
|
index := to_integer(index_vec);
|
152 |
|
|
|
153 |
|
|
r_next(0) <= SQRT_TABLE_1(index);
|
154 |
|
|
rsqr_next(0)<= SQRT_TABLE_2(index);
|
155 |
|
|
|
156 |
|
|
for i in 1 to SQRT_ITER loop
|
157 |
|
|
--operations
|
158 |
|
|
n_extended := n(i-1) * r(i-1);
|
159 |
|
|
d_extended := d(i-1) * rsqr(i-1);
|
160 |
|
|
d_shift := "0" & d_extended(2*WIDTH -2 downto WIDTH);
|
161 |
|
|
r_next_tmp := one_and_half - d_shift;
|
162 |
|
|
rsqr_extended := r_next_tmp * r_next_tmp;
|
163 |
|
|
|
164 |
|
|
--assignments
|
165 |
|
|
n_next(i) <= n_extended(2*WIDTH-2 downto WIDTH-1);
|
166 |
|
|
d_next(i) <= d_extended(2*WIDTH-2 downto WIDTH-1);
|
167 |
|
|
rsqr_next(i) <= rsqr_extended(2*WIDTH-2 downto WIDTH-1);
|
168 |
|
|
r_next(i) <= r_next_tmp;
|
169 |
|
|
|
170 |
|
|
end loop;
|
171 |
|
|
end process;
|
172 |
|
|
|
173 |
|
|
|
174 |
|
|
-- assign output
|
175 |
|
|
Z <= n(SQRT_ITER);
|
176 |
|
|
|
177 |
|
|
end rtl;
|