Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support SVA assert/assume #103

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions pyverilog/ast_code_generator/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,43 @@ def visit_Assign(self, node):
rslt = template.render(template_dict)
rslt = indent_multiline_assign(rslt)
return rslt

def visit_Assert(self, node):
filename = getfilename(node)
template = self.get_template(filename)
template_dict = {
'expr': self.visit(node.expr)
}
rslt = template.render(template_dict)
return rslt

def visit_Assume(self, node):
filename = getfilename(node)
template = self.get_template(filename)
template_dict = {
'expr': self.visit(node.expr)
}
rslt = template.render(template_dict)
return rslt


def visit_AssertStatement(self, node):
filename = getfilename(node)
template = self.get_template(filename)
template_dict = {
'statement': self.visit(node.statement)
}
rslt = template.render(template_dict)
return rslt

def visit_AssumeStatement(self, node):
filename = getfilename(node)
template = self.get_template(filename)
template_dict = {
'statement': self.visit(node.statement)
}
rslt = template.render(template_dict)
return rslt

def visit_Always(self, node):
filename = getfilename(node)
Expand Down
1 change: 1 addition & 0 deletions pyverilog/ast_code_generator/template/assert.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
assert property ( {{ expr }} );
1 change: 1 addition & 0 deletions pyverilog/ast_code_generator/template/assertstatement.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
assert ( {{ statement }} );
1 change: 1 addition & 0 deletions pyverilog/ast_code_generator/template/assume.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
assume property ( {{ expr }} );
1 change: 1 addition & 0 deletions pyverilog/ast_code_generator/template/assumestatement.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
assume ( {{ statement }} );
53 changes: 53 additions & 0 deletions pyverilog/vparser/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,32 @@ def children(self):
nodelist.append(self.false_value)
return tuple(nodelist)

class Assert(Node):
attr_names = ()

def __init__(self, expr, lineno=0):
self.lineno = lineno
self.expr = expr

def children(self):
nodelist = []
if self.expr:
nodelist.append(self.expr)
return tuple(nodelist)

class Assume(Node):
attr_names = ()

def __init__(self, expr, lineno=0):
self.lineno = lineno
self.expr = expr

def children(self):
nodelist = []
if self.expr:
nodelist.append(self.expr)
return tuple(nodelist)


class Assign(Node):
attr_names = ()
Expand Down Expand Up @@ -1278,6 +1304,33 @@ def children(self):
return tuple(nodelist)


class AssumeStatement(Node):
attr_names = ()

def __init__(self, statement, lineno=0):
self.lineno = lineno
self.statement = statement

def children(self):
nodelist = []
if self.statement:
nodelist.append(self.statement)
return tuple(nodelist)

class AssertStatement(Node):
attr_names = ()

def __init__(self, statement, lineno=0):
self.lineno = lineno
self.statement = statement

def children(self):
nodelist = []
if self.statement:
nodelist.append(self.statement)
return tuple(nodelist)


class EmbeddedCode(Node):
attr_names = ('code',)

Expand Down
2 changes: 1 addition & 1 deletion pyverilog/vparser/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def token(self):
'PARAMETER', 'LOCALPARAM', 'SUPPLY0', 'SUPPLY1',
'ASSIGN', 'ALWAYS', 'ALWAYS_FF', 'ALWAYS_COMB', 'ALWAYS_LATCH', 'SENS_OR', 'POSEDGE', 'NEGEDGE', 'INITIAL',
'IF', 'ELSE', 'FOR', 'WHILE', 'CASE', 'CASEX', 'CASEZ', 'UNIQUE', 'ENDCASE', 'DEFAULT',
'WAIT', 'FOREVER', 'DISABLE', 'FORK', 'JOIN',
'WAIT', 'FOREVER', 'DISABLE', 'FORK', 'JOIN', 'ASSERT', 'ASSUME', 'PROPERTY'
)

reserved = {}
Expand Down
25 changes: 25 additions & 0 deletions pyverilog/vparser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,8 @@ def p_standard_item(self, p):
| function
| task
| pragma
| assert
| assume
"""
p[0] = p[1]
p.set_lineno(0, p.lineno(1))
Expand Down Expand Up @@ -845,6 +847,16 @@ def p_assignment_delay(self, p):
'assignment : ASSIGN delays lvalue EQUALS delays rvalue SEMICOLON'
p[0] = Assign(p[3], p[6], p[2], p[5], lineno=p.lineno(1))
p.set_lineno(0, p.lineno(1))

def p_assert(self, p):
'assert : ASSERT PROPERTY LPAREN rvalue RPAREN SEMICOLON'
p[0] = Assert(p[4], lineno=p.lineno(1))
p.set_lineno(0, p.lineno(1))

def p_assume(self, p):
'assume : ASSUME PROPERTY LPAREN rvalue RPAREN SEMICOLON'
p[0] = Assume(p[4], lineno=p.lineno(1))
p.set_lineno(0, p.lineno(1))

# --------------------------------------------------------------------------
def p_lpartselect_lpointer(self, p):
Expand Down Expand Up @@ -1435,6 +1447,8 @@ def p_basic_statement(self, p):
| blocking_substitution
| nonblocking_substitution
| single_statement
| assert_statement
| assume_statement
"""
p[0] = p[1]
p.set_lineno(0, p.lineno(1))
Expand Down Expand Up @@ -2242,6 +2256,17 @@ def p_single_statement_disable(self, p):
p[0] = SingleStatement(p[1], lineno=p.lineno(1))
p.set_lineno(0, p.lineno(1))

def p_assert_statement_disable(self, p):
'assert_statement : ASSERT LPAREN expression RPAREN SEMICOLON'
p[0] = AssertStatement(p[3], lineno=p.lineno(1))
p.set_lineno(0, p.lineno(1))

def p_assume_statement_disable(self, p):
'assume_statement : ASSUME LPAREN expression RPAREN SEMICOLON'
p[0] = AssumeStatement(p[3], lineno=p.lineno(1))
p.set_lineno(0, p.lineno(1))


# fix me: to support task-call-statement
# def p_single_statement_taskcall(self, p):
# 'single_statement : functioncall SEMICOLON'
Expand Down