Skip to content

Commit

Permalink
Merge pull request f4pga#16 from antmicro/cle-ffconfig
Browse files Browse the repository at this point in the history
011-cle-ffconfig
  • Loading branch information
litghost authored Apr 10, 2020
2 parents 0147174 + df5ae7e commit 8008e2f
Show file tree
Hide file tree
Showing 11 changed files with 914 additions and 0 deletions.
45 changes: 45 additions & 0 deletions fuzzers/011-cle-ffconfig/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
BUILD_DIR = build
N := 1

SPECIMENS := $(addprefix $(BUILD_DIR)/specimen_,$(shell seq -f '%03.0f' $(N)))
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))

database: $(SPECIMENS_OK)
$(URAY_SEGMATCH) -o $(BUILD_DIR)/segbits_cle.db $(shell find build -name "segdata_cle*.txt")

pushdb:
$(URAY_MERGEDB) clel_l $(BUILD_DIR)/segbits_cle.db
$(URAY_MERGEDB) clel_r $(BUILD_DIR)/segbits_cle.db
$(URAY_MERGEDB) clem $(BUILD_DIR)/segbits_cle.db
$(URAY_MERGEDB) clem_r $(BUILD_DIR)/segbits_cle.db

define generate =
$(1)/top.v :
bash top.sh $(1)

$(1)/design.bit: $(1)/top.v
cd $(1); \
$(URAY_VIVADO) -mode batch -source ../../generate.tcl; \
test -z "$$$$(fgrep CRITICAL vivado.log)"

$(1)/segdata: $(1)/design.bit
cd $(1); \
bash ../../generate.sh

$(1)/OK: $(1)/segdata
touch $$@

endef

$(foreach specimen,$(SPECIMENS),$(eval $(call generate,$(specimen))))

run:
$(MAKE) clean
$(MAKE) database
$(MAKE) pushdb
touch run.ok

clean:
rm -rf $(BUILD_DIR) run.ok

.PHONY: database pushdb run clean
110 changes: 110 additions & 0 deletions fuzzers/011-cle-ffconfig/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# clb-ffconfig Fuzzer

Documents FF configuration.

Note Vivado GUI is misleading in some cases where it shows configuration per FF, but its actually per SLICE

## Primitive pin map

| Element | CE | CK | D | SR | Q |
|----------|----|----|---|-----|---|
| FDRE | CE | C | D | R | Q |
| FDPE | CE | C | D | PRE | Q |
| FDSE | CE | C | D | S | Q |
| FDCE | CE | C | D | CLR | Q |
| LDPE | GE | G | D | PRE | Q |
| LDCE | GE | G | D | CLR | Q |


## Primitive bit map

| Prim | FFSYNC | LATCH | ZRST |
|------|--------|-------|------|
|FDPE | | | |
|FDSE | X | | |
|FDRE | X | | X |
|FDCE | | | X |
|LDCE | | X | X |
|LDPE | | X | |


### FFSYNC

Configures whether a storage element is synchronous or asynchronous.

Scope: entire site (not individual FFs)

| FFSYNC | Reset | Applicable prims |
|--------|--------------|---------------------------|
|0 | Synchronous | FDPE, FDCE, LDCE, LDPE |
|1 | Asynchronous | FDSE, FDRE |


### LATCH

Configures latch vs FF behavior for the CLB

| LATCH | Description | Primitives |
|-------|-------------|------------|
|0 | All storage elements in the CLB are FF's | FDPE, FDSE, FDRE, FDCE |
|1 | LUT6 storage elements are latches (LDCE or LDPE). LUT5 storage elements cannot be used | LDCE, LDPE |


### N*FF.ZRST

Configures stored value when reset is asserted

| Prim |ZRST|On reset|
|-----------------------|----|----- |
|FDRE, FDCE, and LDCE | 0 | 1 |
|FDRE, FDCE, and LDCE | 1 | 0 |
|FDPE, FDSE, and LDPE | 0 | 0 |
|FDPE, FDSE, and LDPE | 1 | 1 |


## N*FF.ZINI

Sets GSR FF or latch value

| LATCH | ZINI | Set to |
|-------|------|--------|
| FF | 0 | 1 |
| FF | 1 | 0 |
| LATCH | 0 | 0 |
| LATCH | 1 | 1 |


## CEUSEDMUX

Configures ability to drive clock enable (CE) or always enable clock

| CEUSEDMUX | Description |
|-----------|-------------------------|
| 0 | always on (CE=1) |
| 1 | controlled (CE=mywire) |


## SRUSEDMUX

Configures ability to reset FF after GSR

| SRUSEDMUX | Description |
|-----------|-----------------------|
| 0 | never reset (R=0) |
| 1 | controlled (R=mywire) |

TODO: how used when SR?

## CLKINV

Configures whether to invert the clock going into a slice.

Scope: entire site (not individual FFs)

| LATCH | CLKINV | Description |
|-------|--------|----------------|
| FF | 0 | normal clock |
| FF | 1 | invert clock |
| LATCH | 0 | invert clock |
| LATCH | 1 | normal clock |

