Skip to content

Commit 0f0ee1b

Browse files
committed
Merge pull request #18 from fukatani/master
Support case statement in function.
2 parents 6869693 + ebb273b commit 0f0ee1b

File tree

4 files changed

+166
-4
lines changed

4 files changed

+166
-4
lines changed

pyverilog/dataflow/bindvisitor.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,18 +362,27 @@ def visit_CaseStatement(self, node):
362362
start_frame = self.frames.getCurrent()
363363
caseframes = []
364364
self._case(node.comp, node.caselist, caseframes)
365+
#self._case(node.comp, tuple(reversed(list(node.caselist))), caseframes)
365366
self.frames.setCurrent(start_frame)
366367
for f in caseframes:
367368
self.copyBlockingAssigns(f, start_frame)
368369

369370
def visit_CasexStatement(self, node):
370371
return self.visit_CaseStatement(node)
371-
372+
372373
def _case(self, comp, caselist, myframes):
373374
if len(caselist) == 0: return
374375

375376
case = caselist[0]
376-
cond = Eq(comp, case)
377+
cond = IntConst('1')
378+
if case.cond is not None:
379+
if len(case.cond) > 1:
380+
cond = Eq(comp, case.cond[0])
381+
for c in case.cond[1:]:
382+
cond = Lor(cond, Eq(comp, c))
383+
else:
384+
cond = Eq(comp, case.cond[0])
385+
#else: raise Exception
377386
label = self.labels.get( self.frames.getLabelKey('if') )
378387
current = self.stackNextFrame(label, 'if',
379388
frametype='ifthen',
@@ -919,7 +928,7 @@ def getCondlist(self, scope):
919928
if cond is not None:
920929
ret.append(self.makeDFTree(cond, self.reduceIfScope(s)))
921930
if frame.isModule(): break
922-
if frame.isFunctioncall(): break
931+
#if frame.isFunctioncall(): break
923932
s = frame.previous
924933
ret.reverse()
925934
return tuple(ret)
@@ -932,7 +941,7 @@ def getFlowlist(self, scope):
932941
cond = frame.getCondition()
933942
if cond is not None: ret.append(not frame.isIfelse())
934943
if frame.isModule(): break
935-
if frame.isFunctioncall(): break
944+
#if frame.isFunctioncall(): break
936945
s = frame.previous
937946
ret.reverse()
938947
return tuple(ret)

testcode/case_in_func.v

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module TOP(IN1,SEL);
2+
input IN1,SEL;
3+
reg bit;
4+
5+
6+
always @* begin
7+
bit <= func1(IN1,SEL);
8+
end
9+
10+
function func1;
11+
input in1;
12+
input sel;
13+
case(sel)
14+
'h0:
15+
func1 = in1;
16+
default:
17+
func1 = 1'b0;
18+
endcase
19+
endfunction
20+
21+
/*
22+
always @* begin
23+
case(SEL)
24+
'h0:
25+
bit = IN1;
26+
default:
27+
bit = 1'b0;
28+
endcase
29+
end
30+
*/
31+
32+
endmodule
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import os
2+
import sys
3+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) )
4+
from pyverilog.dataflow.dataflow_analyzer import VerilogDataflowAnalyzer
5+
from pyverilog.dataflow.optimizer import VerilogDataflowOptimizer
6+
from pyverilog.controlflow.controlflow_analyzer import VerilogControlflowAnalyzer
7+
codedir = '../../testcode/'
8+
9+
expected = """\
10+
TOP.SEL: TOP_SEL
11+
TOP.md_always0.al_block0.al_functioncall0.in1: TOP_IN1
12+
TOP.md_always0.al_block0.al_functioncall0._rn1_func1: 1'd0
13+
TOP.bit: (((TOP_SEL=='d0))? TOP_IN1 : 1'd0)
14+
TOP.md_always0.al_block0.al_functioncall0.func1: (((TOP_SEL=='d0))? TOP_IN1 : 1'd0)
15+
TOP.md_always0.al_block0.al_functioncall0.sel: TOP_SEL
16+
TOP.md_always0.al_block0.al_functioncall0._rn0_func1: TOP_IN1
17+
TOP.IN1: TOP_IN1
18+
"""
19+
20+
def test():
21+
filelist = [codedir + 'case_in_func.v']
22+
topmodule = 'TOP'
23+
noreorder = False
24+
nobind = False
25+
include = None
26+
define = None
27+
28+
analyzer = VerilogDataflowAnalyzer(filelist, topmodule,
29+
noreorder=noreorder,
30+
nobind=nobind,
31+
preprocess_include=include,
32+
preprocess_define=define)
33+
analyzer.generate()
34+
35+
directives = analyzer.get_directives()
36+
instances = analyzer.getInstances()
37+
terms = analyzer.getTerms()
38+
binddict = analyzer.getBinddict()
39+
40+
optimizer = VerilogDataflowOptimizer(terms, binddict)
41+
optimizer.resolveConstant()
42+
43+
c_analyzer = VerilogControlflowAnalyzer(topmodule, terms,
44+
binddict,
45+
resolved_terms=optimizer.getResolvedTerms(),
46+
resolved_binddict=optimizer.getResolvedBinddict(),
47+
constlist=optimizer.getConstlist()
48+
)
49+
50+
output = []
51+
for tk in sorted(c_analyzer.resolved_terms.keys(), key=lambda x:str(x[0])):
52+
tree = c_analyzer.makeTree(tk)
53+
output.append(str(tk) + ': ' + tree.tocode())
54+
55+
rslt = '\n'.join(output) + '\n'
56+
57+
print(rslt)
58+
assert(rslt == expected)
59+
60+
if __name__ == '__main__':
61+
test()

