#!/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 ''' Generate a primitive to place at every I/O Unlike CLB tests, the LFSR for this is inside the ROI, not driving it ''' import os import random import sys #random.seed(int(os.getenv("SEED"), 16)) from prjxray import util from prjxray import verilog def gen_iobs(): ''' IOB33S: main IOB of a diff pair IOB33M: secondary IOB of a diff pair IOB33: not a diff pair. Relatively rare (at least in ROI...2 of them?) Focus on IOB33S to start ''' for _tile_name, site_name, site_type in util.get_roi().gen_sites( #['IOB33', 'IOB33S', 'IOB33M']): ['IOB33S']): yield site_name, site_type def write_pins(ports): pinstr = '' for site, (name, dir_, cell) in sorted(ports.items(), key=lambda x: x[1]): # pinstr += 'set_property -dict "PACKAGE_PIN %s IOSTANDARD LVCMOS33" [get_ports %s]' % (packpin, port) pinstr += '%s,%s,%s,%s\n' % (site, name, dir_, cell) open('params.csv', 'w').write(pinstr) def run(): # All possible values iosites = {} for site_name, site_type in gen_iobs(): iosites[site_name] = site_type # Assigned in this design ports = {} DIN_N = 0 DOUT_N = 0 def remain_sites(): return set(iosites.keys()) - set(ports.keys()) def rand_site(): '''Get a random, unused site''' return random.choice(list(remain_sites())) def get_site(): return next(iter(remain_sites())) def assign_i(site, name): nonlocal DIN_N assert site not in ports cell = "di_bufs[%u].ibuf" % DIN_N DIN_N += 1 ports[site] = (name, 'input', cell) def assign_o(site, name): nonlocal DOUT_N assert site not in ports cell = "do_bufs[%u].obuf" % DOUT_N DOUT_N += 1 ports[site] = (name, 'output', cell) # Assign at least one di and one do assign_i(get_site(), 'di[0]') assign_o(get_site(), 'do[0]') # Now assign the rest randomly #while len(remain_sites()): # assign_o(rand_site(), 'do[%u]' % DOUT_N) #write_pins(ports) print( ''' `define N_DI %u `define N_DO %u module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do); genvar i; //Instantiate BUFs so we can LOC them wire [`N_DI-1:0] di_buf; generate for (i = 0; i < `N_DI; i = i+1) begin:di_bufs IBUF #( ) ibuf(.I(di[i]), .O(di_buf[i])); end endgenerate wire [`N_DO-1:0] do_unbuf; generate for (i = 0; i < `N_DO; i = i+1) begin:do_bufs OBUF #( ) obuf(.I(do_unbuf[i]), .O(do[i])); end endgenerate roi roi(.di(di_buf), .do(do_unbuf)); endmodule //Arbitrary terminate into LUTs module roi(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do); genvar i; generate for (i = 0; i < `N_DI; i = i+1) begin:dis (* KEEP, DONT_TOUCH *) LUT6 #( .INIT(64'h8000_0000_0000_0001) ) lut ( .I0(di[i]), .I1(di[i]), .I2(di[i]), .I3(di[i]), .I4(di[i]), .I5(di[i]), .O()); end endgenerate generate for (i = 0; i < `N_DO; i = i+1) begin:dos (* KEEP, DONT_TOUCH *) LUT6 #( .INIT(64'h8000_0000_0000_0001) ) lut ( .I0(), .I1(), .I2(), .I3(), .I4(), .I5(), .O(do[i])); end endgenerate endmodule ''' % (DIN_N, DOUT_N)) if __name__ == '__main__': run()