3 changes: 3 additions & 0 deletions fuzzers/011-cle-ffconfig/bits.dbf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# NOCLKINV is inverse of CLKINV
CLB.SLICE_X0.CLKINV ^ CLB.SLICE_X0.NOCLKINV
CLB.SLICE_X1.CLKINV ^ CLB.SLICE_X1.NOCLKINV
89 changes: 89 additions & 0 deletions fuzzers/011-cle-ffconfig/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env python3
'''
FDCE Primitive: D Flip-Flop with Clock Enable and Asynchronous Clear
FDPE Primitive: D Flip-Flop with Clock Enable and Asynchronous Preset
FDRE Primitive: D Flip-Flop with Clock Enable and Synchronous Reset
FDSE Primitive: D Flip-Flop with Clock Enable and Synchronous Set
LDCE Primitive: Transparent Data Latch with Asynchronous Clear and Gate Enable
LDPE Primitive: Transparent Data Latch with Asynchronous Preset and Gate Enable
'''

from prims import isff, isl

from utils.segmaker import Segmaker

segmk = Segmaker("design.bits", bits_per_word=16)


def loadtop():
'''
i,prim,loc,bel
0,FDPE,SLICE_X12Y100,C5FF
1,FDPE,SLICE_X15Y100,A5FF
2,FDPE_1,SLICE_X16Y100,B5FF
3,LDCE_1,SLICE_X17Y100,BFF
'''
f = open('top.txt', 'r')
f.readline()
ret = {}
for l in f:
i, prim, loc, bel, init = l.split(",")
i = int(i)
init = int(init)
ret[loc] = (i, prim, loc, bel, init)
return ret


top = loadtop()


def vs2i(s):
return {"1'b0": 0, "1'b1": 1}[s]


print("Loading tags from design.txt")
with open("design.txt", "r") as f:
for line in f:
'''
puts $fp "$type $tile $grid_x $grid_y $ff $bel_type $used $usedstr"
CLEM CLEM_X10Y137 30 13 SLICE_X13Y137/AFF REG_INIT 1 FDRE
CLEM CLEM_X10Y137 30 13 SLICE_X12Y137/D2FF FF_INIT 0
'''
line = line.split()
tile_type = line[0]
tile_name = line[1]
grid_x = line[2]
grid_y = line[3]
# Other code uses BEL name
# SLICE_X12Y137/D2FF
site_ff_name = line[4]
site, ff_name = site_ff_name.split('/')
ff_type = line[5]
used = int(line[6])
cel_prim = None
cel_name = None
if used:
cel_name = line[7]
cel_prim = line[8]
cinv = int(line[9])
init = vs2i(line[10])

# A B C D E F G H
which = ff_name[0]
# LUT6 vs LUT5 FF
is2 = '2' in ff_name

if used:
segmk.add_site_tag(site, "%s.ZINI" % ff_name, 1 ^ init)
'''
On name:
The primitives you listed have a control input to set the FF value to zero (clear/reset),
the other three primitives have a control input that sets the FF value to one.
Z => inversion
'''
segmk.add_site_tag(site, "%s.ZRST" % ff_name,
cel_prim in ('FDRE', 'FDCE', 'LDCE'))

segmk.compile()
segmk.write()
9 changes: 9 additions & 0 deletions fuzzers/011-cle-ffconfig/generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
${URAY_BITREAD} -F $URAY_ROI_FRAMES -o design.bits -z -y design.bit

touch segdata_clel_l.txt
touch segdata_clel_r.txt
touch segdata_clem.txt
touch segdata_clem_r.txt

python3 ../../generate.py
65 changes: 65 additions & 0 deletions fuzzers/011-cle-ffconfig/generate.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
create_project -force -part $::env(URAY_PART) design design
read_verilog top.v
synth_design -top top

set_property -dict "PACKAGE_PIN $::env(URAY_PIN_00) IOSTANDARD LVCMOS33" [get_ports clk]

create_pblock roi

set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
set_param tcl.collectionResultDisplayLimit 0

set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
set_property IS_ENABLED 0 [get_drc_checks {NDRV-1}]
set_property IS_ENABLED 0 [get_drc_checks {UCIO-1}]
set_property IS_ENABLED 0 [get_drc_checks {NSTD-1}]
set_property IS_ENABLED 0 [get_drc_checks {RTSTAT-4}]
set_property IS_ENABLED 0 [get_drc_checks {RTSTAT-6}]
set_property IS_ENABLED 0 [get_drc_checks {RTSTAT-10}]

place_design -directive Quick
route_design -directive Quick

write_checkpoint -force design.dcp
write_bitstream -force design.bit

# Get all FF's in pblock
set ffs [get_bels -filter {TYPE =~ *} */*FF]

set fp [open "design.txt" w]
# set ff [lindex $ffs 0]
# set ff [get_bels SLICE_X23Y100/AFF]
# proc putl {lst} { foreach line $lst {puts $line} }
foreach ff $ffs {
# Tile information
set tile [get_tile -of_objects $ff]
set type [get_property TYPE $tile]

# Location information
set grid_x [get_property GRID_POINT_X $tile]
set grid_y [get_property GRID_POINT_Y $tile]

# FF BEL information
set bel_type [get_property TYPE $ff]
set used [get_property IS_USED $ff]
set usedstr ""

if $used {
set ffc [get_cells -of_objects $ff]
set cell_bel [get_property BEL $ffc]

# ex: FDRE
set ref_name [get_property REF_NAME $ffc]

# Flip-Flops : have CLOCK pin
# Latches : have GATE pin
set cpin [get_pins -of_objects $ffc -filter {REF_PIN_NAME == C || REF_PIN_NAME == G}]
set cinv [get_property IS_INVERTED $cpin]

set init [get_property INIT $ffc]

set usedstr "$cell_bel $ref_name $cinv $init"
}
puts $fp "$type $tile $grid_x $grid_y $ff $bel_type $used $usedstr"
}
close $fp
Loading

0 comments on commit 8008e2f

Please sign in to comment.