Skip to content

Commit

Permalink
Merge pull request #150 from hgomersall/initial_value_support
Browse files Browse the repository at this point in the history
Initial value support
  • Loading branch information
jandecaluwe committed Jun 19, 2016
2 parents edd3856 + 4b4be7b commit f4fde1c
Show file tree
Hide file tree
Showing 3 changed files with 497 additions and 24 deletions.
48 changes: 45 additions & 3 deletions myhdl/conversion/_toVHDL.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class _ToVHDLConvertor(object):
"use_clauses",
"architecture",
"std_logic_ports",
"initial_values"
)

def __init__(self):
Expand All @@ -126,6 +127,7 @@ def __init__(self):
self.use_clauses = None
self.architecture = "MyHDL"
self.std_logic_ports = False
self.initial_values = False

def __call__(self, func, *args, **kwargs):
global _converting
Expand Down Expand Up @@ -411,8 +413,31 @@ def _writeSigDecls(f, intf, siglist, memlist):
category=ToVHDLWarning
)
# the following line implements initial value assignments
# print >> f, "%s %s%s = %s;" % (s._driven, r, s._name, int(s._val))
print("signal %s: %s%s;" % (s._name, p, r), file=f)

sig_vhdl_obj = inferVhdlObj(s)

if not toVHDL.initial_values:
val_str = ""
else:

if isinstance(sig_vhdl_obj, vhd_std_logic):
# Single bit
val_str = " := '%s'" % int(s._init)
elif isinstance(sig_vhdl_obj, vhd_int):
val_str = " := %s" % s._init
elif isinstance(sig_vhdl_obj, (vhd_signed, vhd_unsigned)):
val_str = ' := %dX"%s"' % (
sig_vhdl_obj.size, str(s._init))

elif isinstance(sig_vhdl_obj, vhd_enum):
val_str = ' := %s' % (s._init,)

else:
# default to no initial value
val_str = ''

print("signal %s: %s%s%s;" % (s._name, p, r, val_str), file=f)

elif s._read:
# the original exception
# raise ToVHDLError(_error.UndrivenSignal, s._name)
Expand All @@ -436,8 +461,25 @@ def _writeSigDecls(f, intf, siglist, memlist):
r = _getRangeString(m.elObj)
p = _getTypeString(m.elObj)
t = "t_array_%s" % m.name

if not toVHDL.initial_values:
val_str = ""
else:
sig_vhdl_objs = [inferVhdlObj(each) for each in m.mem]

if all([each._init == m.mem[0]._init for each in m.mem]):
val_str = (
' := (others => %dX"%s")' %
(sig_vhdl_objs[0].size, str(m.mem[0]._init)))
else:
_val_str = ',\n '.join(
['%dX"%s"' % (obj.size, str(each._init)) for
obj, each in zip(sig_vhdl_objs, m.mem)])

val_str = ' := (\n ' + _val_str + ')'

print("type %s is array(0 to %s-1) of %s%s;" % (t, m.depth, p, r), file=f)
print("signal %s: %s;" % (m.name, t), file=f)
print("signal %s: %s%s;" % (m.name, t, val_str), file=f)
print(file=f)


Expand Down
89 changes: 68 additions & 21 deletions myhdl/conversion/_toVerilog.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import sys
import math
import os
import textwrap

import inspect
from datetime import datetime
Expand Down Expand Up @@ -107,7 +108,8 @@ class _ToVerilogConvertor(object):
"no_myhdl_header",
"no_testbench",
"portmap",
"trace"
"trace",
"initial_values"
)

def __init__(self):
Expand All @@ -121,6 +123,7 @@ def __init__(self):
self.no_myhdl_header = False
self.no_testbench = False
self.trace = False
self.initial_values = False

