mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
Init list of enums (#428)
* correct initial_values for List Of Signal(enum) * added dedicated test for ListOfSignal(enum)
This commit is contained in:
parent
9f25c072f4
commit
e95762e4ef
@ -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.44"
|
__version__ = "0.11.45"
|
||||||
|
|
||||||
|
|
||||||
class StopSimulation(Exception):
|
class StopSimulation(Exception):
|
||||||
|
@ -224,7 +224,6 @@ class _ToVHDLConvertor(object):
|
|||||||
raise ToVHDLError(_error.PortInList, portname)
|
raise ToVHDLError(_error.PortInList, portname)
|
||||||
# add enum types to port-related set
|
# add enum types to port-related set
|
||||||
if isinstance(s._val, EnumItemType):
|
if isinstance(s._val, EnumItemType):
|
||||||
print('EnumItemType', s._val)
|
|
||||||
obj = s._val._type
|
obj = s._val._type
|
||||||
if obj in _enumTypeSet:
|
if obj in _enumTypeSet:
|
||||||
_enumTypeSet.remove(obj)
|
_enumTypeSet.remove(obj)
|
||||||
@ -544,14 +543,20 @@ def _writeSigDecls(f, intf, siglist, memlist):
|
|||||||
val_str = (
|
val_str = (
|
||||||
' := (others => \'%s\')' % str(int(m.mem[0]._init)))
|
' := (others => \'%s\')' % str(int(m.mem[0]._init)))
|
||||||
|
|
||||||
|
elif isinstance(m.mem[0]._init, EnumItemType):
|
||||||
|
val_str = (' := (others => {})'.format(m.mem[0]._init._toVHDL()))
|
||||||
else:
|
else:
|
||||||
val_str = (
|
val_str = (
|
||||||
' := (others => %dX"%s")' %
|
' := (others => %dX"%s")' %
|
||||||
(sig_vhdl_objs[0].size, str(m.mem[0]._init)))
|
(sig_vhdl_objs[0].size, str(m.mem[0]._init)))
|
||||||
else:
|
else:
|
||||||
_val_str = ',\n '.join(
|
if isinstance(m.mem[0]._init, EnumItemType):
|
||||||
['%dX"%s"' % (obj.size, str(each._init)) for
|
_val_str = ',\n '.join(['{}'.format(each._init._toVHDL()) for
|
||||||
obj, each in zip(sig_vhdl_objs, m.mem)])
|
each in m.mem])
|
||||||
|
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 + ')'
|
val_str = ' := (\n ' + _val_str + ')'
|
||||||
|
|
||||||
|
@ -37,19 +37,18 @@ import warnings
|
|||||||
import myhdl
|
import myhdl
|
||||||
from myhdl import *
|
from myhdl import *
|
||||||
from myhdl import ToVerilogError, ToVerilogWarning
|
from myhdl import ToVerilogError, ToVerilogWarning
|
||||||
|
from myhdl._block import _Block
|
||||||
|
from myhdl._enum import EnumItemType
|
||||||
from myhdl._extractHierarchy import (_HierExtr, _isMem, _getMemInfo,
|
from myhdl._extractHierarchy import (_HierExtr, _isMem, _getMemInfo,
|
||||||
_UserVerilogCode, _userCodeMap)
|
_UserVerilogCode, _userCodeMap)
|
||||||
|
from myhdl._getHierarchy import _getHierarchy
|
||||||
from myhdl._instance import _Instantiator
|
from myhdl._instance import _Instantiator
|
||||||
|
from myhdl._Signal import _Signal, Constant
|
||||||
|
from myhdl._ShadowSignal import _TristateSignal, _TristateDriver
|
||||||
from myhdl.conversion._misc import (_error, _kind, _context,
|
from myhdl.conversion._misc import (_error, _kind, _context,
|
||||||
_ConversionMixin, _Label, _genUniqueSuffix, _isConstant)
|
_ConversionMixin, _Label, _genUniqueSuffix, _isConstant)
|
||||||
from myhdl.conversion._analyze import (_analyzeSigs, _analyzeGens, _analyzeTopFunc,
|
from myhdl.conversion._analyze import (_analyzeSigs, _analyzeGens, _analyzeTopFunc,
|
||||||
_Ram, _Rom)
|
_Ram, _Rom)
|
||||||
from myhdl._Signal import _Signal, Constant
|
|
||||||
from myhdl._ShadowSignal import _TristateSignal, _TristateDriver
|
|
||||||
|
|
||||||
from myhdl._block import _Block
|
|
||||||
from myhdl._getHierarchy import _getHierarchy
|
|
||||||
|
|
||||||
_converting = 0
|
_converting = 0
|
||||||
_profileFunc = None
|
_profileFunc = None
|
||||||
@ -501,20 +500,23 @@ def _intRepr(n, radix=''):
|
|||||||
# write size for large integers (beyond 32 bits signed)
|
# write size for large integers (beyond 32 bits signed)
|
||||||
# with some safety margin
|
# with some safety margin
|
||||||
# XXX signed indication 's' ???
|
# XXX signed indication 's' ???
|
||||||
p = abs(n)
|
if isinstance(n, EnumItemType):
|
||||||
size = ''
|
return n._toVerilog()
|
||||||
num = str(p).rstrip('L')
|
else:
|
||||||
if radix == "hex" or p >= 2 ** 30:
|
p = abs(n)
|
||||||
radix = "'h"
|
size = ''
|
||||||
num = hex(p)[2:].rstrip('L')
|
num = str(p).rstrip('L')
|
||||||
if p >= 2 ** 30:
|
if radix == "hex" or p >= 2 ** 30:
|
||||||
size = int(math.ceil(math.log(p + 1, 2))) + 1 # sign bit!
|
radix = "'h"
|
||||||
# if not radix:
|
num = hex(p)[2:].rstrip('L')
|
||||||
# radix = "'d"
|
if p >= 2 ** 30:
|
||||||
r = "%s%s%s" % (size, radix, num)
|
size = int(math.ceil(math.log(p + 1, 2))) + 1 # sign bit!
|
||||||
if n < 0: # add brackets and sign on negative numbers
|
# if not radix:
|
||||||
r = "(-%s)" % r
|
# radix = "'d"
|
||||||
return r
|
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):
|
def _convertGens(genlist, vfile):
|
||||||
|
97
myhdl/test/conversion/general/test_listofenums.py
Normal file
97
myhdl/test/conversion/general/test_listofenums.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
'''
|
||||||
|
Created on 4 feb. 2024
|
||||||
|
|
||||||
|
@author: josy
|
||||||
|
'''
|
||||||
|
|
||||||
|
from myhdl import (block, Signal, intbv, delay, always_comb, always_seq, enum,
|
||||||
|
always, instance, StopSimulation, ResetSignal, Constant,
|
||||||
|
conversion)
|
||||||
|
from myhdl import ConversionError
|
||||||
|
from myhdl.conversion._misc import _error
|
||||||
|
|
||||||
|
|
||||||
|
@block
|
||||||
|
def listofenums(Clk, Reset, Start, Progress, Ended):
|
||||||
|
listofenums_states = enum('IDLE', 'Doing_Nothing', 'Procrastinating', 'Getting_Ready', 'Executing', encoding='one_hot')
|
||||||
|
|
||||||
|
smn, smp = [Signal(listofenums_states.IDLE) for __ in range(2)]
|
||||||
|
stack = [Constant(listofenums_states.IDLE),
|
||||||
|
Constant(listofenums_states.Doing_Nothing),
|
||||||
|
Constant(listofenums_states.Procrastinating),
|
||||||
|
Constant(listofenums_states.Getting_Ready),
|
||||||
|
Constant(listofenums_states.Executing)]
|
||||||
|
NBR_STATES = len(stack)
|
||||||
|
stateindex = Signal(intbv(0)[3:])
|
||||||
|
|
||||||
|
@always_comb
|
||||||
|
def smcomb():
|
||||||
|
Ended.next = 0
|
||||||
|
|
||||||
|
# if smp == listofenums_states.IDLE:
|
||||||
|
if Start:
|
||||||
|
smn.next = stack[1]
|
||||||
|
# else:
|
||||||
|
# smn.next = smp
|
||||||
|
elif Progress:
|
||||||
|
if stateindex < NBR_STATES - 1:
|
||||||
|
smn.next = stack[stateindex + 1]
|
||||||
|
else:
|
||||||
|
smn.next = smp
|
||||||
|
else:
|
||||||
|
smn.next = smp
|
||||||
|
|
||||||
|
'''
|
||||||
|
note that if we exchange the two following lines
|
||||||
|
we get a failing conversion to VHDL (only; Verilog is fine ...)
|
||||||
|
'''
|
||||||
|
if smp == listofenums_states.Executing:
|
||||||
|
# if stateindex == NBR_STATES - 1:
|
||||||
|
Ended.next = 1
|
||||||
|
|
||||||
|
# smn.next = smp
|
||||||
|
# if smp == listofenums_states.IDLE:
|
||||||
|
# if Start:
|
||||||
|
# smn.next = listofenums_states.Doing_Nothing
|
||||||
|
#
|
||||||
|
# elif smp == listofenums_states.Doing_Nothing:
|
||||||
|
# if Start:
|
||||||
|
# smn.next = listofenums_states.Procrastinating
|
||||||
|
#
|
||||||
|
# elif smp == listofenums_states.Procrastinating:
|
||||||
|
# if Start:
|
||||||
|
# smn.next = listofenums_states.Getting_Ready
|
||||||
|
#
|
||||||
|
# elif smp == listofenums_states.Getting_Ready:
|
||||||
|
# if Start:
|
||||||
|
# smn.next = listofenums_states.Executing
|
||||||
|
#
|
||||||
|
# elif smp == listofenums_states.Executing:
|
||||||
|
# smn.next = listofenums_states.Executing
|
||||||
|
# Ended.next = 1
|
||||||
|
#
|
||||||
|
# else:
|
||||||
|
# smn.next = listofenums_states.IDLE
|
||||||
|
|
||||||
|
@always_seq(Clk.posedge, reset=Reset)
|
||||||
|
def smsync():
|
||||||
|
smp.next = smn
|
||||||
|
if Start or Progress:
|
||||||
|
if stateindex < NBR_STATES - 1:
|
||||||
|
stateindex.next = stateindex + 1
|
||||||
|
|
||||||
|
return smcomb, smsync
|
||||||
|
|
||||||
|
|
||||||
|
def test_listofenums():
|
||||||
|
Clk, Start, Progress, Ended = [Signal(bool(0)) for __ in range(4)]
|
||||||
|
Reset = ResetSignal(0, 1, False)
|
||||||
|
assert listofenums(Clk, Reset, Start, Progress, Ended).analyze_convert() == 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
Clk, Start, Progress, Ended = [Signal(bool(0)) for __ in range(4)]
|
||||||
|
Reset = ResetSignal(0, 1, False)
|
||||||
|
dfc = listofenums(Clk, Reset, Start, Progress, Ended)
|
||||||
|
dfc.convert(hdl='Verilog', initial_values=True)
|
||||||
|
dfc.convert(hdl='VHDL', initial_values=True)
|
Loading…
x
Reference in New Issue
Block a user