Tile column Pattern analysis

43 views
Skip to first unread message

Masood Raeisi

unread,
Apr 28, 2020, 8:23:34 PM4/28/20
to RapidWright
Hello,

I want to automate a specific module creation, which uses only logic blocks,

What is the best way of analyzing tile column pattern based on the number of slices?

let's say I need a pblock of 10*10 for my module,
I want to generate the module in a way it be place-able on most areas of device.
so I need to get the list one unique column patterns that include 10 slices,

what I need is the list of slice numbers which is the start of different patterns, how can I fetch that? (for example: SLICE_X0Y0)
I want to use this start points in a tcl script which creates a pbock at that slice start point with size 10*10 dimension (SLICE_X0Y0:SLICE_X10Y10)

Sincerely

RapidWright

unread,
Apr 29, 2020, 1:51:28 PM4/29/20
to RapidWright
I would ask what the constraint is on having your pblock be 10 slice columns wide.  Spanning 10 columns would not make the block very relocate-able on most devices.  If you said, 'I need 100 slices', then we can look at the architecture and snap to regular architectural boundaries.  For example, Series 7 devices (such as the PYNQ-Z1 xc7z020) have a clock region height of 50 slices, so you could go with 2 columns of 50, or 4 columns of 25.  Using similar code as to Pre-implemented Modules - Part 1 tutorial:

>>> d = Device.getDevice(Device.PYNQ_Z1)
>>> m = TileColumnPattern.genColumnPatternMap(d)
>>> list(filter(lambda e: "BRAM" not in e.getKey().toString() and "DSP" not in e.getKey().toString() and e.getKey().size() == 4, m.entrySet()))
>>> filtered.sort(key=lambda x: x.getValue().size(), reverse=True)
>>> from pprint import pprint
>>> pprint(filtered)
[[CLBLM_R, CLBLL_L, CLBLM_R, CLBLL_L]=[73, 77, 97, 102],
 [CLBLL_L, CLBLM_R, CLBLL_L, CLBLM_R]=[74, 99, 103, 169],
 [CLBLL_R, CLBLM_L, CLBLL_R, CLBLM_L]=[128],
 [CLBLM_R, CLBLL_L, CLBLM_L, CLBLL_R]=[81],
 [CLBLM_R, CLBLL_L, CLBLM_R, CLBLL_R]=[106],
 [CLBLL_L, CLBLM_R, CLBLL_L, CLBLM_L]=[78],
 [CLBLM_L, CLBLM_R, CLBLL_L, CLBLM_R]=[70],
 [CLBLM_L, CLBLL_R, CLBLM_L, CLBLL_R]=[129],
 [CLBLM_R, CLBLL_R, CLBLM_L, CLBLL_R]=[110],
 [CLBLM_L, CLBLM_R, CLBLM_L, CLBLM_R]=[149],
 [CLBLL_L, CLBLM_R, CLBLL_R, CLBLM_L]=[107]]



Using 4 columns would give you 4 different instances where the tile column pattern occurs.  You may also want to be aware of other considerations such as carry chain usage beyond the size of a slice.  Do you need LUTRAM (SLICEM) or just LUTs?  Some of these considerations are attempted by automation in the PBlockGenerator.

Masood Raeisi

unread,
Apr 29, 2020, 2:39:29 PM4/29/20
to RapidWright
Hi, thanks for your answer,
I thought about using lambda with "BRAM" not in and "DSP" not in with size 10 or as you said 4, but it will filter the patterns which have a DSP or BRAM or both in the middle which is not I want,
and yes, my design uses mostly lutram (SLICEM) in the design,
I'm not targeting any particular device now, I'm experimenting with these two parts: "xc7z020clg400-1" or PYNQ-Z1 as you said and "xc7z100ffg900-2"
.
I'm not trying to replicate my module over the device, I'm trying to study different placement of my modules to examine the timing and I want to automate it
putting my module in square (like 10*10) or other like (4*25) is also something I'm trying to study and see which one gives me the better result.

list(filter(lambda e: "BRAM" not in e.getKey().toString() and "DSP" not in e.getKey().toString() and e.getKey().size() == 4, m.entrySet()))

will give me the output you mentioned, but I also want to include the cases where there is one BRAM or DSP or even both there but still have the size of for example 4 SLICEs;
what I'm doing now is that I query multiple times with different scenarios like: (for size 10)

filtered = list(filter(lambda e: not TileTypeEnum.BRAM_L in e.getKey() and not TileTypeEnum.BRAM_R in e.getKey() and not TileTypeEnum.DSP_L in e.getKey() and not TileTypeEnum.DSP_R in e.getKey() and e.getKey().size() == 10, colMap.entrySet()))
filtered
= list(filter(lambda e: TileTypeEnum.BRAM_L in e.getKey() and not TileTypeEnum.BRAM_R in e.getKey() and not TileTypeEnum.DSP_L in e.getKey() and not TileTypeEnum.DSP_R in e.getKey() and e.getKey().size() == 11, colMap.entrySet()))
...
...
...


which works, but I was wondering if there is a better/simpler way of querying all column patterns which include X slices with and without DSP and BRAM for given number of X?

RapidWright

unread,
Apr 29, 2020, 4:47:25 PM4/29/20
to RapidWright
Here is one way off the top of my head...

>>> filtered = list(filter(lambda e: e.getKey().toString().count("CLB") == 4, m.entrySet()))
>>> filtered.sort(key=lambda x: x.getValue().size(), reverse=True)
>>> pprint(filtered)
[[CLBLM_R, CLBLL_L, CLBLM_R, CLBLL_L]=[73, 77, 97, 102],
 [CLBLL_L, CLBLM_R, CLBLL_L, CLBLM_R]=[74, 99, 103, 169],
 [BRAM_L, CLBLM_R, CLBLM_L, DSP_R, CLBLM_L, CLBLM_R]=[59, 138],
 [CLBLM_R, CLBLM_L, DSP_R, CLBLM_L, CLBLM_R]=[63, 142],
 [CLBLM_L, CLBLL_R, BRAM_L, CLBLM_R, CLBLM_L]=[133],
 [CLBLM_R, CLBLL_L, CLBLM_R, CLBLL_R]=[106],
 [CLBLM_R, CLBLM_L, BRAM_R, CLBLL_L, CLBLM_R]=[162],
 [CLBLL_L, CLBLM_R, CLBLL_L, CLBLM_L]=[78],
 [DSP_L, CLBLM_R, CLBLM_L, BRAM_R, CLBLL_L, CLBLM_R]=[158],
 [DSP_R, CLBLM_L, CLBLM_R, CLBLL_L, CLBLM_R]=[68],
 [CLBLL_L, CLBLM_R, BRAM_L, CLBLM_R, CLBLM_L, DSP_R]=[54],
 [CLBLM_L, CLBLM_R, DSP_L, CLBLM_R, CLBLM_L, BRAM_R]=[153],
 [CLBLL_R, BRAM_L, CLBLM_R, CLBLL_L, CLBLM_R]=[92],
 [CLBLM_L, DSP_R, CLBLM_L, CLBLM_R, CLBLL_L]=[64],
 [CLBLM_L, CLBLM_R, CLBLM_L, CLBLM_R]=[149],
 [CLBLM_L, DSP_R, CLBLM_L, CLBLM_R, CLBLM_L]=[143],
 [CLBLM_R, CLBLM_L, CLBLM_R, DSP_L, CLBLM_R]=[152],
 [BRAM_R, CLBLL_L, CLBLM_R, CLBLL_L, CLBLM_R]=[167],
 [CLBLM_R, CLBLL_L, CLBLM_L, CLBLL_R, BRAM_L]=[81],
 [CLBLL_L, CLBLM_R, BRAM_L, CLBLM_R, CLBLM_L]=[54],
 [CLBLL_R, BRAM_L, CLBLM_R, CLBLM_L, DSP_R, CLBLM_L]=[136],
 [CLBLM_L, BRAM_R, CLBLL_L, CLBLM_R, CLBLL_L]=[163],
 [CLBLM_R, CLBLL_R, CLBLM_L, CLBLL_R]=[110],
 [CLBLM_L, CLBLL_R, BRAM_L, CLBLM_R, CLBLM_L, DSP_R]=[133],
 [CLBLL_R, CLBLM_L, CLBLL_R, CLBLM_L]=[128],
 [DSP_R, CLBLM_L, CLBLM_R, CLBLM_L, CLBLM_R]=[147],
 [CLBLM_L, CLBLL_R, CLBLM_L, CLBLL_R]=[129],
 [CLBLM_L, CLBLL_R, BRAM_L, CLBLM_R, CLBLL_L]=[89],
 [CLBLM_L, CLBLL_R, CLBLM_L, CLBLL_R, BRAM_L]=[129],
 [BRAM_L, CLBLM_R, CLBLL_L, CLBLM_R, CLBLL_L]=[93],
 [CLBLL_L, CLBLM_R, CLBLL_R, CLBLM_L]=[107],
 [CLBLM_L, CLBLM_R, CLBLL_L, CLBLM_R]=[70],
 [CLBLM_R, CLBLL_L, CLBLM_L, CLBLL_R]=[81],
 [CLBLM_L, CLBLM_R, DSP_L, CLBLM_R, CLBLM_L]=[153],
 [CLBLL_R, CLBLM_L, CLBLL_R, BRAM_L, CLBLM_R]=[132],
 [CLBLM_L, CLBLM_R, CLBLM_L, CLBLM_R, DSP_L]=[149],
 [DSP_R, CLBLM_L, CLBLM_R, CLBLM_L, CLBLM_R, DSP_L]=[147],
 [CLBLL_L, CLBLM_L, CLBLL_R, BRAM_L, CLBLM_R]=[83],
 [CLBLM_R, CLBLL_L, CLBLM_R, BRAM_L, CLBLM_R]=[53],
 [CLBLM_R, BRAM_L, CLBLM_R, CLBLM_L, DSP_R, CLBLM_L]=[57],
 [CLBLM_R, DSP_L, CLBLM_R, CLBLM_L, BRAM_R, CLBLL_L]=[156]]



Reply all
Reply to author
Forward
0 new messages