2from .top_down
import TopDown
3from ..primitives
import *
4from ..utils
import dprint, is_tree_type, get_ids_in_tree
5from ..utils
import terminate_with_no_trace
6from ..utils
import ContextManager
7from lark
import Tree, Token
8from functools
import reduce
11from .interface_generation
import Interface, PortDecl
16interface_inst_arg =
''
17port_decl_inst_arg =
''
26 """Translate low-level format of the _hdl.txt into Verilog
27 Note that type defs are already expanded at this point, so all htypeinfo/htype should only include primitive types
28 This pass does not perform any tree transformation that alters the semantics, but **only** generates Verilog
50 """denotes one of four types of scope: loop, switch, branch, None
51 currently, this is only useful for determine the handling of breaks
56 assert scope
in [
'loop',
'switch',
'branch'],
'Incorrect scope type'
64 return '\n'.join(tree.children)
67 itf_name = tree.children[0]
68 port_decls = tree.children[1:]
69 res = f
'{self.get_current_ind_prefix()}{interface_arg}interface {itf_name};\n'
72 for port_decl
in port_decls:
74 name, *args = port_decl.type.children
75 tpe = Primitive.get_primitive(name)
76 assert tpe
is not None,
'Type {} is not defined'.format(name)
78 if isinstance(tx, array):
80 type_signature = tx.to_str(port_decl.name)
82 type_signature = tx.T.to_str(port_decl.name)
83 res += f
'{self.get_current_ind_prefix()}{type_signature}\n'
87 for port_decl
in port_decls:
88 p: PortDecl = port_decl
89 if p.direction ==
'input':
90 in_names.append(p.name)
91 elif p.direction ==
'output':
92 out_names.append(p.name)
93 modport = f
'{self.get_current_ind_prefix()}modport port0(\n'
95 modport += f
'{self.get_current_ind_prefix()}input {",".join(in_names)},\n'
96 modport += f
'{self.get_current_ind_prefix()}output {",".join(out_names)}\n'
98 modport += f
'{self.get_current_ind_prefix()});\n'
102 res += f
'{self.get_current_ind_prefix()}endinterface\n'
106 dprint(tree.pretty())
108 return tree.children[0]
112 res =
'\n'.join(tree.children)
117 assert len(tree.children) == 1
118 return tree.children[0]
121 if isinstance(tree, str):
123 elif isinstance(tree, Tree):
124 if tree.data
in [
'hvarref']:
125 return tree.children[0]
126 elif tree.data
in [
'harrayref',
'hslice']:
128 assert False,
'Cannot extract variable name from {}'.format(tree)
131 """return a list of variable names"""
132 if isinstance(tree, Tree)
and tree.data
in [
'hconcat']:
133 return reduce(
lambda x, y: x + y, [self.
__get_var_names(sub)
for sub
in tree.children])
139 with self.
ctx.add_values(is_in_hmethodcall=
True):
142 if tree.children[0] ==
'zhw__plane_reg2__plane_reg_func_0':
143 return f
'// TODO: fix this function call {tree.children}';
144 return '{}({})'.format(tree.children[0],
','.join(map(str, tree.children[1:])))
147 warnings.warn(
'hwait encountered, not implemented')
152 return '{' +
','.join(tree.children) +
'}'
164 isinstance(vn, Token)
and vn.type ==
'INTF_ID'
168 all_none = all(t
is None for t
in tpes)
170 t
is not None or is_intf[i]
for i, t
in enumerate(tpes)
172 assert len(is_intf) == len(tpes)
173 if not all_none
and not all_non_none:
174 raise ValueError(
'LHS of assignment must be all local variables or all non-local variables. On line: {}.'.format(tree.line))
175 is_nb = [isinstance(tpe, sc_signal)
or
176 isinstance(tpe, sc_out)
or
177 isinstance(tpe, array)
and isinstance(tpe.get_element_type(), sc_signal)
for tpe
in tpes]
180 is_nb[i]
or is_intf[i]
for i
in range(len(is_nb))
184 all_nb = all(is_nb)
or current_proc
in [
'#thread_sync#']
185 all_b = all(
not p
for p
in is_nb)
or (self.
is_in_thread and current_proc
in [
'#function#'])
186 if not all_nb
and not all_b:
187 raise ValueError(
'The assignment must not mix blocking assignment and non-blocking assignment. On line: {}.'.format(tree.line))
199 if current_proc
in sense_list
or (current_proc
in [
'#function#',
'#thread_sync#']
and not (self.
is_in_thread and current_proc ==
'#function#')):
214 assert len(tree.children) == 2
216 op =
'=' if self.
in_for_init or blocking
or is_local_var
else '<='
221 if type(l) == Tree
and l.data ==
'harrayref':
227 if type(r) == Tree
and r.data ==
'harrayref':
233 r =
"(({} & ~(~($bits({})'('b0)) << (({})-({})+1))) << ({})) | (({}) & ((~($bits({})'('b0)) ) << (({}) + 1) | ~(( ~($bits({})'('b0)) ) << ({}))))".format(
239 elif type(r) == Tree
and r.data ==
'harrayref':
243 if (current_proc
is None)
or (
'thread' not in current_proc
and '#function#' not in current_proc):
246 res =
'{} {} {}'.format(l, op, r)
253 raise RuntimeError(
'Unsupported node: syscwrite')
255 res =
'{} {} {}'.format(tree.children[1], tree.children[0], tree.children[2])
261 lit, tpe = tree.children
262 assert hasattr(tpe,
'width'),
'Literal width type should have width member'
264 return "{}{}'d{}".format(
'-' if lit < 0
else '', w, abs(lit))
268 return '{} ? {} : {}'.format(tree.children[0], tree.children[1], tree.children[2])
271 """stops at literal, it is some kinds of terminal"""
273 assert len(tree.children) == 1
274 return str(tree.children[0])
277 assert len(tree.children) == 1
278 if is_tree_type(tree.children[0],
'func_param_name_stub'):
279 return tree.children[0].children[0]
280 stripped = tree.children[0].replace(
"#",
"")
284 """syscread: hsigassignr, token"""
286 return tree.children[1]
289 """check whether the tree valuates to constant"""
290 if isinstance(tree, int):
292 elif is_tree_type(tree,
'hliteral'):
294 elif is_tree_type(tree,
'hbinop'):
299 assert harrayref_node.data ==
'harrayref'
300 if is_tree_type(harrayref_node.children[0],
'hsigassignr'):
302 harrayref_node.children = harrayref_node.children[1:]
310 if isinstance(tree.children[0], Tree)
and tree.children[0].data ==
'hslice':
311 if len(tree.children[0].children) == 3:
312 hslice = tree.children[0]
313 l, r = hslice.children[1:]
318 if isinstance(tree.children[0], Tree)
and tree.children[0].data ==
'hslice':
319 hslice = tree.children[0]
320 var = hslice.children[0]
322 if len(hslice.children) == 3:
323 l, r = hslice.children[1:]
324 elif len(hslice.children) == 2:
325 m = hslice.children[1]
328 if l_const
and r_const:
329 idx =
'{}:{}'.format(l, r)
334 tree.children = [var, l, r,
"(({}) >> ({})) & ~(~($bits({})'('b0)) << (({}) - ({}) + 1))".format(var, r, var, l, r)]
337 var, idx = tree.children
338 res =
'{}[{}]'.format(var, idx)
342 warnings.warn(
'Implementing SigAssignL as non-blocking')
352 method_call_lhs = is_tree_type(tree.children[1],
'hmethodcall')
354 if tree.children[0] ==
'ARRAYSUBSCRIPT':
355 res =
'{}[({})]'.format(tree.children[1], tree.children[2])
358 if self.
ctx.is_in_hmethodcall:
360 res =
'{} & (1 << {})'.format(tree.children[1], tree.children[2])
362 op = tree.children[0]
367 res =
'{{({}), ({})}}'.format(tree.children[1], tree.children[2])
369 res =
'({}) {} ({})'.format(tree.children[1],
'>>>', tree.children[2])
371 res =
'{{ ({}) {} ({}) }}'.format(tree.children[1],
',', tree.children[2])
373 res =
'{} <= ({})'.format(tree.children[1], tree.children[2])
375 res =
'({}) {} ({})'.format(tree.children[1], op, tree.children[2])
380 return "{}{}".format(tree.children[1], tree.children[0])
384 return "{}{}".format(tree.children[0], tree.children[1])
388 if len(tree.children) == 1:
389 return tree.children[0]
390 elif len(tree.children) == 2:
391 res =
'{}({})'.format(tree.children[0], tree.children[1])
408 assert len(tree.children) <= 1,
"hcstmt should contain 0 or 1 child"
410 return tree.children[0]
423 return tree.children[0]
429 return '\n'.join(tree.children)
436 res =
'{}{}: begin\n{}\n{}end'.format(ind, tree.children[0],
'\n'.join(tree.children[1:]), ind)
441 return tree.children[0]
448 res =
'{}case({})\n{}\n{}endcase'.format(ind, tree.children[0], tree.children[1], ind)
456 res =
'{}break;'.format(ind)
462 noindent = [
'hcstmt',
'ifstmt',
'forstmt',
'switchstmt',
'casestmt',
'breakstmt',
'whilestmt',
'dostmt']
463 nosemico = [
'hcstmt',
'ifstmt',
'forstmt',
'switchstmt',
'casestmt',
'breakstmt',
'whilestmt',
'dostmt']
464 for x
in tree.children:
467 if x.data
in noindent:
468 indentation.append(
'')
471 if x.data
in nosemico:
479 if isinstance(x[1], Tree):
480 if x[1].data ==
'expression_in_stmt':
482 x = (x[0], x[1].children[0], x[2])
483 res = str(x[0]) + str(x[1]) + str(x[2])
484 elif x[1].data ==
'portbinding':
486 if hasattr(x[1],
'swap_for_for_loop'):
489 if 'NONAME' in ch[0]:
490 dot_access =
'' if 'NONAME' in ch[0]
else (ch[0] +
'.')
493 interface_name = Interface.generate_instance_name(module_name,
False)
494 dot_access =
'{}.'.format(interface_name)
495 assignment = f
"assign {ch[1]} = {dot_access}{ch[2]}"
504 if 'NONAME' in ch[0]:
505 dot_access =
'' if 'NONAME' in ch[0]
else (ch[0] +
'.')
508 interface_name = Interface.generate_instance_name(module_name,
False)
509 dot_access =
'{}.'.format(interface_name)
511 assignment = f
"{ind}assign {dot_access}{ch[1]} = {ch[2]}"
512 res =
''.join([x[0], assignment, x[2]])
513 elif x[1].data ==
'hnamedsensvar':
514 res = f
'{x[0]} /* always {x[1].children[1]} */ {x[2]}'
516 assert False,
'Unrecognized construct: {}'.format(x[1])
520 except Exception
as e:
525 res =
'\n'.join(map(f_concat,
526 filter(
lambda x: x[1]
is not None, zip(indentation, tree.children, sep))
531 warnings.warn(
'Encountered noop at line: {}'.format(tree.meta.line))
540 res =
"{}while({}) begin\n".format(prefix, tree.children[0])
541 res +=
''.join(tree.children[1:])
542 res +=
'\n{}end'.format(prefix)
553 res =
"{}do begin\n".format(prefix)
554 res +=
''.join(tree.children[1:])
555 res +=
'\n{}end while({})'.format(prefix, tree.children[0])
562 res =
'\n'.join(tree.children)
572 """used to service temporary indent removal, such as that in for condition"""
584 res = ind +
'if ({}) begin\n'.format(tree.children[0])
585 if len(tree.children) > 1:
586 res += tree.children[1] +
'\n'
589 if len(tree.children) == 3:
590 res +=
' else begin\n' + tree.children[2]
604 return tree.children[0]
610 return tree.children[0]
614 return tree.children[0]
618 return tree.children[0]
627 new_children.extend(self.visit(t)
for t
in tree.children[:3])
631 new_children.extend(self.visit(t)
for t
in tree.children[3:])
634 if len(new_children) == 3:
635 warnings.warn(
"empty for loop")
636 for_init, for_cond, for_post = new_children
639 for_init, for_cond, for_post, for_body = new_children
642 res = ind +
'for ({};{};{}) begin\n'.format(for_init, for_cond, for_post)
643 res += for_body +
'\n'
653 return tree.children[0]
657 return tree.children[0]
664 proc_name = tree.children[0]
667 for sv
in tree.children[1:]:
669 sens_var, sens_edge = sv.children
670 if is_tree_type(sv.children[0],
"hsensvar"):
671 warnings.warn(
"Malformatted sensitivity list")
672 sens_edge, sens_var = sv.children[0].children
673 if sens_edge ==
'posedge_event':
675 elif sens_edge ==
'negedge_event':
679 sen_str =
'{} {}'.format(edge, sens_var)
681 if isinstance(sens_var, Token):
682 sens_var = sens_var.value
683 if sens_edge ==
'always':
685 elif sens_edge
in [
'pos',
'posedge_event']:
686 sen_str =
'posedge {}'.format(sens_var)
687 elif sens_edge
in [
'neg',
'negedge_event']:
688 sen_str =
'negedge {}'.format(sens_var)
690 raise ValueError(
'Edge can only be one of pos/neg/always')
695 warnings.warn(
'value change is deprecated, but is detected in hcode', DeprecationWarning)
697 return tree.children[0]
709 return any(
'posedge' in x
or 'negedge' in x
for x
in sense_list)
712 proc_name, proc_name_2, prevardecl, *body = tree.children
715 for n
in prevardecl.children:
716 var_name = n.children[0].children[0]
720 if hasattr(tree,
'force_sensevar'):
721 tree.children = [tree.force_sensevar] + tree.children
723 if hasattr(tree,
'force_sensevar'):
724 tree.force_sensevar = tree.children[0]
725 tree.children = tree.children[1:]
728 proc_name, proc_name_2, prevardecl, *body = tree.children
730 prevardecl.children = list(filter(
lambda x:
not is_tree_type(x,
'vardeclrn'), prevardecl.children))
733 decls = list(map(
lambda x: x[0] +
';', prevardecl.children))
734 decls_init = list(map(
lambda x:
'{} = {};'.format(x[1], x[2]), filter(
lambda x: len(x) == 3
and x[2]
is not None, prevardecl.children)))
736 assert proc_name
in sense_list,
"Process name {} is not in module {}".format(proc_name, self.
current_module)
738 if hasattr(tree,
'force_sensevar'):
739 res = ind +
'always @({}) begin: {}\n'.format(tree.force_sensevar, proc_name)
741 res = ind +
'always_ff @({}) begin: {}\n'.format(
' or '.join(self.
get_sense_list()[proc_name]), proc_name)
743 res = ind +
'always @({}) begin: {}\n'.format(
' or '.join(self.
get_sense_list()[proc_name]), proc_name)
747 res += ind + (
'\n' + ind).join(decls) +
'\n'
748 res += ind + (
'\n' + ind).join(decls_init) +
'\n'
751 res +=
'\n'.join(body) +
'\n'
761 assert var_name
not in self.
local_variables,
'Local variable {} already existed'.format(var_name)
766 name, *args = tree.children
767 tpe = Primitive.get_primitive(name)
768 assert tpe
is not None,
'Type {} is not defined'.format(name)
774 """Return statement is detected and omitted.\n"""
775 """ A return statement may not produce expected result,\n"""
776 """ consider removing it in the C++ code.\n"""
778 if len(tree.children) == 1:
779 return 'return {}'.format(tree.children[0])
780 elif len(tree.children) == 0:
784 assert len(tree.children)
in [0, 1],
'return statement can only have 0 or 1 return value'
788 var_name, tpe = tree.children
790 decl = tpe.to_str(var_name, context=ctx)
795 return decl, var_name,
None
807 if len(tree.children) == 2:
808 var_name, tpe = tree.children
809 elif len(tree.children) == 3:
810 var_name, tpe, init_val = tree.children
812 assert False,
'children size of vardeclinit is not 2 or 3, there might be a bug in the translator'
814 decl = tpe.to_str(var_name, context=ctx)
819 return (decl, var_name, init_val)
823 this expansion should only be invoked by expanding_binding_ref and should not be invoked elsewhere
824 the reason is that we need to collect binding information per arry-like port
827 return '{}[{}]'.format(tree.children[0], tree.children[1])
830 if not is_tree_type(tree,
'hbindingarrayref'):
831 raise ValueError(
'expand_binding_ref only accepts hbindingarrayref')
832 self.__push_back(tree)
833 return '{}[{}]'.format(tree.children[0], tree.children[1])
836 interface: Interface = self.
itf_meta.get(mod_type_name,
None)
839 res += ind +
'{} {}();\n'.format(
840 interface.interface_name,
841 Interface.generate_instance_name(mod_name, is_array)
846 interface: Interface = self.
itf_meta.get(mod_type_name,
None)
848 return Interface.generate_instance_name(mod_name, is_array)
855 mod_name, mod_type = tree.children
856 mod_type_name = mod_type.children[0].children[1].children[0]
857 mod_array_dimension = mod_type.children[0].children[2]
860 map(
lambda x:
'_'.join([self.
current_module, mod_name, str(x)]), range(len(mod_array_dimension)))
863 for genvar
in genvar_names:
864 res += ind +
'genvar {};\n'.format(genvar)
866 for idx, (genvar, dim)
in enumerate(zip(genvar_names, mod_array_dimension)):
867 res += ind +
"/*generate*/ for ({} = 0; {} < {}; {} = {} + 1) begin {}\n".format(
868 genvar, genvar, dim, genvar, genvar,
': ' + mod_name
if idx == 0
else ''
876 res += ind +
"{} mod(\n".format(mod_type_name)
880 warnings.warn(
'Port bindings for module instance name {} not found'.format(mod_name))
887 def extract_binding_name(x):
889 return get_ids_in_tree(x[0])[0]
896 orig_bindings = bindings
897 bindings_normal = list(filter(
lambda x:
'.' not in extract_binding_name(x), orig_bindings))
898 bindings_hier = list(filter(
lambda x:
'.' in extract_binding_name(x), orig_bindings))
899 bindings = bindings_normal
906 for binding
in bindings:
908 if type(binding) == list:
911 warnings.warn(
'Using Tree as binding is deprecated', DeprecationWarning)
912 sub, par = binding.children
913 if is_tree_type(sub,
'hbindingarrayref'):
915 sub_name = get_ids_in_tree(sub)[0].value
916 if sub_name
not in array_bindings:
917 array_bindings[sub_name] = {}
920 array_bindings[sub_name][sub.children[1].children[0]] = par
923 if is_tree_type(par,
'hbindingarrayref'):
926 par = par.children[0].value
927 binding_str.append(ind +
'.{}({})'.format(sub.children[0].value, par))
928 for sub_name, bindings
in array_bindings.items():
930 array_seq = [
None] * len(bindings)
931 for idx, b
in bindings.items():
935 binding_str.append(ind +
".{}('{{ {} }})".format(
936 sub_name,
','.join(array_seq)
940 interface: Interface = self.
itf_meta.get(mod_type_name,
None)
943 res += ind + interface.generate_instance_name(mod_name,
True)
952 for _
in mod_array_dimension:
956 tree.children = [res]
962 mod_name, mod_type = tree.children
964 mod_name =
'_'.join(mod_name.split(
'#'))
965 if len(mod_type.children[0].children) > 1:
966 warnings.warn(
'Type parameters for modules are not supported')
967 mod_type_name = mod_type.children[0].children[0]
969 warnings.warn(
'Port bindings for module instance name {} not found'.format(mod_name))
973 def extract_binding_name(x):
975 return get_ids_in_tree(x[0])[0]
983 mod_type_name,
'',
False)
984 interface: Interface = self.
itf_meta.get(mod_type_name,
None)
988 orig_bindings = bindings
989 bindings_normal = list(filter(
lambda x:
'.' not in extract_binding_name(x), orig_bindings))
990 bindings_hier = list(filter(
lambda x:
'.' in extract_binding_name(x), orig_bindings))
991 bindings = bindings_normal
993 res = ind + interface_inst_arg + interface_decl +
'\n'
994 res += ind +
'{}{} {}('.format(module_inst_arg, mod_type_name, mod_name) +
'\n'
1000 for binding
in bindings:
1002 if type(binding) == list:
1005 warnings.warn(
'Using Tree as binding is deprecated', DeprecationWarning)
1006 sub, par = binding.children
1007 if is_tree_type(sub,
'hbindingarrayref'):
1009 sub_name = get_ids_in_tree(sub)[0].value
1010 if sub_name
not in array_bindings:
1011 array_bindings[sub_name] = {}
1014 array_bindings[sub_name][sub.children[1].children[0]] = par
1017 if is_tree_type(par,
'hbindingarrayref'):
1020 par = par.children[0].value
1022 for port_decl
in interface.interfaces:
1023 if port_decl.name == sub.children[0].value:
1024 assert port_decl.direction
in [
'input',
'output'],
"Interface port direction not recognized"
1025 if port_decl.direction ==
'input':
1026 binding_str.append(ind +
'assign {}.{} = {};'.format(interface_instance_name, sub.children[0].value, par))
1027 elif port_decl.direction ==
'output':
1028 binding_str.append(ind +
'assign {} = {}.{};'.format(par, interface_instance_name, sub.children[0].value))
1030 for sub_name, bindings
in array_bindings.items():
1033 array_seq = [
None] * len(bindings)
1034 for idx, b
in bindings.items():
1038 binding_str.append(ind +
".{}('{{ {} }})".format(
1039 sub_name,
','.join(array_seq)
1042 for binding
in bindings:
1046 if interface_instance_name:
1047 res += ind + interface_instance_name
1054 res +=
'\n'.join(binding_str)
1057 res += ind +
"always @(*) begin\n"
1061 for bl, br
in bindings_hier:
1062 res += ind +
'{} = {};\n'.format(bl.children[0], br.children[0])
1065 res += ind +
"end\n"
1067 tree.children = [res]
1072 val, rot = tree.children
1073 return '({} << {}) | ($unsigned({}) >> ($bits({}) - {}))'.format(val, rot, val, val, rot)
1076 val = tree.children[0]
1077 return '(|{})'.format(val)
1081 l, r = tree.children[0], tree.children[1]
1082 res =
'{{ {}, {} }}'.format(l, r)
1087 return tree.children
1092 for t
in tree.children:
1093 new_children.extend(t)
1094 tree.children = new_children
1100 return tree.children[0]
1105 var_name, tpe = tree.children
1107 decl = tpe.to_str(var_name, context=ctx)
1108 return decl, var_name,
None
1116 if len(tree.children) != 0:
1117 tpe = tree.children[0]
1118 res = tpe.to_str(var_name=
'')
1125 return '$unsigned({})'.format(tree.children[0])
1129 return '$signed({})'.format(tree.children[0])
1133 return '$unsigned({})'.format(tree.children[0])
1137 return '$signed({})'.format(tree.children[0])
1151 function_name, return_type = tree.children[:2]
1153 for ch
in tree.children[2:]:
1154 if is_tree_type(ch,
'hfunctionparams'):
1155 params =
', '.join(map(
lambda x: x[0], ch.children))
1156 elif is_tree_type(ch,
'hfunctionlocalvars'):
1158 elif is_tree_type(ch,
"hfunctionbody"):
1164 localvars =
'\n'.join(map(
lambda x: ind + x[0] +
';', localvar.children))
1166 body =
'\n'.join(body.children)
1169 res =
'{}function automatic {} {} ({});\n{}begin\n{}\n{}\n{}end\n{}endfunction'.format(ind, return_type, function_name,
1171 localvars, body, ind, ind)
1176 assert isinstance(port_or_sig, Tree)
and \
1177 port_or_sig.data
in [
'sigdecltype',
'portdecltype'], \
1178 'collect_type must be invoked with portdecltype or sigdecltype, but got: {}'.format(port_or_sig)
1179 id = port_or_sig.children[0].children[0]
1180 tpe = port_or_sig.children[1]
1210 raise ValueError(
'Duplicate signal declaration: {}'.format(id))
1230 proc_name, *body = tree.children
1240 assert thread_name
in sense_list,
"Process name {} is not in module {}".format(proc_name, self.
current_module)
1243 if 'posedge clk' not in sense_list:
1244 warnings.warn(
"Clock not detected in senstivity list, adding one by default")
1245 sense_list = [
'posedge clk'] + sense_list
1246 res = ind +
'always @({}) begin: {}\n'.format(
' or '.join(sense_list), proc_name)
1248 res = ind +
'always @(*) begin: {}\n'.format(proc_name)
1251 proc_name, *body = tree.children
1253 res +=
'\n'.join(body) +
'\n'
1279 res =
'\n'.join(genvars)
1284 return "\n".join(tree.children)
1292 initialization_block = []
1293 encountered_initblock =
False
1295 genbindinglist =
None
1296 for t
in tree.children:
1297 if isinstance(t, Tree)
and t.data ==
'portbindinglist':
1299 assert False,
"Deadcode"
1300 elif is_tree_type(t,
'hmodinitblock'):
1301 if encountered_initblock:
1302 raise ValueError(
'Only one hmodinitblock should present')
1303 encountered_initblock =
True
1304 name = t.children[0]
1305 initblock, portbindings, senslist, genbindinglist =
None,
None, [],
None
1306 for ch
in t.children[1:]:
1307 if ch.data ==
'hcstmt':
1309 elif ch.data ==
'portbindinglist':
1311 elif ch.data ==
'hsenslist':
1313 elif ch.data ==
'vardecl':
1315 elif ch.data ==
'hnamedsensevar':
1317 elif ch.data ==
'genbindinglist':
1320 raise ValueError(ch.pretty())
1330 for bds
in portbindings.children[1]:
1331 mod_name = bds.children[0]
1332 bindings = bds.children[1:]
1337 if initblock
and initblock.children:
1338 initialization_block.append(initblock.children[0])
1339 tree.children = list(filter(
lambda x:
not isinstance(x, Tree)
or x.data !=
'portbindinglist', tree.children))
1344 module_name = tree.children[0]
1345 modportsiglist =
None
1351 for t
in tree.children:
1352 if isinstance(t, Tree):
1353 if t.data ==
'modportsiglist':
1355 elif t.data ==
'processlist':
1357 elif t.data ==
'hgenerateblock':
1358 generatelist.append(t.children[0])
1359 elif t.data ==
'hfunction':
1360 functionlist.append(t)
1364 ports = list(filter(
lambda x: isinstance(x, Tree)
and x.data ==
'portdecltype', modportsiglist.children))
1365 sigs = list(filter(
lambda x: isinstance(x, Tree)
and x.data ==
'sigdecltype', modportsiglist.children))
1366 vars = list(filter(
lambda x: isinstance(x, tuple), modportsiglist.children))
1367 mods = list(filter(
lambda x: isinstance(x, Tree)
and
1368 (x.data ==
'moduleinst' or x.data ==
'modulearrayinst'),
1369 modportsiglist.children))
1371 ports, sigs =
None,
None
1374 res = module_arg +
'module {} ('.format(module_name) +
'\n'
1380 for idx, p
in enumerate(ports):
1381 name, tpe = p.children
1382 name = name.children[0].value
1384 if idx == len(ports) - 1:
1386 port_str += ind + tpe.to_str(name, type_context) +
'\n'
1388 interface = self.
itf_meta.get(module_name,
None)
1390 port_str = port_decl_inst_arg +
' ' + interface.interface_name +
'.port0 ' + interface.generate_interface_decl_name() +
'\n'
1397 for idx, p
in enumerate(sigs):
1398 name, tpe = p.children
1399 name = name.children[0].value
1401 res += ind + tpe.to_str(name, type_context) +
'\n'
1410 if initialization_block:
1413 res +=
'{}initial begin\n'.format(ind)
1414 res +=
'\n'.join(initialization_block)
1415 res +=
'\n{}end\n'.format(ind)
1420 res += m.children[0] +
'\n'
1424 for proc
in processlist.children:
1425 if is_tree_type(proc,
'hthread'):
1428 if len(proc.children) == 3:
1429 thread_name, thread_sync, thread_comb = proc.children
1430 elif len(proc.children) == 4:
1431 thread_name, thread_func, thread_sync, thread_comb = proc.children
1433 assert False,
"thread should have 3 or 4 children node"
1436 res +=
'{}// Thread: {}\n'.format(ind, thread_name)
1439 res += thread_sync +
"\n"
1441 res += thread_func +
"\n"
1442 res += thread_comb +
"\n"
1449 assert False,
"functionlist should be empty, there may be a bug in the code"
1451 for f
in generatelist:
1454 res +=
"\n".join(genbindinglist.children) +
"\n"
1460 return tree.children[0]
1463 assert len(tree.children) == 2,
"sc_max node should only have 2 children"
1465 L = tree.children[0]
1466 R = tree.children[1]
1467 return "(({}) < ({}) ? ({}) : ({}))".format(L, R, R, L)
1470 assert len(tree.children) == 2,
"sc_min node should only have 2 children"
1472 L = tree.children[0]
1473 R = tree.children[1]
1474 return "(({}) < ({}) ? ({}) : ({}))".format(L, R, L, R)
1477 return name.endswith(
'#')
1480 for decl, name, init
in vars:
1483 decl = decl.replace(
'#',
"")
1485 decl = decl +
' = ' + str(init) +
';'
1488 res += ind + decl +
'\n'
1493 for t
in tree.children:
1495 new_children.append(v.children)
1498 (t[1].to_str(t[0], context=ctx), t[0],
None)
for t
in new_children
1500 return tree.children
1502 """called for the special genblock"""
1508 new_children.extend(self.visit(t)
for t
in tree.children[:3])
1512 new_children.extend(self.visit(t)
for t
in tree.children[3:])
1515 if len(new_children) == 3:
1516 warnings.warn(
"empty for loop")
1517 for_init, for_cond, for_post = new_children
1520 for_init, for_cond, for_post, for_body = new_children
1523 res = ind +
'/*generate*/ for ({};{};{}) begin\n'.format(for_init, for_cond, for_post)
1524 res += for_body +
'\n'
1534 hgenvarecl, *body = tree.children
1535 tree.children = [
';\n'.join([
1536 t[0]
for t
in hgenvarecl
1537 ]) +
';\n' +
"\n".join(body)]