Skip to content

Commit d845eea

Browse files
committed
Merge branch 'verilog-importer-fixes'
2 parents 17036a5 + 3cc141d commit d845eea

5 files changed

Lines changed: 130 additions & 76 deletions

File tree

Plugins/VerilogImport/VerilogParameterParser.cpp

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
namespace
3333
{
34-
const QRegularExpression TYPE_RULE("(\\w+)\\s+(?:(" + VerilogSyntax::RANGE + ")?\\s*(" +
34+
const QRegularExpression TYPE_RULE("(?:localparam|parameter)?\\s*((?:\\w|:)+\\s+)?((?:\\w|:)+)?\\s*(?:(" + VerilogSyntax::RANGE + ")?\\s*(" +
3535
VerilogSyntax::RANGE + "))?\\s*" + VerilogSyntax::NAME_VALUE, QRegularExpression::CaseInsensitiveOption);
3636
}
3737

@@ -63,12 +63,19 @@ void VerilogParameterParser::setHighlighter(Highlighter* highlighter)
6363
void VerilogParameterParser::import(QString const& componentDeclaration, QSharedPointer<Component> targetComponent,
6464
QSharedPointer<ComponentInstantiation> targetComponentInstantiation)
6565
{
66-
QStringList declarations = findDeclarations(componentDeclaration);
66+
auto declarations = findDeclarations(componentDeclaration);
6767

68-
QList<QSharedPointer<ModuleParameter> > parsedParameters;
69-
for (QString const& declaration : declarations)
68+
QList<QPair<QSharedPointer<ModuleParameter>, QString> > parsedParameters; // For mapping parameter type (localparam/parameter) to parsed parameter
69+
for (auto const& declaration : declarations)
7070
{
71-
parsedParameters.append(parseParameters(declaration));
71+
auto params = parseParameters(declaration.value_);
72+
73+
// In most cases size of params should be 1
74+
std::for_each(params.begin(), params.end(),
75+
[&declaration, &parsedParameters](QSharedPointer<ModuleParameter> moduleParam)
76+
{
77+
parsedParameters.append(std::make_pair(moduleParam, declaration.type_));
78+
});
7279
}
7380

7481
if (targetComponentInstantiation.isNull() == false)
@@ -90,7 +97,11 @@ void VerilogParameterParser::import(QString const& componentDeclaration, QShared
9097
}
9198
}
9299

93-
targetComponentInstantiation->getModuleParameters()->append(parsedParameters);
100+
std::for_each(parsedParameters.cbegin(), parsedParameters.cend(),
101+
[&targetComponentInstantiation](auto const& pair)
102+
{
103+
targetComponentInstantiation->getModuleParameters()->append(pair.first);
104+
});
94105
}
95106

