Support string replication with variable (#4341)
This commit is contained in:
parent
294d78e0e2
commit
9aa90569bf
|
|
@ -729,19 +729,12 @@ private:
|
|||
// width: value(LHS) * width(RHS)
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
|
||||
V3Const::constifyParamsNoWarnEdit(nodep->rhsp()); // rhsp may change
|
||||
|
||||
uint32_t times = 1;
|
||||
|
||||
const AstConst* const constp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (!constp) {
|
||||
nodep->v3error("Replication value isn't a constant.");
|
||||
return;
|
||||
}
|
||||
uint32_t times = constp->toUInt();
|
||||
if (times == 0
|
||||
&& !VN_IS(nodep->backp(), Concat)) { // Concat Visitor will clean it up.
|
||||
nodep->v3error("Replication value of 0 is only legal under a concatenation"
|
||||
" (IEEE 1800-2017 11.4.12.1)");
|
||||
times = 1;
|
||||
}
|
||||
if (constp) times = constp->toUInt();
|
||||
|
||||
AstNodeDType* const vdtypep = m_vup->dtypeNullSkipRefp();
|
||||
if (VN_IS(vdtypep, QueueDType) || VN_IS(vdtypep, DynArrayDType)
|
||||
|
|
@ -775,7 +768,7 @@ private:
|
|||
<< vdtypep->prettyDTypeNameQ() << " data type");
|
||||
}
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
|
||||
if (nodep->lhsp()->isString()) {
|
||||
if ((vdtypep && vdtypep->isString()) || nodep->lhsp()->isString()) {
|
||||
AstNode* const newp
|
||||
= new AstReplicateN{nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
nodep->rhsp()->unlinkFrBack()};
|
||||
|
|
@ -783,6 +776,13 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
return;
|
||||
} else {
|
||||
if (!constp) nodep->v3error("Replication value isn't a constant.");
|
||||
if (times == 0
|
||||
&& !VN_IS(nodep->backp(), Concat)) { // Concat Visitor will clean it up.
|
||||
nodep->v3error("Replication value of 0 is only legal under a concatenation"
|
||||
" (IEEE 1800-2017 11.4.12.1)");
|
||||
times = 1; // Set to 1, so we can continue looking for errors
|
||||
}
|
||||
nodep->dtypeSetLogicUnsized((nodep->lhsp()->width() * times),
|
||||
(nodep->lhsp()->widthMin() * times),
|
||||
VSigning::UNSIGNED);
|
||||
|
|
@ -801,18 +801,7 @@ private:
|
|||
if (m_vup->prelim()) {
|
||||
iterateCheckString(nodep, "LHS", nodep->lhsp(), BOTH);
|
||||
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
|
||||
const AstConst* const constp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (!constp) {
|
||||
nodep->v3error("Replication value isn't a constant.");
|
||||
return;
|
||||
}
|
||||
const uint32_t times = constp->toUInt();
|
||||
if (times == 0
|
||||
&& !VN_IS(nodep->backp(), Concat)) { // Concat Visitor will clean it up.
|
||||
nodep->v3error("Replication value of 0 is only legal under a concatenation"
|
||||
" (IEEE 1800-2017 11.4.12.1)");
|
||||
}
|
||||
V3Const::constifyParamsNoWarnEdit(nodep->rhsp()); // rhsp may change
|
||||
nodep->dtypeSetString();
|
||||
}
|
||||
if (m_vup->final()) {
|
||||
|
|
|
|||
|
|
@ -8,15 +8,12 @@
|
|||
| ^
|
||||
... For warning description see https://verilator.org/warn/WIDTHEXPAND?v=latest
|
||||
... Use "/* verilator lint_off WIDTHEXPAND */" and lint_on around source to disable this message.
|
||||
%Error: t/t_math_repl_bad.v:13:12: Expecting expression to be constant, but can't convert a TESTPLUSARGS to constant.
|
||||
: ... In instance t
|
||||
13 | o = {$test$plusargs("NON-CONSTANT") {1'b1}};
|
||||
| ^~~~~~~~~~~~~~
|
||||
%Error: t/t_math_repl_bad.v:13:43: Replication value isn't a constant.
|
||||
: ... In instance t
|
||||
13 | o = {$test$plusargs("NON-CONSTANT") {1'b1}};
|
||||
| ^
|
||||
%Error: Internal Error: t/t_math_repl_bad.v:13:9: ../V3Width.cpp:#: Node has no type
|
||||
: ... In instance t
|
||||
%Warning-WIDTHEXPAND: t/t_math_repl_bad.v:13:9: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS's REPLICATE generates 1 bits.
|
||||
: ... In instance t
|
||||
13 | o = {$test$plusargs("NON-CONSTANT") {1'b1}};
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#!/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(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// Use this file as a template for submitting bugs, etc.
|
||||
// This module takes a single clock input, and should either
|
||||
// $write("*-* All Finished *-*\n");
|
||||
// $finish;
|
||||
// on success, or $stop.
|
||||
//
|
||||
// The code as shown applies a random vector to the Test
|
||||
// module, then calculates a CRC on the Test module's outputs.
|
||||
//
|
||||
// **If you do not wish for your code to be released to the public
|
||||
// please note it here, otherwise:**
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2023 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc = 0;
|
||||
|
||||
string s;
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
s = {cyc{"*"}};
|
||||
if (cyc != s.len()) $stop;
|
||||
if (cyc == 0 && s != "") $stop;
|
||||
if (cyc == 1 && s != "*") $stop;
|
||||
if (cyc == 2 && s != "**") $stop;
|
||||
if (cyc == 3 && s != "***") $stop;
|
||||
if (cyc == 4 && s != "****") $stop;
|
||||
if (cyc == 5 && s != "*****") $stop;
|
||||
if (cyc == 5) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue