Added dumping of dummy inout ports, added generation of techmap that ties unconnected ports to 0.

Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
This commit is contained in:
Maciej Kurc 2019-12-17 13:50:38 +01:00
parent 5d140296d5
commit cb26746128
4 changed files with 129 additions and 28 deletions

View File

@ -1,9 +1,11 @@
.PHONY: all clean
all: ps7.v
all: xtra.ok
clean:
rm -rf ps7.v
rm -rf xtra.ok
rm -rf ps7_sim.v
rm -rf ps7_map.v
rm -rf ps7.csv
rm -rf *.xml
rm -rf *.log
@ -12,5 +14,6 @@ clean:
ps7.csv: dump_ps7.tcl
$(XRAY_VIVADO) -mode batch -source dump_ps7.tcl -nojournal -log $(basename $@).log
ps7.v: ps7.csv make_cell.py
xtra.ok: ps7.csv make_cell.py
python3 make_cell.py $<
touch xtra.ok

View File

@ -1,3 +1,3 @@
# PS7 verilog cell definition extractor
Extracts all pins of the PS7 bel from Vivado, groups them into buses, removes those that are not connected (TEST*, DEBUG*) and writes the PS7 verilog cell definition.
Extracts all pins of the PS7 bel from Vivado, groups them into buses, removes those that are not connected (TEST*, DEBUG*) and creates the VPR counterpart for it. It also generates model XML, pb_type XML and techmap which handles unconnected ports correctly.

View File

