mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
parent
654ab117f2
commit
55ad950609
2
Changes
2
Changes
@ -47,7 +47,7 @@ Verilator 5.019 devel
|
||||
* Fix compilers seeing empty input due to file system races (#4708). [Flavien Solt]
|
||||
* Fix shift of > 32-bit number (#4719). [Flavien Solt]
|
||||
* Fix Windows include gates in filesystem Flush implementation. (#4720). [William D. Jones]
|
||||
* Fix 0**0 with wide numbers (#4721). [Flavien Solt]
|
||||
* Fix power operator with wide numbers and constants (#4721) (#4763). [Flavien Solt]
|
||||
* Fix parameter passing to ports (#4723). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix block names of nested do..while loops (#4728). [Ryszard Rozak, Antmicro Ltd.]
|
||||
|
||||
|
@ -3434,10 +3434,6 @@ class ConstVisitor final : public VNVisitor {
|
||||
TREEOP ("AstPowSS {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
|
||||
TREEOP ("AstPowSU {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
|
||||
TREEOP ("AstPowUS {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
|
||||
TREEOP ("AstPow {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)");
|
||||
TREEOP ("AstPowSU {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)");
|
||||
TREEOP ("AstPowUS {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)");
|
||||
TREEOP ("AstPowSU {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)");
|
||||
TREEOP ("AstOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
|
||||
TREEOP ("AstShiftL {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
|
||||
TREEOP ("AstShiftLOvr {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
|
||||
@ -3479,7 +3475,7 @@ class ConstVisitor final : public VNVisitor {
|
||||
TREEOP ("AstMul {operandIsPowTwo($lhsp), operandsSameSize($lhsp,,$rhsp)}", "replaceMulShift(nodep)"); // a*2^n -> a<<n
|
||||
TREEOP ("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)"); // a/2^n -> a>>n
|
||||
TREEOP ("AstModDiv{$lhsp, operandIsPowTwo($rhsp)}", "replaceModAnd(nodep)"); // a % 2^n -> a&(2^n-1)
|
||||
TREEOP ("AstPow {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
|
||||
TREEOP ("AstPow {operandIsTwo($lhsp), !$rhsp.isZero}", "replacePowShift(nodep)"); // 2**a == 1<<a
|
||||
TREEOP ("AstSub {$lhsp.castAdd, operandSubAdd(nodep)}", "AstAdd{AstSub{$lhsp->castAdd()->lhsp(),$rhsp}, $lhsp->castAdd()->rhsp()}"); // ((a+x)-y) -> (a+(x-y))
|
||||
TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE") // 1 & (a == b) -> (IData)(a == b)
|
||||
// Trinary ops
|
||||
|
@ -482,6 +482,11 @@ V3Number& V3Number::setAllBitsXRemoved() {
|
||||
}
|
||||
}
|
||||
}
|
||||
V3Number& V3Number::setValue1() {
|
||||
m_data.num()[0] = {1, 0};
|
||||
for (int i = 1; i < words(); i++) m_data.num()[i] = {0, 0};
|
||||
return *this;
|
||||
}
|
||||
|
||||
V3Number& V3Number::setMask(int nbits) {
|
||||
setZero();
|
||||
@ -2139,18 +2144,18 @@ V3Number& V3Number::opPow(const V3Number& lhs, const V3Number& rhs, bool lsign,
|
||||
NUM_ASSERT_OP_ARGS2(lhs, rhs);
|
||||
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
|
||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||
if (rhs.isEqZero()) return setQuad(1); // Overrides lhs 0 -> return 0
|
||||
if (rhs.isEqZero()) return setValue1(); // Overrides lhs 0 -> return 1
|
||||
// We may want to special case when the lhs is 2, so we can get larger outputs
|
||||
if (rsign && rhs.isNegative()) {
|
||||
if (lhs.isEqZero()) {
|
||||
return setAllBitsXRemoved();
|
||||
} else if (lhs.isEqOne()) {
|
||||
return setQuad(1);
|
||||
return setValue1();
|
||||
} else if (lsign && lhs.isEqAllOnes()) {
|
||||
if (rhs.bitIs1(0)) {
|
||||
return setAllBits1(); // -1^odd=-1
|
||||
} else {
|
||||
return setQuad(1); // -1^even=1
|
||||
return setValue1(); // -1^even=1
|
||||
}
|
||||
}
|
||||
return setZero();
|
||||
|
@ -581,6 +581,7 @@ public:
|
||||
V3Number& setAllBitsZ();
|
||||
V3Number& setAllBits0();
|
||||
V3Number& setAllBits1();
|
||||
V3Number& setValue1();
|
||||
V3Number& setMask(int nbits); // IE if nbits=1, then 0b1, if 2->0b11, if 3->0b111 etc
|
||||
|
||||
// ACCESSORS
|
||||
|
@ -12,6 +12,8 @@
|
||||
#ifndef TEST_CHECK_H_
|
||||
#define TEST_CHECK_H_
|
||||
|
||||
#include <iostream>
|
||||
|
||||
extern int errors;
|
||||
|
||||
#ifdef TEST_VERBOSE
|
||||
|
@ -1,7 +1,7 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2005 by Wilson Snyder.
|
||||
// any use, without warranty, 2023 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`define STRINGIFY(x) `"x`"
|
||||
@ -235,6 +235,11 @@ module t (/*AUTOARG*/
|
||||
$write("- cyc%0d: %0x**%0x = sh %0x\n", cyc, a, b, shifted);
|
||||
`endif
|
||||
// Constant versions
|
||||
`checkh(67'h0 ** 21'h0, 67'h1);
|
||||
`checkh(67'h1 ** 21'h0, 67'h1);
|
||||
`checkh(67'h2 ** 21'h0, 67'h1);
|
||||
`checkh(67'h0 ** 21'h1, 67'h0);
|
||||
`checkh(67'h0 ** 21'h4, 67'h0);
|
||||
`checkh(67'h1 ** 21'h31, 67'h1);
|
||||
`checkh(67'h2 ** 21'h10, 67'h10000);
|
||||
`checkh(67'd10 ** 21'h3, 67'h3e8);
|
||||
|
42
test_regress/t/t_math_pow7.cpp
Normal file
42
test_regress/t/t_math_pow7.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// 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
|
||||
|
||||
#include VM_PREFIX_INCLUDE
|
||||
|
||||
#include "TestCheck.h"
|
||||
|
||||
int errors = 0;
|
||||
|
||||
std::unique_ptr<VM_PREFIX> topp;
|
||||
int main(int argc, char** argv) {
|
||||
vluint64_t sim_time = 1100;
|
||||
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
||||
contextp->commandArgs(argc, argv);
|
||||
topp.reset(new VM_PREFIX{"top"});
|
||||
|
||||
topp->eval();
|
||||
{ contextp->timeInc(10); }
|
||||
|
||||
int cyc = 0;
|
||||
|
||||
while ((contextp->time() < sim_time) && !contextp->gotFinish()) {
|
||||
topp->eval();
|
||||
contextp->timeInc(5);
|
||||
|
||||
++cyc;
|
||||
if (cyc > 10) break;
|
||||
}
|
||||
|
||||
TEST_CHECK_EQ(topp->out_data, 1);
|
||||
|
||||
topp->final();
|
||||
topp.reset();
|
||||
|
||||
printf("*-* All Finished *-*\n");
|
||||
return errors != 0;
|
||||
}
|
27
test_regress/t/t_math_pow7.pl
Executable file
27
test_regress/t/t_math_pow7.pl
Executable file
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
verilator_flags2 => [
|
||||
"--exe",
|
||||
"$Self->{t_dir}/$Self->{name}.cpp"
|
||||
],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
29
test_regress/t/t_math_pow7.v
Normal file
29
test_regress/t/t_math_pow7.v
Normal file
@ -0,0 +1,29 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2005 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`define STRINGIFY(x) `"x`"
|
||||
|
||||
`define stop $stop
|
||||
`ifdef VERILATOR
|
||||
`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)
|
||||
`else
|
||||
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); end while(0)
|
||||
`endif
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
out_data
|
||||
);
|
||||
|
||||
output [11:0] out_data;
|
||||
wire [11:0] out_data;
|
||||
wire [11:0] a;
|
||||
wire [2:0] b;
|
||||
assign a = 12'h000 ** { b };
|
||||
assign b = 3'b0;
|
||||
assign out_data = a;
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user