mirror of
https://github.com/verilator/verilator.git
synced 2025-04-04 19:52:39 +00:00
Support unpacked array port in protect-lib and hierarchical verilation (#2672)
* Add a test to use unpacked array port in hierarchical verilation and protect-lib. * V3EmitV supports unpacked array variables * Can Emit local unpacked array properly * Update golden of t_debug_emitv * Support unpacked array port in protect-lib * Remove t_prot_lib_unpacked_bad test as unpacked array is supported now.
This commit is contained in:
parent
c23de458ed
commit
ff3d35ca61
@ -634,11 +634,31 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
virtual void visit(AstTopScope* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstScope* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
puts(" ");
|
||||
iterate(nodep->dtypep());
|
||||
puts(" ");
|
||||
puts(nodep->prettyName());
|
||||
if (nodep->isIO()) {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
puts(" ");
|
||||
}
|
||||
std::vector<const AstUnpackArrayDType*> unpackps;
|
||||
for (AstNodeDType* dtypep = nodep->dtypep(); dtypep;) {
|
||||
dtypep = dtypep->skipRefp();
|
||||
if (AstUnpackArrayDType* unpackp = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
unpackps.push_back(unpackp);
|
||||
dtypep = unpackp->subDTypep();
|
||||
} else {
|
||||
iterate(dtypep);
|
||||
puts(" ");
|
||||
puts(nodep->prettyName());
|
||||
dtypep = nullptr;
|
||||
}
|
||||
}
|
||||
// If nodep is an unpacked array, append unpacked dimensions
|
||||
for (const auto& unpackp : unpackps) {
|
||||
puts("[");
|
||||
puts(cvtToStr(unpackp->rangep()->leftConst()));
|
||||
puts(":");
|
||||
puts(cvtToStr(unpackp->rangep()->rightConst()));
|
||||
puts("]");
|
||||
}
|
||||
if (!m_suppressVarSemi) {
|
||||
puts(";\n");
|
||||
} else {
|
||||
|
@ -388,10 +388,6 @@ private:
|
||||
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
if (!nodep->isIO()) return;
|
||||
if (VN_IS(nodep->dtypep(), UnpackArrayDType)) {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: unpacked arrays with protect-lib on "
|
||||
<< nodep->prettyNameQ());
|
||||
}
|
||||
if (nodep->direction() == VDirection::INPUT) {
|
||||
if (nodep->isUsedClock() || nodep->attrClocker() == VVarAttrClocker::CLOCKER_YES) {
|
||||
UASSERT_OBJ(m_hasClk, nodep, "checkIfClockExists() didn't find this clock");
|
||||
@ -410,13 +406,7 @@ private:
|
||||
virtual void visit(AstNode*) override {}
|
||||
|
||||
string cInputConnection(AstVar* varp) {
|
||||
string frstmt;
|
||||
string ket;
|
||||
bool useSetWSvlv = V3Task::dpiToInternalFrStmt(varp, varp->name(), frstmt, ket);
|
||||
if (useSetWSvlv) {
|
||||
return frstmt + ket + " handlep__V->" + varp->name() + ", " + varp->name() + ");\n";
|
||||
}
|
||||
return "handlep__V->" + varp->name() + " = " + frstmt + ket + ";\n";
|
||||
return V3Task::assignDpiToInternal("handlep__V->" + varp->name(), varp);
|
||||
}
|
||||
|
||||
void handleClock(AstVar* varp) {
|
||||
@ -445,6 +435,13 @@ private:
|
||||
|
||||
void handleInput(AstVar* varp) { m_modPortsp->addNodep(varp->cloneTree(false)); }
|
||||
|
||||
static void addLocalVariable(AstTextBlock* textp, AstVar* varp, const char* suffix) {
|
||||
AstVar* newVarp
|
||||
= new AstVar(varp->fileline(), AstVarType::VAR, varp->name() + suffix, varp->dtypep());
|
||||
textp->addNodep(newVarp);
|
||||
textp->addText(varp->fileline(), ";\n");
|
||||
}
|
||||
|
||||
void handleOutput(AstVar* varp) {
|
||||
FileLine* fl = varp->fileline();
|
||||
m_modPortsp->addNodep(varp->cloneTree(false));
|
||||
@ -455,18 +452,11 @@ private:
|
||||
m_seqParamsp->addText(fl, varp->name() + "_tmp__V\n");
|
||||
}
|
||||
|
||||
AstNodeDType* comboDtypep = varp->dtypep()->cloneTree(false);
|
||||
m_comboDeclsp->addNodep(comboDtypep);
|
||||
m_comboDeclsp->addText(fl, " " + varp->name() + "_combo__V;\n");
|
||||
addLocalVariable(m_comboDeclsp, varp, "_combo__V");
|
||||
|
||||
if (m_hasClk) {
|
||||
AstNodeDType* seqDtypep = varp->dtypep()->cloneTree(false);
|
||||
m_seqDeclsp->addNodep(seqDtypep);
|
||||
m_seqDeclsp->addText(fl, " " + varp->name() + "_seq__V;\n");
|
||||
|
||||
AstNodeDType* tmpDtypep = varp->dtypep()->cloneTree(false);
|
||||
m_tmpDeclsp->addNodep(tmpDtypep);
|
||||
m_tmpDeclsp->addText(fl, " " + varp->name() + "_tmp__V;\n");
|
||||
addLocalVariable(m_seqDeclsp, varp, "_seq__V");
|
||||
addLocalVariable(m_tmpDeclsp, varp, "_tmp__V");
|
||||
|
||||
m_nbAssignsp->addText(fl, varp->name() + "_seq__V <= " + varp->name() + "_tmp__V;\n");
|
||||
m_seqAssignsp->addText(fl, varp->name() + " = " + varp->name() + "_seq__V;\n");
|
||||
|
@ -1676,9 +1676,45 @@ string V3Task::assignInternalToDpi(AstVar* portp, bool isPtr, const string& frSu
|
||||
return stmt;
|
||||
}
|
||||
|
||||
bool V3Task::dpiToInternalFrStmt(AstVar* portp, const string& frName, string& frstmt,
|
||||
string& ket) {
|
||||
return TaskDpiUtils::dpiToInternalFrStmt(portp, frName, frstmt, ket);
|
||||
string V3Task::assignDpiToInternal(const string& lhsName, AstVar* varp) {
|
||||
// Create assignment from DPI temporary into internal format
|
||||
// DPI temporary is scalar or 1D array (if unpacked array)
|
||||
// Internal representation is scalar, 1D, or multi-dimensional array (similar to SV)
|
||||
const string frName = varp->name();
|
||||
string frstmt;
|
||||
string ket;
|
||||
const bool useSetWSvlv = TaskDpiUtils::dpiToInternalFrStmt(varp, frName, frstmt, ket);
|
||||
|
||||
const std::vector<std::pair<AstUnpackArrayDType*, int>> dimStrides
|
||||
= TaskDpiUtils::unpackDimsAndStrides(varp->dtypep());
|
||||
const int total = dimStrides.empty()
|
||||
? 1
|
||||
: dimStrides.front().first->elementsConst() * dimStrides.front().second;
|
||||
const int widthWords = varp->basicp()->widthWords();
|
||||
string statements;
|
||||
for (int i = 0; i < total; ++i) {
|
||||
string lhs = lhsName;
|
||||
// extract a scalar from multi-dimensional array (internal format)
|
||||
for (auto&& dimStride : dimStrides) {
|
||||
const size_t dimIdx = (i / dimStride.second) % dimStride.first->elementsConst();
|
||||
lhs += "[" + cvtToStr(dimIdx) + "]";
|
||||
}
|
||||
// extract a scalar from DPI temporary var that is scalar or 1D array
|
||||
if (useSetWSvlv) {
|
||||
statements += frstmt + ket + " " + lhs + ", " + frName + " + "
|
||||
+ cvtToStr(i * widthWords) + ");\n";
|
||||
} else {
|
||||
string rhs = frstmt;
|
||||
if (!dimStrides.empty()) {
|
||||
// e.g. time is 64bit svLogicVector
|
||||
const int coef = varp->basicp()->isDpiLogicVec() ? widthWords : 1;
|
||||
rhs += "[" + cvtToStr(i * coef) + "]";
|
||||
}
|
||||
rhs += ket;
|
||||
statements += lhs + " = " + rhs + ";\n";
|
||||
}
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
|
||||
const char* V3Task::dpiTemporaryVarSuffix() {
|
||||
|
@ -39,8 +39,7 @@ public:
|
||||
static V3TaskConnects taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp);
|
||||
static string assignInternalToDpi(AstVar* portp, bool isPtr, const string& frSuffix,
|
||||
const string& toSuffix, const string& frPrefix = "");
|
||||
static bool dpiToInternalFrStmt(AstVar* portp, const string& frName, string& frstmt,
|
||||
string& ket);
|
||||
static string assignDpiToInternal(const string& lhsName, AstVar* rhsp);
|
||||
static const char* dpiTemporaryVarSuffix();
|
||||
};
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
module Vt_debug_emitv;
|
||||
input logic clk;
|
||||
input logic in;
|
||||
signed int [31:0] [0:2] t.array;
|
||||
logic logic [15:0] t.pubflat;
|
||||
logic logic [15:0] t.pubflat_r;
|
||||
int signed int [31:0] t.fd;
|
||||
int signed int [31:0] t.i;
|
||||
int signed int [31:0] t.cyc;
|
||||
int signed int [31:0] t.fo;
|
||||
int signed int [31:0] t.sum;
|
||||
string string t.str;
|
||||
int signed int [31:0] t._Vpast_0_0;
|
||||
int signed int [31:0] t._Vpast_1_0;
|
||||
int signed int [31:0] t.unnamedblk3.i;
|
||||
signed int [31:0] t.array[0:2];
|
||||
logic [15:0] t.pubflat;
|
||||
logic [15:0] t.pubflat_r;
|
||||
signed int [31:0] t.fd;
|
||||
signed int [31:0] t.i;
|
||||
signed int [31:0] t.cyc;
|
||||
signed int [31:0] t.fo;
|
||||
signed int [31:0] t.sum;
|
||||
string t.str;
|
||||
signed int [31:0] t._Vpast_0_0;
|
||||
signed int [31:0] t._Vpast_1_0;
|
||||
signed int [31:0] t.unnamedblk3.i;
|
||||
@(*)@([settle])@([initial])@(posedge clk)@(negedge
|
||||
clk)always @(
|
||||
*)@(
|
||||
@ -199,21 +199,21 @@ module Vt_debug_emitv;
|
||||
always @(negedge clk) begin
|
||||
$display("negedge clk, pfr = %x", t.pubflat_r);
|
||||
end
|
||||
int signed int [31:0] __Vtask_t.sub.inc__2__i;
|
||||
int signed int [31:0] __Vtask_t.sub.inc__2__o;
|
||||
int signed int [31:0] __Vfunc_t.sub.f__3__Vfuncout;
|
||||
int signed int [31:0] __Vfunc_t.sub.f__3__v;
|
||||
logic logic [15:0] __Vdly__t.pubflat_r;
|
||||
int signed int [31:0] __Vdly__t.cyc;
|
||||
int signed int [31:0] __Vdly__t._Vpast_0_0;
|
||||
int signed int [31:0] __Vdly__t._Vpast_1_0;
|
||||
signed int [31:0] __Vtask_t.sub.inc__2__i;
|
||||
signed int [31:0] __Vtask_t.sub.inc__2__o;
|
||||
signed int [31:0] __Vfunc_t.sub.f__3__Vfuncout;
|
||||
signed int [31:0] __Vfunc_t.sub.f__3__v;
|
||||
logic [15:0] __Vdly__t.pubflat_r;
|
||||
signed int [31:0] __Vdly__t.cyc;
|
||||
signed int [31:0] __Vdly__t._Vpast_0_0;
|
||||
signed int [31:0] __Vdly__t._Vpast_1_0;
|
||||
endmodule
|
||||
package Vt_debug_emitv___024unit;
|
||||
endpackage
|
||||
package Vt_debug_emitv_Pkg;
|
||||
endpackage
|
||||
class Vt_debug_emitv___024unit__03a__03aCls;
|
||||
int signed int [31:0] member;
|
||||
signed int [31:0] member;
|
||||
|
||||
???? // CFUNC '__VnoInFunc_method'
|
||||
$_CSTMT(Vt_debug_emitv* const __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
|
||||
|
@ -31,7 +31,7 @@ execute(
|
||||
file_grep($Self->{obj_dir} . "/Vsub0/sub0.sv", /^module\s+(\S+)\s+/, "sub0");
|
||||
file_grep($Self->{obj_dir} . "/Vsub1/sub1.sv", /^module\s+(\S+)\s+/, "sub1");
|
||||
file_grep($Self->{obj_dir} . "/Vsub2/sub2.sv", /^module\s+(\S+)\s+/, "sub2");
|
||||
file_grep($Self->{stats}, qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 10);
|
||||
file_grep($Self->{stats}, qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 11);
|
||||
file_grep($Self->{run_log_filename}, qr/MACRO:(\S+) is defined/i, "cplusplus");
|
||||
|
||||
ok(1);
|
||||
|
@ -215,6 +215,82 @@ module sub4 #(
|
||||
reg [7:0] ff;
|
||||
always_ff @(posedge clk) ff <= in + 8'(P0);
|
||||
assign out = ff;
|
||||
|
||||
logic [127:0] sub5_in[2][3];
|
||||
wire [7:0] sub5_out[2][3];
|
||||
sub5 i_sub5(.clk(clk), .in(sub5_in), .out(sub5_out));
|
||||
|
||||
int count = 0;
|
||||
always @(posedge clk) begin
|
||||
if (!count[0]) begin
|
||||
sub5_in[0][0] <= 128'd0;
|
||||
sub5_in[0][1] <= 128'd1;
|
||||
sub5_in[0][2] <= 128'd2;
|
||||
sub5_in[1][0] <= 128'd3;
|
||||
sub5_in[1][1] <= 128'd4;
|
||||
sub5_in[1][2] <= 128'd5;
|
||||
end else begin
|
||||
sub5_in[0][0] <= 128'd0;
|
||||
sub5_in[0][1] <= 128'd0;
|
||||
sub5_in[0][2] <= 128'd0;
|
||||
sub5_in[1][0] <= 128'd0;
|
||||
sub5_in[1][1] <= 128'd0;
|
||||
sub5_in[1][2] <= 128'd0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
count <= count + 1;
|
||||
if (count > 0) begin
|
||||
for (int i = 0; i < 2; ++i) begin
|
||||
for (int j = 0; j < 3; ++j) begin
|
||||
automatic byte exp = !count[0] ? 8'(3 * (1 - i) + (2- j) + 1) : 8'b0;
|
||||
if (sub5_out[i][j] != exp) begin
|
||||
$display("in[%d][%d] act:%d exp:%d", i, j, sub5_out[i][j], exp);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
module sub5 (input wire clk, input wire [127:0] in[2][3], output logic [7:0] out[2][3]); `HIER_BLOCK
|
||||
|
||||
int count = 0;
|
||||
always @(posedge clk) begin
|
||||
count <= count + 1;
|
||||
if (count > 0) begin
|
||||
for (int i = 0; i < 2; ++i) begin
|
||||
for (int j = 0; j < 3; ++j) begin
|
||||
automatic bit [127:0] exp = count[0] ? 128'(3 * i + 128'(j)) : 128'd0;
|
||||
if (in[i][j] != exp) begin
|
||||
$display("in[%d][%d] act:%d exp:%d", i, j, in[i][j], exp);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (count[0]) begin
|
||||
out[0][0] <= 8'd6;
|
||||
out[0][1] <= 8'd5;
|
||||
out[0][2] <= 8'd4;
|
||||
out[1][0] <= 8'd3;
|
||||
out[1][1] <= 8'd2;
|
||||
out[1][2] <= 8'd1;
|
||||
end else begin
|
||||
out[0][0] <= 8'd0;
|
||||
out[0][1] <= 8'd0;
|
||||
out[0][2] <= 8'd0;
|
||||
out[1][0] <= 8'd0;
|
||||
out[1][1] <= 8'd0;
|
||||
out[1][2] <= 8'd0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module delay #(
|
||||
|
@ -33,7 +33,7 @@ if (!$Self->have_cmake) {
|
||||
file_grep($target_dir . 'Vsub0/sub0.sv', /^module\s+(\S+)\s+/, "sub0");
|
||||
file_grep($target_dir . 'Vsub1/sub1.sv', /^module\s+(\S+)\s+/, "sub1");
|
||||
file_grep($target_dir . 'Vsub2/sub2.sv', /^module\s+(\S+)\s+/, "sub2");
|
||||
file_grep($target_dir . 'Vt_hier_block__stats.txt', qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 10);
|
||||
file_grep($target_dir . 'Vt_hier_block__stats.txt', qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 11);
|
||||
file_grep($Self->{obj_dir} . '/run.log', qr/MACRO:(\S+) is defined/i, "cplusplus");
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ execute(
|
||||
file_grep($Self->{obj_dir} . "/Vsub0/sub0.sv", /^module\s+(\S+)\s+/, "sub0");
|
||||
file_grep($Self->{obj_dir} . "/Vsub1/sub1.sv", /^module\s+(\S+)\s+/, "sub1");
|
||||
file_grep($Self->{obj_dir} . "/Vsub2/sub2.sv", /^module\s+(\S+)\s+/, "sub2");
|
||||
file_grep($Self->{stats}, qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 10);
|
||||
file_grep($Self->{stats}, qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 11);
|
||||
file_grep($Self->{run_log_filename}, qr/MACRO:(\S+) is defined/i, "cplusplus");
|
||||
|
||||
ok(1);
|
||||
|
@ -32,7 +32,7 @@ execute(
|
||||
file_grep($Self->{obj_dir} . "/Vsub0/sub0.sv", /^module\s+(\S+)\s+/, "sub0");
|
||||
file_grep($Self->{obj_dir} . "/Vsub1/sub1.sv", /^module\s+(\S+)\s+/, "sub1");
|
||||
file_grep($Self->{obj_dir} . "/Vsub2/sub2.sv", /^module\s+(\S+)\s+/, "sub2");
|
||||
file_grep($Self->{stats}, qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 10);
|
||||
file_grep($Self->{stats}, qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 11);
|
||||
file_grep($Self->{run_log_filename}, qr/MACRO:(\S+) is defined/i, "cplusplus");
|
||||
|
||||
ok(1);
|
||||
|
@ -55,6 +55,14 @@ module t #(parameter GATED_CLK = 0) (/*AUTOARG*/
|
||||
logic [128:0] s129_out;
|
||||
logic [3:0] [31:0] s4x32_in;
|
||||
logic [3:0] [31:0] s4x32_out;
|
||||
/*verilator lint_off LITENDIAN*/
|
||||
logic [0:15] s6x16up_in[0:1][2:0];
|
||||
logic [0:15] s6x16up_out[0:1][2:0];
|
||||
/*verilator lint_on LITENDIAN*/
|
||||
logic [15:0] s8x16up_in[1:0][0:3];
|
||||
logic [15:0] s8x16up_out[1:0][0:3];
|
||||
logic [15:0] s8x16up_3d_in[1:0][0:1][0:1];
|
||||
logic [15:0] s8x16up_3d_out[1:0][0:1][0:1];
|
||||
|
||||
wire clk_en = crc[0];
|
||||
|
||||
@ -80,6 +88,12 @@ module t #(parameter GATED_CLK = 0) (/*AUTOARG*/
|
||||
.s129_out,
|
||||
.s4x32_in,
|
||||
.s4x32_out,
|
||||
.s6x16up_in,
|
||||
.s6x16up_out,
|
||||
.s8x16up_in,
|
||||
.s8x16up_out,
|
||||
.s8x16up_3d_in,
|
||||
.s8x16up_3d_out,
|
||||
.clk_en,
|
||||
.clk);
|
||||
|
||||
@ -99,6 +113,14 @@ module t #(parameter GATED_CLK = 0) (/*AUTOARG*/
|
||||
`DRIVE(s65)
|
||||
`DRIVE(s129)
|
||||
`DRIVE(s4x32)
|
||||
{s6x16up_in[0][0], s6x16up_in[0][1], s6x16up_in[0][2]} = crc[47:0];
|
||||
{s6x16up_in[1][0], s6x16up_in[1][1], s6x16up_in[1][2]} = ~crc[63:16];
|
||||
{s8x16up_in[0][0], s8x16up_in[0][1], s8x16up_in[0][2], s8x16up_in[0][3]} = crc;
|
||||
{s8x16up_in[1][0], s8x16up_in[1][1], s8x16up_in[1][2], s8x16up_in[1][3]} = ~crc;
|
||||
{s8x16up_3d_in[0][0][0], s8x16up_3d_in[0][0][1]} = ~crc[31:0];
|
||||
{s8x16up_3d_in[0][1][0], s8x16up_3d_in[0][1][1]} = ~crc[63:32];
|
||||
{s8x16up_3d_in[1][0][0], s8x16up_3d_in[1][0][1]} = crc[31:0];
|
||||
{s8x16up_3d_in[1][1][0], s8x16up_3d_in[1][1][1]} = crc[63:32];
|
||||
if (cyc == 0) begin
|
||||
accum_in <= x*100;
|
||||
accum_bypass <= '0;
|
||||
@ -155,6 +177,9 @@ module t #(parameter GATED_CLK = 0) (/*AUTOARG*/
|
||||
`CHECK(s65)
|
||||
`CHECK(s129)
|
||||
`CHECK(s4x32)
|
||||
`CHECK(s6x16up)
|
||||
`CHECK(s8x16up)
|
||||
`CHECK(s8x16up_3d)
|
||||
end
|
||||
|
||||
assign accum_bypass_out_expect = accum_bypass ? accum_in :
|
||||
|
@ -25,6 +25,14 @@ module secret #(parameter GATED_CLK = 0)
|
||||
output logic [128:0] s129_out,
|
||||
input [3:0] [31:0] s4x32_in,
|
||||
output logic [3:0] [31:0] s4x32_out,
|
||||
/*verilator lint_off LITENDIAN*/
|
||||
input [0:15] s6x16up_in[0:1][2:0],
|
||||
output logic [0:15] s6x16up_out[0:1][2:0],
|
||||
/*verilator lint_on LITENDIAN*/
|
||||
input [15:0] s8x16up_in[1:0][0:3],
|
||||
output logic [15:0] s8x16up_out[1:0][0:3],
|
||||
input [15:0] s8x16up_3d_in[1:0][0:1][0:1],
|
||||
output logic [15:0] s8x16up_3d_out[1:0][0:1][0:1],
|
||||
input clk_en,
|
||||
input clk /*verilator clocker*/);
|
||||
|
||||
@ -61,6 +69,19 @@ module secret #(parameter GATED_CLK = 0)
|
||||
s4x32_out = s4x32_in;
|
||||
end
|
||||
|
||||
for (genvar i = 0; i < 3; ++i) begin
|
||||
assign s6x16up_out[0][i] = s6x16up_in[0][i];
|
||||
assign s6x16up_out[1][i] = s6x16up_in[1][i];
|
||||
end
|
||||
for (genvar i = 0; i < 4; ++i) begin
|
||||
assign s8x16up_out[0][i] = s8x16up_in[0][i];
|
||||
assign s8x16up_out[1][i] = s8x16up_in[1][i];
|
||||
end
|
||||
for (genvar i = 0; i < 8; ++i) begin
|
||||
assign s8x16up_3d_out[i[2]][i[1]][i[0]] = s8x16up_3d_in[i[2]][i[1]][i[0]];
|
||||
end
|
||||
|
||||
|
||||
sub sub (.sub_in(s33_in), .sub_out(s33_out));
|
||||
|
||||
// Test sequential path
|
||||
|
@ -1,7 +0,0 @@
|
||||
%Error-UNSUPPORTED: t/t_prot_lib_unpacked_bad.v:7:28: Unsupported: unpacked arrays with protect-lib on 'unpacked_in'
|
||||
7 | input unpacked_in [7:0],
|
||||
| ^~~~~~~~~~~
|
||||
%Error-UNSUPPORTED: t/t_prot_lib_unpacked_bad.v:8:28: Unsupported: unpacked arrays with protect-lib on 'unpacked_out'
|
||||
8 | output unpacked_out [7:0]);
|
||||
| ^~~~~~~~~~~~
|
||||
%Error: Exiting due to
|
@ -1,28 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2019 by Todd Strader. 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);
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ["--protect-lib",
|
||||
"secret"],
|
||||
verilator_make_gcc => 0,
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
#run(cmd=>["make",
|
||||
# "-C",
|
||||
# "$Self->{obj_dir}",
|
||||
# "-f",
|
||||
# "V$Self->{name}.mk"]);
|
||||
|
||||
ok(1);
|
||||
1;
|
@ -1,17 +0,0 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2019 by Todd Strader.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module secret_impl (
|
||||
input unpacked_in [7:0],
|
||||
output unpacked_out [7:0]);
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 8; i = i + 1) begin
|
||||
assign unpacked_out[i] = unpacked_in[i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user