parent
f9ecbdc70b
commit
31abe537a0
|
|
@ -416,21 +416,6 @@ struct TriggerKit {
|
||||||
|
|
||||||
VL_UNCOPYABLE(TriggerKit);
|
VL_UNCOPYABLE(TriggerKit);
|
||||||
|
|
||||||
// Create an AstSenTree that is sensitive to the given trigger index. Must not exist yet!
|
|
||||||
AstSenTree* createTriggerSenTree(AstNetlist* netlistp, uint32_t index) const {
|
|
||||||
AstTopScope* const topScopep = netlistp->topScopep();
|
|
||||||
FileLine* const flp = topScopep->fileline();
|
|
||||||
AstVarRef* const vrefp = new AstVarRef{flp, m_vscp, VAccess::READ};
|
|
||||||
AstCMethodHard* const callp
|
|
||||||
= new AstCMethodHard{flp, vrefp, "at", new AstConst{flp, index}};
|
|
||||||
callp->dtypeSetBit();
|
|
||||||
callp->pure(true);
|
|
||||||
AstSenItem* const senItemp = new AstSenItem{flp, VEdgeType::ET_TRUE, callp};
|
|
||||||
AstSenTree* const resultp = new AstSenTree{flp, senItemp};
|
|
||||||
topScopep->addSenTreep(resultp);
|
|
||||||
return resultp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility that assigns the given index trigger to fire when the given variable is zero
|
// Utility that assigns the given index trigger to fire when the given variable is zero
|
||||||
void addFirstIterationTriggerAssignment(AstVarScope* counterp, uint32_t index) const {
|
void addFirstIterationTriggerAssignment(AstVarScope* counterp, uint32_t index) const {
|
||||||
FileLine* const flp = counterp->fileline();
|
FileLine* const flp = counterp->fileline();
|
||||||
|
|
@ -459,6 +444,20 @@ struct TriggerKit {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Create an AstSenTree that is sensitive to the given trigger index. Must not exist yet!
|
||||||
|
AstSenTree* createTriggerSenTree(AstNetlist* netlistp, AstVarScope* const vscp, uint32_t index) {
|
||||||
|
AstTopScope* const topScopep = netlistp->topScopep();
|
||||||
|
FileLine* const flp = topScopep->fileline();
|
||||||
|
AstVarRef* const vrefp = new AstVarRef{flp, vscp, VAccess::READ};
|
||||||
|
AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, "at", new AstConst{flp, index}};
|
||||||
|
callp->dtypeSetBit();
|
||||||
|
callp->pure(true);
|
||||||
|
AstSenItem* const senItemp = new AstSenItem{flp, VEdgeType::ET_TRUE, callp};
|
||||||
|
AstSenTree* const resultp = new AstSenTree{flp, senItemp};
|
||||||
|
topScopep->addSenTreep(resultp);
|
||||||
|
return resultp;
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
// Utility for extra trigger allocation
|
// Utility for extra trigger allocation
|
||||||
|
|
||||||
|
|
@ -727,7 +726,8 @@ void createSettle(AstNetlist* netlistp, SenExprBuilder& senExprBulider,
|
||||||
invertAndMergeSenTreeMap(trigToSen, trig.m_map);
|
invertAndMergeSenTreeMap(trigToSen, trig.m_map);
|
||||||
|
|
||||||
// First trigger is for pure combinational triggers (first iteration)
|
// First trigger is for pure combinational triggers (first iteration)
|
||||||
AstSenTree* const inputChanged = trig.createTriggerSenTree(netlistp, firstIterationTrigger);
|
AstSenTree* const inputChanged
|
||||||
|
= createTriggerSenTree(netlistp, trig.m_vscp, firstIterationTrigger);
|
||||||
|
|
||||||
// Create and the body function
|
// Create and the body function
|
||||||
AstCFunc* const stlFuncp = V3Order::order(
|
AstCFunc* const stlFuncp = V3Order::order(
|
||||||
|
|
@ -800,11 +800,12 @@ AstNode* createInputCombLoop(AstNetlist* netlistp, SenExprBuilder& senExprBuilde
|
||||||
invertAndMergeSenTreeMap(trigToSen, trig.m_map);
|
invertAndMergeSenTreeMap(trigToSen, trig.m_map);
|
||||||
|
|
||||||
// The trigger top level inputs (first iteration)
|
// The trigger top level inputs (first iteration)
|
||||||
AstSenTree* const inputChanged = trig.createTriggerSenTree(netlistp, firstIterationTrigger);
|
AstSenTree* const inputChanged
|
||||||
|
= createTriggerSenTree(netlistp, trig.m_vscp, firstIterationTrigger);
|
||||||
|
|
||||||
// The DPI Export trigger
|
// The DPI Export trigger
|
||||||
AstSenTree* const dpiExportTriggered
|
AstSenTree* const dpiExportTriggered
|
||||||
= trig.createTriggerSenTree(netlistp, dpiExportTriggerIndex);
|
= createTriggerSenTree(netlistp, trig.m_vscp, dpiExportTriggerIndex);
|
||||||
|
|
||||||
// Create and Order the body function
|
// Create and Order the body function
|
||||||
AstCFunc* const icoFuncp
|
AstCFunc* const icoFuncp
|
||||||
|
|
@ -1077,13 +1078,13 @@ void schedule(AstNetlist* netlistp) {
|
||||||
invertAndMergeSenTreeMap(trigToSenAct, actTrigMap);
|
invertAndMergeSenTreeMap(trigToSenAct, actTrigMap);
|
||||||
|
|
||||||
// The DPI Export trigger AstSenTree
|
// The DPI Export trigger AstSenTree
|
||||||
AstSenTree* const dpiExportTriggered
|
AstSenTree* const dpiExportTriggeredAct
|
||||||
= actTrig.createTriggerSenTree(netlistp, dpiExportTriggerIndex);
|
= createTriggerSenTree(netlistp, actTrig.m_vscp, dpiExportTriggerIndex);
|
||||||
|
|
||||||
AstCFunc* const actFuncp = V3Order::order(
|
AstCFunc* const actFuncp = V3Order::order(
|
||||||
netlistp, {&logicRegions.m_pre, &logicRegions.m_act, &logicReplicas.m_act}, trigToSenAct,
|
netlistp, {&logicRegions.m_pre, &logicRegions.m_act, &logicReplicas.m_act}, trigToSenAct,
|
||||||
"act", false, false, [=](const AstVarScope* vscp, std::vector<AstSenTree*>& out) {
|
"act", false, false, [=](const AstVarScope* vscp, std::vector<AstSenTree*>& out) {
|
||||||
if (vscp->varp()->isWrittenByDpi()) out.push_back(dpiExportTriggered);
|
if (vscp->varp()->isWrittenByDpi()) out.push_back(dpiExportTriggeredAct);
|
||||||
});
|
});
|
||||||
splitCheck(actFuncp);
|
splitCheck(actFuncp);
|
||||||
if (v3Global.opt.stats()) V3Stats::statsStage("sched-create-act");
|
if (v3Global.opt.stats()) V3Stats::statsStage("sched-create-act");
|
||||||
|
|
@ -1098,10 +1099,13 @@ void schedule(AstNetlist* netlistp) {
|
||||||
std::unordered_map<const AstSenItem*, const AstSenTree*> trigToSenNba;
|
std::unordered_map<const AstSenItem*, const AstSenTree*> trigToSenNba;
|
||||||
invertAndMergeSenTreeMap(trigToSenNba, nbaTrigMap);
|
invertAndMergeSenTreeMap(trigToSenNba, nbaTrigMap);
|
||||||
|
|
||||||
|
AstSenTree* const dpiExportTriggeredNba
|
||||||
|
= createTriggerSenTree(netlistp, nbaTrigVscp, dpiExportTriggerIndex);
|
||||||
|
|
||||||
AstCFunc* const nbaFuncp = V3Order::order(
|
AstCFunc* const nbaFuncp = V3Order::order(
|
||||||
netlistp, {&logicRegions.m_nba, &logicReplicas.m_nba}, trigToSenNba, "nba",
|
netlistp, {&logicRegions.m_nba, &logicReplicas.m_nba}, trigToSenNba, "nba",
|
||||||
v3Global.opt.mtasks(), false, [=](const AstVarScope* vscp, std::vector<AstSenTree*>& out) {
|
v3Global.opt.mtasks(), false, [=](const AstVarScope* vscp, std::vector<AstSenTree*>& out) {
|
||||||
if (vscp->varp()->isWrittenByDpi()) out.push_back(dpiExportTriggered);
|
if (vscp->varp()->isWrittenByDpi()) out.push_back(dpiExportTriggeredNba);
|
||||||
});
|
});
|
||||||
splitCheck(nbaFuncp);
|
splitCheck(nbaFuncp);
|
||||||
netlistp->evalNbap(nbaFuncp); // Remember for V3LifePost
|
netlistp->evalNbap(nbaFuncp); // Remember for V3LifePost
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// Copyright 2022 by Geza Lore. 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
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
|
||||||
|
#include <svdpi.h>
|
||||||
|
|
||||||
|
#include <Vt_order_dpi_export_8__Dpi.h>
|
||||||
|
|
||||||
|
void call_set_x(svBit val) { set_x(val); }
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env 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.
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
scenarios(vlt_all => 1);
|
||||||
|
|
||||||
|
compile(
|
||||||
|
verilator_flags2 => ["--exe", "$Self->{t_dir}/$Self->{name}.cpp"],
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
check_finished => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// Copyright 2022 by Geza Lore. 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
|
||||||
|
|
||||||
|
module testbench(
|
||||||
|
/*AUTOARG*/
|
||||||
|
// Inputs
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
|
||||||
|
input clk; // Top level input clock
|
||||||
|
|
||||||
|
bit x = 0;
|
||||||
|
|
||||||
|
wire y = x & $c(1);
|
||||||
|
|
||||||
|
export "DPI-C" function set_x;
|
||||||
|
function void set_x(bit val);
|
||||||
|
x = val;
|
||||||
|
endfunction;
|
||||||
|
|
||||||
|
import "DPI-C" context function void call_set_x(bit val);
|
||||||
|
|
||||||
|
bit q = 0;
|
||||||
|
always @(posedge clk) q <= ~q;
|
||||||
|
|
||||||
|
always @(edge q) call_set_x(q);
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
always @(edge clk) begin
|
||||||
|
// This always block needs to evaluate before the NBA to even_other
|
||||||
|
// above is committed, as setting clocks via the set_other_clk uses
|
||||||
|
// blocking assignment.
|
||||||
|
$display("t=%t q=%d x=%d y=%d", $time, q, x, y);
|
||||||
|
if (y !== q) $stop;
|
||||||
|
if (n == 20) begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
n += 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue