aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/sanity/004all08/all08.vhdl
blob: 4a47baddd3a8cfbd04778e21c56578fad9276977 (plain)
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 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 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;