Skip to content

Commit

Permalink
Add support for new port bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
zhuanhao-wu committed Aug 12, 2023
1 parent 6b1d27e commit b687d5e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 12 deletions.
16 changes: 10 additions & 6 deletions plugins/hdl/parselib/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
| continuestmt
| hwait
| hslice
| portbinding
| hnamedsensvar
continuestmt: "hContinue" "NONAME" "NOLIST"
// hvarinitlist can be empty
Expand All @@ -78,7 +80,7 @@
?htobool: ("hBuiltinFunction" "to_bool" | "hNoop" "to_bool") "[" harrayref "]"
htouint: "hBuiltinFunction" "to_uint" "[" (syscread|hvarref|hslice) "]"
htoint: "hBuiltinFunction" "to_int" "[" (syscread|hvarref|hslice) "]"
htoint: "hBuiltinFunction" "to_int" "[" (syscread|hvarref|hslice|harrayref) "]"
htolong: "hBuiltinFunction" "to_long" "[" (syscread|hvarref|hslice) "]"
htoulong: "hBuiltinFunction" "to_ulong" "[" (syscread|hvarref|hslice) "]"
hnoop: "hNoop" "NONAME" "NOLIST"
Expand All @@ -94,11 +96,10 @@
// first component is the id of the module (in parent?)
// second component is initialization list
// third component is port binding list
hmodinitblock: "hModinitblock" ID "[" hcstmt* portbindinglist* hsenslist*"]"
hmodinitblock: "hModinitblock" ID "[" vardecl* hcstmt* hsenslist*"]"
| "hModinitblock" ID "NOLIST"
// Port Bindings
portbindinglist: "hPortbindings" ID "[" portbinding* "]"
portbindinglist: "hCStmt" "NONAME" "[" portbinding* "]"
// hPortbinding u_dut [
// hVarref avg_out NOLIST
// hVarref dut_avg NOLIST
Expand All @@ -108,11 +109,13 @@
| "hPortbinding" ID "[" hvarref hbindingref "]"
| "hPortbinding" ID "[" hbindingarrayref hbindingarrayref "]"
| "hPortbinding" ID "[" hvarref hbindingarrayref "]"
| "hPortbinding" ID "[" hfieldaccess (hvarref|hbinop) "]"
| "hPortbinding" ID "[" hbinop (hvarref|hbinop) "]"
// TODO: replace portbinding with succinct syntax
hbindingref: "hVarref" ID "[" hliteral "]"
// compared array ref in normal expressions
// we use a more restrictive form here
hbindingarrayref: "hBinop" "ARRAYSUBSCRIPT" "[" (hvarref|hbindingarrayref) (hliteral|hbinop) "]"
hbindingarrayref: "hBinop" "ARRAYSUBSCRIPT" "[" (hfieldaccess | hvarref|hbindingarrayref) (hvarref|hliteral|hbinop) "]"
// This is solely for maintaining the semicolon
Expand All @@ -125,7 +128,7 @@
dostmt: "hDoStmt" "NONAME" "[" expression stmt "]"
// for(forinit; forcond; forpostcond) stmts
forstmt: "hForStmt" "NONAME" "[" forinit forcond forpostcond forbody "]"
forstmt: "hForStmt" "NONAME" "[" forinit forcond forpostcond forbody? "]"
forinit: "hPortsigvarlist" "NONAME" "[" vardeclinit "]"
| vardeclinit
| hnoop
Expand Down Expand Up @@ -162,6 +165,7 @@
| "hSenslist" ID "NOLIST"
hsensvar : "hSensvar" "NONAME" "[" (hsensedge|expression|hvalchange) ("hNoop" | "hBuiltinFunction") npa "NOLIST" ("hNoop" npa "NOLIST")* "]"
| hasync
hnamedsensvar : "hSensvar" ID "[" (hsensedge|expression|hvalchange) ("hNoop" | "hBuiltinFunction") npa "NOLIST" ("hNoop" npa "NOLIST")* "]"
hasync : "hSensvar" "ASYNC" "[" expression hliteral "]"
hvalchange: "hNoop" "value_changed_event" "[" expression "]"
Expand Down
1 change: 0 additions & 1 deletion plugins/hdl/parselib/transforms/function_info_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,6 @@ def new_phantom_var_name(self, tpe):
return phantom_var

def __extract_name_from_method_args(self, arg_node, arg_tpe):
dprint(arg_node, arg_tpe)
if is_tree_type(arg_node, 'hvarref'):
return arg_node.children[0]
elif is_tree_types(arg_node, ['hliteral', 'hbinop', 'hmethodcall', 'syscread', 'hunop', 'hslice']):
Expand Down
20 changes: 18 additions & 2 deletions plugins/hdl/parselib/transforms/literal_expansion.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import warnings

import lark
from lark import Token

from parselib.transforms import TopDown
from ..utils import dprint, is_tree_type
from ..utils import dprint, is_tree_type, get_ids_in_tree
from ..grammar import UnexpectedHCodeStructureError


Expand All @@ -16,9 +17,24 @@ def __init__(self, structure):
self.port_binding_module = None
self.field_access = None

def _get_port_binding_moduel(self, tree):
"""
Get the name of the module that corresponds
to this port-binding
"""
if type(tree) == lark.Tree:
if tree.children[0] != 'NONAME':
res = str(self.structure[self.current_module][tree.children[0]])
else:
ids = get_ids_in_tree(tree)
res = str(self.structure[self.current_module][ids[0]])
else:
res = str(self.structure[self.current_module][tree.children[0]])
return res

def portbinding(self, tree):
self.is_port_binding = True
self.port_binding_module = str(self.structure[self.current_module][tree.children[0]])
self.port_binding_module = self._get_port_binding_moduel(tree)
self.__push_up(tree)
self.is_port_binding = False
self.port_binding_module = None
Expand Down
35 changes: 32 additions & 3 deletions plugins/hdl/parselib/transforms/verilog_tranlation.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __init__(self):
self.__current_scope_type = [None]
self.is_in_thread = False
self.thread_comb = False
self.non_thread_comb_signals = set()

def get_current_scope_type(self):
"""denotes one of four types of scope: loop, switch, branch, None
Expand Down Expand Up @@ -163,7 +164,14 @@ def blkassign(self, tree):
elif type(r) == Tree and r.data == 'harrayref':
r = r.children[3]

# FIXME: this handling of shared signal across thread/comb block should be fixed
if 'thread' not in current_proc and '#function#' not in current_proc:
self.non_thread_comb_signals.add(l)

res = '{} {} {}'.format(l, op, r)

if 'thread' in current_proc and l in self.non_thread_comb_signals:
res = ''
return res

def syscwrite(self, tree):
Expand Down Expand Up @@ -389,9 +397,17 @@ def f_concat(x):
if x[1].data == 'expression_in_stmt':
# logging.warning('Expression as a statement may not have an effect. On line: {}'.format(x[1].line))
x = (x[0], x[1].children[0], x[2])
res = str(x[0]) + str(x[1]) + str(x[2])
elif x[1].data == 'portbinding':
ch = x[1].children
assignment = f"{ch[0]}.{ch[1]} = {ch[2]}"
res = ''.join([x[0], assignment, x[2]])
elif x[1].data == 'hnamedsensvar':
res = f'{x[0]} /* always {x[1].children[1]} */ {x[2]}'
else:
assert False, 'Unrecognized construct: {}'.format(x[1])
res = str(x[0]) + str(x[1]) + str(x[2])
else:
res = ''.join(x)
return res
except Exception as e:
print(x[0])
Expand Down Expand Up @@ -505,7 +521,12 @@ def forstmt(self, tree):
new_children.extend(self.visit(t) for t in tree.children[3:])
self.dec_indent()

for_init, for_cond, for_post, for_body = new_children
if len(new_children) == 3:
warnings.warn("empty for loop")
for_init, for_cond, for_post = new_children
for_body = ''
else:
for_init, for_cond, for_post, for_body = new_children

ind = self.get_current_ind_prefix()
res = ind + 'for ({};{};{}) begin\n'.format(for_init, for_cond, for_post)
Expand Down Expand Up @@ -946,7 +967,11 @@ def __generate_hthread_block(self, tree, is_sync):
sense_list = self.get_sense_list()
assert thread_name in sense_list, "Process name {} is not in module {}".format(proc_name, self.current_module)
if is_sync:
res = ind + 'always @({}) begin: {}\n'.format(' or '.join(self.get_sense_list()[thread_name]), proc_name)
sense_list = self.get_sense_list()[thread_name]
if 'posedge clk' not in sense_list:
warnings.warn("Clock not detected in senstivity list, adding one by default")
sense_list = ['posedge clk'] + sense_list
res = ind + 'always @({}) begin: {}\n'.format(' or '.join(sense_list), proc_name)
else:
res = ind + 'always @(*) begin: {}\n'.format(proc_name)
self.inc_indent()
Expand Down Expand Up @@ -996,6 +1021,10 @@ def hmodule(self, tree):
portbindings = ch
elif ch.data == 'hsenslist':
senslist.append(ch)
elif ch.data == 'vardecl':
initblock = ch
elif ch.data == 'hnamedsensevar':
senslist.append(ch)
else:
raise ValueError(ch.pretty())
if initblock:
Expand Down

0 comments on commit b687d5e

Please sign in to comment.