Parse randsequence as UNSUPPORTED.

This commit is contained in:
Wilson Snyder 2023-02-11 13:03:10 -05:00
parent dee2e45e27
commit daa545774e
5 changed files with 494 additions and 85 deletions

View File

@ -523,7 +523,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"endpackage" { FL; return yENDPACKAGE; }
"endprogram" { FL; return yENDPROGRAM; }
"endproperty" { FL; return yENDPROPERTY; }
"endsequence" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"endsequence" { FL; return yENDSEQUENCE; }
"enum" { FL; return yENUM; }
"expect" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"export" { FL; return yEXPORT; }
@ -560,7 +560,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"randc" { FL; return yRANDC; }
"randcase" { FL; return yRANDCASE; }
"randomize" { FL; return yRANDOMIZE; }
"randsequence" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"randsequence" { FL; return yRANDSEQUENCE; }
"ref" { FL; return yREF; }
"restrict" { FL; return yRESTRICT; }
"return" { FL; return yRETURN; }

View File

@ -600,7 +600,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yENDPRIMITIVE "endprimitive"
%token<fl> yENDPROGRAM "endprogram"
%token<fl> yENDPROPERTY "endproperty"
//UNSUP %token<fl> yENDSEQUENCE "endsequence"
%token<fl> yENDSEQUENCE "endsequence"
%token<fl> yENDSPECIFY "endspecify"
%token<fl> yENDTABLE "endtable"
%token<fl> yENDTASK "endtask"
@ -693,7 +693,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yRANDC "randc"
%token<fl> yRANDCASE "randcase"
%token<fl> yRANDOMIZE "randomize"
//UNSUP %token<fl> yRANDSEQUENCE "randsequence"
%token<fl> yRANDSEQUENCE "randsequence"
%token<fl> yRCMOS "rcmos"
%token<fl> yREAL "real"
%token<fl> yREALTIME "realtime"
@ -3550,7 +3550,7 @@ statement_item<nodep>: // IEEE: statement_item
// // IEEE: procedural_assertion_statement
| procedural_assertion_statement { $$ = $1; }
//
//UNSUP randsequence_statement { $$ = $1; }
| randsequence_statement { $$ = $1; }
//
// // IEEE: randcase_statement
| yRANDCASE rand_case_itemList yENDCASE { $$ = new AstRandCase{$1, $2}; }
@ -6343,102 +6343,118 @@ complex_pexpr<nodeExprp>: // IEEE: part of property_expr, see comments there
//**********************************************************************
// Randsequence
//UNSUPrandsequence_statement<nodep>: // ==IEEE: randsequence_statement
//UNSUP yRANDSEQUENCE '(' ')' productionList yENDSEQUENCE { }
//UNSUP | yRANDSEQUENCE '(' id/*production_identifier*/ ')' productionList yENDSEQUENCE { }
//UNSUP ;
randsequence_statement<nodep>: // ==IEEE: randsequence_statement
yRANDSEQUENCE '(' ')' productionList yENDSEQUENCE
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence"); }
| yRANDSEQUENCE '(' id/*production_identifier*/ ')' productionList yENDSEQUENCE
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence"); }
;
//UNSUPproductionList<nodep>: // IEEE: production+
//UNSUP production { $$ = $1; }
//UNSUP | productionList production { $$ = addNextNull($1, $2); }
//UNSUP ;
productionList<nodep>: // IEEE: production+
production { $$ = $1; }
| productionList production { $$ = addNextNull($1, $2); }
;
//UNSUPproduction<nodep>: // ==IEEE: production
//UNSUP productionFront ':' rs_ruleList ';' { }
//UNSUP ;
production<nodep>: // ==IEEE: production
productionFront ':' rs_ruleList ';'
{ // TODO makes a function, probably want a new Ast type instead
SYMP->popScope($$);
$$ = nullptr; BBUNSUP($<fl>2, "Unsupported: randsequence production"); }
;
//UNSUPproductionFront<nodep>: // IEEE: part of production
//UNSUP function_data_type id/*production_identifier*/ { }
//UNSUP | /**/ id/*production_identifier*/ { $$ = $1; }
//UNSUP | function_data_type id/*production_identifier*/ '(' tf_port_listE ')' { }
//UNSUP | /**/ id/*production_identifier*/ '(' tf_port_listE ')' { }
//UNSUP ;
productionFront<nodeFTaskp>: // IEEE: part of production
funcId/*production_identifier*/ { $$ = $1; }
| funcId '(' tf_port_listE ')' { $$ = $1; $$->addStmtsp($3); }
;
//UNSUPrs_ruleList<nodep>: // IEEE: rs_rule+ part of production
//UNSUP rs_rule { $$ = $1; }
//UNSUP | rs_ruleList '|' rs_rule { $$ = addNextNull($1, $3); }
//UNSUP ;
rs_ruleList<nodep>: // IEEE: rs_rule+ part of production
rs_rule { $$ = $1; }
| rs_ruleList '|' rs_rule { $$ = addNextNull($1, $3); }
;
//UNSUPrs_rule<nodep>: // ==IEEE: rs_rule
//UNSUP rs_production_list { $$ = $1; }
//UNSUP | rs_production_list yP_COLONEQ weight_specification { }
//UNSUP | rs_production_list yP_COLONEQ weight_specification rs_code_block { }
//UNSUP ;
rs_rule<nodep>: // ==IEEE: rs_rule
rs_production_list { $$ = $1; }
| rs_production_list yP_COLONEQ weight_specification
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence rule"); }
| rs_production_list yP_COLONEQ weight_specification rs_code_block
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence rule"); }
;
//UNSUPrs_production_list<nodep>: // ==IEEE: rs_production_list
//UNSUP rs_prodList { $$ = $1; }
//UNSUP | yRAND yJOIN /**/ production_item production_itemList { }
//UNSUP | yRAND yJOIN '(' expr ')' production_item production_itemList { }
//UNSUP ;
rs_production_list<nodep>: // ==IEEE: rs_production_list
rs_prodList { $$ = $1; }
| yRAND yJOIN /**/ production_item production_itemList
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence production list"); }
| yRAND yJOIN '(' expr ')' production_item production_itemList
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence production list"); }
;
//UNSUPweight_specification<nodep>: // ==IEEE: weight_specification
//UNSUP yaINTNUM { $$ = $1; }
//UNSUP | idClassSel/*ps_identifier*/ { $$ = $1; }
//UNSUP | '(' expr ')' { $$ = $2; }
//UNSUP ;
weight_specification<nodeExprp>: // ==IEEE: weight_specification
intnumAsConst { $$ = $1; }
| idClassSel/*ps_identifier*/ { $$ = $1; }
| '(' expr ')' { $$ = $2; }
;
//UNSUPrs_code_block<nodep>: // ==IEEE: rs_code_block
//UNSUP '{' '}' { $$ = nullptr; }
//UNSUP | '{' rs_code_blockItemList '}' { $$ = $2; }
//UNSUP ;
rs_code_block<nodep>: // ==IEEE: rs_code_block
'{' '}' { $$ = nullptr; }
| '{' rs_code_blockItemList '}' { $$ = $2; }
;
//UNSUPrs_code_blockItemList<nodep>: // IEEE: part of rs_code_block
//UNSUP rs_code_blockItem { $$ = $1; }
//UNSUP | rs_code_blockItemList rs_code_blockItem { $$ = addNextNull($1, $2); }
//UNSUP ;
rs_code_blockItemList<nodep>: // IEEE: part of rs_code_block
rs_code_blockItem { $$ = $1; }
| rs_code_blockItemList rs_code_blockItem { $$ = addNextNull($1, $2); }
;
//UNSUPrs_code_blockItem<nodep>: // IEEE: part of rs_code_block
//UNSUP data_declaration { $$ = $1; }
//UNSUP | stmt { $$ = $1; }
//UNSUP ;
rs_code_blockItem<nodep>: // IEEE: part of rs_code_block
data_declaration { $$ = $1; }
| stmt { $$ = $1; }
;
//UNSUPrs_prodList<nodep>: // IEEE: rs_prod+
//UNSUP rs_prod { $$ = $1; }
//UNSUP | rs_prodList rs_prod { $$ = addNextNull($1, $2); }
//UNSUP ;
rs_prodList<nodep>: // IEEE: rs_prod+
rs_prod { $$ = $1; }
| rs_prodList rs_prod { $$ = addNextNull($1, $2); }
;
//UNSUPrs_prod<nodep>: // ==IEEE: rs_prod
//UNSUP production_item { $$ = $1; }
//UNSUP | rs_code_block { $$ = $1; }
//UNSUP // // IEEE: rs_if_else
//UNSUP | yIF '(' expr ')' production_item %prec prLOWER_THAN_ELSE { }
//UNSUP | yIF '(' expr ')' production_item yELSE production_item { }
//UNSUP // // IEEE: rs_repeat
//UNSUP | yREPEAT '(' expr ')' production_item { }
//UNSUP // // IEEE: rs_case
//UNSUP | yCASE '(' expr ')' rs_case_itemList yENDCASE { }
//UNSUP ;
rs_prod<nodep>: // ==IEEE: rs_prod
production_item { $$ = $1; }
| rs_code_block { $$ = $1; }
// // IEEE: rs_if_else
| yIF '(' expr ')' production_item %prec prLOWER_THAN_ELSE
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence if"); }
| yIF '(' expr ')' production_item yELSE production_item
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence if"); }
// // IEEE: rs_repeat
| yREPEAT '(' expr ')' production_item
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence repeat"); }
// // IEEE: rs_case
| yCASE '(' expr ')' rs_case_itemList yENDCASE
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence case"); }
;
//UNSUPproduction_itemList<nodep>: // IEEE: production_item+
//UNSUP production_item { $$ = $1; }
//UNSUP | production_itemList production_item { $$ = addNextNull($1, $2); }
//UNSUP ;
production_itemList<nodep>: // IEEE: production_item+
production_item { $$ = $1; }
| production_itemList production_item { $$ = addNextNull($1, $2); }
;
//UNSUPproduction_item<nodep>: // ==IEEE: production_item
//UNSUP id/*production_identifier*/ { $$ = $1; }
//UNSUP | id/*production_identifier*/ '(' list_of_argumentsE ')' { }
//UNSUP ;
production_item<nodep>: // ==IEEE: production_item
id/*production_identifier*/
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence production id"); }
| id/*production_identifier*/ '(' list_of_argumentsE ')'
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence production id"); }
;
//UNSUPrs_case_itemList<nodep>: // IEEE: rs_case_item+
//UNSUP rs_case_item { $$ = $1; }
//UNSUP | rs_case_itemList rs_case_item { $$ = addNextNull($1, $2); }
//UNSUP ;
rs_case_itemList<nodep>: // IEEE: rs_case_item+
rs_case_item { $$ = $1; }
| rs_case_itemList rs_case_item { $$ = addNextNull($1, $2); }
;
//UNSUPrs_case_item<nodep>: // ==IEEE: rs_case_item
//UNSUP caseCondList ':' production_item ';' { }
//UNSUP | yDEFAULT production_item ';' { }
//UNSUP | yDEFAULT ':' production_item ';' { }
//UNSUP ;
rs_case_item<nodep>: // ==IEEE: rs_case_item
caseCondList ':' production_item ';'
{ $$ = nullptr; BBUNSUP($<fl>2, "Unsupported: randsequence case item"); }
| yDEFAULT production_item ';'
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence case item"); }
| yDEFAULT ':' production_item ';'
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: randsequence case item"); }
;
//**********************************************************************
// Checker

