mirror of https://github.com/openXC7/prjxray.git
Add additional features for IDELAY.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
4fd53f65a8
commit
a724be9a08
|
|
@ -2,64 +2,77 @@
|
|||
import json
|
||||
|
||||
from prjxray.segmaker import Segmaker, add_site_group_zero
|
||||
from prjxray import util
|
||||
from prjxray import verilog
|
||||
|
||||
segmk = Segmaker("design.bits", verbose=True)
|
||||
|
||||
# Load tags
|
||||
with open("params.json", "r") as fp:
|
||||
data = json.load(fp)
|
||||
def bitfilter(frame, word):
|
||||
if frame < 26:
|
||||
return False
|
||||
|
||||
idelay_types = ["FIXED", "VARIABLE", "VAR_LOAD"]
|
||||
delay_srcs = ["IDATAIN", "DATAIN"]
|
||||
|
||||
# Output tags
|
||||
for params in data:
|
||||
loc = verilog.unquote(params["LOC"])
|
||||
|
||||
# Delay type
|
||||
value = verilog.unquote(params["IDELAY_TYPE"])
|
||||
value = value.replace(
|
||||
"_PIPE", "") # VAR_LOAD and VAR_LOAD_PIPE are the same
|
||||
add_site_group_zero(
|
||||
segmk, loc, "IDELAY_TYPE_", idelay_types, "FIXED", value)
|
||||
|
||||
# Delay value
|
||||
value = int(params["IDELAY_VALUE"])
|
||||
for i in range(5):
|
||||
segmk.add_site_tag(
|
||||
loc, "IDELAY_VALUE[%01d]" % i, ((value >> i) & 1) != 0)
|
||||
segmk.add_site_tag(
|
||||
loc, "ZIDELAY_VALUE[%01d]" % i, ((value >> i) & 1) == 0)
|
||||
|
||||
# Delay source
|
||||
value = verilog.unquote(params["DELAY_SRC"])
|
||||
for x in delay_srcs:
|
||||
segmk.add_site_tag(loc, "DELAY_SRC_%s" % x, int(value == x))
|
||||
|
||||
value = verilog.unquote(params["HIGH_PERFORMANCE_MODE"])
|
||||
segmk.add_site_tag(loc, "HIGH_PERFORMANCE_MODE", int(value == "TRUE"))
|
||||
|
||||
value = verilog.unquote(params["CINVCTRL_SEL"])
|
||||
segmk.add_site_tag(loc, "CINVCTRL_SEL", int(value == "TRUE"))
|
||||
|
||||
value = verilog.unquote(params["PIPE_SEL"])
|
||||
segmk.add_site_tag(loc, "PIPE_SEL", int(value == "TRUE"))
|
||||
|
||||
if "IS_C_INVERTED" in params:
|
||||
segmk.add_site_tag(loc, "IS_C_INVERTED", int(params["IS_C_INVERTED"]))
|
||||
segmk.add_site_tag(loc, "ZINV_C", 1 ^ int(params["IS_C_INVERTED"]))
|
||||
|
||||
segmk.add_site_tag(
|
||||
loc, "IS_DATAIN_INVERTED", int(params["IS_DATAIN_INVERTED"]))
|
||||
segmk.add_site_tag(
|
||||
loc, "IS_IDATAIN_INVERTED", int(params["IS_IDATAIN_INVERTED"]))
|
||||
|
||||
|
||||
def bitfilter(frame_idx, bit_idx):
|
||||
return True
|
||||
|
||||
|
||||
segmk.compile(bitfilter=bitfilter)
|
||||
segmk.write()
|
||||
def main():
|
||||
segmk = Segmaker("design.bits", verbose=True)
|
||||
|
||||
# Load tags
|
||||
with open("params.json", "r") as fp:
|
||||
data = json.load(fp)
|
||||
|
||||
idelay_types = ["FIXED", "VARIABLE", "VAR_LOAD"]
|
||||
delay_srcs = ["IDATAIN", "DATAIN"]
|
||||
|
||||
# Output tags
|
||||
for params in data:
|
||||
segmk.add_site_tag(params['IDELAY_IN_USE'], 'IN_USE', True)
|
||||
segmk.add_site_tag(params['IDELAY_NOT_IN_USE'], 'IN_USE', False)
|
||||
|
||||
loc = verilog.unquote(params["LOC"])
|
||||
|
||||
# Delay type
|
||||
value = verilog.unquote(params["IDELAY_TYPE"])
|
||||
value = value.replace(
|
||||
"_PIPE", "") # VAR_LOAD and VAR_LOAD_PIPE are the same
|
||||
add_site_group_zero(
|
||||
segmk, loc, "IDELAY_TYPE_", idelay_types, "FIXED", value)
|
||||
|
||||
# Delay value
|
||||
value = int(params["IDELAY_VALUE"])
|
||||
for i in range(5):
|
||||
segmk.add_site_tag(
|
||||
loc, "IDELAY_VALUE[%01d]" % i, ((value >> i) & 1) != 0)
|
||||
segmk.add_site_tag(
|
||||
loc, "ZIDELAY_VALUE[%01d]" % i, ((value >> i) & 1) == 0)
|
||||
|
||||
# Delay source
|
||||
value = verilog.unquote(params["DELAY_SRC"])
|
||||
for x in delay_srcs:
|
||||
segmk.add_site_tag(loc, "DELAY_SRC_%s" % x, int(value == x))
|
||||
|
||||
value = verilog.unquote(params["CINVCTRL_SEL"])
|
||||
segmk.add_site_tag(loc, "CINVCTRL_SEL", int(value == "TRUE"))
|
||||
|
||||
value = verilog.unquote(params["PIPE_SEL"])
|
||||
segmk.add_site_tag(loc, "PIPE_SEL", int(value == "TRUE"))
|
||||
|
||||
if "IS_C_INVERTED" in params:
|
||||
segmk.add_site_tag(
|
||||
loc, "IS_C_INVERTED", int(params["IS_C_INVERTED"]))
|
||||
segmk.add_site_tag(loc, "ZINV_C", 1 ^ int(params["IS_C_INVERTED"]))
|
||||
|
||||
segmk.add_site_tag(
|
||||
loc, "IS_DATAIN_INVERTED", int(params["IS_DATAIN_INVERTED"]))
|
||||
if params['IBUF_IN_USE']:
|
||||
value = verilog.unquote(params["HIGH_PERFORMANCE_MODE"])
|
||||
segmk.add_site_tag(
|
||||
loc, "HIGH_PERFORMANCE_MODE", int(value == "TRUE"))
|
||||
|
||||
segmk.add_site_tag(
|
||||
loc, "IS_IDATAIN_INVERTED", int(params["IS_IDATAIN_INVERTED"]))
|
||||
|
||||
segmk.compile(bitfilter=bitfilter)
|
||||
segmk.write()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -55,33 +55,49 @@ def run():
|
|||
# Header
|
||||
print("// Tile count: %d" % len(tiles))
|
||||
print("// Seed: '%s'" % os.getenv("SEED"))
|
||||
|
||||
ninputs = 0
|
||||
di_idx = []
|
||||
for i, sites in enumerate(tiles):
|
||||
if random.randint(0, 1):
|
||||
di_idx.append(ninputs)
|
||||
ninputs += 1
|
||||
else:
|
||||
di_idx.append(None)
|
||||
|
||||
print(
|
||||
'''
|
||||
module top (
|
||||
(* CLOCK_BUFFER_TYPE = "NONE" *)
|
||||
input wire clk,
|
||||
input wire [{N}:0] di,
|
||||
output wire [{N}:0] do
|
||||
input wire [{N}:0] di
|
||||
);
|
||||
|
||||
wire clk_buf = clk;
|
||||
|
||||
wire [{N}:0] di_buf;
|
||||
wire [{N}:0] do_buf;
|
||||
'''.format(**{"N": len(tiles) - 1}))
|
||||
'''.format(N=ninputs - 1))
|
||||
|
||||
# LOCes IOBs
|
||||
data = []
|
||||
for i, sites in enumerate(tiles):
|
||||
for i, (sites, ibuf_idx) in enumerate(zip(tiles, di_idx)):
|
||||
|
||||
if random.randint(0, 1):
|
||||
iob_i = sites[0]
|
||||
iob_o = sites[2]
|
||||
idelay = sites[1]
|
||||
other_idelay = sites[3]
|
||||
else:
|
||||
iob_i = sites[2]
|
||||
iob_o = sites[0]
|
||||
idelay = sites[3]
|
||||
other_idelay = sites[1]
|
||||
|
||||
use_ibuf = ibuf_idx is not None
|
||||
|
||||
DELAY_SRC = random.choice(["IDATAIN", "DATAIN"])
|
||||
if not use_ibuf:
|
||||
DELAY_SRC = 'DATAIN'
|
||||
|
||||
params = {
|
||||
"LOC":
|
||||
|
|
@ -92,7 +108,7 @@ wire [{N}:0] do_buf;
|
|||
"IDELAY_VALUE":
|
||||
random.randint(0, 31),
|
||||
"DELAY_SRC":
|
||||
"\"" + random.choice(["IDATAIN", "DATAIN"]) + "\"",
|
||||
"\"" + DELAY_SRC + "\"",
|
||||
"HIGH_PERFORMANCE_MODE":
|
||||
"\"" + random.choice(["TRUE", "FALSE"]) + "\"",
|
||||
"CINVCTRL_SEL":
|
||||
|
|
@ -121,14 +137,21 @@ wire [{N}:0] do_buf;
|
|||
|
||||
param_str = ",".join(".%s(%s)" % (k, v) for k, v in params.items())
|
||||
|
||||
print('')
|
||||
print('(* LOC="%s", KEEP, DONT_TOUCH *)' % iob_i)
|
||||
print('IBUF ibuf_%03d (.I(di[%3d]), .O(di_buf[%3d]));' % (i, i, i))
|
||||
print('(* LOC="%s", KEEP, DONT_TOUCH *)' % iob_o)
|
||||
print('OBUF obuf_%03d (.I(do_buf[%3d]), .O(do[%3d]));' % (i, i, i))
|
||||
print(
|
||||
'mod #(%s) mod_%03d (.clk(clk_buf), .I(di_buf[%3d]), .O(do_buf[%3d]));'
|
||||
% (param_str, i, i, i))
|
||||
if use_ibuf:
|
||||
print('')
|
||||
print('(* LOC="%s", KEEP, DONT_TOUCH *)' % iob_i)
|
||||
print(
|
||||
'IBUF ibuf_%03d (.I(di[%3d]), .O(di_buf[%3d]));' %
|
||||
(ibuf_idx, ibuf_idx, ibuf_idx))
|
||||
print(
|
||||
'mod #(%s) mod_%03d (.clk(clk_buf), .I(di_buf[%3d]));' %
|
||||
(param_str, i, ibuf_idx))
|
||||
else:
|
||||
print('mod #(%s) mod_%03d (.clk(clk_buf), .I());' % (param_str, i))
|
||||
|
||||
params['IBUF_IN_USE'] = use_ibuf
|
||||
params["IDELAY_IN_USE"] = idelay
|
||||
params["IDELAY_NOT_IN_USE"] = other_idelay
|
||||
|
||||
data.append(params)
|
||||
|
||||
|
|
@ -147,8 +170,7 @@ endmodule
|
|||
(* KEEP, DONT_TOUCH *)
|
||||
module mod(
|
||||
input wire clk,
|
||||
input wire I,
|
||||
output wire O
|
||||
input wire I
|
||||
);
|
||||
|
||||
parameter LOC = "";
|
||||
|
|
@ -164,6 +186,10 @@ parameter IS_DATAIN_INVERTED = 0;
|
|||
parameter IS_IDATAIN_INVERTED = 0;
|
||||
|
||||
wire x;
|
||||
wire lut;
|
||||
|
||||
(* KEEP, DONT_TOUCH *)
|
||||
LUT2 l( .O(lut) );
|
||||
|
||||
// IDELAY
|
||||
(* LOC=LOC, KEEP, DONT_TOUCH *)
|
||||
|
|
@ -189,24 +215,12 @@ idelay
|
|||
.CINVCTRL(),
|
||||
.CNTVALUEIN(),
|
||||
.IDATAIN(I),
|
||||
.DATAIN(),
|
||||
.DATAIN(lut),
|
||||
.LDPIPEEN(),
|
||||
.DATAOUT(x),
|
||||
.CNTVALUEOUT()
|
||||
);
|
||||
|
||||
// A LUT
|
||||
(* KEEP, DONT_TOUCH *)
|
||||
LUT6 #(.INIT(32'hDEADBEEF)) lut (
|
||||
.I0(x),
|
||||
.I1(x),
|
||||
.I2(x),
|
||||
.I3(x),
|
||||
.I4(x),
|
||||
.I5(x),
|
||||
.O(O)
|
||||
);
|
||||
|
||||
endmodule
|
||||
''')
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue