Skip to content

Commit

Permalink
fix in verilog parser to better support large multi-wire declaration …
Browse files Browse the repository at this point in the history
…lines
  • Loading branch information
jacobdbrown4 committed Oct 5, 2023
1 parent 46af114 commit dbc83ca
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 14 deletions.
43 changes: 29 additions & 14 deletions spydrnet/parsers/verilog/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ def parse_verilog(self):
if time_scale is not None:
self.current_definition["VERILOG.TimeScale"] = time_scale
if len(star_properties.keys()) > 0:
self.current_definition["VERILOG.InlineConstraints"] = star_properties
self.current_definition[
"VERILOG.InlineConstraints"
] = star_properties
star_properties = {}

elif token == vt.PRIMITIVE:
Expand Down Expand Up @@ -306,7 +308,9 @@ def parse_primitive_body(self):

while token != vt.END_MODULE and token != vt.END_PRIMITIVE:
token = self.peek_token()
if token == vt.FUNCTION: # these constructs may contain input output or inout
if (
token == vt.FUNCTION
): # these constructs may contain input output or inout
while token != vt.END_FUNCTION:
token = self.next_token()
elif token == vt.TASK: # these constructs may contain input output or inout
Expand Down Expand Up @@ -718,7 +722,18 @@ def parse_cable_declaration(self, properties, var_type=None):
"reg, tri1, tri0, or wire", "for cable declaration", token
)
var_type = token
self.parse_cable_declaration_helper(properties, var_type)

token = self.next_token()
while token == vt.COMMA:
self.parse_cable_declaration_helper({}, var_type)
token = self.next_token()

assert token == vt.SEMI_COLON, self.error_string(
vt.SEMI_COLON, "to end cable declaration", token
)

def parse_cable_declaration_helper(self, properties, var_type=None):
token = self.peek_token()
if token == vt.OPEN_BRACKET:
left, right = self.parse_brackets()
Expand All @@ -737,14 +752,6 @@ def parse_cable_declaration(self, properties, var_type=None):
)
cable["VERILOG.InlineConstraints"] = properties

token = self.next_token()
if token == vt.COMMA: # continue listing wires
self.parse_cable_declaration({}, var_type)
else:
assert token == vt.SEMI_COLON, self.error_string(
vt.SEMI_COLON, "to end cable declaration", token
)

def parse_instantiation(self, properties):
token = self.next_token()
assert vt.is_valid_identifier(token), self.error_string(
Expand Down Expand Up @@ -1040,7 +1047,9 @@ def connect_implicitly_mapped_ports(self):
cable, left, right = self.parse_variable_instantiation()
wires = self.get_wires_from_cable(cable, left, right)

if (index > len(port_list) - 1): # no port exists yet i.e. no module information in netlist
if (
index > len(port_list) - 1
): # no port exists yet i.e. no module information in netlist
# print("Not enough ports for "+ instance.name)
port = instance.reference.create_port()
self.populate_new_port(port, None, len(wires) - 1, 0, None)
Expand Down Expand Up @@ -1248,7 +1257,9 @@ def create_assignment_instance(self, width):
instance.reference = definition
return instance

def connect_wires_for_assign(self, l_cable, l_left, l_right, r_cable, r_left, r_right):
def connect_wires_for_assign(
self, l_cable, l_left, l_right, r_cable, r_left, r_right
):
"""connect the wires in r_left to the wires in l_left"""

out_wires = self.get_wires_from_cable(l_cable, l_left, l_right)
Expand Down Expand Up @@ -1420,7 +1431,9 @@ def create_or_update_cable(
in_upper = None
in_lower = None

if (defining and in_lower is not None): # if the cable width is being defined then recenter the cable
if (
defining and in_lower is not None
): # if the cable width is being defined then recenter the cable
cable.lower_index = in_lower
cable_lower = cable.lower_index
cable_upper = cable.lower_index + len(cable.wires) - 1
Expand Down Expand Up @@ -1524,7 +1537,9 @@ def create_or_update_port(
in_upper = None
in_lower = None

if (defining and in_lower is not None): # if the cable width is being defined then recenter the cable
if (
defining and in_lower is not None
): # if the cable width is being defined then recenter the cable
port.lower_index = in_lower
port_lower = port.lower_index
port_upper = port.lower_index + len(port.pins) - 1
Expand Down
30 changes: 30 additions & 0 deletions tests/spydrnet/parsers/verilog/tests/test_verilogParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1906,6 +1906,36 @@ def test_constant_parsing(self):
cable, _, _ = parser.parse_variable_instantiation()
self.assertEqual(cable.name, "\\<const1>", "Check const wire name")

def test_parse_multi_cable_declaration(self):
"""
make sure that parser can properly handle a line with a large number of
wire declarations
"""
parser = VerilogParser()
parser.current_definition = sdn.Definition()

wire_names = []
token_list = ["wire"]
i = 0
abc = list(x for x in "abcdefghijklmnopqrstuvwxyz")
for letter in abc:
for letter2 in abc:
for letter3 in abc:
name = letter + letter2 + letter3
token_list.append(name)
token_list.append(",")
wire_names.append(name)
i += 1
token_list.append("final")
token_list.append(";")
wire_names.append("final")

tokenizer = self.TestTokenizer(token_list)
parser.tokenizer = tokenizer
parser.parse_cable_declaration({})
cable_list = list(x for x in parser.current_definition.get_cables())
self.assertEqual(len(cable_list), i + 1)


if __name__ == "__main__":
unittest.main()

0 comments on commit dbc83ca

Please sign in to comment.