1
0
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:
Josy Boelen 2024-02-04 18:40:30 +01:00 committed by GitHub
parent 9f25c072f4
commit e95762e4ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 129 additions and 25 deletions

View File

@ -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):

View File

@ -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,10 +543,16 @@ 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:
if isinstance(m.mem[0]._init, EnumItemType):
_val_str = ',\n '.join(['{}'.format(each._init._toVHDL()) for
each in m.mem])
else: else:
_val_str = ',\n '.join( _val_str = ',\n '.join(
['%dX"%s"' % (obj.size, str(each._init)) for ['%dX"%s"' % (obj.size, str(each._init)) for

View File

@ -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,6 +500,9 @@ 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' ???
if isinstance(n, EnumItemType):
return n._toVerilog()
else:
p = abs(n) p = abs(n)
size = '' size = ''
num = str(p).rstrip('L') num = str(p).rstrip('L')
@ -509,8 +511,8 @@ def _intRepr(n, radix=''):
num = hex(p)[2:].rstrip('L') num = hex(p)[2:].rstrip('L')
if p >= 2 ** 30: if p >= 2 ** 30:
size = int(math.ceil(math.log(p + 1, 2))) + 1 # sign bit! size = int(math.ceil(math.log(p + 1, 2))) + 1 # sign bit!
# if not radix: # if not radix:
# radix = "'d" # radix = "'d"
r = "%s%s%s" % (size, radix, num) r = "%s%s%s" % (size, radix, num)
if n < 0: # add brackets and sign on negative numbers if n < 0: # add brackets and sign on negative numbers
r = "(-%s)" % r r = "(-%s)" % r

View 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)