| #!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| # |
| # Copyright (C) 2017-2020 The Project X-Ray Authors. |
| # |
| # Use of this source code is governed by a ISC-style |
| # license that can be found in the LICENSE file or at |
| # https://opensource.org/licenses/ISC |
| # |
| # SPDX-License-Identifier: ISC |
| ''' |
| 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 * |
| |
| from prjxray.segmaker import Segmaker |
| |
| segmk = Segmaker("design.bits") |
| |
| |
| def ones(l): |
| #return l + [x + '_1' for x in l] |
| #return sorted(l + [x + '_1' for x in l]) |
| ret = [] |
| for x in l: |
| ret.append(x) |
| ret.append(x + '_1') |
| return ret |
| |
| |
| 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" |
| |
| CLBLM_L CLBLM_L_X10Y137 30 13 SLICE_X13Y137/AFF REG_INIT 1 FDRE |
| CLBLM_L CLBLM_L_X10Y137 30 13 SLICE_X12Y137/D5FF 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/D5FF |
| 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] |
| # ex: FDCE |
| cel_prim = line[8] |
| # 1'b1 |
| # cinv = int(line[9][-1]) |
| cinv = int(line[9]) |
| init = vs2i(line[10]) |
| #init = int(line[10]) |
| |
| # A B C D |
| which = ff_name[0] |
| # LUT6 vs LUT5 FF |
| is5 = '5' in ff_name |
| |
| if used: |
| segmk.add_site_tag(site, "%s.ZINI" % ff_name, 1 ^ init) |
| |
| # CLKINV turns out to be more complicated than origianlly thought |
| if isff(cel_prim): |
| segmk.add_site_tag(site, "CLKINV", cinv) |
| segmk.add_site_tag(site, "NOCLKINV", 1 ^ cinv) |
| else: |
| segmk.add_site_tag(site, "CLKINV", 1 ^ cinv) |
| segmk.add_site_tag(site, "NOCLKINV", cinv) |
| |
| # Synchronous vs asynchronous FF |
| # Unlike most bits, shared between all CLB FFs |
| segmk.add_site_tag(site, "FFSYNC", cel_prim in ('FDSE', 'FDRE')) |
| |
| # Latch bit |
| # Only applies to LUT6 (non-5) FF's |
| if not is5: |
| segmk.add_site_tag(site, "LATCH", isl(cel_prim)) |
| ''' |
| 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() |