blob: dd3d9259316518e3ac35cf8c5f5db30db3ae4852 [file] [log] [blame]
#!/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
import json
import io
import os
import random
import re
random.seed(int(os.getenv("SEED"), 16))
from prjxray import util
from prjxray import lut_maker
from prjxray import verilog
from prjxray.db import Database
def gen_sites():
db = Database(util.get_db_root(), util.get_part())
grid = db.grid()
for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc)
for site_name, site_type in gridinfo.sites.items():
if site_type in ['BSCAN', 'CAPTURE', 'ICAP', 'USR_ACCESS',
'STARTUP', 'FRAME_ECC', 'DCIRESET']:
if site_name not in 'ICAP_X0Y0':
yield site_name, site_type
def write_csv_params(params):
pinstr = 'tile,site,\n'
for vals in params:
pinstr += ','.join(map(str, vals)) + '\n'
open('params.csv', 'w').write(pinstr)
def generate_params():
bscan_already_on = False
icap_already_on = False
tile_params = []
for loci, (site, site_type) in enumerate(sorted(gen_sites())):
p = {}
if site_type in "ICAP" and not icap_already_on:
p["ICAP_WIDTH"] = verilog.quote(
random.choice(["X32", "X8", "X16"]))
elif site_type in "BSCAN" and not bscan_already_on:
p["JTAG_CHAIN"] = random.randint(1, 4)
bscan_already_on = True
elif site_type in "CAPTURE":
p["ONESHOT"] = verilog.quote(random.choice(["TRUE", "FALSE"]))
elif site_type in "STARTUP":
p["PROG_USR"] = verilog.quote(random.choice(["TRUE", "FALSE"]))
elif site_type in "FRAME_ECC":
p["FARSRC"] = verilog.quote(random.choice(["FAR", "EFAR"]))
elif site_type in [
"DCIRESET", "USR_ACCESS"
]: #The primitives from these sites have no parameters
p["ENABLED"] = random.randint(0, 1)
else:
continue
p["LOC"] = verilog.quote(site)
tile_params.append(
{
"site": site,
"site_type": site_type,
"module": "mod_{}".format(site_type),
"params": p
})
return tile_params
def generate_netlist(params):
DUTN = len(params)
DIN_N = DUTN * 32
DOUT_N = DUTN * 32
string_output = io.StringIO()
any_bscan = False
any_icap = False
usr_access_on = False
capture_on = False
startup_on = False
frame_ecc_on = False
dcireset_on = False
luts = lut_maker.LutMaker()
verilog.top_harness(DIN_N, DOUT_N)
print(
'''
module roi(input clk, input [%d:0] din, output [%d:0] dout);''' %
(DIN_N - 1, DOUT_N - 1))
for loci, param in enumerate(params):
ports = {
'din': 'din[{} +: 8]'.format(8 * loci),
'dout': 'dout[{} +: 8]'.format(8 * loci),
'clk': 'clk'
}
if param["site_type"] in "BSCAN":
ports = {
'din':
'{{din[{} +: 7],{}}}'.format(
8 * loci + 1, luts.get_next_output_net()),
'dout':
'{{dout[{} +: 7],{}}}'.format(
8 * loci + 1, luts.get_next_input_net()),
'clk':
'clk'
}
any_bscan = True
elif param["site_type"] in ["ICAP"]:
any_icap = True
elif param["site_type"] in ["CAPTURE"]:
capture_on = True
elif param["site_type"] in ["STARTUP"]:
startup_on = True
elif param["site_type"] in ["FRAME_ECC"]:
frame_ecc_on = True
elif param["site_type"] in ["USR_ACCESS", "DCIRESET"]:
if not param["params"]["ENABLED"]:
continue
if param["site_type"] in ["DCIRESET"]:
dcireset_on = True
else:
usr_access_on = True
else:
continue
verilog.instance(
param["module"],
"inst_{}".format(param["site"]),
ports,
param["params"],
string_buffer=string_output)
#Generate LUTs
for l in luts.create_wires_and_luts():
print(l)
print(string_output.getvalue())
print(
'''
endmodule
// ---------------------------------------------------------------------''')
if any_icap:
print(
'''
module mod_ICAP (input [7:0] din, output [7:0] dout, input clk);
parameter ICAP_WIDTH = "X32";
parameter LOC = "ICAP_X0Y0";
wire [23:0] icap_out;
(* KEEP, DONT_TOUCH, LOC=LOC *)
ICAPE2 #(
.ICAP_WIDTH(ICAP_WIDTH),
.SIM_CFG_FILE_NAME("NONE")
)
ICAPE2_inst (
.O({icap_out, dout}),
.CLK(clk),
.CSIB(),
.I({24'd0, din}),
.RDWRB()
);
endmodule
''')
if capture_on:
print(
'''
module mod_CAPTURE (input [7:0] din, output [7:0] dout, input clk);
parameter ONESHOT ="TRUE";
parameter LOC = "ICAP_X0Y0";
(* KEEP, DONT_TOUCH, LOC=LOC *)
CAPTUREE2 #(
.ONESHOT(ONESHOT) // Specifies the procedure for performing single readback per CAP trigger.
)
CAPTUREE2_inst (
.CAP(1'b0),
.CLK(clk)
);
endmodule
''')
if usr_access_on:
print(
'''
module mod_USR_ACCESS (input [7:0] din, output [7:0] dout, input clk);
parameter ENABLED = 1;
parameter LOC = "USR_ACCESS_X0Y0";
wire [23:0] usr_access_wire;
(* KEEP, DONT_TOUCH, LOC=LOC *)
USR_ACCESSE2 USR_ACCESSE2_inst (
.CFGCLK(),
.DATA({usr_access_wire, dout}),
.DATAVALID()
);
endmodule
''')
if any_bscan:
print(
'''
module mod_BSCAN (input [7:0] din, output [7:0] dout, input clk);
parameter JTAG_CHAIN = 1;
parameter LOC = "BSCAN_X0Y0";
(* KEEP, DONT_TOUCH, LOC=LOC *)
BSCANE2 #(
.JTAG_CHAIN(JTAG_CHAIN)
)
dut (
.CAPTURE(),
.DRCK(),
.RESET(),
.RUNTEST(),
.SEL(),
.SHIFT(),
.TCK(),
.TDI(dout[0]),
.TMS(),
.UPDATE(),
.TDO(din[0])
);
endmodule
''')
if startup_on:
print(
'''
module mod_STARTUP (input [7:0] din, output [7:0] dout, input clk);
parameter LOC = "STARTUP_X0Y0";
parameter PROG_USR = "FALSE";
(* KEEP, DONT_TOUCH, LOC=LOC *)
STARTUPE2 #(
.PROG_USR(PROG_USR), // Activate program event security feature. Requires encrypted bitstreams.
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation.
)
STARTUPE2_inst (
.CFGCLK(),
.CFGMCLK(),
.EOS(),
.PREQ(dout[0]),
.CLK(clk),
.GSR(),
.GTS(),
.KEYCLEARB(),
.PACK(),
.USRCCLKO(),
.USRCCLKTS(),
.USRDONEO(),
.USRDONETS()
);
endmodule
''')
if frame_ecc_on:
print(
'''
module mod_FRAME_ECC (input [7:0] din, output [7:0] dout, input clk);
parameter LOC = "FRAME_ECC_X0Y0";
parameter FARSRC = "EFAR";
wire [25:0] far_wire;
assign dout[7:0] = far_wire[7:0];
(* KEEP, DONT_TOUCH, LOC=LOC *)
FRAME_ECCE2 #(
.FARSRC(FARSRC),
.FRAME_RBT_IN_FILENAME("NONE")
)
FRAME_ECCE2_inst (
.CRCERROR(),
.ECCERROR(),
.ECCERRORSINGLE(),
.FAR(far_wire),
.SYNBIT(),
.SYNDROME(),
.SYNDROMEVALID(),
.SYNWORD()
);
endmodule
''')
if dcireset_on:
print(
'''
module mod_DCIRESET (input [7:0] din, output [7:0] dout, input clk);
parameter LOC = "FRAME_ECC_X0Y0";
parameter ENABLED = 1;
(* KEEP, DONT_TOUCH, LOC=LOC *)
DCIRESET DCIRESET_inst (
.LOCKED(dout[0]),
.RST(dout[1])
);
endmodule
''')
def run():
params = generate_params()
generate_netlist(params)
with open('params.jl', 'w') as f:
json.dump(params, f, indent=2)
if __name__ == '__main__':
run()