| #!/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() |