View File

@ -0,0 +1,152 @@
%Error-UNSUPPORTED: t/t_randsequence.v:23:17: Unsupported: randsequence production id
23 | main : one;
| ^~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_randsequence.v:23:15: Unsupported: randsequence production
23 | main : one;
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:24:14: Unsupported: randsequence production
24 | one : { o = 1; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:22:7: Unsupported: randsequence
22 | randsequence(main)
| ^~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:40:16: Unsupported: randsequence production id
40 | main: one two three;
| ^~~
%Error-UNSUPPORTED: t/t_randsequence.v:40:20: Unsupported: randsequence production id
40 | main: one two three;
| ^~~
%Error-UNSUPPORTED: t/t_randsequence.v:40:24: Unsupported: randsequence production id
40 | main: one two three;
| ^~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:40:14: Unsupported: randsequence production
40 | main: one two three;
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:41:13: Unsupported: randsequence production
41 | two: { do if ((seq) !== (1)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", "t/t_randsequence.v",41, (seq), (1)); $stop; end while(0);; seq = 2; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:42:13: Unsupported: randsequence production
42 | one: { do if ((seq) !== (0)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", "t/t_randsequence.v",42, (seq), (0)); $stop; end while(0);; seq = 1; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:43:15: Unsupported: randsequence production
43 | three: { do if ((seq) !== (2)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", "t/t_randsequence.v",43, (seq), (2)); $stop; end while(0);; seq = 3; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:39:7: Unsupported: randsequence
39 | randsequence(main)
| ^~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:51:17: Unsupported: randsequence production
51 | unnamed: { seq = 2; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:50:7: Unsupported: randsequence
50 | randsequence()
| ^~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:58:17: Unsupported: randsequence production
58 | unnamed: { };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:57:7: Unsupported: randsequence
57 | randsequence()
| ^~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:65:19: Unsupported: randsequence production id
65 | main: one | two | three := 2;
| ^~~
%Error-UNSUPPORTED: t/t_randsequence.v:65:25: Unsupported: randsequence production id
65 | main: one | two | three := 2;
| ^~~
%Error-UNSUPPORTED: t/t_randsequence.v:65:31: Unsupported: randsequence production id
65 | main: one | two | three := 2;
| ^~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:65:31: Unsupported: randsequence rule
65 | main: one | two | three := 2;
| ^~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:65:17: Unsupported: randsequence production
65 | main: one | two | three := 2;
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:66:16: Unsupported: randsequence production
66 | one: { ++counts[0]; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:67:16: Unsupported: randsequence production
67 | two: { ++counts[1]; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:68:18: Unsupported: randsequence production
68 | three: { ++counts[2]; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:64:10: Unsupported: randsequence
64 | randsequence(main)
| ^~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:79:19: Unsupported: randsequence production id
79 | main: one_if;
| ^~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:79:17: Unsupported: randsequence production
79 | main: one_if;
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:80:38: Unsupported: randsequence production id
80 | one_if: if (i % 10 == 0) count_1 else most;
| ^~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:80:51: Unsupported: randsequence production id
80 | one_if: if (i % 10 == 0) count_1 else most;
| ^~~~
%Error-UNSUPPORTED: t/t_randsequence.v:80:21: Unsupported: randsequence if
80 | one_if: if (i % 10 == 0) count_1 else most;
| ^~
%Error-UNSUPPORTED: t/t_randsequence.v:80:19: Unsupported: randsequence production
80 | one_if: if (i % 10 == 0) count_1 else most;
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:81:20: Unsupported: randsequence production
81 | count_1: { ++counts[1]; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:82:20: Unsupported: randsequence production
82 | count_2: { ++counts[2]; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:83:20: Unsupported: randsequence production
83 | count_3: { ++counts[3]; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:84:20: Unsupported: randsequence production
84 | count_4: { ++counts[4]; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:85:16: Unsupported: randsequence production
85 | bad: { $stop; };
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:87:24: Unsupported: randsequence production id
87 | 0: bad;
| ^~~
%Error-UNSUPPORTED: t/t_randsequence.v:87:22: Unsupported: randsequence case item
87 | 0: bad;
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:88:27: Unsupported: randsequence production id
88 | 1, 2: count_2;
| ^~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:88:25: Unsupported: randsequence case item
88 | 1, 2: count_2;
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:89:30: Unsupported: randsequence production id
89 | 3, 4, 5: count_3;
| ^~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:89:28: Unsupported: randsequence case item
89 | 3, 4, 5: count_3;
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:90:30: Unsupported: randsequence production id
90 | default: count_4;
| ^~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:90:21: Unsupported: randsequence case item
90 | default: count_4;
| ^~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:86:19: Unsupported: randsequence case
86 | most: case (i % 10)
| ^~~~
%Error-UNSUPPORTED: t/t_randsequence.v:86:17: Unsupported: randsequence production
86 | most: case (i % 10)
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:78:10: Unsupported: randsequence
78 | randsequence(main)
| ^~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:103:19: Unsupported: randsequence production id
103 | main: one_if;
| ^~~~~~
%Error-UNSUPPORTED: t/t_randsequence.v:103:17: Unsupported: randsequence production
103 | main: one_if;
| ^
%Error-UNSUPPORTED: t/t_randsequence.v:104:38: Unsupported: randsequence production id
104 | one_if: if (i % 10 == 0) count_1 else most;
| ^~~~~~~
%Error: Exiting due to

View File

@ -0,0 +1,24 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2022 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(simulator => 1);
compile(
fails => $Self->{vlt_all},
expect_filename => $Self->{golden_filename},
);
execute(
check_finished => 1,
) if !$Self->{vlt_all};
ok(1);
1;

View File

@ -0,0 +1,217 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// Copyright 2023 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
`define check_range(gotv,minv,maxv) do if ((gotv) < (minv) || (gotv) > (maxv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d-%0d\n", `__FILE__,`__LINE__, (gotv), (minv), (maxv)); $stop; end while(0);
`define check_within_30_percent(gotv,val) `check_range((gotv), (val) * 70 / 100, (val) * 130 / 100)
module t(/*AUTOARG*/);
localparam int COUNT = 1000;
int seq;
int counts[8];
function automatic int sfunc();
int o = 2;
randsequence(main)
main : one;
one : { o = 1; };
endsequence
return o;
endfunction
task prep();
for (int i = 0; i < COUNT; ++i) counts[i] = 0;
endtask
initial begin;
if (sfunc() != 1) $stop;
// simple
prep();
seq = 0;
randsequence(main)
main: one two three;
two: { `checkd(seq, 1); seq = 2; };
one: { `checkd(seq, 0); seq = 1; };
three: { `checkd(seq, 2); seq = 3; };
endsequence
`checkd(seq, 3);
// simple unnamed
prep();
seq = 0;
randsequence()
unnamed: { seq = 2; };
endsequence
`checkd(seq, 2);
// empty block
prep();
randsequence()
unnamed: { };
endsequence
// weight
prep();
for (int i = 0; i < COUNT; ++i) begin
randsequence(main)
main: one | two | three := 2;
one: { ++counts[0]; };
two: { ++counts[1]; };
three: { ++counts[2]; };
endsequence
end
`check_within_30_percent(counts[0], COUNT * 1 / 4);
`check_within_30_percent(counts[1], COUNT * 1 / 4);
`check_within_30_percent(counts[2], COUNT * 2 / 4);
// case
prep();
for (int i = 0; i < COUNT; ++i) begin
randsequence(main)
main: one_if;
one_if: if (i % 10 == 0) count_1 else most;
count_1: { ++counts[1]; };
count_2: { ++counts[2]; };
count_3: { ++counts[3]; };
count_4: { ++counts[4]; };
bad: { $stop; };
most: case (i % 10)
0: bad;
1, 2: count_2;
3, 4, 5: count_3;
default: count_4;
endcase;
endsequence
end
`check_within_30_percent(counts[1], COUNT * 1 / 10);
`check_within_30_percent(counts[2], COUNT * 2 / 10);
`check_within_30_percent(counts[3], COUNT * 3 / 10);
`check_within_30_percent(counts[4], COUNT * 4 / 10);
// case - different default
prep();
for (int i = 0; i < COUNT; ++i) begin
randsequence(main)
main: one_if;
one_if: if (i % 10 == 0) count_1 else most;
count_1: { ++counts[1]; };
count_2: { ++counts[2]; };
count_3: { ++counts[3]; };
count_4: { ++counts[4]; };
bad: { $stop; };
most: case (i % 10)
0: bad;
1, 2: count_2;
3, 4, 5: count_3;
default count_4; // No :
endcase;
endsequence
end
`check_within_30_percent(counts[1], COUNT * 1 / 10);
`check_within_30_percent(counts[2], COUNT * 2 / 10);
`check_within_30_percent(counts[3], COUNT * 3 / 10);
`check_within_30_percent(counts[4], COUNT * 4 / 10);
// repeat
prep();
randsequence(main)
main: repeat(10) count_1;
count_1: { ++counts[1]; };
endsequence
`checkd(counts[1], 10);
// rand join
prep();
for (int i = 0; i < COUNT; ++i) begin
randsequence(main)
main: rand join count_1 count_2;
count_1: { ++counts[1]; };
count_2: { ++counts[2]; };
endsequence
end
`check_within_30_percent(counts[1], COUNT * 1 / 1);
`check_within_30_percent(counts[2], COUNT * 1 / 1);
// rand join weight (TODO weight not tested yet)
prep();
for (int i = 0; i < COUNT; ++i) begin
randsequence(main)
main: rand join (1.0) count_1 count_2;
count_1: { ++counts[1]; };
count_2: { ++counts[2]; };
endsequence
randsequence(main)
main: rand join (0.0) count_3 count_4;
count_3: { ++counts[3]; };
count_4: { ++counts[4]; };
endsequence
end
`check_within_30_percent(counts[1], COUNT * 1 / 1);
`check_within_30_percent(counts[2], COUNT * 1 / 1);
`check_within_30_percent(counts[3], COUNT * 1 / 1);
`check_within_30_percent(counts[4], COUNT * 1 / 1);
// break
prep();
for (int i = 0; i < COUNT; ++i) begin
automatic bit fiftyfifty = i[0];
randsequence(main)
main: count_1 check count_2;
check: count_3 { if (fiftyfifty) break; } count_4;
count_1: { ++counts[1]; };
count_2: { ++counts[2]; };
count_3: { ++counts[3]; };
count_4: { ++counts[4]; };
endsequence
end
`checkd(counts[1], COUNT * 1 / 1);
`checkd(counts[2], COUNT * 1 / 2); // break
`checkd(counts[3], COUNT * 1 / 1);
`checkd(counts[4], COUNT * 1 / 2); // break or return
// return
prep();
for (int i = 0; i < COUNT; ++i) begin
automatic bit fiftyfifty = i[0];
randsequence(main)
main: count_1 check count_2;
check: count_3 { if (fiftyfifty) return; } count_4;
count_1: { ++counts[1]; };
count_2: { ++counts[2]; };
count_3: { ++counts[3]; };
count_4: { ++counts[4]; };
endsequence
end
`checkd(counts[1], COUNT * 1 / 1);
`checkd(counts[2], COUNT * 1 / 1); // return
`checkd(counts[3], COUNT * 1 / 1);
`checkd(counts[4], COUNT * 1 / 2); // break or return
// functions
prep();
for (int i = 0; i < COUNT; ++i) begin
randsequence(main)
main: f_1 f_2 f_3;
f_1 : func(10);
f_2 : func(20);
f_3 : fnoarg;
void func(int n) : { counts[1] += n; };
void fnoarg : { ++counts[2]; };
endsequence
end
`checkd(counts[1], COUNT * (10 + 20));
`checkd(counts[2], COUNT * 1 / 1); // return
$write("*-* All Finished *-*\n");
$finish;
end
endmodule