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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
-- Files containing most (if not all) features of vhdl08.
-- Like a comment.
-- TODO: at specifications.
context ctxt_ieee is
library ieee;
use ieee.std_logic_1164.all;
end ctxt_ieee;
context work.ctxt_ieee;
package pkg is
-- TODO: file param,
procedure clear (v : out std_logic_vector);
type my_enum is
(lit_a, lit_b, lit_c, 'e');
type my_short is range -2**15 to 2**15 - 1;
type DISTANCE is range 0 to 1E16 units
-- primary unit:
angstrom;
-- metric lengths:
nm = 10 angstrom;
um = 1000 nm;
mm = 1000 um;
cm = 10 mm;
end units;
type my_float is range 0.0 to 1.0e20;
attribute user_attr : boolean;
attribute user_attr of clear [std_logic_vector]: procedure is True;
type cell;
type cell_acc is access cell;
type cell is record
chain : cell_acc;
val : natural;
end record;
procedure prepend (ch : inout cell_acc; val : natural);
type text_file is file of string;
type sharedcounter is protected
procedure increment (n : natural);
procedure decrement (n : natural);
end protected;
end pkg;
package body pkg is
procedure clear (v : out std_logic_vector) is
begin
v := (v'range => '0');
end clear;
procedure prepend (ch : inout cell_acc; val : natural)
is
variable res : cell_acc;
variable len : natural;
begin
-- Check if already in the list.
res := ch;
while res /= null loop
if res.val = val then
return;
end if;
res := res.all.chain;
end loop;
len := 0;
res := ch;
loop
exit when res = null;
len := len + 1;
res := res.chain;
next when res.val = val;
end loop;
res := new cell'(chain => ch, val => val);
ch := res;
end prepend;
type sharedcounter is protected body
variable val : natural := 0;
procedure increment (n : natural) is
begin
val := val + n;
end increment;
procedure decrement (n : natural) is
begin
val := val - n;
end decrement;
end protected body;
end pkg;
library ieee;
use ieee.std_logic_1164.all;
entity reg is
generic (width : natural);
port (clk : std_logic;
rst_n : std_logic;
d : in std_logic_vector (width - 1 downto 0);
q : out std_logic_vector (width - 1 downto 0));
subtype bus_type is std_logic_vector (width - 1 downto 0);
begin
assert width < 128 report "large width" severity warning;
end reg;
architecture behav of reg is
begin
process (clk, rst_n)
begin
if rising_edge(clk) then
if rst_n = '0' then
q <= (others => '0');
else
q <= d;
end if;
end if;
end process;
end behav;
entity reg_tb is
end reg_tb;
library ieee;
use ieee.std_logic_1164.all;
use work.pkg.all;
architecture behav of reg_tb is
component reg is
generic (width : natural);
port (clk : std_logic;
rst_n : std_logic;
d : in std_logic_vector (width - 1 downto 0);
q : out std_logic_vector (width - 1 downto 0));
end component reg;
subtype data_type is std_logic_vector (31 downto 0);
function get_vector (n : natural) return data_type is
begin
case n is
when 0 =>
return x"0000_0000";
when 1 =>
return x"0000_0001";
when 2 =>
return x"1111_1111";
when 3 | 4 =>
return data_type'(x"3333_4444");
when 5 to 7 =>
return (0 to 5 => '1', 6 | 7 => '0', others => '1');
when others =>
return x"ffff_ffff";
end case;
end get_vector;
signal clk : std_logic bus;
signal rst_n : std_logic := '0';
signal din, dout : data_type;
alias my_clk : std_logic is clk;
group syn is (signal <>);
group sig_syn : syn (clk, rst_n);
type data_array_type is array (natural range <>) of data_type;
file input_file : text_file;
procedure disp_msg (msg : string) is
begin
report msg
severity note;
end disp_msg;
begin
process
begin
clk <= '0', '1' after 10 ns;
wait for 20 ns;
end process;
rst_n <= '0', '1' after 25 ns;
disp_msg ("start of design");
process
begin
disp_msg (msg => "test is starting");
for i in 1 to 10 loop
din <= get_vector(i);
wait until rising_edge(my_clk);
end loop;
wait;
end process;
compute: process
variable v : integer;
variable b1, b2, b3 : boolean;
variable bv1, bv2 : bit_vector (0 to 7);
begin
b2 := true;
b1 := (b2 and b3) or b1;
b3 := (b1 xor b2) nand b3;
b2 := (b1 nor b2) xnor b3;
bv1 := bv2 sll v;
bv2 := bv1 rol v;
bv1 := not(bv2 sra (v rem 3));
v := -2;
v := ((3 * v) / 4) ** 2;
v := (v + 4) - 1;
v := natural (v mod 128);
b1 := v >= 3;
b2 := v /= 4;
b3 := b2 or (v = 5);
report "v = " & integer'image (v) severity note;
wait;
end process compute;
cmp_reg : reg
generic map (width => 32)
port map (clk => clk,
rst_n => rst_n,
d => din,
q => dout);
blk1: block (clk)
signal dout2 : data_type register;
disconnect dout2 : data_type after 1 ns;
signal dout3 : data_type;
signal dout4 : data_type;
begin
assert dout (7 downto 0) = din (7 downto 0);
assert dout'right = 0;
dout2 <= guarded din;
with dout(0) select
dout4 <= din when '0',
(others => '1') when others;
g1: for i in 0 to 40 generate
g2: if i <= data_type'left generate
cmp: entity work.reg
generic map (width => 1)
port map (clk => clk,
rst_n => rst_n,
d(0) => din (i),
q(0) => dout3 (i));
end generate g2;
end generate g1;
end block;
end behav;
configuration cfg of reg_tb is
for behav
-- component configuration.
for cmp_reg : reg
use entity work.reg;
end for;
-- TODO: blocks, generate
end for;
end cfg;
|