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
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
|
-- 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');
subtype my_enum_lit is my_enum range lit_b to 'e';
pure function "+" (v : my_enum) return my_enum;
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; -- Large unit.
end units;
type my_float is range 0.0 to 1.0e20;
type my_array1d is array (my_short range <>) of boolean;
subtype my_array1d10 is my_array1d (1 to 10);
type my_array2d is array (natural range <>, natural range <>) of boolean;
subtype my_array2d_8x8 is my_array2d (1 to 8, 1 to 8);
type d2c_type is array (0 to 9) of character;
type chess_type is array (1 to 8, 1 to 8) of std_logic_vector;
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;
b0, b1 : bit;
end record;
procedure prepend (variable ch : inout cell_acc; val : natural);
type text_file is file of string;
function is_eof (file t : text_file; fake : boolean) return boolean;
alias iseof is is_eof [text_file, boolean return boolean];
type sharedcounter is protected
procedure increment (n : natural);
procedure decrement (constant n : natural);
impure function get return natural;
end protected;
type my_urec is record
l : std_ulogic;
adr : std_ulogic_vector;
dat : std_ulogic_vector;
end record;
subtype my_urec8 is my_urec (adr (1 downto 0), dat (7 downto 0));
subtype my_slv is (resolved) std_ulogic_vector;
end pkg;
package body pkg is
pure function "+" (v : my_enum) return my_enum is
begin
return v;
end "+";
procedure clear (v : out std_logic_vector) is
begin
v := (v'range => '0');
end clear;
procedure prepend (variable 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;
null;
end loop;
len := 0;
res := ch;
L1: loop
exit L1 when res = null;
len := len + 1;
res := res.chain;
next when res.val = val;
end loop;
res := new cell'(chain => ch, val => val, b0 | b1 => '0');
ch := res;
end prepend;
function is_eof (file t : text_file; fake : boolean) return boolean is
begin
s: if fake then
return false;
else
return endfile (t);
end if s;
end is_eof;
procedure check_is_eof parameter (filename : string)
is
file f : text_file open read_mode is filename;
file f2, f3 : text_file;
begin
null;
end check_is_eof;
type sharedcounter is protected body
variable val : natural := 0;
procedure increment (n : natural) is
begin
val := val + n;
end increment;
procedure decrement (constant n : natural) is
begin
val := val - n;
end procedure decrement;
impure function get return natural is
begin
return val;
end function get;
end protected body;
end pkg;
package genpkg is
generic (val : natural := 5;
function plus (l, r : integer) return integer);
procedure add (l : inout integer);
end genpkg;
package body genpkg is
procedure add (l : inout integer) is
begin
l := plus (l, val);
end add;
end genpkg;
package genpkg2 is
generic (v : natural;
type t1;
package subgenpkg is new work.genpkg generic map (<>));
end genpkg2;
package my_adder_pkg is new work.genpkg generic map (val => open, plus => "+");
library ieee, work;
use ieee.std_logic_1164.all;
entity reg is
generic (width : natural);
port (clk : std_logic;
signal 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
ass1: postponed assert width < 128 report "large width" severity warning;
end reg;
library ieee;
use work.pkg.sharedcounter, ieee.std_logic_1164.all;
architecture behav of reg
is
shared variable counter : sharedcounter;
begin
process (clk, rst_n)
begin
if rising_edge(clk) then
if rst_n = '0' then
q <= (others => '0');
counter.increment (1);
else
q <= d;
end if;
end if;
end process;
end behav;
configuration reg_conf1 of reg is
for behav
end for;
end reg_conf1;
library ieee, work;
use ieee.std_logic_1164.all;
entity check_zero is
port (i0 : in std_logic);
end check_zero;
architecture behav of check_zero is
begin
assert (i0 = '0');
end behav;
entity reg_tb is
generic (conf : natural := 2);
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;
component check_zero is
port (i0 : in std_logic);
end component check_zero;
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 32x"0000_0000";
when 1 =>
return 32d"1";
when 2 =>
return 32sb"1";
when 3 | 4 =>
return data_type'(x"3333_4444");
when 5 to 7 =>
return (0 to 5 => '1', 6 | 7 => '0', others => '1');
when 8 =>
return ('0', '1', '0', others => '0');
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;
signal s1 : std_logic;
signal si : integer;
signal si2 : integer;
alias my_clk : std_logic is clk;
group syn is (subtype, signal <>);
group sig_syn : syn (data_type, clk, rst_n);
type data_array_type is array (natural range <>) of data_type;
constant zero : natural := 0;
procedure disp_msg (msg : string) is
begin
if msg'left (1) /= 1 then
report "strange start" severity note;
elsif msg'length > 20 then
report "long message";
else
report msg
severity note;
end if;
end disp_msg;
for cmpz0 : check_zero use entity work.check_zero port map (i0 => i0);
for cmpz1 : check_zero use open;
for others : check_zero use entity work.check_zero;
begin
process
begin
clk <= '0', '1' after 10 ns;
wait for 20 ns;
end process;
rst_n <= '0', '1' after 25 ns;
si2 <= 1 when rst_n = '0' else
2 when rst_n = '1';
cmpz0 : check_zero port map (i0 => din (0));
cmpz1 : check_zero port map (i0 => din (1));
cmpz2 : check_zero port map (i0 => din (2));
disp_msg ("start of design");
process (all)
begin
s1 <= not rst_n;
assert s1'driving and s1'driving_value /= '0';
end process;
si <= integer'(1) when clk = '0' else 2;
assert si'event or si'active or si'last_value < 3;
assert si'last_active < 10 ns and si'last_event < 10 ns;
assert si'transaction = '0';
postponed process is
begin
disp_msg (msg => "test is starting """ & reg_tb'simple_name & '"');
for i in 1 to 10 loop
din <= get_vector(i);
wait on my_clk until rising_edge(my_clk);
end loop;
wait;
end process;
compute: process
subtype byte_idx is natural range 0 to 7;
variable v : integer;
variable b1, b2, b3 : boolean;
variable bv1, bv2 : bit_vector (byte_idx);
variable d : distance;
begin
b2 := true;
b1 := (b2 and b3) or b1;
b3 := (b1 xor b2) nand b3;
b2 := (b1 nor b2) xnor b3;
assert byte_idx'left = 0 and byte_idx'low = 0;
assert byte_idx'right = 7 and byte_idx'high = 7;
assert byte_idx'ascending;
assert boolean'pos(b1) = 1;
bv1 := bv2 sll v;
bv2 := (bv1 rol v) and 8x"f0";
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);
d := 1.5 cm when v >= 0 else mm;
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;
for cmpz1_0, cmpz1_1 : check_zero use entity work.check_zero;
begin
assert dout (7 downto 0) = din (7 downto 0);
assert dout'right = 0;
cmpz1_0 : check_zero port map (i0 => din (0));
cmpz1_1 : check_zero port map (i0 => din (1));
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;
blk2: block is
generic (w : natural);
generic map (w => 1);
port (di : std_logic_vector (w - 1 downto 0);
do : out std_logic_vector (w - 1 downto 0));
port map (di => din (0 downto 0),
do => dout (0 downto 0));
for all : check_zero use entity work.check_zero;
begin
cmpz1_0 : check_zero port map (i0 => din (0));
g4: case conf generate
when g4_1: 1 | 2 =>
begin
cmp : configuration work.reg_conf1
generic map (width => 1)
port map (clk => clk,
rst_n => std_logic (rst_n),
d => di,
q => do);
end g4_1;
when others =>
end generate g4;
end block blk2;
end behav;
configuration cfg of reg_tb is
for behav
-- component configuration.
for cmp_reg : reg
use entity work.reg (behav);
end for;
for blk1
for g1(1)
end for;
for g1(2 to 3)
for g2
end for;
end for;
end for;
end for;
end cfg;
|