Merge pull request #613 from larsclausen/param-no-default
Support parameters without default value
This commit is contained in:
commit
3f048f266a
16
Module.cc
16
Module.cc
|
|
@ -139,3 +139,19 @@ PNamedItem::SymbolType Module::symbol_type() const
|
|||
|
||||
return MODULE;
|
||||
}
|
||||
|
||||
bool Module::can_be_toplevel() const
|
||||
{
|
||||
// Don't choose library modules.
|
||||
if (library_flag)
|
||||
return false;
|
||||
|
||||
// Don't choose modules with parameters without default value
|
||||
for (std::map<perm_string,param_expr_t*>::const_iterator cur =
|
||||
parameters.begin(); cur != parameters.end(); cur++) {
|
||||
if (cur->second->expr == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
2
Module.h
2
Module.h
|
|
@ -166,6 +166,8 @@ class Module : public PScopeExtra, public PNamedItem {
|
|||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
bool can_be_toplevel() const;
|
||||
|
||||
private:
|
||||
void dump_specparams_(std::ostream&out, unsigned indent) const;
|
||||
std::list<PGate*> gates_;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
// SystemVerilog allows parameters without default values in the parameter port
|
||||
// list. Check that this is supported. The test should fail in Verilog mode.
|
||||
|
||||
module a #(
|
||||
parameter A
|
||||
);
|
||||
|
||||
initial begin
|
||||
if (A == 1) begin
|
||||
$display("PASSED");
|
||||
end else begin
|
||||
$display("FAILED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
a #(.A(1)) i_a();
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Check that not providing a value during module instantiation for a parameter
|
||||
// without a default value generates an error.
|
||||
|
||||
module a #(
|
||||
parameter A
|
||||
);
|
||||
|
||||
initial begin
|
||||
$display("FAILED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
a i_a();
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Check that parameters without default values outside the parameter port list
|
||||
// generate an error.
|
||||
|
||||
module a;
|
||||
|
||||
parameter A;
|
||||
|
||||
initial begin
|
||||
$display("FAILED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
a #(.A(10)) i_a();
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// Check that modules with undefined parameters do not get picked as top-level
|
||||
// modules.
|
||||
|
||||
module a #(
|
||||
parameter A
|
||||
);
|
||||
initial $display("FAILED");
|
||||
endmodule
|
||||
|
||||
module b #(
|
||||
parameter B = 1
|
||||
);
|
||||
initial $display("PASSED");
|
||||
endmodule
|
||||
|
|
@ -78,6 +78,7 @@ br_gh567 normal ivltests
|
|||
check_constant_3 normal ivltests
|
||||
function4 normal ivltests
|
||||
parameter_in_generate1 normal ivltests
|
||||
parameter_no_default normal ivltests
|
||||
parameter_omit1 normal ivltests
|
||||
parameter_omit2 normal ivltests
|
||||
parameter_omit3 normal ivltests
|
||||
|
|
|
|||
|
|
@ -317,6 +317,10 @@ packeda normal,-g2009 ivltests
|
|||
packeda2 normal,-g2009 ivltests
|
||||
parameter_in_generate2 CE,-g2005-sv ivltests
|
||||
parameter_invalid_override CE,-g2005-sv ivltests gold=parameter_invalid_override.gold
|
||||
parameter_no_default CE,-g2005-sv ivltests
|
||||
parameter_no_default_fail1 CE ivltests
|
||||
parameter_no_default_fail2 CE ivltests
|
||||
parameter_no_default_toplvl normal,-g2005-sv ivltests
|
||||
parameter_type2 normal,-g2009 ivltests
|
||||
parpkg_test normal,-g2009 ivltests
|
||||
parpkg_test2 normal,-g2009 ivltests
|
||||
|
|
|
|||
|
|
@ -696,6 +696,7 @@ param_test4 normal ivltests
|
|||
param_times normal ivltests # param has multiplication.
|
||||
parameter_type normal ivltests gold=parameter_type.gold
|
||||
parameter_in_generate1 CE ivltests
|
||||
parameter_no_default CE ivltests
|
||||
parameter_omit1 CE ivltests
|
||||
parameter_omit2 CE ivltests
|
||||
parameter_omit3 CE ivltests
|
||||
|
|
|
|||
3
main.cc
3
main.cc
|
|
@ -1187,8 +1187,7 @@ int main(int argc, char*argv[])
|
|||
for (mod = pform_modules.begin()
|
||||
; mod != pform_modules.end() ; ++ mod ) {
|
||||
|
||||
/* Don't choose library modules. */
|
||||
if ((*mod).second->library_flag)
|
||||
if (!(*mod).second->can_be_toplevel())
|
||||
continue;
|
||||
|
||||
/* Don't choose modules instantiated in other
|
||||
|
|
|
|||
|
|
@ -827,9 +827,19 @@ void NetScope::evaluate_parameter_(Design*des, param_ref_t cur)
|
|||
}
|
||||
|
||||
// If the parameter has already been evaluated, quietly return.
|
||||
if (cur->second.val_expr == 0)
|
||||
if (cur->second.val != 0)
|
||||
return;
|
||||
|
||||
if (cur->second.val_expr == 0) {
|
||||
cerr << this->get_fileline() << ": error: "
|
||||
<< "Missing value for parameter `"
|
||||
<< cur->first << "`." << endl;
|
||||
des->errors += 1;
|
||||
|
||||
cur->second.val = new NetEConst(verinum(verinum::Vx));
|
||||
return;
|
||||
}
|
||||
|
||||
// Guess the varaiable type of the parameter. If the parameter has no
|
||||
// given type, then guess the type from the expression and use that to
|
||||
// evaluate.
|
||||
|
|
|
|||
13
parse.y
13
parse.y
|
|
@ -4901,7 +4901,11 @@ module_port_list_opt
|
|||
that the port declarations may use them. */
|
||||
module_parameter_port_list_opt
|
||||
:
|
||||
| '#' '(' module_parameter_port_list ')'
|
||||
| '#' '('
|
||||
{ pform_start_parameter_port_list(); }
|
||||
module_parameter_port_list
|
||||
{ pform_end_parameter_port_list(); }
|
||||
')'
|
||||
;
|
||||
|
||||
module_parameter
|
||||
|
|
@ -5580,7 +5584,12 @@ parameter_assign_list
|
|||
;
|
||||
|
||||
parameter_assign
|
||||
: IDENTIFIER '=' expression parameter_value_ranges_opt
|
||||
: IDENTIFIER parameter_value_ranges_opt
|
||||
{ pform_set_parameter(@1, lex_strings.make($1), param_is_local,
|
||||
param_data_type, 0, $2);
|
||||
delete[]$1;
|
||||
}
|
||||
| IDENTIFIER '=' expression parameter_value_ranges_opt
|
||||
{ PExpr*tmp = $3;
|
||||
pform_set_parameter(@1, lex_strings.make($1), param_is_local,
|
||||
param_data_type, tmp, $4);
|
||||
|
|
|
|||
25
pform.cc
25
pform.cc
|
|
@ -386,6 +386,9 @@ static unsigned pform_timescale_line;
|
|||
bool allow_timeunit_decl = true;
|
||||
bool allow_timeprec_decl = true;
|
||||
|
||||
// Track whether the current parameter declaration is in a parameter port list
|
||||
static bool pform_in_parameter_port_list = false;
|
||||
|
||||
static inline void FILE_NAME(LineInfo*obj, const char*file, unsigned lineno)
|
||||
{
|
||||
obj->set_lineno(lineno);
|
||||
|
|
@ -1378,6 +1381,16 @@ void pform_startmodule(const struct vlltype&loc, const char*name,
|
|||
pform_bind_attributes(cur_module->attributes, attr);
|
||||
}
|
||||
|
||||
void pform_start_parameter_port_list()
|
||||
{
|
||||
pform_in_parameter_port_list = true;
|
||||
}
|
||||
|
||||
void pform_end_parameter_port_list()
|
||||
{
|
||||
pform_in_parameter_port_list = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called by the parser to make a simple port
|
||||
* reference. This is a name without a .X(...), so the internal name
|
||||
|
|
@ -3228,6 +3241,17 @@ void pform_set_parameter(const struct vlltype&loc,
|
|||
return;
|
||||
}
|
||||
|
||||
if (expr == 0) {
|
||||
if (is_local) {
|
||||
VLerror(loc, "error: localparam must have a value.");
|
||||
} else if (!pform_in_parameter_port_list) {
|
||||
VLerror(loc, "error: parameter declared outside parameter "
|
||||
"port list must have a default value.");
|
||||
} else {
|
||||
pform_requires_sv(loc, "parameter without default value");
|
||||
}
|
||||
}
|
||||
|
||||
bool overridable = !is_local;
|
||||
|
||||
if (scope == pform_cur_generate && !is_local) {
|
||||
|
|
@ -3240,7 +3264,6 @@ void pform_set_parameter(const struct vlltype&loc,
|
|||
overridable = false;
|
||||
}
|
||||
|
||||
assert(expr);
|
||||
Module::param_expr_t*parm = new Module::param_expr_t();
|
||||
FILE_NAME(parm, loc);
|
||||
|
||||
|
|
|
|||
3
pform.h
3
pform.h
|
|
@ -614,4 +614,7 @@ void pform_put_enum_type_in_scope(enum_type_t*enum_set);
|
|||
|
||||
bool pform_requires_sv(const struct vlltype&loc, const char *feature);
|
||||
|
||||
void pform_start_parameter_port_list();
|
||||
void pform_end_parameter_port_list();
|
||||
|
||||
#endif /* IVL_pform_H */
|
||||
|
|
|
|||
|
|
@ -1485,11 +1485,9 @@ void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const
|
|||
cur->second->data_type->debug_dump(out);
|
||||
else
|
||||
out << "(nil type)";
|
||||
out << " " << (*cur).first << " = ";
|
||||
if ((*cur).second->expr)
|
||||
out << *(*cur).second->expr;
|
||||
else
|
||||
out << "/* ERROR */";
|
||||
out << " " << (*cur).first << " = "
|
||||
<< *(*cur).second->expr;
|
||||
for (LexicalScope::range_t*tmp = (*cur).second->range
|
||||
; tmp ; tmp = tmp->next) {
|
||||
if (tmp->exclude_flag)
|
||||
|
|
|
|||
Loading…
Reference in New Issue