@ -3,7 +3,7 @@ set_property design_mode PinPlanning [current_fileset]
open_io_design -name io_1
set fp [open ps7.csv w]
puts $fp "name,is_input,is_output"
puts $fp "name,is_input,is_output,is_bidir"
set pins [get_bel_pins -of_objects [get_bels -of_objects [get_sites PS7* -of_objects [get_tiles PSS*]]]]
foreach pin $pins {
@ -11,8 +11,9 @@ foreach pin $pins {
set pin_name [lindex [split $pin "/"] 2]
set is_input [get_property IS_INPUT $pin]
set is_output [get_property IS_OUTPUT $pin]
set is_bidir [get_property IS_BIDIR $pin]
puts $fp "$pin_name,$is_input,$is_output"
puts $fp "$pin_name,$is_input,$is_output,$is_bidir"
}
close $fp

View File

@ -7,7 +7,6 @@ from collections import defaultdict
# =============================================================================
def main():
BUS_REGEX = re.compile("(.*[A-Z_])([0-9]+)$")
@ -41,10 +40,18 @@ def main():
idx = 0
# Get direction
if int(pin["is_input"]):
is_input = int(pin["is_input"])
is_output = int(pin["is_output"])
is_bidir = int(pin["is_bidir"])
if is_input and not is_output and not is_bidir:
direction = "input"
if int(pin["is_output"]):
elif not is_input and is_output and not is_bidir:
direction = "output"
elif not is_input and not is_output and is_bidir:
direction = "inout"
else:
assert False, pin
# Add to bus
bus = buses[name]
@ -90,9 +97,12 @@ def main():
# .....................................................
# Generate XML model
pb_name = "PS7"
blif_model = "PS7_VPR"
model_xml = """<models>
<model name="PS7">
"""
<model name="{}">
""".format(blif_model)
# Inputs
model_xml += """ <input_ports>
@ -101,7 +111,7 @@ def main():
bus = buses[name]
# Skip not relevant pins
if bus["class"] not in ["normal", "mio"]:
if bus["class"] not in ["normal"]:
continue
if bus["direction"] != "input":
@ -117,7 +127,7 @@ def main():
bus = buses[name]
# Skip not relevant pins
if bus["class"] not in ["normal", "mio"]:
if bus["class"] not in ["normal"]:
continue
if bus["direction"] != "output":
@ -136,9 +146,6 @@ def main():
# .....................................................
# Generate XML pb_type
pb_name = "PS7"
blif_model = "PS7"
pb_xml = """<pb_type name="{}" blif_model=".subckt {}" num_pb="1">
""".format(pb_name, blif_model)
@ -146,7 +153,7 @@ def main():
bus = buses[name]
# Skip not relevant pins
if bus["class"] not in ["normal", "mio"]:
if bus["class"] not in ["normal"]:
continue
pb_xml += " <{} name=\"{}\" num_pins=\"{}\"/>\n".format(
@ -159,8 +166,42 @@ def main():
fp.write(pb_xml)
# .....................................................
# Prepare Verilog module definition for the PS7
pin_strs = []
# Prepare Verilog module definition for the PS7_VPR
port_defs = []
for name in sorted(buses.keys()):
bus = buses[name]
# Skip not relevant pins (eg. MIO and DDR)
if bus["class"] not in ["normal"]:
continue
# Generate port definition
if bus["width"] > 1:
port_str = " {} [{:>2d}:{:>2d}] {}".format(
bus["direction"].ljust(6), bus["max"], bus["min"], name)
else:
port_str = " {} {}".format(bus["direction"].ljust(6), name)
port_defs.append(port_str)
verilog = """(* blackbox *)
module PS7_VPR (
{}
);
endmodule
""".format(",\n".join(port_defs))
with open("ps7_sim.v", "w") as fp:
fp.write(verilog)
# .....................................................
# Prepare techmap that maps PS7 to PS7_VPR and handles
# unconnected inputs (ties them to GND)
port_defs = []
port_conns = []
param_defs = []
wire_defs = []
for name in sorted(buses.keys()):
bus = buses[name]
@ -168,25 +209,81 @@ def main():
if bus["class"] not in ["normal", "mio"]:
continue
# Generate port definition
if bus["width"] > 1:
pin_str = " {} [{:>2d}:{:>2d}] {}".format(
port_str = " {} [{:>2d}:{:>2d}] {}".format(
bus["direction"].ljust(6), bus["max"], bus["min"], name)
else:
pin_str = " {} {}".format(bus["direction"].ljust(6), name)
port_str = " {} {}".format(bus["direction"].ljust(6), name)
pin_strs.append(pin_str)
port_defs.append(port_str)
verilog = """(* blackbox *)
module PS7 (
{}
# MIO and DDR pins are not mapped as they are dummy
if bus["class"] == "mio":
continue
# This is an input port, needs to be tied to GND if unconnected
if bus["direction"] == "input":
# Techmap parameter definition
param_defs.append(" parameter _TECHMAP_CONSTMSK_{}_ = 0;".format(name.upper()))
param_defs.append(" parameter _TECHMAP_CONSTVAL_{}_ = 0;".format(name.upper()))
# Wire definition using generate statement. Necessary for detection
# of unconnected ports.
wire_defs.append("""
generate if((_TECHMAP_CONSTMSK_{name_upr}_ == {N}'d0) && (_TECHMAP_CONSTVAL_{name_upr}_ == {N}'d0))
wire [{M}:0] {name_lwr} = {N}'d0;
else
wire [{M}:0] {name_lwr} = {name};
end""".format(
name=name,
name_upr=name.upper(),
name_lwr=name.lower(),
N=bus["width"],
M=bus["width"]-1
))
# Connection to the "generated" wire.
port_conns.append(" .{name:<25}({name_lwr})".format(
name=name,
name_lwr=name.lower()
))
# An output port
else:
# Direct connection
port_conns.append(" .{name:<25}({name})".format(name=name))
# Format the final verilog.
verilog = """module PS7 (
{port_defs}
);
endmodule
""".format(",\n".join(pin_strs))
// Techmap specific parameters.
{param_defs}
with open("ps7.v", "w") as fp:
// Detect all unconnected inputs and tie them to 0.
{wire_defs}
// Replacement cell.
PS7_VPR _TECHMAP_REPLACE_ (
{port_conns}
);
endmodule
""".format(
port_defs=",\n".join(port_defs),
param_defs="\n".join(param_defs),
wire_defs="\n".join(wire_defs),
port_conns=",\n".join(port_conns)
)
with open("ps7_map.v", "w") as fp:
fp.write(verilog)
# =============================================================================
if __name__ == "__main__":
main()