def __call__(self, func, *args, **kwargs):
global _converting
Expand Down Expand Up @@ -327,8 +330,17 @@ def _writeSigDecls(f, intf, siglist, memlist):
if s._driven == 'reg':
k = 'reg'
# the following line implements initial value assignments
# print >> f, "%s %s%s = %s;" % (k, r, s._name, int(s._val))
print("%s %s%s%s;" % (k, p, r, s._name), file=f)
# don't initial value "wire", inital assignment to a wire
# equates to a continuous assignment [reference]
if not toVerilog.initial_values or k == 'wire':
print("%s %s%s%s;" % (k, p, r, s._name), file=f)
else:
if isinstance(s._init, myhdl._enum.EnumItemType):
print("%s %s%s%s = %s;" %
(k, p, r, s._name, s._init._toVerilog()), file=f)
else:
print("%s %s%s%s = %s;" %
(k, p, r, s._name, _intRepr(s._init)), file=f)
elif s._read:
# the original exception
# raise ToVerilogError(_error.UndrivenSignal, s._name)
Expand All @@ -353,9 +365,42 @@ def _writeSigDecls(f, intf, siglist, memlist):
r = _getRangeString(m.elObj)
p = _getSignString(m.elObj)
k = 'wire'
initial_assignments = None
if m._driven:
k = m._driven
print("%s %s%s%s [0:%s-1];" % (k, p, r, m.name, m.depth), file=f)

if toVerilog.initial_values:
if all([each._init == m.mem[0]._init for each in m.mem]):

initialize_block_name = ('INITIALIZE_' + m.name).upper()
_initial_assignments = (
'''
initial begin: %s
integer i;
for(i=0; i<%d; i=i+1) begin
%s[i] = %s;
end
end
''' % (initialize_block_name, len(m.mem), m.name,
_intRepr(m.mem[0]._init)))

initial_assignments = (
textwrap.dedent(_initial_assignments))

else:
val_assignments = '\n'.join(
[' %s[%d] <= %s;' %
(m.name, n, _intRepr(each._init))
for n, each in enumerate(m.mem)])
initial_assignments = (
'initial begin\n' + val_assignments + '\nend')

print("%s %s%s%s [0:%s-1];" % (k, p, r, m.name, m.depth),
file=f)

if initial_assignments is not None:
print(initial_assignments, file=f)

print(file=f)
for s in constwires:
if s._type in (bool, intbv):
Expand Down Expand Up @@ -431,6 +476,24 @@ def _getSignString(s):
else:
return ''

def _intRepr(n, radix=''):
# write size for large integers (beyond 32 bits signed)
# with some safety margin
# XXX signed indication 's' ???
p = abs(n)
size = ''
num = str(p).rstrip('L')
if radix == "hex" or p >= 2**30:
radix = "'h"
num = hex(p)[2:].rstrip('L')
if p >= 2**30:
size = int(math.ceil(math.log(p+1,2))) + 1 # sign bit!
# if not radix:
# radix = "'d"
r = "%s%s%s" % (size, radix, num)
if n < 0: # add brackets and sign on negative numbers
r = "(-%s)" % r
return r

def _convertGens(genlist, vfile):
blockBuf = StringIO()
Expand Down Expand Up @@ -531,23 +594,7 @@ def dedent(self):
self.ind = self.ind[:-4]

def IntRepr(self, n, radix=''):
# write size for large integers (beyond 32 bits signed)
# with some safety margin
# XXX signed indication 's' ???
p = abs(n)
size = ''
num = str(p).rstrip('L')
if radix == "hex" or p >= 2**30:
radix = "'h"
num = hex(p)[2:].rstrip('L')
if p >= 2**30:
size = int(math.ceil(math.log(p + 1, 2))) + 1 # sign bit!
# if not radix:
# radix = "'d"
r = "%s%s%s" % (size, radix, num)
if n < 0: # add brackets and sign on negative numbers
r = "(-%s)" % r
return r
return _intRepr(n, radix)

def writeDeclaration(self, obj, name, dir):
if dir:
Expand Down

0 comments on commit f4fde1c

Please sign in to comment.