tests/dataflow_test/test_func.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import os
2+
import sys
3+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) )
4+
from pyverilog.dataflow.dataflow_analyzer import VerilogDataflowAnalyzer
5+
from pyverilog.dataflow.optimizer import VerilogDataflowOptimizer
6+
from pyverilog.controlflow.controlflow_analyzer import VerilogControlflowAnalyzer
7+
codedir = '../../testcode/'
8+
9+
expected = """\
10+
TOP.RST_X: TOP_RST_X
11+
TOP.md_always0.al_block0.al_if0_ELSE.al_block2.al_functioncall0.inc: (((!TOP_RST_X))? TOP_al_block0_al_block2_al_functioncall0_inc : (((!TOP_RST_X))? (((&TOP_al_block0_al_block2_al_functioncall0_inc))? 'd0 : (((!TOP_RST_X))? (TOP_al_block0_al_block2_al_functioncall0_inc+'d1) : (TOP_cnt+'d1))) : (((&TOP_al_block0_al_block2_al_functioncall0_inc))? (((!TOP_RST_X))? (TOP_al_block0_al_block2_al_functioncall0_inc+'d1) : (TOP_cnt+'d1)) : (((!TOP_RST_X))? (((&(TOP_al_block0_al_block2_al_functioncall0_inc+'d1)))? 'd0 : (((!TOP_RST_X))? (TOP_al_block0_al_block2_al_functioncall0_inc+'d1) : (TOP_cnt+'d1))) : (((&(TOP_cnt+'d1)))? 'd0 : (((!TOP_RST_X))? (TOP_al_block0_al_block2_al_functioncall0_inc+'d1) : (TOP_cnt+'d1)))))))
12+
TOP.md_always0.al_block0.al_if0_ELSE.al_block2.al_functioncall0._rn1_inc: (((!TOP_RST_X))? (TOP_al_block0_al_block2_al_functioncall0__rn1_inc+'d1) : (TOP_cnt+'d1))
13+
TOP.cnt: (((!TOP_RST_X))? 'd0 : (((!TOP_RST_X))? TOP_cnt : (((&TOP_al_block0_al_block2_al_functioncall0_inc))? 'd0 : (((!TOP_RST_X))? (TOP_cnt+'d1) : (TOP_cnt+'d1)))))
14+
TOP.md_always0.al_block0.al_if0_ELSE.al_block2.al_functioncall0.in: (((!TOP_RST_X))? TOP_al_block0_al_block2_al_functioncall0_in : TOP_cnt)
15+
TOP.CLK: TOP_CLK
16+
TOP.md_always0.al_block0.al_if0_ELSE.al_block2.al_functioncall0._rn0_inc: 'd0
17+
"""
18+
19+
def test():
20+
filelist = [codedir + 'function.v']
21+
topmodule = 'TOP'
22+
noreorder = False
23+
nobind = False
24+
include = None
25+
define = None
26+
27+
analyzer = VerilogDataflowAnalyzer(filelist, topmodule,
28+
noreorder=noreorder,
29+
nobind=nobind,
30+
preprocess_include=include,
31+
preprocess_define=define)
32+
analyzer.generate()
33+
34+
directives = analyzer.get_directives()
35+
instances = analyzer.getInstances()
36+
terms = analyzer.getTerms()
37+
binddict = analyzer.getBinddict()
38+
39+
optimizer = VerilogDataflowOptimizer(terms, binddict)
40+
optimizer.resolveConstant()
41+
42+
c_analyzer = VerilogControlflowAnalyzer(topmodule, terms,
43+
binddict,
44+
resolved_terms=optimizer.getResolvedTerms(),
45+
resolved_binddict=optimizer.getResolvedBinddict(),
46+
constlist=optimizer.getConstlist()
47+
)
48+
49+
output = []
50+
for tk in sorted(c_analyzer.resolved_terms.keys(), key=lambda x:str(x[0])):
51+
tree = c_analyzer.makeTree(tk)
52+
output.append(str(tk) + ': ' + tree.tocode())
53+
54+
rslt = '\n'.join(output) + '\n'
55+
56+
print(rslt)
57+
assert(rslt == expected)
58+
59+
if __name__ == '__main__':
60+
test()

0 commit comments

Comments
 (0)