Add --pins-sc-uint-bool to force SystemC uint type (#5192)

This commit is contained in:
Bartłomiej Chmiel 2024-06-25 11:27:09 +02:00 committed by GitHub
parent 4c584c17e6
commit 9e2c8aefc8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 129 additions and 15 deletions

View File

@ -410,6 +410,7 @@ detailed descriptions of these arguments.
--pins-inout-enables Specify that __en and __out signals be created for inouts
--pins-sc-biguint Specify types for top-level ports
--pins-sc-uint Specify types for top-level ports
--pins-sc-uint-bool Specify types for top-level ports
--pins-uint8 Specify types for top-level ports
--no-pins64 Don't use uint64_t's for 33-64 bit sigs
--pipe-filter <command> Filter all input through a script

View File

@ -1004,6 +1004,10 @@ Summary:
:vlopt:`--pins-sc-biguint` combination, it results in sc_uint being used
between 2 and 64 and sc_biguint being used between 65 and 512.
.. option:: --pins-sc-uint-bool
Specifies SystemC inputs/outputs one bit wide should use sc_uint<1>.
.. option:: --pins-sc-biguint
Specifies SystemC inputs/outputs greater than 65 bits wide should use

View File

@ -2067,6 +2067,7 @@ public:
bool isScQuad() const;
bool isScBv() const;
bool isScUint() const;
bool isScUintBool() const;
bool isScBigUint() const;
bool isScSensitive() const { return m_scSensitive; }
bool isSigPublic() const;

View File

@ -380,6 +380,9 @@ bool AstVar::isScBv() const {
bool AstVar::isScUint() const {
return ((isSc() && v3Global.opt.pinsScUint() && width() >= 2 && width() <= 64) && !isScBv());
}
bool AstVar::isScUintBool() const {
return (isSc() && v3Global.opt.pinsScUintBool() && width() == 1);
}
bool AstVar::isScBigUint() const {
return ((isSc() && v3Global.opt.pinsScBigUint() && width() >= 65 && width() <= 512)
&& !isScBv());
@ -671,7 +674,7 @@ string AstVar::scType() const {
if (isScBigUint()) {
return (string{"sc_dt::sc_biguint<"} + cvtToStr(widthMin())
+ "> "); // Keep the space so don't get >>
} else if (isScUint()) {
} else if (isScUint() || isScUintBool()) {
return (string{"sc_dt::sc_uint<"} + cvtToStr(widthMin())
+ "> "); // Keep the space so don't get >>
} else if (isScBv()) {

View File

@ -192,10 +192,10 @@ public:
}
void emitScIQW(AstVar* nodep) {
UASSERT_OBJ(nodep->isSc(), nodep, "emitting SystemC operator on non-SC variable");
puts(nodep->isScBigUint() ? "SB"
: nodep->isScUint() ? "SU"
: nodep->isScBv() ? "SW"
: (nodep->isScQuad() ? "SQ" : "SI"));
puts(nodep->isScBigUint() ? "SB"
: (nodep->isScUint() || nodep->isScUintBool()) ? "SU"
: nodep->isScBv() ? "SW"
: (nodep->isScQuad() ? "SQ" : "SI"));
}
void emitDatap(AstNode* nodep) {
// When passing to a function with va_args the compiler doesn't

View File

@ -694,7 +694,7 @@ class EmitCTrace final : EmitCFunc {
const AstVarRef* const varrefp = VN_CAST(nodep->declp()->valuep(), VarRef);
if (!varrefp) return false;
AstVar* const varp = varrefp->varp();
return varp->isSc() && varp->isScUint();
return varp->isSc() && (varp->isScUint() || varp->isScUintBool());
}
void emitTraceInitOne(AstTraceDecl* nodep, int enumNum) {

View File

@ -1406,6 +1406,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
m_pinsScUint = flag;
if (!m_pinsScBigUint) m_pinsBv = 65;
});
DECL_OPTION("-pins-sc-uint-bool", CbOnOff, [this](bool flag) { m_pinsScUintBool = flag; });
DECL_OPTION("-pins-sc-biguint", CbOnOff, [this](bool flag) {
m_pinsScBigUint = flag;
m_pinsBv = 513;

View File

@ -260,6 +260,7 @@ private:
bool m_pedantic = false; // main switch: --Wpedantic
bool m_pinsInoutEnables = false;// main switch: --pins-inout-enables
bool m_pinsScUint = false; // main switch: --pins-sc-uint
bool m_pinsScUintBool = false; // main switch: --pins-sc-uint-bool
bool m_pinsScBigUint = false; // main switch: --pins-sc-biguint
bool m_pinsUint8 = false; // main switch: --pins-uint8
bool m_ppComments = false; // main switch: --pp-comments
@ -514,6 +515,7 @@ public:
bool pedantic() const { return m_pedantic; }
bool pinsInoutEnables() const { return m_pinsInoutEnables; }
bool pinsScUint() const { return m_pinsScUint; }
bool pinsScUintBool() const { return m_pinsScUintBool; }
bool pinsScBigUint() const { return m_pinsScBigUint; }
bool pinsUint8() const { return m_pinsUint8; }
bool ppComments() const { return m_ppComments; }

View File

@ -967,6 +967,10 @@ sub _compile_vlt_flags {
my $checkflags = $self->_checkflags(%param);
die "%Error: specify threads via 'threads =>' argument, not as a command line option" unless ($checkflags !~ /(^|\s)-?-threads\s/);
$self->{coverage} = 1 if ($checkflags =~ /-coverage\b/);
my $driver_verilator_flags = ' '.join(' ', driver_verilator_flags()).' ';
$self->{pins_sc_uint_bool} = 1 if (($checkflags =~ /-pins-sc-uint-bool\b/)
|| ($driver_verilator_flags =~ /-pins-sc-uint-bool\b/));
$self->{savable} = 1 if ($checkflags =~ /-savable\b/);
$self->{sc} = 1 if ($checkflags =~ /-sc\b/);
$self->{timing} = 1 if ($checkflags =~ / -?-timing\b/ || $checkflags =~ / -?-binary\b/ );
@ -1963,8 +1967,13 @@ sub _make_main {
if ($self->sc) {
print $fh "extern int sc_main(int argc, char** argv);\n";
print $fh "int sc_main(int argc, char** argv) {\n";
print $fh " sc_signal<bool> fastclk;\n" if $self->{inputs}{fastclk};
print $fh " sc_signal<bool> clk;\n" if $self->{inputs}{clk};
if ($self->{pins_sc_uint_bool}) {
print $fh " sc_signal<sc_dt::sc_uint<1>> fastclk;\n" if $self->{inputs}{fastclk};
print $fh " sc_signal<sc_dt::sc_uint<1>> clk;\n" if $self->{inputs}{clk};
} else {
print $fh " sc_signal<bool> fastclk;\n" if $self->{inputs}{fastclk};
print $fh " sc_signal<bool> clk;\n" if $self->{inputs}{clk};
}
print $fh " sc_set_time_resolution(1, $Self->{sc_time_resolution});\n";
print $fh " sc_time sim_time($self->{sim_time}, $Self->{sc_time_resolution});\n";
} else {
@ -2059,7 +2068,11 @@ sub _make_main {
print $fh " topp->nextTimeSlot() / MAIN_TIME_MULTIPLIER <= cycles) {\n";
print $fh " new_time = topp->nextTimeSlot();\n";
print $fh " } else {\n";
print $fh " ${set}clk = !${set}clk;\n";
if ($self->{pins_sc_uint_bool}) {
print $fh " ${set}clk.write(!${set}clk.read());\n";
} else {
print $fh " ${set}clk = !${set}clk;\n";
}
print $fh " }\n";
print $fh " contextp->time(new_time);\n";
} else {
@ -2070,11 +2083,19 @@ sub _make_main {
for (my $i = 0; $i < 5; $i++) {
my $action = 0;
if ($self->{inputs}{fastclk}) {
print $fh " ${set}fastclk = !${set}fastclk;\n";
if ($self->{pins_sc_uint_bool}) {
print $fh " ${set}fastclk.write(!${set}fastclk.read());\n";
} else {
print $fh " ${set}fastclk = !${set}fastclk;\n";
}
$action = 1;
}
if ($i == 0 && $self->{inputs}{clk}) {
print $fh " ${set}clk = !${set}clk;\n";
if ($self->{pins_sc_uint_bool}) {
print $fh " ${set}clk.write(!${set}clk.read());\n";
} else {
print $fh " ${set}clk = !${set}clk;\n";
}
$action = 1;
}
if ($self->{savable}) {
@ -2206,10 +2227,18 @@ sub _make_top_v {
print $fh " fastclk = 1;\n" if $self->{inputs}{fastclk};
print $fh " clk = 1;\n" if $self->{inputs}{clk};
print $fh " while (\$time < $self->{sim_time}) begin\n";
for (my $i = 0; $i < 5; $i++) {
print $fh " #1;\n";
print $fh " fastclk = !fastclk;\n" if $self->{inputs}{fastclk};
print $fh " clk = !clk;\n" if $i == 4 && $self->{inputs}{clk};
if ($self->{pins_sc_uint_bool}) {
for (my $i = 0; $i < 5; $i++) {
print $fh " #1;\n";
print $fh " fastclk.write(!fastclk.read());\n" if $self->{inputs}{fastclk};
print $fh " clk.write(!clk.read());\n" if $i == 4 && $self->{inputs}{clk};
}
} else {
for (my $i = 0; $i < 5; $i++) {
print $fh " #1;\n";
print $fh " fastclk = !fastclk;\n" if $self->{inputs}{fastclk};
print $fh " clk = !clk;\n" if $i == 4 && $self->{inputs}{clk};
}
}
print $fh " end\n";
print $fh " end\n";

View File

@ -0,0 +1,43 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 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(vlt => 1);
top_filename("t/t_var_pinsizes.v");
compile(
verilator_flags2 => ["-sc --pins-sc-uint-bool --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
{
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_in<sc_dt::sc_uint<1>\s> \s+ &i1;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_in<uint32_t> \s+ &i8;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_in<uint32_t> \s+ &i16;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_in<uint32_t> \s+ &i32;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_in<uint64_t> \s+ &i64;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_in<sc_dt::sc_bv<65>\s> \s+ &i65;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_in<sc_dt::sc_bv<128>\s> \s+ &i128;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_in<sc_dt::sc_bv<513>\s> \s+ &i513;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_out<sc_dt::sc_uint<1>\s> \s+ &o1;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_out<uint32_t> \s+ &o8;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_out<uint32_t> \s+ &o16;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_out<uint32_t> \s+ &o32;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_out<uint64_t> \s+ &o64;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_out<sc_dt::sc_bv<65>\s> \s+ &o65;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_out<sc_dt::sc_bv<128>\s> \s+ &o128;/x);
file_grep("$Self->{obj_dir}/$Self->{vm_prefix}.h", qr/sc_core::sc_out<sc_dt::sc_bv<513>\s> \s+ &o513;/x);
}
execute();
ok(1);
1;

View File

@ -0,0 +1,30 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 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
# This test runs the very first time we've executed Verilator --sc
# after building so we make sure to run with --gdbbt, so if it dumps we'll
# get a trace.
scenarios(simulator => 1);
top_filename("t/t_a1_first_cc.v");
$DEBUG_QUIET = "--debug --debugi 0 --gdbbt --no-dump-tree";
compile(
verilator_flags2 => [$DEBUG_QUIET, "-sc --trace --pins-sc-uint-bool"],
);
execute(
check_finished => 1,
);
ok(1);
1;