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
|
toVerilog -- function that converts a design to Verilog
|
||||||
|
|
||||||
"""
|
"""
|
||||||
__version__ = "0.11.46"
|
__version__ = "0.11.47"
|
||||||
|
|
||||||
|
|
||||||
class StopSimulation(Exception):
|
class StopSimulation(Exception):
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
""" Block with the @block decorator function. """
|
""" Block with the @block decorator function. """
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
#from functools import wraps
|
# from functools import wraps
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
import myhdl
|
import myhdl
|
||||||
@ -34,8 +34,11 @@ from myhdl._Signal import _Signal, _isListOfSigs
|
|||||||
|
|
||||||
from weakref import WeakValueDictionary
|
from weakref import WeakValueDictionary
|
||||||
|
|
||||||
|
|
||||||
class _error:
|
class _error:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
_error.ArgType = "%s: A block should return block or instantiator objects"
|
_error.ArgType = "%s: A block should return block or instantiator objects"
|
||||||
_error.InstanceError = "%s: subblock %s should be encapsulated in a block decorator"
|
_error.InstanceError = "%s: subblock %s should be encapsulated in a block decorator"
|
||||||
|
|
||||||
@ -87,15 +90,16 @@ def _getCallInfo():
|
|||||||
return _CallInfo(name, modctxt, symdict)
|
return _CallInfo(name, modctxt, symdict)
|
||||||
|
|
||||||
|
|
||||||
### I don't think this is the right place for uniqueifying the name.
|
# ## 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
|
# ## 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.
|
# ## there should not be the corresponding global state to be maintained here.
|
||||||
### The name should be whatever it is, which is then uniqueified at
|
# ## The name should be whatever it is, which is then uniqueified at
|
||||||
### conversion time. Perhaps this happens already (FIXME - check and fix)
|
# ## conversion time. Perhaps this happens already (FIXME - check and fix)
|
||||||
### ~ H Gomersall 24/11/2017
|
# ## ~ H Gomersall 24/11/2017
|
||||||
_inst_name_set = set()
|
_inst_name_set = set()
|
||||||
_name_set = set()
|
_name_set = set()
|
||||||
|
|
||||||
|
|
||||||
def _uniqueify_name(proposed_name):
|
def _uniqueify_name(proposed_name):
|
||||||
'''Creates a unique block name from the proposed name by appending
|
'''Creates a unique block name from the proposed name by appending
|
||||||
a suitable number to the end. Every name this function returns is
|
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,
|
return _Block(self.bound_func, self, name, self.srcfile,
|
||||||
self.srcline, *args, **kwargs)
|
self.srcline, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class block(object):
|
class block(object):
|
||||||
|
|
||||||
def __init__(self, func):
|
def __init__(self, func):
|
||||||
@ -304,14 +309,27 @@ class _Block(object):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
hdl (Optional[str]): Target HDL. Defaults to Verilog
|
hdl (Optional[str]): Target HDL. Defaults to Verilog
|
||||||
|
|
||||||
path (Optional[str]): Destination folder. Defaults to current
|
path (Optional[str]): Destination folder. Defaults to current
|
||||||
working dir.
|
working dir.
|
||||||
|
|
||||||
name (Optional[str]): Module and output file name. Defaults to
|
name (Optional[str]): Module and output file name. Defaults to
|
||||||
`self.mod.__name__`
|
`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
|
trace(Optional[bool]): Verilog only. Whether the testbench should
|
||||||
dump all signal waveforms. Defaults to False.
|
dump all signal waveforms. Defaults to False.
|
||||||
|
|
||||||
testbench (Optional[bool]): Verilog only. Specifies whether a
|
testbench (Optional[bool]): Verilog only. Specifies whether a
|
||||||
testbench should be created. Defaults to True.
|
testbench should be created. Defaults to True.
|
||||||
|
|
||||||
timescale(Optional[str]): Verilog only. Defaults to '1ns/10ps'
|
timescale(Optional[str]): Verilog only. Defaults to '1ns/10ps'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -337,17 +355,17 @@ class _Block(object):
|
|||||||
setattr(converter, k, v)
|
setattr(converter, k, v)
|
||||||
return converter(self)
|
return converter(self)
|
||||||
|
|
||||||
def config_sim(self, trace=False, **kwargs) :
|
def config_sim(self, trace=False, **kwargs):
|
||||||
self._config_sim['trace'] = trace
|
self._config_sim['trace'] = trace
|
||||||
if trace:
|
if trace:
|
||||||
for k, v in kwargs.items() :
|
for k, v in kwargs.items():
|
||||||
setattr(myhdl.traceSignals, k, v)
|
setattr(myhdl.traceSignals, k, v)
|
||||||
myhdl.traceSignals(self)
|
myhdl.traceSignals(self)
|
||||||
|
|
||||||
def run_sim(self, duration=None, quiet=0):
|
def run_sim(self, duration=None, quiet=0):
|
||||||
if self.sim is None:
|
if self.sim is None:
|
||||||
sim = self
|
sim = self
|
||||||
#if self._config_sim['trace']:
|
# if self._config_sim['trace']:
|
||||||
# sim = myhdl.traceSignals(self)
|
# sim = myhdl.traceSignals(self)
|
||||||
self.sim = myhdl._Simulation.Simulation(sim)
|
self.sim = myhdl._Simulation.Simulation(sim)
|
||||||
self.sim.run(duration, quiet)
|
self.sim.run(duration, quiet)
|
||||||
|
@ -359,13 +359,19 @@ def _writeSigDecls(f, intf, siglist, memlist):
|
|||||||
if not m._used:
|
if not m._used:
|
||||||
continue
|
continue
|
||||||
# infer attributes for the case of named signals in a list
|
# 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:
|
if not m._driven and s._driven:
|
||||||
m._driven = s._driven
|
m._driven = s._driven
|
||||||
|
# once suffices
|
||||||
|
break
|
||||||
if not m._read and s._read:
|
if not m._read and s._read:
|
||||||
m._read = s._read
|
m._read = s._read
|
||||||
|
# once suffices
|
||||||
|
break
|
||||||
|
|
||||||
if not m._driven and not m._read:
|
if not m._driven and not m._read:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
r = _getRangeString(m.elObj)
|
r = _getRangeString(m.elObj)
|
||||||
p = _getSignString(m.elObj)
|
p = _getSignString(m.elObj)
|
||||||
k = 'wire'
|
k = 'wire'
|
||||||
@ -375,21 +381,23 @@ def _writeSigDecls(f, intf, siglist, memlist):
|
|||||||
|
|
||||||
if toVerilog.initial_values and not k == 'wire':
|
if toVerilog.initial_values and not k == 'wire':
|
||||||
if all([each._init == m.mem[0]._init for each in m.mem]):
|
if all([each._init == m.mem[0]._init for each in m.mem]):
|
||||||
|
if toVerilog.initial_values == 'skip_zero_mem_init':
|
||||||
initialize_block_name = ('INITIALIZE_' + m.name).upper()
|
pass
|
||||||
_initial_assignments = (
|
else:
|
||||||
'''
|
initialize_block_name = ('INITIALIZE_' + m.name).upper()
|
||||||
initial begin: %s
|
_initial_assignments = (
|
||||||
integer i;
|
'''
|
||||||
for(i=0; i<%d; i=i+1) begin
|
initial begin: %s
|
||||||
%s[i] = %s;
|
integer i;
|
||||||
|
for(i=0; i<%d; i=i+1) begin
|
||||||
|
%s[i] = %s;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
''' % (initialize_block_name, len(m.mem), m.name,
|
||||||
''' % (initialize_block_name, len(m.mem), m.name,
|
_intRepr(m.mem[0]._init)))
|
||||||
_intRepr(m.mem[0]._init)))
|
|
||||||
|
|
||||||
initial_assignments = (
|
initial_assignments = (
|
||||||
textwrap.dedent(_initial_assignments))
|
textwrap.dedent(_initial_assignments))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
val_assignments = '\n'.join(
|
val_assignments = '\n'.join(
|
||||||
|
@ -115,7 +115,8 @@ class _VerificationClass(object):
|
|||||||
name = func.func.__name__
|
name = func.func.__name__
|
||||||
else:
|
else:
|
||||||
warnings.warn(
|
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,
|
stacklevel=2,
|
||||||
category=DeprecationWarning,
|
category=DeprecationWarning,
|
||||||
)
|
)
|
||||||
|
@ -40,6 +40,22 @@ def ForLoopError2(a, out):
|
|||||||
return logic
|
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
|
@block
|
||||||
def ForLoop1(a, out):
|
def ForLoop1(a, out):
|
||||||
|
|
||||||
@ -386,6 +402,15 @@ def testForLoopError2():
|
|||||||
assert False
|
assert False
|
||||||
|
|
||||||
|
|
||||||
|
def testForLoopError3():
|
||||||
|
try:
|
||||||
|
analyze(LoopBench(ForLoopError3))
|
||||||
|
except ConversionError as e:
|
||||||
|
assert e.kind == _error.Requirement
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
|
||||||
def testForLoop1():
|
def testForLoop1():
|
||||||
assert verify(LoopBench(ForLoop1)) == 0
|
assert verify(LoopBench(ForLoop1)) == 0
|
||||||
|
|
||||||
|
@ -2,12 +2,13 @@ import os
|
|||||||
path = os.path
|
path = os.path
|
||||||
from random import randrange
|
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.conversion import analyze
|
||||||
from myhdl import ConversionError
|
from myhdl import ConversionError
|
||||||
from myhdl.conversion._misc import _error
|
from myhdl.conversion._misc import _error
|
||||||
|
|
||||||
|
|
||||||
|
@block
|
||||||
def ForLoopError1(a, out):
|
def ForLoopError1(a, out):
|
||||||
|
|
||||||
@instance
|
@instance
|
||||||
@ -23,6 +24,7 @@ def ForLoopError1(a, out):
|
|||||||
return logic
|
return logic
|
||||||
|
|
||||||
|
|
||||||
|
@block
|
||||||
def LoopBench(LoopTest):
|
def LoopBench(LoopTest):
|
||||||
|
|
||||||
a = Signal(intbv(-1)[16:])
|
a = Signal(intbv(-1)[16:])
|
||||||
@ -43,7 +45,7 @@ def LoopBench(LoopTest):
|
|||||||
|
|
||||||
def testForLoopError1():
|
def testForLoopError1():
|
||||||
try:
|
try:
|
||||||
analyze(LoopBench, ForLoopError1)
|
analyze(LoopBench(ForLoopError1))
|
||||||
except ConversionError as e:
|
except ConversionError as e:
|
||||||
assert e.kind == _error.Requirement
|
assert e.kind == _error.Requirement
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user