Support or/and/xor array intrinsic methods, bug1210.

This commit is contained in:
Wilson Snyder 2017-09-13 19:37:47 -04:00
parent 77804b4d38
commit 256eb4bba0
5 changed files with 93 additions and 1 deletions

View File

@ -4,6 +4,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 3.911 devel
*** Support or/and/xor array intrinsic methods, bug1210. [Mike Popoloski]
*** Fix ordering of arrayed cell wide connections, bug1202 partial. [Mike Popoloski]
**** Fix LITENDIAN warning on arrayed cells, bug1202. [Mike Popoloski]

View File

@ -1536,6 +1536,45 @@ private:
nodep->v3error("Unknown built-in enum method '"<<nodep->fromp()->prettyTypeName()<<"'");
}
}
else if (AstUnpackArrayDType* arrayType = fromDtp->castUnpackArrayDType()) {
enum {
UNKNOWN = 0,
ARRAY_OR,
ARRAY_AND,
ARRAY_XOR
} methodId;
methodId = UNKNOWN;
if (nodep->name() == "or") methodId = ARRAY_OR;
else if (nodep->name() == "and") methodId = ARRAY_AND;
else if (nodep->name() == "xor") methodId = ARRAY_XOR;
if (methodId) {
if (nodep->pinsp()) nodep->v3error("Arguments passed to array method, but it does not take arguments");
FileLine* fl = nodep->fileline();
AstNode* newp = NULL;
for (int i = 0; i < arrayType->elementsConst(); ++i) {
AstNode* arrayRef = nodep->fromp()->cloneTree(false);
AstNode* selector = new AstArraySel(fl, arrayRef, i);
if (!newp)
newp = selector;
else {
switch (methodId) {
case ARRAY_OR: newp = new AstOr(fl, newp, selector); break;
case ARRAY_AND: newp = new AstAnd(fl, newp, selector); break;
case ARRAY_XOR: newp = new AstXor(fl, newp, selector); break;
default: nodep->v3fatalSrc("bad case");
}
}
}
nodep->replaceWith(newp);
nodep->deleteTree(); VL_DANGLING(nodep);
}
else {
nodep->v3error("Unknown built-in array method '"<<nodep->fromp()->prettyTypeName()<<"'");
}
}
else {
nodep->v3error("Unsupported: Member call on non-enum object '"
<<nodep->fromp()->prettyTypeName()<<"' which is a '"<<nodep->fromp()->dtypep()->prettyTypeName()<<"'");

View File

@ -2894,6 +2894,11 @@ parenE:
// // IEEE: built_in_method_call
// // method_call_root not needed, part of expr resolution
// // What's left is below array_methodNoRoot
array_methodNoRoot<nodep>:
yOR { $$ = new AstFuncRef($1, "or", NULL); }
| yAND { $$ = new AstFuncRef($1, "and", NULL); }
| yXOR { $$ = new AstFuncRef($1, "xor", NULL); }
;
dpi_import_export<nodep>: // ==IEEE: dpi_import_export
yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE function_prototype ';'
@ -3040,7 +3045,7 @@ expr<nodep>: // IEEE: part of expression/constant_expression/primary
// // method_call
| ~l~expr '.' function_subroutine_callNoMethod { $$ = new AstDot($2,$1,$3); }
// // method_call:array_method requires a '.'
//UNSUP ~l~expr '.' array_methodNoRoot { UNSUP }
| ~l~expr '.' array_methodNoRoot { $$ = new AstDot($2,$1,$3); }
//
// // IEEE: let_expression
// // see funcRef

View File

@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 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.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;

View File

@ -0,0 +1,28 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2014 by Wilson Snyder.
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
`define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
logic [2:0] foo [1:0];
initial begin
foo[0] = 3'b101;
foo[1] = 3'b011;
`checkh(foo.or, 3'b111);
`checkh(foo.and, 3'b001);
`checkh(foo.xor, 3'b110);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule