Added support for analog pad in Core2Chip & libresocio.

This commit is contained in:
Jean-Paul Chaput 2021-05-22 15:22:40 +02:00
parent fd67ca6cda
commit 3858461beb
3 changed files with 44 additions and 17 deletions

View File

@ -1,4 +1,4 @@
#
# This file is part of the Coriolis Software. # This file is part of the Coriolis Software.
# Copyright (c) SU 2020-2020, All Rights Reserved # Copyright (c) SU 2020-2020, All Rights Reserved
# #
@ -629,6 +629,7 @@ class IoPadConf ( object ):
def isClock ( self ): return self.flags & IoPadConf.CLOCK def isClock ( self ): return self.flags & IoPadConf.CLOCK
def isTristate ( self ): return self.flags & IoPadConf.TRISTATE def isTristate ( self ): return self.flags & IoPadConf.TRISTATE
def isBidir ( self ): return self.flags & IoPadConf.BIDIR def isBidir ( self ): return self.flags & IoPadConf.BIDIR
def isAnalog ( self ): return self._datas[0] & IoPin.ANALOG
def __repr__ ( self ): def __repr__ ( self ):
s = '<IoPadConf {} iopad="{}" from="{}"'.format(self.instanceName,self.padNetName,self.fromCoreNetName) s = '<IoPadConf {} iopad="{}" from="{}"'.format(self.instanceName,self.padNetName,self.fromCoreNetName)
@ -920,6 +921,7 @@ class IoPin ( object ):
WEST = 0x0008 WEST = 0x0008
A_BEGIN = 0x0010 A_BEGIN = 0x0010
A_END = 0x0020 A_END = 0x0020
ANALOG = 0x0040
A_MASK = A_BEGIN|A_END A_MASK = A_BEGIN|A_END
SIDE_MASK = EAST|WEST|NORTH|SOUTH SIDE_MASK = EAST|WEST|NORTH|SOUTH
@ -931,7 +933,8 @@ class IoPin ( object ):
, (IoPin.EAST , 'EAST' ) , (IoPin.EAST , 'EAST' )
, (IoPin.WEST , 'WEST' ) , (IoPin.WEST , 'WEST' )
, (IoPin.A_BEGIN, 'A_BEGIN') , (IoPin.A_BEGIN, 'A_BEGIN')
, (IoPin.A_END , 'A_END' ) ): , (IoPin.A_END , 'A_END' )
, (IoPin.ANALOG , 'ANALOG' ) ):
if value & constant: if value & constant:
if len(s): s += '|' if len(s): s += '|'
s += 'IoPin.'+name s += 'IoPin.'+name

View File

@ -86,6 +86,7 @@ class IoNet ( object ):
IsElem = 0x0001 IsElem = 0x0001
IsEnable = 0x0002 IsEnable = 0x0002
IsAnalog = 0x0004
DoExtNet = 0x0008 DoExtNet = 0x0008
PadPassthrough = 0x0010 PadPassthrough = 0x0010
reVHDLVector = re.compile( r'(?P<name>[^(]*)\((?P<index>[\d]+)\)$' ) reVHDLVector = re.compile( r'(?P<name>[^(]*)\((?P<index>[\d]+)\)$' )
@ -116,6 +117,7 @@ class IoNet ( object ):
def isElem ( self ): return self._flags & IoNet.IsElem def isElem ( self ): return self._flags & IoNet.IsElem
def isEnable ( self ): return self._flags & IoNet.IsEnable def isEnable ( self ): return self._flags & IoNet.IsEnable
def isAnalog ( self ): return self._flags & IoNet.IsAnalog
def isGlobal ( self ): return self.isGlobal( self._name ) def isGlobal ( self ): return self.isGlobal( self._name )
def isSpecial ( self ): return self._type != Net.Type.LOGICAL def isSpecial ( self ): return self._type != Net.Type.LOGICAL
def setFlags ( self, flags ): self._flags |= flags def setFlags ( self, flags ): self._flags |= flags
@ -137,9 +139,9 @@ class IoNet ( object ):
def coronaNetName ( self ): def coronaNetName ( self ):
s = self._name s = self._name
if self.coreNet.getDirection() & Net.Direction.IN: if self.coreNet.getDirection() & Net.Direction.IN:
s += '_from_pad' s += '_from_pad'
elif self.coreNet.getDirection() & Net.Direction.OUT: elif self.coreNet.getDirection() & Net.Direction.OUT:
s += '_to_pad' s += '_to_pad'
if self._flags & IoNet.IsElem: s += '({})'.format(self._index) if self._flags & IoNet.IsElem: s += '({})'.format(self._index)
return s return s
@ -169,6 +171,10 @@ class IoNet ( object ):
if state == True: self._flags |= IoNet.IsEnable if state == True: self._flags |= IoNet.IsEnable
else: self._flags &= ~IoNet.IsEnable else: self._flags &= ~IoNet.IsEnable
def setAnalog ( self, state ):
if state == True: self._flags |= IoNet.IsAnalog
else: self._flags &= ~IoNet.IsAnalog
def buildNets ( self ): def buildNets ( self ):
""" """
Creates the signals in corona and chip Cells, then connect them Creates the signals in corona and chip Cells, then connect them
@ -189,13 +195,15 @@ class IoNet ( object ):
self.coreToChip.icore.getPlug( self.coreNet ).setNet( self.coronaNet ) self.coreToChip.icore.getPlug( self.coreNet ).setNet( self.coronaNet )
# Chip "internal" net, connect Corona instance net to I/O inside the chip. # Chip "internal" net, connect Corona instance net to I/O inside the chip.
if not self.chipIntNet: if not self.chipIntNet:
internal_net = "internal_" + self.coronaNetName chipIntNetName = "internal_" + self.coronaNetName
self.chipIntNet = Net.create( self.coreToChip.chip, internal_net ) if self._flags & IoNet.IsAnalog:
chipIntNetName = self.coronaNetName
self.chipIntNet = Net.create( self.coreToChip.chip, chipIntNetName )
if netType != Net.Type.LOGICAL: if netType != Net.Type.LOGICAL:
self.chipIntNet.setType( netType ) self.chipIntNet.setType( netType )
self.coreToChip.icorona.getPlug( self.coronaNet ).setNet( self.chipIntNet ) self.coreToChip.icorona.getPlug( self.coronaNet ).setNet( self.chipIntNet )
# Chip "external" net, connected to the pad I/O to the outside world. # Chip "external" net, connected to the pad I/O to the outside world.
if self._flags & IoNet.PadPassthrough: if self._flags & (IoNet.PadPassthrough | IoNet.IsAnalog):
self.chipExtNet = self.chipIntNet self.chipExtNet = self.chipIntNet
elif not self.chipExtNet and (self._flags & IoNet.DoExtNet): elif not self.chipExtNet and (self._flags & IoNet.DoExtNet):
self.chipExtNet = self.coreToChip.chip.getNet( self.chipExtNetName ) self.chipExtNet = self.coreToChip.chip.getNet( self.chipExtNetName )
@ -225,7 +233,8 @@ class IoPad ( object ):
OUT = 0x0002 OUT = 0x0002
BIDIR = 0x0004 BIDIR = 0x0004
TRI_OUT = 0x0008 TRI_OUT = 0x0008
UNSUPPORTED = 0x0010 ANALOG = 0x0010
UNSUPPORTED = 0x0020
@staticmethod @staticmethod
def directionToStr ( direction ): def directionToStr ( direction ):
@ -233,6 +242,7 @@ class IoPad ( object ):
if direction == IoPad.OUT: return "OUT" if direction == IoPad.OUT: return "OUT"
if direction == IoPad.BIDIR: return "BIDIR" if direction == IoPad.BIDIR: return "BIDIR"
if direction == IoPad.TRI_OUT: return "TRI_OUT" if direction == IoPad.TRI_OUT: return "TRI_OUT"
if direction == IoPad.ANALOG: return "ANALOG"
if direction == IoPad.UNSUPPORTED: return "UNSUPPORTED" if direction == IoPad.UNSUPPORTED: return "UNSUPPORTED"
return "Invalid value" return "Invalid value"
@ -254,6 +264,7 @@ class IoPad ( object ):
s = '<IoPad "{}" '.format(self.padInstanceName) s = '<IoPad "{}" '.format(self.padInstanceName)
for ioNet in self.nets: for ioNet in self.nets:
s += ' {}'.format(ioNet.coreNetName) s += ' {}'.format(ioNet.coreNetName)
s += ' direction={}'.format(self.direction)
s += '>' s += '>'
return s return s
@ -266,7 +277,8 @@ class IoPad ( object ):
trace( 550, '\tIoPad.addNet() net={} iopad={}\n'.format(ioNet,self)) trace( 550, '\tIoPad.addNet() net={} iopad={}\n'.format(ioNet,self))
self.nets.append( ioNet ) self.nets.append( ioNet )
if len(self.nets) == 1: if len(self.nets) == 1:
if self.nets[0].coreNet.getDirection() == Net.Direction.IN: self.direction = IoPad.IN if self.nets[0].isAnalog(): self.direction = IoPad.ANALOG
elif self.nets[0].coreNet.getDirection() == Net.Direction.IN: self.direction = IoPad.IN
elif self.nets[0].coreNet.getDirection() == Net.Direction.OUT: self.direction = IoPad.OUT elif self.nets[0].coreNet.getDirection() == Net.Direction.OUT: self.direction = IoPad.OUT
elif self.nets[0].coreNet.getName() == 'scout': self.direction = IoPad.OUT elif self.nets[0].coreNet.getName() == 'scout': self.direction = IoPad.OUT
else: else:
@ -279,11 +291,11 @@ class IoPad ( object ):
if (self.direction == IoPad.OUT) \ if (self.direction == IoPad.OUT) \
and (self.coreToChip.getPadInfo(IoPad.TRI_OUT) is not None): and (self.coreToChip.getPadInfo(IoPad.TRI_OUT) is not None):
print( WarningMessage( 'IoPad.addNet(): No simple pad in direction {} for "{}", fallback to output tristate.' \ print( WarningMessage( 'IoPad.addNet(): No simple pad in direction {} for "{}", fallback to output tristate.' \
.format(netDirectionToStr(self.direction),ioNet.padInstanceName)) ) .format(IoPad.directionToStr(self.direction),ioNet.padInstanceName)) )
self.direction = IoPad.TRI_OUT self.direction = IoPad.TRI_OUT
else: else:
print( WarningMessage( 'IoPad.addNet(): No simple pad in direction {} for "{}", fallback to bi-directional.' \ print( WarningMessage( 'IoPad.addNet(): No simple pad in direction {} for "{}", fallback to bi-directional.' \
.format(netDirectionToStr(self.direction),ioNet.padInstanceName)) ) .format(IoPad.directionToStr(self.direction),ioNet.padInstanceName)) )
self.direction = IoPad.BIDIR self.direction = IoPad.BIDIR
elif len(self.nets) == 2: elif len(self.nets) == 2:
if self.direction != IoPad.BIDIR: if self.direction != IoPad.BIDIR:
@ -305,6 +317,7 @@ class IoPad ( object ):
enable signal (if any) do not need an external chip signal enable signal (if any) do not need an external chip signal
(it is *not* connected to the outside world). (it is *not* connected to the outside world).
""" """
trace( 550, '\tIoPad.createPad() {}\n'.format( self ))
padInfo = self.coreToChip.getPadInfo( self.direction ) padInfo = self.coreToChip.getPadInfo( self.direction )
if padInfo is None: if padInfo is None:
if len(self.nets) == 0: if len(self.nets) == 0:
@ -317,8 +330,12 @@ class IoPad ( object ):
, IoPad.directionToStr(self.direction) , IoPad.directionToStr(self.direction)
, self.padInstanceName )) , self.padInstanceName ))
connexions = [] connexions = []
# Case of BIDIR as fallback for simple IN/OUT. if (self.direction == IoPad.ANALOG):
self.nets[0].buildNets()
connexions.append( ( self.nets[0].chipExtNet , padInfo.padNet ) )
connexions.append( ( self.coreToChip.newDummyNet(), padInfo.coreNets[1] ) )
if (self.direction == IoPad.BIDIR) and (len(self.nets) < 3): if (self.direction == IoPad.BIDIR) and (len(self.nets) < 3):
# Case of BIDIR as fallback for simple IN/OUT.
self.nets[0].setFlags( IoNet.DoExtNet ) self.nets[0].setFlags( IoNet.DoExtNet )
self.nets[0].buildNets() self.nets[0].buildNets()
if len(self.nets) < 2: if len(self.nets) < 2:
@ -658,11 +675,14 @@ class CoreToChip ( object ):
.format(ioPadConf.instanceName,netName,self.core.getName()) )) .format(ioPadConf.instanceName,netName,self.core.getName()) ))
continue continue
ioNet = self.getIoNet( coreNet ) ioNet = self.getIoNet( coreNet )
if ioPadConf.isBidir() or ioPadConf.isTristate(): if ioPadConf.isAnalog():
if coreNet.getName() == ioPadConf.enableNetName: ioNet.setAnalog( True )
ioNet.setEnable( True ) else:
if not ioNet.isEnable(): if ioPadConf.isBidir() or ioPadConf.isTristate():
ioNet.chipExtNetName = ioPadConf.padNetName if coreNet.getName() == ioPadConf.enableNetName:
ioNet.setEnable( True )
if not ioNet.isEnable():
ioNet.chipExtNetName = ioPadConf.padNetName
ioPadConf.udata.addNet( ioNet ) ioPadConf.udata.addNet( ioNet )
ioPads.append( ioPadConf ) ioPads.append( ioPadConf )
trace( 550, '\tProcessed all IoPadConf, looking for orphaned core nets...\n' ) trace( 550, '\tProcessed all IoPadConf, looking for orphaned core nets...\n' )

View File

@ -56,6 +56,7 @@ class CoreToChip ( BaseCoreToChip ):
self.ioPadNames = { 'in' :'IOPadIn' self.ioPadNames = { 'in' :'IOPadIn'
, 'tri_out' :'IOPadOut' , 'tri_out' :'IOPadOut'
, 'bidir' :'IOPadInOut' , 'bidir' :'IOPadInOut'
, 'analog' :'IOPadAnalog'
, 'vdd' :'IOPadVdd' , 'vdd' :'IOPadVdd'
, 'vss' :'IOPadVss' , 'vss' :'IOPadVss'
, 'iovdd' :'IOPadIOVdd' , 'iovdd' :'IOPadIOVdd'
@ -76,6 +77,9 @@ class CoreToChip ( BaseCoreToChip ):
, BaseCoreToChip.IoPadInfo( IoPad.BIDIR , BaseCoreToChip.IoPadInfo( IoPad.BIDIR
, self.ioPadNames['bidir'] , self.ioPadNames['bidir']
, 'pad', ['s', 'd', 'de'] ) , 'pad', ['s', 'd', 'de'] )
, BaseCoreToChip.IoPadInfo( IoPad.ANALOG
, self.ioPadNames['analog']
, 'pad', ['pad', 'padres'] )
] ]
self._getPadLib() self._getPadLib()
return return