mirror of
https://github.com/myhdl/myhdl.git
synced 2024-12-14 07:44:38 +08:00
_toVerilog.py: expanding initial_values
kwarg to add 'skip_zero_mem_init' choice to skip generating initial block when all values are zero (#431)
This commit is contained in:
parent
e356d8a589
commit
6520f32194
@ -49,7 +49,7 @@ traceSignals -- function that enables signal tracing in a VCD file
|
||||
toVerilog -- function that converts a design to Verilog
|
||||
|
||||
"""
|
||||
__version__ = "0.11.46"
|
||||
__version__ = "0.11.47"
|
||||
|
||||
|
||||
class StopSimulation(Exception):
|
||||
|
@ -20,7 +20,7 @@
|
||||
""" Block with the @block decorator function. """
|
||||
import inspect
|
||||
|
||||
#from functools import wraps
|
||||
# from functools import wraps
|
||||
import functools
|
||||
|
||||
import myhdl
|
||||
@ -34,8 +34,11 @@ from myhdl._Signal import _Signal, _isListOfSigs
|
||||
|
||||
from weakref import WeakValueDictionary
|
||||
|
||||
|
||||
class _error:
|
||||
pass
|
||||
|
||||
|
||||
_error.ArgType = "%s: A block should return block or instantiator objects"
|
||||
_error.InstanceError = "%s: subblock %s should be encapsulated in a block decorator"
|
||||
|
||||
@ -87,15 +90,16 @@ def _getCallInfo():
|
||||
return _CallInfo(name, modctxt, symdict)
|
||||
|
||||
|
||||
### I don't think this is the right place for uniqueifying the name.
|
||||
### This seems to me to be a conversion concern, not a block concern, and
|
||||
### there should not be the corresponding global state to be maintained here.
|
||||
### The name should be whatever it is, which is then uniqueified at
|
||||
### conversion time. Perhaps this happens already (FIXME - check and fix)
|
||||
### ~ H Gomersall 24/11/2017
|
||||
# ## I don't think this is the right place for uniqueifying the name.
|
||||
# ## This seems to me to be a conversion concern, not a block concern, and
|
||||
# ## there should not be the corresponding global state to be maintained here.
|
||||
# ## The name should be whatever it is, which is then uniqueified at
|
||||
# ## conversion time. Perhaps this happens already (FIXME - check and fix)
|
||||
# ## ~ H Gomersall 24/11/2017
|
||||
_inst_name_set = set()
|
||||
_name_set = set()
|
||||
|
||||
|
||||
def _uniqueify_name(proposed_name):
|
||||
'''Creates a unique block name from the proposed name by appending
|
||||
a suitable number to the end. Every name this function returns is
|
||||
@ -140,6 +144,7 @@ class _bound_function_wrapper(object):
|
||||
return _Block(self.bound_func, self, name, self.srcfile,
|
||||
self.srcline, *args, **kwargs)
|
||||
|
||||
|
||||
class block(object):
|
||||
|
||||
def __init__(self, func):
|
||||
@ -304,14 +309,27 @@ class _Block(object):
|
||||
|
||||
Args:
|
||||
hdl (Optional[str]): Target HDL. Defaults to Verilog
|
||||
|
||||
path (Optional[str]): Destination folder. Defaults to current
|
||||
working dir.
|
||||
|
||||
name (Optional[str]): Module and output file name. Defaults to
|
||||
`self.mod.__name__`
|
||||
|
||||
initial_vales(Optional[bool(), str]):
|
||||
Verilog: False: no initial values
|
||||
True: all initial values, using initial blocks for memories
|
||||
'skip_zero_mem_init': same as for `True` except no initial blocks are
|
||||
generated for memories where all values are zero,
|
||||
which is the default at start-up of (most or all) FPGAs
|
||||
VHDL: True or False only ('skip_zero_mem_init' will be treated as `True` ...)
|
||||
|
||||
trace(Optional[bool]): Verilog only. Whether the testbench should
|
||||
dump all signal waveforms. Defaults to False.
|
||||
|
||||
testbench (Optional[bool]): Verilog only. Specifies whether a
|
||||
testbench should be created. Defaults to True.
|
||||
|
||||
timescale(Optional[str]): Verilog only. Defaults to '1ns/10ps'
|
||||
"""
|
||||
|
||||
@ -337,17 +355,17 @@ class _Block(object):
|
||||
setattr(converter, k, v)
|
||||
return converter(self)
|
||||
|
||||
def config_sim(self, trace=False, **kwargs) :
|
||||
def config_sim(self, trace=False, **kwargs):
|
||||
self._config_sim['trace'] = trace
|
||||
if trace:
|
||||
for k, v in kwargs.items() :
|
||||
for k, v in kwargs.items():
|
||||
setattr(myhdl.traceSignals, k, v)
|
||||
myhdl.traceSignals(self)
|
||||
|
||||
def run_sim(self, duration=None, quiet=0):
|
||||
if self.sim is None:
|
||||
sim = self
|
||||
#if self._config_sim['trace']:
|
||||
# if self._config_sim['trace']:
|
||||
# sim = myhdl.traceSignals(self)
|
||||
self.sim = myhdl._Simulation.Simulation(sim)
|
||||
self.sim.run(duration, quiet)
|
||||
|
@ -359,13 +359,19 @@ def _writeSigDecls(f, intf, siglist, memlist):
|
||||
if not m._used:
|
||||
continue
|
||||
# infer attributes for the case of named signals in a list
|
||||
for i, s in enumerate(m.mem):
|
||||
for s in m.mem:
|
||||
if not m._driven and s._driven:
|
||||
m._driven = s._driven
|
||||
# once suffices
|
||||
break
|
||||
if not m._read and s._read:
|
||||
m._read = s._read
|
||||
# once suffices
|
||||
break
|
||||
|
||||
if not m._driven and not m._read:
|
||||
continue
|
||||
|
||||
r = _getRangeString(m.elObj)
|
||||
p = _getSignString(m.elObj)
|
||||
k = 'wire'
|
||||
@ -375,21 +381,23 @@ def _writeSigDecls(f, intf, siglist, memlist):
|
||||
|
||||
if toVerilog.initial_values and not k == 'wire':
|
||||
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;
|
||||
if toVerilog.initial_values == 'skip_zero_mem_init':
|
||||
pass
|
||||
else:
|
||||
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
|
||||
end
|
||||
''' % (initialize_block_name, len(m.mem), m.name,
|
||||
_intRepr(m.mem[0]._init)))
|
||||
''' % (initialize_block_name, len(m.mem), m.name,
|
||||
_intRepr(m.mem[0]._init)))
|
||||
|
||||
initial_assignments = (
|
||||
textwrap.dedent(_initial_assignments))
|
||||
initial_assignments = (
|
||||
textwrap.dedent(_initial_assignments))
|
||||
|
||||
else:
|
||||
val_assignments = '\n'.join(
|
||||
|
@ -115,7 +115,8 @@ class _VerificationClass(object):
|
||||
name = func.func.__name__
|
||||
else:
|
||||
warnings.warn(
|
||||
"\n analyze()/verify(): Deprecated usage: See http://dev.myhdl.org/meps/mep-114.html",
|
||||
"\n analyze()/verify(): Deprecated usage: See http://dev.myhdl.org/meps/mep-114.html"
|
||||
f"\n Found hdl = {hdl} - func is: {func}",
|
||||
stacklevel=2,
|
||||
category=DeprecationWarning,
|
||||
)
|
||||
|
@ -40,6 +40,22 @@ def ForLoopError2(a, out):
|
||||
return logic
|
||||
|
||||
|
||||
@block
|
||||
def ForLoopError3(a, out):
|
||||
|
||||
@instance
|
||||
def logic():
|
||||
while 1:
|
||||
yield a
|
||||
var = 0
|
||||
for i in range(1, 4, -1):
|
||||
if a[i] == 1:
|
||||
var += 1
|
||||
out.next = var
|
||||
|
||||
return logic
|
||||
|
||||
|
||||
@block
|
||||
def ForLoop1(a, out):
|
||||
|
||||
@ -386,6 +402,15 @@ def testForLoopError2():
|
||||
assert False
|
||||
|
||||
|
||||
def testForLoopError3():
|
||||
try:
|
||||
analyze(LoopBench(ForLoopError3))
|
||||
except ConversionError as e:
|
||||
assert e.kind == _error.Requirement
|
||||
else:
|
||||
assert False
|
||||
|
||||
|
||||
def testForLoop1():
|
||||
assert verify(LoopBench(ForLoop1)) == 0
|
||||
|
||||
|
@ -2,12 +2,13 @@ import os
|
||||
path = os.path
|
||||
from random import randrange
|
||||
|
||||
from myhdl import (Signal, intbv, delay, instance)
|
||||
from myhdl import (block, Signal, intbv, delay, instance)
|
||||
from myhdl.conversion import analyze
|
||||
from myhdl import ConversionError
|
||||
from myhdl.conversion._misc import _error
|
||||
|
||||
|
||||
@block
|
||||
def ForLoopError1(a, out):
|
||||
|
||||
@instance
|
||||
@ -23,6 +24,7 @@ def ForLoopError1(a, out):
|
||||
return logic
|
||||
|
||||
|
||||
@block
|
||||
def LoopBench(LoopTest):
|
||||
|
||||
a = Signal(intbv(-1)[16:])
|
||||
@ -43,7 +45,7 @@ def LoopBench(LoopTest):
|
||||
|
||||
def testForLoopError1():
|
||||
try:
|
||||
analyze(LoopBench, ForLoopError1)
|
||||
analyze(LoopBench(ForLoopError1))
|
||||
except ConversionError as e:
|
||||
assert e.kind == _error.Requirement
|
||||
else:
|
||||
|
Loading…
x
Reference in New Issue
Block a user