diff --git a/SDFTools/examples/example1/test.dot b/SDFTools/examples/example1/test.dot
index 8a8797ef..4dff5dc5 100755
--- a/SDFTools/examples/example1/test.dot
+++ b/SDFTools/examples/example1/test.dot
@@ -31,9 +31,17 @@ source [label=<
-source:i -> filter:i [headlabel=<7>,taillabel=<5>,label="f32(11)"]
-
-filter:i -> sink:i [headlabel=<5>,taillabel=<5>,label="f32(5)"]
+source:i -> filter:i [headlabel=<
+
>,taillabel=<
+>,label="f32(11)"]
+
+filter:i -> sink:i [headlabel=<
+>,taillabel=<
+>,label="f32(5)"]
}
diff --git a/SDFTools/examples/example1/test.pdf b/SDFTools/examples/example1/test.pdf
index b3c1f012..82166212 100755
Binary files a/SDFTools/examples/example1/test.pdf and b/SDFTools/examples/example1/test.pdf differ
diff --git a/SDFTools/examples/example2/test.dot b/SDFTools/examples/example2/test.dot
index dc3a90e0..6bb73e30 100755
--- a/SDFTools/examples/example2/test.dot
+++ b/SDFTools/examples/example2/test.dot
@@ -23,13 +23,13 @@ arm_add_f321 [label=<
arm_add_f32 (CMSIS-DSP) |
o |
-
+
| ib |
- |
-
->];
+
+ |
+>];
arm_scale_f321 [label=<
@@ -39,13 +39,13 @@ arm_scale_f321 [label=<
arm_scale_f32 (CMSIS-DSP) |
o |
-
+
| ib |
- |
-
->];
+
+ |
+>];
arm_scale_f322 [label=<
@@ -55,13 +55,13 @@ arm_scale_f322 [label=<
arm_scale_f32 (CMSIS-DSP) |
o |
-
+
| ib |
- |
-
->];
+
+ |
+>];
audioWin [label=<
@@ -99,7 +99,8 @@ toMono [label=<
toMono (Unzip) |
o1 |
-
+
+
|
o2 |
@@ -107,7 +108,6 @@ toMono [label=<
>];
-
srcDelay [label=<
@@ -116,26 +116,62 @@ srcDelay [label=<
>];
-src:i -> srcDelay:i [taillabel=<320>]
-
-srcDelay:i -> toMono:i [headlabel=<320>,label="f32(330)"]
-
-
-toMono:o1 -> arm_scale_f321:ia [headlabel=<160>,taillabel=<160>,label="f32(160)"]
-
-toMono:o2 -> arm_scale_f322:ia [headlabel=<160>,taillabel=<160>,label="f32(160)"]
-
-arm_scale_f321:o -> arm_add_f321:ia [headlabel=<160>,taillabel=<160>,label="f32(160)"]
-
-arm_scale_f322:o -> arm_add_f321:ib [headlabel=<160>,taillabel=<160>,label="f32(160)"]
-
-arm_add_f321:o -> audioWin:i [headlabel=<320>,taillabel=<160>,label="f32(320)"]
-
-audioWin:i -> mfcc:i [headlabel=<640>,taillabel=<640>,label="f32(640)"]
-
-mfcc:i -> mfccWind:i [headlabel=<250>,taillabel=<10>,label="f32(250)"]
-
-mfccWind:i -> TFLite:i [headlabel=<500>,taillabel=<500>,label="f32(500)"]
+src:i -> srcDelay:i [taillabel=<
+>]
+
+srcDelay:i -> toMono:i [headlabel=<
+>,label="f32(330)"]
+
+
+toMono:o1 -> arm_scale_f321:ia [headlabel=<
+>,taillabel=<
+>,label="f32(160)"]
+
+toMono:o2 -> arm_scale_f322:ia [headlabel=<
+>,taillabel=<
+>,label="f32(160)"]
+
+arm_scale_f321:o -> arm_add_f321:ia [headlabel=<
+>,taillabel=<
+>,label="f32(160)"]
+
+arm_scale_f322:o -> arm_add_f321:ib [headlabel=<
+>,taillabel=<
+>,label="f32(160)"]
+
+arm_add_f321:o -> audioWin:i [headlabel=<
+>,taillabel=<
+>,label="f32(320)"]
+
+audioWin:i -> mfcc:i [headlabel=<
+>,taillabel=<
+>,label="f32(640)"]
+
+mfcc:i -> mfccWind:i [headlabel=<
+>,taillabel=<
+>,label="f32(250)"]
+
+mfccWind:i -> TFLite:i [headlabel=<
+>,taillabel=<
+>,label="f32(500)"]
HALF [label=<
diff --git a/SDFTools/examples/example2/test.pdf b/SDFTools/examples/example2/test.pdf
index 38415ac6..485a0e51 100755
Binary files a/SDFTools/examples/example2/test.pdf and b/SDFTools/examples/example2/test.pdf differ
diff --git a/SDFTools/examples/example3/test.dot b/SDFTools/examples/example3/test.dot
index 4c072ec7..87632a28 100755
--- a/SDFTools/examples/example3/test.dot
+++ b/SDFTools/examples/example3/test.dot
@@ -16,13 +16,13 @@ arm_mult_f321 [label=<
arm_mult_f32 (CMSIS-DSP) |
o |
-
+
| ib |
- |
-
-
>];
+
+ |
+>];
audioOverlap [label=<
@@ -82,21 +82,53 @@ toReal [label=<
-src:i -> audioWin:i [headlabel=<128>,taillabel=<192>,label="f32(256)"]
-
-audioWin:i -> arm_mult_f321:ia [headlabel=<256>,taillabel=<256>,label="f32(256)"]
-
-arm_mult_f321:o -> toCmplx:i [headlabel=<256>,taillabel=<256>,label="f32(256)"]
-
-toCmplx:i -> cfft:i [headlabel=<512>,taillabel=<512>,label="f32(512)"]
-
-cfft:i -> icfft:i [headlabel=<512>,taillabel=<512>,label="f32(512)"]
-
-icfft:i -> toReal:i [headlabel=<512>,taillabel=<512>,label="f32(512)"]
-
-toReal:i -> audioOverlap:i [headlabel=<256>,taillabel=<256>,label="f32(256)"]
-
-audioOverlap:i -> sink:i [headlabel=<192>,taillabel=<128>,label="f32(256)"]
+src:i -> audioWin:i [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
+
+audioWin:i -> arm_mult_f321:ia [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
+
+arm_mult_f321:o -> toCmplx:i [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
+
+toCmplx:i -> cfft:i [headlabel=<
+>,taillabel=<
+>,label="f32(512)"]
+
+cfft:i -> icfft:i [headlabel=<
+>,taillabel=<
+>,label="f32(512)"]
+
+icfft:i -> toReal:i [headlabel=<
+>,taillabel=<
+>,label="f32(512)"]
+
+toReal:i -> audioOverlap:i [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
+
+audioOverlap:i -> sink:i [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
HANN [label=<
diff --git a/SDFTools/examples/example3/test.pdf b/SDFTools/examples/example3/test.pdf
index c4360537..5c1db1b7 100755
Binary files a/SDFTools/examples/example3/test.pdf and b/SDFTools/examples/example3/test.pdf differ
diff --git a/SDFTools/examples/example4/test.dot b/SDFTools/examples/example4/test.dot
index 4c072ec7..87632a28 100755
--- a/SDFTools/examples/example4/test.dot
+++ b/SDFTools/examples/example4/test.dot
@@ -16,13 +16,13 @@ arm_mult_f321 [label=<
arm_mult_f32 (CMSIS-DSP) |
o |
-
+
| ib |
- |
-
-
>];
+
+ |
+
>];
audioOverlap [label=<
@@ -82,21 +82,53 @@ toReal [label=<
-src:i -> audioWin:i [headlabel=<128>,taillabel=<192>,label="f32(256)"]
-
-audioWin:i -> arm_mult_f321:ia [headlabel=<256>,taillabel=<256>,label="f32(256)"]
-
-arm_mult_f321:o -> toCmplx:i [headlabel=<256>,taillabel=<256>,label="f32(256)"]
-
-toCmplx:i -> cfft:i [headlabel=<512>,taillabel=<512>,label="f32(512)"]
-
-cfft:i -> icfft:i [headlabel=<512>,taillabel=<512>,label="f32(512)"]
-
-icfft:i -> toReal:i [headlabel=<512>,taillabel=<512>,label="f32(512)"]
-
-toReal:i -> audioOverlap:i [headlabel=<256>,taillabel=<256>,label="f32(256)"]
-
-audioOverlap:i -> sink:i [headlabel=<192>,taillabel=<128>,label="f32(256)"]
+src:i -> audioWin:i [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
+
+audioWin:i -> arm_mult_f321:ia [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
+
+arm_mult_f321:o -> toCmplx:i [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
+
+toCmplx:i -> cfft:i [headlabel=<
+>,taillabel=<
+>,label="f32(512)"]
+
+cfft:i -> icfft:i [headlabel=<
+>,taillabel=<
+>,label="f32(512)"]
+
+icfft:i -> toReal:i [headlabel=<
+>,taillabel=<
+>,label="f32(512)"]
+
+toReal:i -> audioOverlap:i [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
+
+audioOverlap:i -> sink:i [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
HANN [label=<
diff --git a/SDFTools/examples/example4/test.pdf b/SDFTools/examples/example4/test.pdf
index c4360537..5c1db1b7 100755
Binary files a/SDFTools/examples/example4/test.pdf and b/SDFTools/examples/example4/test.pdf differ
diff --git a/SDFTools/examples/example5/test.dot b/SDFTools/examples/example5/test.dot
index 2bbf4bd7..b28b8dee 100755
--- a/SDFTools/examples/example5/test.dot
+++ b/SDFTools/examples/example5/test.dot
@@ -52,15 +52,35 @@ toMono [label=<
-src:i -> toMono:i [headlabel=<384>,taillabel=<384>,label="q15(384)"]
-
-toMono:i -> audioWin:i [headlabel=<768>,taillabel=<192>,label="q15(768)"]
-
-audioWin:i -> mfcc:i [headlabel=<1024>,taillabel=<1024>,label="q15(1024)"]
-
-mfcc:i -> mfccWin:i [headlabel=<377>,taillabel=<13>,label="q15(377)"]
-
-mfccWin:i -> sink:i [headlabel=<754>,taillabel=<754>,label="q15(754)"]
+src:i -> toMono:i [headlabel=<
+>,taillabel=<
+>,label="q15(384)"]
+
+toMono:i -> audioWin:i [headlabel=<
+>,taillabel=<
+>,label="q15(768)"]
+
+audioWin:i -> mfcc:i [headlabel=<
+>,taillabel=<
+>,label="q15(1024)"]
+
+mfcc:i -> mfccWin:i [headlabel=<
+>,taillabel=<
+>,label="q15(377)"]
+
+mfccWin:i -> sink:i [headlabel=<
+>,taillabel=<
+>,label="q15(754)"]
}
diff --git a/SDFTools/examples/example5/test.pdf b/SDFTools/examples/example5/test.pdf
index bac671a5..ce5864fb 100755
Binary files a/SDFTools/examples/example5/test.pdf and b/SDFTools/examples/example5/test.pdf differ
diff --git a/SDFTools/examples/example6/test.dot b/SDFTools/examples/example6/test.dot
index 5d03f6b6..76451a60 100755
--- a/SDFTools/examples/example6/test.dot
+++ b/SDFTools/examples/example6/test.dot
@@ -45,13 +45,29 @@ src [label=<
-src:i -> audioWin:i [headlabel=<128>,taillabel=<192>,label="f32(256)"]
-
-audioWin:i -> mfcc:i [headlabel=<256>,taillabel=<256>,label="f32(256)"]
-
-mfcc:i -> mfccWin:i [headlabel=<13>,taillabel=<13>,label="f32(13)"]
-
-mfccWin:i -> sink:i [headlabel=<13>,taillabel=<26>,label="f32(26)"]
+src:i -> audioWin:i [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
+
+audioWin:i -> mfcc:i [headlabel=<
+>,taillabel=<
+>,label="f32(256)"]
+
+mfcc:i -> mfccWin:i [headlabel=<
+>,taillabel=<
+>,label="f32(13)"]
+
+mfccWin:i -> sink:i [headlabel=<
+>,taillabel=<
+>,label="f32(26)"]
}
diff --git a/SDFTools/examples/example6/test.pdf b/SDFTools/examples/example6/test.pdf
index dcf9b4c8..f4c0c35b 100755
Binary files a/SDFTools/examples/example6/test.pdf and b/SDFTools/examples/example6/test.pdf differ
diff --git a/SDFTools/sdf/schedule/config.py b/SDFTools/sdf/schedule/config.py
index ae47021a..1a7afc6d 100755
--- a/SDFTools/sdf/schedule/config.py
+++ b/SDFTools/sdf/schedule/config.py
@@ -68,6 +68,9 @@ class Configuration:
# True for an horizontal graphviz layout
self.horizontal = True
+ # Display FIFO buffers in graph instead of datatype
+ self.displayFIFOBuf = False
+
@property
def debug(self):
return (self.debugLimit > 0)
diff --git a/SDFTools/sdf/schedule/description.py b/SDFTools/sdf/schedule/description.py
index 3e14729f..c276fbaf 100755
--- a/SDFTools/sdf/schedule/description.py
+++ b/SDFTools/sdf/schedule/description.py
@@ -40,6 +40,9 @@ from sdf.schedule.node import *
from sdf.schedule.config import *
from sdf.schedule.types import *
+# To debug graph coloring for memory optimization
+#import matplotlib.pyplot as plt
+
class IncompatibleIO(Exception):
pass
@@ -67,16 +70,14 @@ class FIFODesc:
def __init__(self,fifoid):
# The FIFO is in fact just an array
self.isArray=False
- # Max distance between a write and a read to the FIFO
- # If it is 1, data written to FIFO
- # is immediately read so buffer can be reused
- self.distance=1
# FIFO length
self.length=0
# FIFO type
self.theType=None
# Buffer used by FIFO
self.buffer=None
+ # Used for plot in graphviz
+ self.bufferID=-1
self._fifoID=fifoid
# Source IO
self.src = None
@@ -84,15 +85,16 @@ class FIFODesc:
self.dst = None
# FIFO delay
self.delay=0
- # Can use a shared buffer ?
- self.isShared = False
-
- self._writeTime= 0
- # Track when FIFO is used
- # For allocation of shared buffers we need
- # to know when 2 buffers are used at same time
- self._timeOfUse=[]
+ # Used for liveliness analysis
+ # To share buffers between FIFO in memory optimization
+ # mode, we need to know when a FIFO is in use.
+ # We compute the maximum extent : so the biggest interval
+ # and not a disconnected union of intervals
+ # This could be improved. We could use
+ # a disjoint union of intervals but they should be mapped
+ # to the same node in the interference graph
+ self._liveInterval=(-1,-1)
# shared buffer number not yet allocated
self.sharedNB=-1
@@ -110,36 +112,31 @@ class FIFODesc:
return(self.delay>0)
def dump(self):
- shared=0
- if self.isShared:
- shared=1
- print("array %d dist %d len %d %s id %d src %s:%s dst %s:%s shared:%d" %
+
+ print("array %d len %d %s id %d src %s:%s dst %s:%s " %
(self.isArray,
- self.distance,
self.length,
self.theType.ctype,
self.fifoID,
self.src.owner.nodeID,
self.src.name,
self.dst.owner.nodeID,
- self.dst.name,
- shared))
+ self.dst.name))
@property
def fifoID(self):
return self._fifoID
def recordWrite(self,theTime):
- self._timeOfUse.append(theTime)
- if self._writeTime == 0:
- self._writeTime = theTime
+ start,stop=self._liveInterval
+ if start==-1:
+ self._liveInterval=(theTime,stop)
def recordRead(self,theTime):
- self._timeOfUse.append(theTime)
- delta = theTime - self._writeTime
- self._writeTime = 0
- if delta > self.distance:
- self.distance = delta
+ start,stop=self._liveInterval
+ if (theTime > stop):
+ self._liveInterval=(start,theTime)
+
def analyzeStep(vec,allFIFOs,theTime):
"""Analyze an evolution step to know which FIFOs are read and written to"""
@@ -209,7 +206,7 @@ class Graph():
return(res)
- def initializeFIFODescriptions(self,config,allFIFOs, fifoLengths):
+ def initializeFIFODescriptions(self,config,allFIFOs, fifoLengths,maxTime):
"""Initialize FIFOs datastructure"""
for fifo in allFIFOs:
edge = self._sortedEdges[fifo.fifoID]
@@ -218,113 +215,126 @@ class Graph():
fifo.src=src
fifo.dst=dst
fifo.delay=self.getDelay(edge)
+ # When a FIFO is working as an array then its buffer may
+ # potentially be shared with other FIFOs workign as arrays
if src.nbSamples == dst.nbSamples:
if fifo.delay==0:
fifo.isArray = True
- if fifo.distance==1:
- if fifo.delay==0:
- fifo.isShared = True
fifo.theType = src.theType
#fifo.dump()
- # When we have bufA -> Node -> bufB then
- # bufA and bufB can't share the same memory.
- # For the allocation of shared buffer we scan all times
- # of use and for each time we look at the FIFOs which
- # can be potentially shared.
+ bufferID=0
+ allBuffers=[]
- # For each time of use, record the potentially shareable fifos
- # which are used
- fifoForTime={}
- for fifo in allFIFOs:
- if fifo.isShared:
- for t in fifo._timeOfUse:
- if t in fifoForTime:
- fifoForTime[t].append(fifo)
- else:
- fifoForTime[t]=[fifo]
-
- # If several shareable FIFOs are used at same time, they
- # must be assigned to different shared buffers if possible
- usedAtSameTime={}
- for t in sorted(fifoForTime.keys()):
- if len(fifoForTime[t])>2:
- # This case is not managed in this version.
- # It could occur with quadripoles for instance
- for fifo in fifoForTime[t]:
- fifo.isShared=False
- elif len(fifoForTime[t])==2:
- # 2 FIFOs are used at the same time
- fifoA = fifoForTime[t][0]
- fifoB = fifoForTime[t][1]
- if fifoA.sharedNB >= 0 and fifoA.sharedNB == fifoB.sharedNB:
- # Those FIFOs are already both assigned to a buffer
- # and we can't reassign and they use the same buffer
- # So we can't consistently associate shared buffers to those
- # FIFOs
- fifoA.isShared=False
- fifoB.isShared=False
- else:
- # The 2 FIFOs were never associated with a shared buffer
- if fifoA.sharedNB < 0 and fifoB.sharedNB < 0:
- fifoA.sharedNB=0
- fifoB.sharedNB=1
- # One FIFO is associated, so we associate the other one
- # to the other shared buffer
- elif fifoA.sharedNB < 0:
- fifoA.sharedNB = 1 - fifoB.sharedNB
- else:
- fifoB.sharedNB = 1 - fifoA.sharedNB
- else:
- fifoA = fifoForTime[t][0]
- if fifoA.sharedNB < 0:
- fifoA.sharedNB = 0
-
+ # Compute a graph describing when FIFOs are used at the same time
+ # The use graph coloring to allocate buffer to those FIFOs.
+ # Then size the buffer based on the longest FIFO using it
+ if config.memoryOptimization:
+ G = nx.Graph()
+
+ for fifo in allFIFOs:
+ if fifo.isArray:
+ G.add_node(fifo)
+
+ # Create the interference graph
+
+ # Dictionary of active FIFOs at a given time.
+ # The time is a scheduling step
+ active={}
+ currentTime=0
+ while currentTime<=maxTime:
+ # Remove fifo no more active.
+ # Thei stop time < currenTime
+ toDelete=[]
+ for k in active:
+ start,stop=k._liveInterval
+ if stop node -> dst
+ # At time t, node will read for src and the stop time
+ # will be currentTime t.
+ # And it will write to dst and the start time will be
+ # currentTime
+ # So, src and dst are both live at this time.
+ # Which means the condition on the stop time must be
+ # stop >= currentTime and not a strict comparison
+ if start<=currentTime and stop >= currentTime:
+ if not (fifo in active):
+ for k in active:
+ G.add_edge(k,fifo)
+ active[fifo]=True
+
+ currentTime = currentTime + 1
+
+ # To debug and display the graph
+ if False:
+ labels={}
+ for n in G.nodes:
+ labels[n]="%s -> %s" % (n.src.owner.nodeName,n.dst.owner.nodeName)
+
+ pos = nx.spring_layout(G, seed=3113794652)
+ subax1 = plt.subplot(121)
+ nx.draw_networkx_edges(G, pos, width=1.0, alpha=0.5)
+
+ nx.draw_networkx_labels(G, pos, labels, font_size=10)
+ plt.show()
+ quit()
+
+ # Graph coloring
+ d = nx.coloring.greedy_color(G, strategy="largest_first")
+
+ # Allocate the colors (buffer ID) to the FIFO
+ # and keep track of the max color number
+ # Since other buffers (for real FIFOs) will have their
+ # numbering start after this one.
+ for fifo in d:
+ fifo.sharedNB=d[fifo]
+ bufferID=max(bufferID,fifo.sharedNB)
- # Now we create buffers
- maxSharedA=0
- maxSharedB=0
- allBuffers=[]
- for fifo in allFIFOs:
- lengthInBytes = fifo.theType.bytes * fifo.length
- if fifo.isShared:
- if fifo.sharedNB == 0:
- if lengthInBytes > maxSharedA:
- maxSharedA = lengthInBytes
- if fifo.sharedNB == 1:
- if lengthInBytes > maxSharedB:
- maxSharedB = lengthInBytes
- bufferID=0
- sharedA=None
- sharedB=None
- if maxSharedA > 0 and config.memoryOptimization:
- # Create the shared buffer if memory optimization on
- sharedA = FifoBuffer(bufferID,CType(UINT8),maxSharedA)
- allBuffers.append(sharedA)
- bufferID = bufferID + 1
-
- if maxSharedB > 0 and config.memoryOptimization:
- # Create the shared buffer if memory optimization on
- sharedB = FifoBuffer(bufferID,CType(UINT8),maxSharedB)
- allBuffers.append(sharedB)
- bufferID = bufferID + 1
+
+ # Compute the max size for each shared buffer
+ maxSizes={}
+ for fifo in d:
+ lengthInBytes = fifo.theType.bytes * fifo.length
+ if fifo.sharedNB in maxSizes:
+ maxSizes[fifo.sharedNB] = max(maxSizes[fifo.sharedNB],lengthInBytes)
+ else:
+ maxSizes[fifo.sharedNB]=lengthInBytes
+
+ # Create the buffers
+ for theID in maxSizes:
+ sharedA = FifoBuffer(theID,CType(UINT8),maxSizes[theID])
+ allBuffers.append(sharedA)
for fifo in allFIFOs:
# Use shared buffer if memory optimization
- if fifo.isShared and config.memoryOptimization:
- if fifo.sharedNB == 0:
- fifo.buffer=sharedA
- else:
- fifo.buffer=sharedB
+ if fifo.isArray and config.memoryOptimization:
+ fifo.buffer=allBuffers[fifo.sharedNB]
+ fifo.bufferID=fifo.sharedNB
+ # Create a new buffer for a real FIFO
+ # Use bufferID which is starting after the numbers allocated
+ # to shared buffers
else:
buf = FifoBuffer(bufferID,fifo.theType,fifo.length)
allBuffers.append(buf)
fifo.buffer=buf
+ fifo.bufferID = bufferID
bufferID = bufferID + 1
+ # Compute the total memory used in bytes
self._totalMemory = 0
for buf in allBuffers:
self._totalMemory = self._totalMemory + buf._theType.bytes * buf._length
@@ -529,7 +539,7 @@ class Graph():
fifoMax=np.floor(bMax).astype(np.int32)
- allBuffers=self.initializeFIFODescriptions(config,allFIFOs,fifoMax)
+ allBuffers=self.initializeFIFODescriptions(config,allFIFOs,fifoMax,evolutionTime)
self._allFIFOs = allFIFOs
self._allBuffers = allBuffers
return(Schedule(self,self._sortedNodes,self._sortedEdges,schedule))
diff --git a/SDFTools/sdf/templates/dot_template.dot b/SDFTools/sdf/templates/dot_template.dot
index ce22313e..abfa5a74 100755
--- a/SDFTools/sdf/templates/dot_template.dot
+++ b/SDFTools/sdf/templates/dot_template.dot
@@ -115,10 +115,23 @@ digraph structs {
| {{fifos[id].src.nbSamples}}
|
>]
+{% if config.displayFIFOBuf %}
+{{delayBoxID(id)}}:i -> {{io(fifos[id].dst.owner,fifos[id].dst)}} [headlabel=<
+| {{fifos[id].dst.nbSamples}}
+ |
>,label="buf{{fifos[id].bufferID}}"]
+{% else %}
{{delayBoxID(id)}}:i -> {{io(fifos[id].dst.owner,fifos[id].dst)}} [headlabel=<
| {{fifos[id].dst.nbSamples}}
|
>,label="{{fifos[id].theType.graphViztype}}({{fifos[id].length}})"]
+{% endif %}
+{% else %}
+{% if config.displayFIFOBuf %}
+{{io(fifos[id].src.owner,fifos[id].src)}} -> {{io(fifos[id].dst.owner,fifos[id].dst)}} [headlabel=<
+| {{fifos[id].dst.nbSamples}}
+ |
>,taillabel=<
+| {{fifos[id].src.nbSamples}}
+ |
>,label="buf{{fifos[id].bufferID}}"]
{% else %}
{{io(fifos[id].src.owner,fifos[id].src)}} -> {{io(fifos[id].dst.owner,fifos[id].dst)}} [headlabel=<
{{fifos[id].dst.nbSamples}}
@@ -126,6 +139,7 @@ digraph structs {
| {{fifos[id].src.nbSamples}}
| >,label="{{fifos[id].theType.graphViztype}}({{fifos[id].length}})"]
{% endif %}
+{% endif %}
{% endfor %}
{% for c in constObjs %}
|