Add support for module input port default values (issue #489).
This commit is contained in:
parent
60a77b08d2
commit
c7eaa06a2b
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -104,6 +104,11 @@ perm_string Module::get_port_name(unsigned idx) const
|
||||||
return ports[idx]->name;
|
return ports[idx]->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PExpr* Module::get_port_default_value(unsigned idx) const
|
||||||
|
{
|
||||||
|
assert(idx < ports.size());
|
||||||
|
return ports[idx] ? ports[idx]->default_value : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PGate* Module::get_gate(perm_string name)
|
PGate* Module::get_gate(perm_string name)
|
||||||
|
|
|
||||||
8
Module.h
8
Module.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_Module_H
|
#ifndef IVL_Module_H
|
||||||
#define IVL_Module_H
|
#define IVL_Module_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -60,11 +60,13 @@ class Module : public PScopeExtra, public PNamedItem {
|
||||||
objects. Each port has a name and an ordered list of
|
objects. Each port has a name and an ordered list of
|
||||||
wires. The name is the means that the outside uses to
|
wires. The name is the means that the outside uses to
|
||||||
access the port, the wires are the internal connections to
|
access the port, the wires are the internal connections to
|
||||||
the port. */
|
the port. In SystemVerilog, input ports may also have a
|
||||||
|
default value. */
|
||||||
public:
|
public:
|
||||||
struct port_t {
|
struct port_t {
|
||||||
perm_string name;
|
perm_string name;
|
||||||
vector<PEIdent*> expr;
|
vector<PEIdent*> expr;
|
||||||
|
PExpr*default_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -148,6 +150,8 @@ class Module : public PScopeExtra, public PNamedItem {
|
||||||
// Return port name ("" for undeclared port)
|
// Return port name ("" for undeclared port)
|
||||||
perm_string get_port_name(unsigned idx) const;
|
perm_string get_port_name(unsigned idx) const;
|
||||||
|
|
||||||
|
PExpr* get_port_default_value(unsigned idx) const;
|
||||||
|
|
||||||
PGate* get_gate(perm_string name);
|
PGate* get_gate(perm_string name);
|
||||||
|
|
||||||
const list<PGate*>& get_gates() const;
|
const list<PGate*>& get_gates() const;
|
||||||
|
|
|
||||||
10
elaborate.cc
10
elaborate.cc
|
|
@ -1323,9 +1323,15 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
|
|
||||||
perm_string port_name = rmod->get_port_name(idx);
|
perm_string port_name = rmod->get_port_name(idx);
|
||||||
|
|
||||||
// Skip unconnected module ports. This happens when a
|
// If the port is unconnected, substitute the default
|
||||||
// null parameter is passed in.
|
// value. The parser ensures that a default value only
|
||||||
|
// exists for input ports.
|
||||||
|
if (pins[idx] == 0)
|
||||||
|
pins[idx] = rmod->get_port_default_value(idx);
|
||||||
|
|
||||||
|
// Skip unconnected module ports. This happens when a
|
||||||
|
// null parameter is passed in and there is no default
|
||||||
|
// value.
|
||||||
if (pins[idx] == 0) {
|
if (pins[idx] == 0) {
|
||||||
|
|
||||||
if (pins_fromwc[idx]) {
|
if (pins_fromwc[idx]) {
|
||||||
|
|
|
||||||
19
parse.y
19
parse.y
|
|
@ -4634,6 +4634,22 @@ port_declaration
|
||||||
delete[]$4;
|
delete[]$4;
|
||||||
$$ = ptmp;
|
$$ = ptmp;
|
||||||
}
|
}
|
||||||
|
| attribute_list_opt K_input net_type_opt data_type_or_implicit IDENTIFIER '=' expression
|
||||||
|
{ if (!gn_system_verilog()) {
|
||||||
|
yyerror("error: Default port values require SystemVerilog.");
|
||||||
|
}
|
||||||
|
Module::port_t*ptmp;
|
||||||
|
perm_string name = lex_strings.make($5);
|
||||||
|
data_type_t*use_type = $4;
|
||||||
|
ptmp = pform_module_port_reference(name, @2.text, @2.first_line);
|
||||||
|
ptmp->default_value = $7;
|
||||||
|
pform_module_define_port(@2, name, NetNet::PINPUT, $3, use_type, $1);
|
||||||
|
port_declaration_context.port_type = NetNet::PINPUT;
|
||||||
|
port_declaration_context.port_net_type = $3;
|
||||||
|
port_declaration_context.data_type = $4;
|
||||||
|
delete[]$5;
|
||||||
|
$$ = ptmp;
|
||||||
|
}
|
||||||
| attribute_list_opt K_inout net_type_opt data_type_or_implicit IDENTIFIER dimensions_opt
|
| attribute_list_opt K_inout net_type_opt data_type_or_implicit IDENTIFIER dimensions_opt
|
||||||
{ Module::port_t*ptmp;
|
{ Module::port_t*ptmp;
|
||||||
perm_string name = lex_strings.make($5);
|
perm_string name = lex_strings.make($5);
|
||||||
|
|
@ -5972,6 +5988,7 @@ port_reference
|
||||||
Module::port_t*ptmp = new Module::port_t;
|
Module::port_t*ptmp = new Module::port_t;
|
||||||
ptmp->name = perm_string();
|
ptmp->name = perm_string();
|
||||||
ptmp->expr.push_back(wtmp);
|
ptmp->expr.push_back(wtmp);
|
||||||
|
ptmp->default_value = 0;
|
||||||
|
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
$$ = ptmp;
|
$$ = ptmp;
|
||||||
|
|
@ -5995,6 +6012,7 @@ port_reference
|
||||||
Module::port_t*ptmp = new Module::port_t;
|
Module::port_t*ptmp = new Module::port_t;
|
||||||
ptmp->name = perm_string();
|
ptmp->name = perm_string();
|
||||||
ptmp->expr.push_back(tmp);
|
ptmp->expr.push_back(tmp);
|
||||||
|
ptmp->default_value = 0;
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
$$ = ptmp;
|
$$ = ptmp;
|
||||||
}
|
}
|
||||||
|
|
@ -6006,6 +6024,7 @@ port_reference
|
||||||
FILE_NAME(wtmp, @1);
|
FILE_NAME(wtmp, @1);
|
||||||
ptmp->name = lex_strings.make($1);
|
ptmp->name = lex_strings.make($1);
|
||||||
ptmp->expr.push_back(wtmp);
|
ptmp->expr.push_back(wtmp);
|
||||||
|
ptmp->default_value = 0;
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
$$ = ptmp;
|
$$ = ptmp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
pform.cc
1
pform.cc
|
|
@ -1394,6 +1394,7 @@ Module::port_t* pform_module_port_reference(perm_string name,
|
||||||
FILE_NAME(tmp, file, lineno);
|
FILE_NAME(tmp, file, lineno);
|
||||||
ptmp->name = name;
|
ptmp->name = name;
|
||||||
ptmp->expr.push_back(tmp);
|
ptmp->expr.push_back(tmp);
|
||||||
|
ptmp->default_value = 0;
|
||||||
|
|
||||||
return ptmp;
|
return ptmp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue