Support SystemVerilog .name and .* interconnect.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@906 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
01e9bc4855
commit
d2ce499b59
2
Changes
2
Changes
|
|
@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
* Verilator 3.64**
|
||||
|
||||
*** Support SystemVerilog .name and .* interconnect.
|
||||
|
||||
*** Support while and do-while loops.
|
||||
|
||||
**** Fix dotted bit reference to local memory. [Eugene Weber]
|
||||
|
|
|
|||
|
|
@ -893,7 +893,7 @@ as the build system.
|
|||
|
||||
=head1 VERILOG 2001 (IEEE 1364-2001) SUPPORT
|
||||
|
||||
Verilator supports the more common Verilog 2001 language features. This
|
||||
Verilator supports almost all Verilog 2001 language features. This
|
||||
includes signed numbers, "always @*", comma separated sensitivity lists,
|
||||
generate statements, multidimensional arrays, localparam, and C-style
|
||||
declarations inside port lists.
|
||||
|
|
@ -907,15 +907,16 @@ Verilator partially supports the uwire keyword.
|
|||
|
||||
=head1 SYSTEMVERILOG (IEEE 1800-2005) SUPPORT
|
||||
|
||||
Verilator currently has very minimal support for SystemVerilog as they
|
||||
become more common, contact the author if a feature you need is missing.
|
||||
Verilator currently has very minimal support for SystemVerilog. As
|
||||
SystemVerilog features enter common usage they will be added. Contact the
|
||||
author if a feature you need is missing.
|
||||
|
||||
Verilator implements the full SystemVerilog 1800-2005 preprocessor subset,
|
||||
including function call-like preprocessor defines.
|
||||
|
||||
Verilator supports $bits, $countones, $error, $fatal, $info, $isunknown,
|
||||
$onehot, $onehot0, $warning, always_comb, always_ff, always_latch, and
|
||||
final.
|
||||
$onehot, $onehot0, $warning, always_comb, always_ff, always_latch,
|
||||
do-while, and final. It also supports .name and .* interconnection.
|
||||
|
||||
Verilator partially supports assert.
|
||||
|
||||
|
|
|
|||
|
|
@ -298,6 +298,7 @@ void AstCell::dump(ostream& str) {
|
|||
this->AstNode::dump(str);
|
||||
if (modp()) { str<<" -> "; modp()->dump(str); }
|
||||
else { str<<" ->UNLINKED:"<<modName(); }
|
||||
if (pinStar()) str<<" [.*]";
|
||||
}
|
||||
void AstCellInline::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
|
|
@ -307,6 +308,7 @@ void AstPin::dump(ostream& str) {
|
|||
this->AstNode::dump(str);
|
||||
if (modVarp()) { str<<" -> "; modVarp()->dump(str); }
|
||||
else { str<<" ->UNLINKED"; }
|
||||
if (svImplicit()) str<<" [.SV]";
|
||||
}
|
||||
void AstVarXRef::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
|
|
|
|||
|
|
@ -576,10 +576,11 @@ private:
|
|||
int m_pinNum; // Pin number
|
||||
string m_name; // Pin name, or "" for number based interconnect
|
||||
AstVar* m_modVarp; // Input/output this pin connects to on submodule.
|
||||
bool m_svImplicit; // Pin is SystemVerilog .name'ed
|
||||
public:
|
||||
AstPin(FileLine* fl, int pinNum, const string& name, AstNode* exprp)
|
||||
:AstNode(fl)
|
||||
,m_name(name) {
|
||||
,m_name(name), m_svImplicit(false) {
|
||||
m_pinNum = pinNum;
|
||||
m_modVarp = NULL;
|
||||
setNOp1p(exprp); }
|
||||
|
|
@ -596,6 +597,8 @@ public:
|
|||
AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin
|
||||
AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable
|
||||
void modVarp(AstVar* varp) { m_modVarp=varp; }
|
||||
bool svImplicit() const { return m_svImplicit; }
|
||||
void svImplicit(bool flag) { m_svImplicit=flag; }
|
||||
};
|
||||
|
||||
struct AstModule : public AstNode {
|
||||
|
|
@ -652,12 +655,14 @@ private:
|
|||
string m_name; // Cell name
|
||||
string m_origName; // Original name before dot addition
|
||||
string m_modName; // Module the cell instances
|
||||
bool m_pinStar; // Pin list has .*
|
||||
AstModule* m_modp; // [AfterLink] Pointer to module instanced
|
||||
public:
|
||||
AstCell(FileLine* fl, const string& instName, const string& modName,
|
||||
AstPin* pinsp, AstPin* paramsp, AstRange* rangep)
|
||||
: AstNode(fl)
|
||||
, m_name(instName), m_origName(instName), m_modName(modName), m_modp(NULL) {
|
||||
, m_name(instName), m_origName(instName), m_modName(modName)
|
||||
, m_pinStar(false), m_modp(NULL) {
|
||||
addNOp1p(pinsp); addNOp2p(paramsp); setNOp3p(rangep); }
|
||||
virtual ~AstCell() {}
|
||||
virtual AstType type() const { return AstType::CELL;}
|
||||
|
|
@ -674,6 +679,8 @@ public:
|
|||
void origName(const string& name) { m_origName = name; }
|
||||
string modName() const { return m_modName; } // * = Instance name
|
||||
void modName(const string& name) { m_modName = name; }
|
||||
bool pinStar() const { return m_pinStar; }
|
||||
void pinStar(bool flag) { m_pinStar = flag; }
|
||||
AstPin* pinsp() const { return op1p()->castPin(); } // op1 = List of cell ports
|
||||
AstPin* paramsp() const { return op2p()->castPin(); } // op2 = List of parameter #(##) values
|
||||
AstRange* rangep() const { return op3p()->castRange(); } // op3 = Range of arrayed instants (NULL=not ranged)
|
||||
|
|
|
|||
|
|
@ -372,7 +372,8 @@ private:
|
|||
}
|
||||
}
|
||||
// Deal with implicit definitions
|
||||
if (m_idState==ID_RESOLVE && nodep->modVarp()) {
|
||||
if (m_idState==ID_RESOLVE && nodep->modVarp()
|
||||
&& !nodep->svImplicit()) { // SV 19.11.3: .name pins don't allow implicit decls
|
||||
pinImplicitExprRecurse(nodep->exprp());
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
|
|
|
|||
|
|
@ -163,6 +163,32 @@ private:
|
|||
new V3GraphEdge(&m_graph, vertex(m_modp), vertex(modp), 1, false);
|
||||
}
|
||||
}
|
||||
// Convert .* to list of pins
|
||||
if (nodep->modp() && nodep->pinStar()) {
|
||||
// Note what pins exist
|
||||
UINFO(9," CELL .* connect "<<nodep<<endl);
|
||||
V3SymTable ports; // Symbol table of all connected port names
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
if (pinp->name()=="") pinp->v3error("Connect by position is illegal in .* connected cells");
|
||||
if (!ports.findIdName(pinp->name())) {
|
||||
ports.insert(pinp->name(), pinp);
|
||||
}
|
||||
}
|
||||
// We search ports, rather then in/out declarations as they aren't resolved yet,
|
||||
// and it's easier to do it now then in V3Link when we'd need to repeat steps.
|
||||
for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) {
|
||||
if (AstPort* portp = portnodep->castPort()) {
|
||||
if (!ports.findIdName(portp->name())) {
|
||||
UINFO(9," need PORT "<<portp<<endl);
|
||||
// Create any not already connected
|
||||
AstPin* newp = new AstPin(nodep->fileline(),0,portp->name(),
|
||||
new AstVarRef(nodep->fileline(),portp->name(),false));
|
||||
newp->svImplicit(true);
|
||||
nodep->addPinsp(newp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Convert unnamed pins to pin number based assignments
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
if (pinp->name()=="") pinp->name("__pinNumber"+cvtToStr(pinp->pinNum()));
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public:
|
|||
static AstCase* s_caseAttrp; // Current case statement for attribute adding
|
||||
static AstRange* s_varRangep; // Pointer to range for next signal declaration
|
||||
static int s_pinNum; // Pin number currently parsing
|
||||
static bool s_pinStar; // Encountered SystemVerilog .*
|
||||
static string s_instModule; // Name of module referenced for instantiations
|
||||
static AstPin* s_instParamp; // Parameters for instantiations
|
||||
static bool s_trace; // Tracing is turned on
|
||||
|
|
@ -75,6 +76,7 @@ AstVarType V3Parse::s_varIO = AstVarType::UNKNOWN;
|
|||
bool V3Parse::s_varSigned = false;
|
||||
AstRange* V3Parse::s_varRangep = NULL;
|
||||
int V3Parse::s_pinNum = -1;
|
||||
bool V3Parse::s_pinStar = false;
|
||||
string V3Parse::s_instModule;
|
||||
AstPin* V3Parse::s_instParamp = NULL;
|
||||
AstVar* V3Parse::s_varAttrp = NULL;
|
||||
|
|
@ -108,6 +110,7 @@ class AstSenTree;
|
|||
AstBegin* beginp;
|
||||
AstCase* casep;
|
||||
AstCaseItem* caseitemp;
|
||||
AstCell* cellp;
|
||||
AstConst* constp;
|
||||
AstFunc* funcp;
|
||||
AstFuncRef* funcrefp;
|
||||
|
|
@ -240,7 +243,8 @@ class AstSenTree;
|
|||
%type<varp> netSig netSigList
|
||||
%type<rangep> rangeListE regrangeE anyrange rangeList delayrange portrangeE
|
||||
%type<varp> param paramList
|
||||
%type<nodep> instnameList instname
|
||||
%type<nodep> instnameList
|
||||
%type<cellp> instname
|
||||
%type<pinp> cellpinList cellpinlist2 cellpinitemE instparamListE
|
||||
%type<nodep> defpList defpOne
|
||||
%type<sentreep> sensitivityE
|
||||
|
|
@ -614,10 +618,10 @@ instnameList: instname { $$ = $1; }
|
|||
| instnameList ',' instname { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
instname: yID funcRange '(' cellpinList ')' { $$ = new AstCell($3,*$1,V3Parse::s_instModule,$4,V3Parse::s_instParamp,$2); }
|
||||
instname: yID funcRange '(' cellpinList ')' { $$ = new AstCell($3,*$1,V3Parse::s_instModule,$4,V3Parse::s_instParamp,$2); $$->pinStar(V3Parse::s_pinStar); }
|
||||
;
|
||||
|
||||
cellpinList: {V3Parse::s_pinNum=1;} cellpinlist2 { $$ = $2; }
|
||||
cellpinList: {V3Parse::s_pinNum=1; V3Parse::s_pinStar=false; } cellpinlist2 { $$ = $2; }
|
||||
;
|
||||
|
||||
cellpinlist2: cellpinitemE { $$ = $1; }
|
||||
|
|
@ -625,6 +629,8 @@ cellpinlist2: cellpinitemE { $$ = $1; }
|
|||
;
|
||||
|
||||
cellpinitemE: /* empty */ { $$ = NULL; V3Parse::s_pinNum++; }
|
||||
| '.' '*' { $$ = NULL; if (V3Parse::s_pinStar) $1->v3error("Duplicate .* in a cell"); V3Parse::s_pinStar=true; }
|
||||
| '.' yID { $$ = new AstPin($1,V3Parse::s_pinNum++,*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);}
|
||||
| '.' yID '(' ')' { $$ = NULL; V3Parse::s_pinNum++; }
|
||||
| '.' yID '(' expr ')' { $$ = new AstPin($1,V3Parse::s_pinNum++,*$2,$4); }
|
||||
| expr { $$ = new AstPin(CRELINE(),V3Parse::s_pinNum++,"",$1); }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# 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
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2007 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
integer cyc; initial cyc=1;
|
||||
|
||||
supply0 [1:0] low;
|
||||
supply1 [1:0] high;
|
||||
|
||||
reg [7:0] isizedwire;
|
||||
reg ionewire;
|
||||
|
||||
wire oonewire;
|
||||
wire [7:0] osizedreg; // From sub of t_inst_v2k_sub.v
|
||||
|
||||
t_inst sub
|
||||
(
|
||||
.osizedreg,
|
||||
.oonewire,
|
||||
// Inputs
|
||||
.isizedwire (isizedwire[7:0]),
|
||||
.*
|
||||
//.ionewire (ionewire)
|
||||
);
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (cyc!=0) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc==1) begin
|
||||
ionewire <= 1'b1;
|
||||
isizedwire <= 8'd8;
|
||||
end
|
||||
if (cyc==2) begin
|
||||
if (low != 2'b00) $stop;
|
||||
if (high != 2'b11) $stop;
|
||||
if (oonewire !== 1'b1) $stop;
|
||||
if (isizedwire !== 8'd8) $stop;
|
||||
end
|
||||
if (cyc==3) begin
|
||||
ionewire <= 1'b0;
|
||||
isizedwire <= 8'd7;
|
||||
end
|
||||
if (cyc==4) begin
|
||||
if (oonewire !== 1'b0) $stop;
|
||||
if (isizedwire !== 8'd7) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t_inst
|
||||
(
|
||||
output reg [7:0] osizedreg,
|
||||
output wire oonewire /*verilator public*/,
|
||||
input [7:0] isizedwire,
|
||||
input wire ionewire
|
||||
);
|
||||
|
||||
assign oonewire = ionewire;
|
||||
|
||||
always @* begin
|
||||
osizedreg = isizedwire;
|
||||
end
|
||||
|
||||
endmodule
|
||||
Loading…
Reference in New Issue