diff --git a/.gitignore b/.gitignore index 3a74b130a..387b4fc95 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,6 @@ work_vcom/ # Test artifacts myhdl/**/*.v myhdl/**/*.vhd + +# Pycharm ide junk +.idea/ diff --git a/myhdl/conversion/_VHDLNameValidation.py b/myhdl/conversion/_VHDLNameValidation.py new file mode 100644 index 000000000..28ab471ad --- /dev/null +++ b/myhdl/conversion/_VHDLNameValidation.py @@ -0,0 +1,47 @@ +import warnings +from myhdl import * +from myhdl import ToVHDLWarning +from myhdl.conversion import _analyze +import pytest + +#A list of all reserved words within VHDL which should not be used for +#anything other than their own specific purpose +_vhdl_keywords = ["abs", "access", "after", "alias", "all", + "and", "architecture", "array", "assert", + "attribute", "begin", "block", "body", "buffer", + "bus", "case", "component", "configuration", + "constant", "disconnect", "downto", "else", + "elseif", "end", "entity", "exit", "file", "for", + "function", "generate", "generic", "group", + "guarded", "if", "impure", "in", "inertial", + "inout", "is", "label", "library", "linkage", + "literal", "loop", "map", "mod", "nand", "new", + "next", "nor", "not", "null", "of", "on", "open", + "or", "others", "out", "package", "port", + "postponed", "procedure", "process", "pure", + "range", "record", "register", "reject", "rem", + "report", "return", "rol", "ror", "select", + "severity", "signal", "shared", "sla", "sll", "sra", + "srl", "subtype", "then", "to", "transport", "type", + "unaffected", "units", "until", "use", "variable", + "wait", "when", "while", "with", "xnor", "xor"]; + +#A list to hold all signal names being used in lowercase to raise an error +#if no names are reused with different casing +_usedNames = []; + +#Function which compares current parsed signal/entity to all keywords to +#ensure reserved words are not being used for the wrong purpose +def _nameValid(name): + for keyword in _vhdl_keywords: + if name == keyword: + warnings.warn("VHDL keyword used: %s" % (name), category=ToVHDLWarning) + for saved_name in _usedNames: + if name.lower() == saved_name: + warnings.warn("Previously used name being reused: %s" % (name), category=ToVHDLWarning) + _usedNames.append(name.lower()) + if name[0] == '_': + warnings.warn("VHDL variable names cannot contain '_': %s" % (name), category=ToVHDLWarning) + for char in name: + if char == '-': + warnings.warn("VHDL variable names cannot contain '-': %s" % (name), category=ToVHDLWarning) diff --git a/myhdl/conversion/_toVHDL.py b/myhdl/conversion/_toVHDL.py index 9f285d627..bd8acd151 100644 --- a/myhdl/conversion/_toVHDL.py +++ b/myhdl/conversion/_toVHDL.py @@ -55,6 +55,8 @@ from myhdl._util import _flatten from myhdl._compat import integer_types, class_types, StringIO from myhdl._ShadowSignal import _TristateSignal, _TristateDriver +from myhdl.conversion._VHDLNameValidation import _nameValid + from myhdl._block import _Block from myhdl._getHierarchy import _getHierarchy @@ -353,6 +355,8 @@ def _writeModuleHeader(f, intf, needPck, lib, arch, useClauses, doc, stdLogicPor pt = st = _getTypeString(s) if convertPort: pt = "std_logic_vector" + # Check if VHDL keyword or reused name + _nameValid(s._name) if s._driven: if s._read: if not isinstance(s, _TristateSignal): @@ -439,6 +443,8 @@ def _writeSigDecls(f, intf, siglist, memlist): print("signal %s: %s%s%s;" % (s._name, p, r, val_str), file=f) elif s._read: + # Check if VHDL keyword or reused name + _nameValid(s._name) # the original exception # raise ToVHDLError(_error.UndrivenSignal, s._name) # changed to a warning and a continuous assignment to a wire @@ -458,6 +464,8 @@ def _writeSigDecls(f, intf, siglist, memlist): m._read = s._read if not m._driven and not m._read: continue + # Check if VHDL keyword or reused name + _nameValid(m.name) r = _getRangeString(m.elObj) p = _getTypeString(m.elObj) t = "t_array_%s" % m.name