20201. string type declarations - Comment out
21212. automatic keyword - Remove
22223. Assignment pattern syntax '{...} - Convert to compatible format
23+ 4. procedural logic declaration initialization - Split declaration and assignment
2324"""
2425
2526import re
2627import sys
2728import os
2829
30+ PROCEDURAL_START_RE = re .compile (r'^\s*(always(?:_\w+)?|initial|final)\b' )
31+ LOGIC_INIT_DECL_RE = re .compile (
32+ r'^(\s*)logic\s+'
33+ r'((?:signed\s+)?(?:\[[^\]]+\]\s*)*)'
34+ r'([A-Za-z_][A-Za-z0-9_$]*)'
35+ r'(\s*(?:\[[^\]]+\]\s*)*)'
36+ r'\s*=\s*(.*?);\s*(//.*)?$'
37+ )
38+
2939def preprocess_automatic_keyword (content ):
3040 """
3141 Remove automatic keyword (not supported by Yosys)
@@ -42,6 +52,58 @@ def preprocess_automatic_keyword(content):
4252
4353 return content
4454
55+ def preprocess_procedural_logic_initialization (content ):
56+ """
57+ Split initialized logic declarations inside procedural blocks.
58+
59+ Yosys accepts local declarations in procedural blocks, but rejects
60+ declaration-time initialization there.
61+
62+ Original:
63+ always_comb begin
64+ logic tmp = in_valid & in_ready;
65+ end
66+
67+ Converted:
68+ always_comb begin
69+ logic tmp;
70+ tmp = in_valid & in_ready;
71+ end
72+ """
73+ lines = content .splitlines ()
74+ result = []
75+ procedural_depth = 0
76+
77+ def count_keyword (line , keyword ):
78+ code = line .split ('//' , 1 )[0 ]
79+ return len (re .findall (rf'\b{ keyword } \b' , code ))
80+
81+ for line in lines :
82+ in_procedural = procedural_depth > 0
83+ match = LOGIC_INIT_DECL_RE .match (line ) if in_procedural else None
84+
85+ if match :
86+ indent , packed_dims , name , unpacked_dims , initializer , comment = match .groups ()
87+ packed_dims = ' ' .join (packed_dims .split ())
88+ unpacked_dims = '' .join (unpacked_dims .split ())
89+ dims = f' { packed_dims } ' if packed_dims else ''
90+ comment = f' { comment } ' if comment else ''
91+ result .append (f"{ indent } logic{ dims } { name } { unpacked_dims } ;" )
92+ result .append (f"{ indent } { name } = { initializer } ;{ comment } " )
93+ else :
94+ result .append (line )
95+
96+ begins = count_keyword (line , 'begin' )
97+ ends = count_keyword (line , 'end' )
98+ if PROCEDURAL_START_RE .match (line ):
99+ procedural_depth += max (begins - ends , 1 )
100+ elif procedural_depth > 0 :
101+ procedural_depth += begins - ends
102+ if procedural_depth < 0 :
103+ procedural_depth = 0
104+
105+ return '\n ' .join (result ) + ('\n ' if content .endswith ('\n ' ) else '' )
106+
45107def preprocess_string_type (content ):
46108 """
47109 Comment out string type declarations (not supported by Yosys)
@@ -137,6 +199,9 @@ def preprocess_file(input_file, output_file):
137199 # Remove automatic keyword
138200 content = preprocess_automatic_keyword (content )
139201
202+ # Split initialized procedural logic declarations
203+ content = preprocess_procedural_logic_initialization (content )
204+
140205 # Comment out string type declarations
141206 content = preprocess_string_type (content )
142207
0 commit comments