96107
replaceNamesReferencesWithIds(parsedParameters, targetComponent, targetComponentInstantiation);
@@ -99,7 +110,8 @@ void VerilogParameterParser::import(QString const& componentDeclaration, QShared
99110
//-----------------------------------------------------------------------------
100111
// Function: VerilogParameterParser::findDeclarations()
101112
//-----------------------------------------------------------------------------
102-
QStringList VerilogParameterParser::findDeclarations(QString const& input)
113+
// QStringList VerilogParameterParser::findDeclarations(QString const& input)
114+
QList<VerilogParameterParser::ParameterDeclaration> VerilogParameterParser::findDeclarations(QString const& input)
103115
{
104116
return findParameterDeclarations(input, findParameterSection(input));
105117
}
@@ -146,6 +158,15 @@ QList<QSharedPointer<ModuleParameter> > VerilogParameterParser::parseParameters(
146158

147159
// Find the type and the declaration. Only one per declaration is supported.
148160
QString type = parseType(input);
161+
QString typeWithModifier = type;
162+
QString signingModifier = TYPE_RULE.match(input).captured(2);
163+
164+
// Create complete type if there is a sign modifier
165+
if (QRegularExpression("(signed|unsigned)").match(signingModifier.toLower()).hasMatch())
166+
{
167+
typeWithModifier.append(QStringLiteral(" ") % signingModifier); // e.g. int unsigned
168+
}
169+
149170
QString bitWidthLeft = parseBitWidthLeft(input);
150171
QString bitWidthRight = parseBitWidthRight(input);
151172
QString arrayLeft = parseArrayLeft(input);
@@ -156,7 +177,7 @@ QList<QSharedPointer<ModuleParameter> > VerilogParameterParser::parseParameters(
156177
inputWithoutComments.remove(QRegularExpression(VerilogSyntax::COMMENT));
157178

158179
QString parameterDefinition = "(" + VerilogSyntax::NAMES + ")\\s*=((\\s*(" +
159-
VerilogSyntax::OPERATION_OR_ALPHANUMERIC + ")+\\s*)+)";
180+
VerilogSyntax::PARAMETER_VALUE + ")+\\s*)+)";
160181

161182
QRegularExpression parameterRule(parameterDefinition + "(\\s*,\\s*" + parameterDefinition + ")*",
162183
QRegularExpression::CaseInsensitiveOption);
@@ -177,7 +198,7 @@ QList<QSharedPointer<ModuleParameter> > VerilogParameterParser::parseParameters(
177198
// Each name value pair produces a new module parameter, but the type and the description is recycled.
178199
QSharedPointer<ModuleParameter> moduleParameter = QSharedPointer<ModuleParameter>(new ModuleParameter());
179200
moduleParameter->setName(name);
180-
moduleParameter->setDataType(type);
201+
moduleParameter->setDataType(typeWithModifier);
181202
moduleParameter->setType(createTypeFromDataType(type));
182203
moduleParameter->setValue(value);
183204
moduleParameter->setUsageType("nontyped");
@@ -211,39 +232,41 @@ QString VerilogParameterParser::createTypeFromDataType(QString const& dataType)
211232
//-----------------------------------------------------------------------------
212233
// Function: VerilogParameterParser::findDeclarations()
213234
//-----------------------------------------------------------------------------
214-
QStringList VerilogParameterParser::findParameterDeclarations(QString const& componentDeclaration,
235+
// QStringList VerilogParameterParser::findParameterDeclarations(QString const& componentDeclaration,
236+
QList<VerilogParameterParser::ParameterDeclaration > VerilogParameterParser::findParameterDeclarations(QString const& componentDeclaration,
215237
QString const& parameterArea)
216238
{
217239
// List of detected parameter declarations.
218-
QStringList declarations;
240+
QList<ParameterDeclaration> declarations;
219241

220242
// Rule used to detect parameter declarations.
221-
QRegularExpression declarationRule("\\bparameter\\s+.*(?:"
243+
QRegularExpression declarationRule("\\b(localparam|parameter)\\s+.*(?:"
222244
"(;[ \\t]*" + VerilogSyntax::COMMENT + ")|"
223245
"(;|$)|"
224-
"(,([ \\t]*" + VerilogSyntax::COMMENT +")?(?=\\s*\\bparameter\\b)))",
246+
"(,([ \\t]*" + VerilogSyntax::COMMENT +")?(?=\\s*\\b(?:localparam|parameter)\\b)))",
225247
QRegularExpression::CaseInsensitiveOption | QRegularExpression::InvertedGreedinessOption |
226248
QRegularExpression::DotMatchesEverythingOption);
227-
249+
228250
QRegularExpression commentBegin(QStringLiteral("//"));
229251
QRegularExpression lineBegin(QStringLiteral("^|\\r?\\n"));
230252

231253
QRegularExpressionMatchIterator iter = declarationRule.globalMatch(parameterArea);
232254
while (iter.hasNext())
233255
{
234256
QRegularExpressionMatch match = iter.next();
235-
QString declaration = match.captured();
257+
auto fullDeclaration = match.captured();
258+
auto paramType = match.captured(1); // get the param type: localparam or parameter
236259
int declarationBegin = match.capturedStart();
237260

238261
// Check keyword parameter is not inside a comment.
239262
if (parameterArea.lastIndexOf(lineBegin, declarationBegin) > parameterArea.lastIndexOf(commentBegin, declarationBegin))
240263
{
241264
if (highlighter_)
242265
{
243-
highlighter_->applyHighlight(declaration, KactusColors::Importer::MODELPARAMETER, componentDeclaration);
266+
highlighter_->applyHighlight(fullDeclaration, KactusColors::Importer::MODELPARAMETER, componentDeclaration);
244267
}
245268

246-
declarations.append(declaration);
269+
declarations.append(ParameterDeclaration{paramType, fullDeclaration});
247270
}
248271
}
249272

@@ -270,7 +293,7 @@ QString VerilogParameterParser::parseType(QString const& input)
270293
//-----------------------------------------------------------------------------
271294
QString VerilogParameterParser::parseBitWidthLeft(QString const& declaration)
272295
{
273-
QString bitRange = TYPE_RULE.match(declaration).captured(3);
296+
QString bitRange = TYPE_RULE.match(declaration).captured(4);
274297

275298
QRegularExpressionMatch rangeMatch = VerilogSyntax::CAPTURING_RANGE.match(bitRange);
276299
QString left = rangeMatch.captured(1);
@@ -283,7 +306,7 @@ QString VerilogParameterParser::parseBitWidthLeft(QString const& declaration)
283306
//-----------------------------------------------------------------------------
284307
QString VerilogParameterParser::parseBitWidthRight(QString const& declaration)
285308
{
286-
QString bitRange = TYPE_RULE.match(declaration).captured(3);
309+
QString bitRange = TYPE_RULE.match(declaration).captured(4);
287310

288311
QRegularExpressionMatch rangeMatch = VerilogSyntax::CAPTURING_RANGE.match(bitRange);
289312
QString right = rangeMatch.captured(2);
@@ -296,7 +319,7 @@ QString VerilogParameterParser::parseBitWidthRight(QString const& declaration)
296319
//-----------------------------------------------------------------------------
297320
QString VerilogParameterParser::parseArrayLeft(QString const& declaration)
298321
{
299-
QString bitRange = TYPE_RULE.match(declaration).captured(2);
322+
QString bitRange = TYPE_RULE.match(declaration).captured(3);
300323

301324
return VerilogSyntax::CAPTURING_RANGE.match(bitRange).captured(1);
302325
}
@@ -306,7 +329,7 @@ QString VerilogParameterParser::parseArrayLeft(QString const& declaration)
306329
//-----------------------------------------------------------------------------
307330
QString VerilogParameterParser::parseArrayRight(QString const& declaration)
308331
{
309-
QString bitRange = TYPE_RULE.match(declaration).captured(2);
332+
QString bitRange = TYPE_RULE.match(declaration).captured(3);
310333

311334
return VerilogSyntax::CAPTURING_RANGE.match(bitRange).captured(2);
312335
}
@@ -345,10 +368,10 @@ QString VerilogParameterParser::parseDescription(QString const& input)
345368
//-----------------------------------------------------------------------------
346369
// Function: VerilogParameterParser::copyIdsFromOldModelParameters()
347370
//-----------------------------------------------------------------------------
348-
void VerilogParameterParser::copyIdsFromOldModelParameters(QList<QSharedPointer<ModuleParameter> > parsedParameters,
371+
void VerilogParameterParser::copyIdsFromOldModelParameters(QList<QPair<QSharedPointer<ModuleParameter>, QString> > parsedParameters,
349372
QSharedPointer<ComponentInstantiation> targetComponentInstantiation)
350373
{
351-
for (QSharedPointer<ModuleParameter> parameter : parsedParameters)
374+
for (auto const& [parameter, type] : parsedParameters)
352375
{
353376
for (QSharedPointer<ModuleParameter> existingParameter :
354377
*targetComponentInstantiation->getModuleParameters())
@@ -366,14 +389,14 @@ void VerilogParameterParser::copyIdsFromOldModelParameters(QList<QSharedPointer<
366389
// Function: VerilogParameterParser::replaceReferenceNamesWithIds()
367390
//-----------------------------------------------------------------------------
368391
void VerilogParameterParser::replaceNamesReferencesWithIds(
369-
QList<QSharedPointer<ModuleParameter> > parsedParameters,
392+
QList<QPair<QSharedPointer<ModuleParameter>, QString> > const& parsedParameters,
370393
QSharedPointer<Component> targetComponent,
371394
QSharedPointer<ComponentInstantiation> targetComponentInstantiation)
372395
{
373-
for (QSharedPointer<ModuleParameter> moduleParameter : parsedParameters)
396+
for (auto const& [moduleParameter, type] : parsedParameters)
374397
{
375398
QSharedPointer<Parameter> targetParameter =
376-
Search::findByName(moduleParameter->name(), *targetComponent->getParameters());
399+
Search::findByName(moduleParameter->name(), *targetComponent->getParameters());
377400

378401
if (targetParameter.isNull())
379402
{
@@ -391,6 +414,12 @@ void VerilogParameterParser::replaceNamesReferencesWithIds(
391414
targetParameter->setDescription(moduleParameter->description());
392415
targetParameter->increaseUsageCount();
393416

417+
if (type.compare(QStringLiteral("localparam")) == 0)
418+
{
419+
targetParameter->setValueResolve(QStringLiteral("immediate"));
420+
moduleParameter->setValueResolve(QStringLiteral("immediate"));
421+
}
422+
394423
moduleParameter->setValue(targetParameter->getValueId());
395424
}
396425

@@ -416,7 +445,7 @@ void VerilogParameterParser::replaceNameReferencesWithParameterIds(QSharedPointe
416445
{
417446
foreach (QSharedPointer<Parameter> define, *targetComponent->getParameters())
418447
{
419-
QRegularExpression macroUsage("`?" + define->name() + "\\b");
448+
QRegularExpression macroUsage("`?" + define->name() + "(?![\\._])"); // don't match systemverilog struct field accesses, e.g MyStruct.field, and other things that can cause partial match
420449

421450
QString parameterValue = replaceNameWithId(parameter->getValue(), macroUsage, define);
422451
parameter->setValue(parameterValue);

Plugins/VerilogImport/VerilogParameterParser.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ class VerilogParameterParser : public HighlightSource
3131
{
3232
public:
3333

34+
//! Describes a single (system)verilog module parameter declaration found in module
35+
struct ParameterDeclaration
36+
{
37+
QString type_; // parameter or localparam
38+
QString value_;
39+
};
40+
3441
//! The constructor.
3542
VerilogParameterParser();
3643

@@ -65,7 +72,7 @@ class VerilogParameterParser : public HighlightSource
6572
*
6673
* @return The resulting list of parameter declarations.
6774
*/
68-
QStringList findDeclarations(QString const& input);
75+
QList<ParameterDeclaration> findDeclarations(QString const& input);
6976

7077
/*!
7178
* Parses parameters out of declaration.
@@ -95,7 +102,8 @@ class VerilogParameterParser : public HighlightSource
95102
*
96103
* @return The resulting list of declarations.
97104
*/
98-
QStringList findParameterDeclarations(QString const& componentDeclaration, QString const& parameterArea);
105+
// QStringList findParameterDeclarations(QString const& componentDeclaration, QString const& parameterArea);
106+
QList<ParameterDeclaration> findParameterDeclarations(QString const& componentDeclaration, QString const& parameterArea);
99107

100108
/*!
101109
* Create an IP-XACT type for the parameter according to the given data type.
@@ -166,15 +174,15 @@ class VerilogParameterParser : public HighlightSource
166174
* @param [in] parsedParameters The parsed model parameters.
167175
* @param [in] targetComponent The component to import to.
168176
*/
169-
void copyIdsFromOldModelParameters(QList<QSharedPointer<ModuleParameter> > parsedParameters,
177+
void copyIdsFromOldModelParameters(QList<QPair<QSharedPointer<ModuleParameter>, QString> > parsedParameters,
170178
QSharedPointer<ComponentInstantiation> targetComponentInstantiation);
171179

172180
/*!
173181
* Replaces the referenced model parameter names with their ids in model parameter values.
174182
*
175183
* @param [in] targetComponent The component whose model parameter values to replace.
176184
*/
177-
void replaceNamesReferencesWithIds(QList<QSharedPointer<ModuleParameter> > parsedParameters,
185+
void replaceNamesReferencesWithIds(QList<QPair<QSharedPointer<ModuleParameter>, QString> > const& parsedParameters,
178186
QSharedPointer<Component> targetComponent,
179187
QSharedPointer<ComponentInstantiation> targetComponentInstantiation);
180188

Plugins/VerilogImport/VerilogPortParser.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ namespace
6363
"(" + VerilogSyntax::NAMES + ")\\s*[;](?:[ \\t]*"+ VerilogSyntax::COMMENT + ")?");
6464

6565
//! Declaration for verilog parameters.
66-
const QString MODULE_PARAMETER_DECLARATION("\\s*#\\((\\s*parameter.*)+\\s*\\)");
66+
const QString MODULE_PARAMETER_DECLARATION("\\s*#\\(([\\s\\S]*?)\\)"); // just match the parameter list section, not the stuff inside (allow e.g. system verilog localparams)
6767

6868
//! Port declaration for Verilog-1995 style.
6969
const QString PORT_DECLARATION_1995("\\((\\s*\\w*,)*\\s*\\w+\\s*\\);");
@@ -75,13 +75,13 @@ namespace
7575
const QString DECLARATION_1995(MODULE_AND_PARAMETERS_DECLARATION + PORT_DECLARATION_1995);
7676

7777
//! Modified module declaration for use in checking ports
78-
const QString NEW_MODULE_DECLARATION("(?:^|\\r?\\n)[ \t]*(?:macro)?module\\s*\\w*");
78+
const QString NEW_MODULE_DECLARATION("(?:^|\\r?\\n)[ \t]*(?:macro)?module\\s+\\w+");
7979

8080
//! Everything after module and parameter declaration.
8181
const QString MODULE_DECLARATION_REST("\\s*\\([^;]*");
8282

8383
//! Full declaration of a verilog module.
84-
const QString FULL_MODULE_DECLARATION(NEW_MODULE_DECLARATION + "(" + MODULE_PARAMETER_DECLARATION + ")?" + MODULE_DECLARATION_REST);
84+
const QString FULL_MODULE_DECLARATION(NEW_MODULE_DECLARATION + "(" + MODULE_PARAMETER_DECLARATION + ")?" + MODULE_DECLARATION_REST);
8585
}
8686

8787
//-----------------------------------------------------------------------------

Plugins/VerilogImport/VerilogSyntax.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ namespace VerilogSyntax
5757

5858
//! An expression that may contain an operator or an alphanumeric symbol.
5959
const QString OPERATION_OR_ALPHANUMERIC("({[^}]*})|([$<>+*\\(\\)\\{\\}/-])|([']?[{(])|(`?\\w+)|((\\w+)?'\\w+)|\"\\w+\"");
60-
60+
61+
//! Expression for parameter value, accepts systemverilog style types with class scope (operator ::) and struct accessor (operator ., e.g. mystruct.var)
62+
const QString PARAMETER_VALUE("({[^}]*})|([$<>+*\\(\\)\\{\\}/-])|([']?[{(])|((\\w+)?'\\w+)|\"\\w+\"|(`?(?:\\d+|[A-Za-z_]\\w*(?:(?:::|.)[A-Za-z_]\\w*)*))");
63+
6164
//! Name + value pair, e.g. name=value.
6265
const QString NAME_VALUE = "\\w+\\s*=(\\s*(" + OPERATION_OR_ALPHANUMERIC + "))+";
6366

0 commit comments

Comments
 (0)