Skip to content

Commit

Permalink
Merge pull request f4pga#1500 from antmicro/iobufds_support
Browse files Browse the repository at this point in the history
IOBUFDS support
  • Loading branch information
litghost committed Jun 26, 2020
2 parents a200ace + 17772bf commit 751a444
Show file tree
Hide file tree
Showing 16 changed files with 1,256 additions and 68 deletions.
13 changes: 13 additions & 0 deletions xc/common/primitives/iob33m/iob33m.model.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,17 @@
<port name="OB"/>
</output_ports>
</model>
<model name="IOBUFDS_M_VPR">
<input_ports>
<port name="I" combinational_sink_ports="IOPAD_$out OB"/>
<port name="T" combinational_sink_ports="IOPAD_$out OB"/>
<port name="IOPAD_$inp" combinational_sink_ports="O"/>
<port name="IB" combinational_sink_ports="O"/>
</input_ports>
<output_ports>
<port name="O"/>
<port name="IOPAD_$out"/>
<port name="OB"/>
</output_ports>
</model>
</models>
54 changes: 54 additions & 0 deletions xc/common/primitives/iob33m/iob33m.pb_type.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,60 @@
</interconnect>
</mode>

<mode name="IOBUFDS_M">
<xi:include href="../iob33/inpad.pb_type.xml"/>
<xi:include href="../iob33/outpad.pb_type.xml"/>

<pb_type name="IOBUFDS_M_VPR" blif_model=".subckt IOBUFDS_M_VPR" num_pb="1">
<input name="I" num_pins="1"/>
<input name="T" num_pins="1"/>
<output name="O" num_pins="1"/>
<input name="IOPAD_$inp" num_pins="1"/>
<output name="IOPAD_$out" num_pins="1"/>
<input name="IB" num_pins="1"/>
<output name="OB" num_pins="1"/>

<delay_constant max="10e-12" in_port="I" out_port="IOPAD_$out"/>
<delay_constant max="10e-12" in_port="I" out_port="OB"/>
<delay_constant max="10e-12" in_port="T" out_port="IOPAD_$out"/>
<delay_constant max="10e-12" in_port="T" out_port="OB"/>
<delay_constant max="10e-12" in_port="IB" out_port="O"/>
<delay_constant max="10e-12" in_port="IOPAD_$inp" out_port="O"/>

<metadata>
<meta name="fasm_params">
LVCMOS12_LVCMOS15_LVCMOS18_LVCMOS25_LVCMOS33_LVTTL_SSTL135_SSTL15.SLEW.SLOW = LVCMOS12_LVCMOS15_LVCMOS18_LVCMOS25_LVCMOS33_LVTTL_SSTL135_SSTL15_SLEW_SLOW
LVCMOS12_LVCMOS15_LVCMOS18_SSTL135_SSTL15.STEPDOWN = LVCMOS12_LVCMOS15_LVCMOS18_SSTL135_SSTL15_STEPDOWN
LVCMOS15_SSTL15.DRIVE.I16_I_FIXED = LVCMOS15_SSTL15_DRIVE_I16_I_FIXED
SSTL135.DRIVE.I_FIXED = SSTL135_DRIVE_I_FIXED
SSTL135_SSTL15.IN_DIFF = SSTL135_SSTL15_IN_DIFF
SSTL135_SSTL15.SLEW.FAST = SSTL135_SSTL15_SLEW_FAST
IN_TERM.UNTUNED_SPLIT_40 = IN_TERM_UNTUNED_SPLIT_40
IN_TERM.UNTUNED_SPLIT_50 = IN_TERM_UNTUNED_SPLIT_50
IN_TERM.UNTUNED_SPLIT_60 = IN_TERM_UNTUNED_SPLIT_60
PULLTYPE.PULLUP = PULLTYPE_PULLUP
PULLTYPE.PULLDOWN = PULLTYPE_PULLDOWN
PULLTYPE.NONE = PULLTYPE_NONE
PULLTYPE.KEEPER = PULLTYPE_KEEPER
</meta>
</metadata>
</pb_type>

<interconnect>
<direct name="I" input="IOB33_MODES.O" output="IOBUFDS_M_VPR.I"/>
<direct name="T" input="IOB33_MODES.T" output="IOBUFDS_M_VPR.T"/>
<direct name="O" input="IOBUFDS_M_VPR.O" output="IOB33_MODES.I"/>
<direct name="IOPAD_$out" input="IOBUFDS_M_VPR.IOPAD_$out" output="outpad.outpad">
<pack_pattern name="IOBUFDS_M_VPR_to_PAD"/>
</direct>
<direct name="IOPAD_$inp" input="inpad.inpad" output="IOBUFDS_M_VPR.IOPAD_$inp">
<pack_pattern name="IOBUFDS_M_VPR_to_PAD"/>
</direct>
<direct name="OB" input="IOBUFDS_M_VPR.OB" output="IOB33_MODES.DIFFO_OUT"/>
<direct name="IB" input="IOB33_MODES.DIFFI_IN" output="IOBUFDS_M_VPR.IB"/>
</interconnect>
</mode>

</pb_type>

<interconnect>
Expand Down
10 changes: 10 additions & 0 deletions xc/common/primitives/iob33s/iob33s.model.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,14 @@
<port name="OB"/>
</output_ports>
</model>
<model name="IOBUFDS_S_VPR">
<input_ports>
<port name="IB" combinational_sink_ports="IOPAD_$out"/>
<port name="IOPAD_$inp" combinational_sink_ports="OB"/>
</input_ports>
<output_ports>
<port name="OB"/>
<port name="IOPAD_$out"/>
</output_ports>
</model>
</models>
46 changes: 46 additions & 0 deletions xc/common/primitives/iob33s/iob33s.pb_type.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,52 @@

</mode>

<mode name="IOBUFDS_S">
<xi:include href="../iob33/inpad.pb_type.xml"/>
<xi:include href="../iob33/outpad.pb_type.xml"/>

<pb_type name="IOBUFDS_S_VPR" blif_model=".subckt IOBUFDS_S_VPR" num_pb="1">
<input name="IB" num_pins="1"/>
<output name="OB" num_pins="1"/>
<input name="IOPAD_$inp" num_pins="1"/>
<output name="IOPAD_$out" num_pins="1"/>

<delay_constant max="10e-12" in_port="IB" out_port="IOPAD_$out"/>
<delay_constant max="10e-12" in_port="IOPAD_$inp" out_port="OB"/>

<metadata>
<meta name="fasm_params">
LVCMOS12_LVCMOS15_LVCMOS18_LVCMOS25_LVCMOS33_LVTTL_SSTL135_SSTL15.SLEW.SLOW = LVCMOS12_LVCMOS15_LVCMOS18_LVCMOS25_LVCMOS33_LVTTL_SSTL135_SSTL15_SLEW_SLOW
LVCMOS12_LVCMOS15_LVCMOS18_SSTL135_SSTL15.STEPDOWN = LVCMOS12_LVCMOS15_LVCMOS18_SSTL135_SSTL15_STEPDOWN
LVCMOS15_SSTL15.DRIVE.I16_I_FIXED = LVCMOS15_SSTL15_DRIVE_I16_I_FIXED
SSTL135.DRIVE.I_FIXED = SSTL135_DRIVE_I_FIXED
SSTL135_SSTL15.IN_DIFF = SSTL135_SSTL15_IN_DIFF
SSTL135_SSTL15.SLEW.FAST = SSTL135_SSTL15_SLEW_FAST
IN_TERM.UNTUNED_SPLIT_40 = IN_TERM_UNTUNED_SPLIT_40
IN_TERM.UNTUNED_SPLIT_50 = IN_TERM_UNTUNED_SPLIT_50
IN_TERM.UNTUNED_SPLIT_60 = IN_TERM_UNTUNED_SPLIT_60
PULLTYPE.PULLUP = PULLTYPE_PULLUP
PULLTYPE.PULLDOWN = PULLTYPE_PULLDOWN
PULLTYPE.NONE = PULLTYPE_NONE
PULLTYPE.KEEPER = PULLTYPE_KEEPER
</meta>
</metadata>
</pb_type>

<interconnect>
<direct name="IB" input="IOB33_MODES.DIFFO_IN" output="IOBUFDS_S_VPR.IB"/>
<direct name="OB" input="IOBUFDS_S_VPR.OB" output="IOB33_MODES.PADOUT"/>

<direct name="IOPAD_$out" input="IOBUFDS_S_VPR.IOPAD_$out" output="outpad.outpad">
<pack_pattern name="IOBUFDS_S_VPR_to_PAD"/>
</direct>
<direct name="IOPAD_$inp" input="inpad.inpad" output="IOBUFDS_S_VPR.IOPAD_$inp">
<pack_pattern name="IOBUFDS_S_VPR_to_PAD"/>
</direct>
</interconnect>

</mode>

</pb_type>

<interconnect>
Expand Down
143 changes: 111 additions & 32 deletions xc/common/utils/add_pack_patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,28 @@
IOPAD_OLOGIC_REGEX = re.compile("OLOGICE3.OQ_to_IOB33[MS]?.O")
IOPAD_ILOGIC_REGEX = re.compile("IOB33[MS]?.I_to_ILOGICE3.D")

# =============================================================================


def get_top_pb_type(element):
""" Returns the top level pb_type given a subelement of the XML tree."""
top_pb_type = element.getparent()

# Already top-level
parent = element.getparent()
if parent is not None and parent.tag == "complexblocklist":
return None

# Traverse
while True:
next_parent = top_pb_type.getparent()
parent = element.getparent()

if next_parent.tag in 'complexblocklist':
return top_pb_type
if parent is None:
return None
if parent.tag == "complexblocklist":
assert element.tag == "pb_type", element.tag
return element

top_pb_type = next_parent
element = parent


def check_direct(element, list_to_check):
Expand Down Expand Up @@ -83,6 +93,9 @@ def add_pack_pattern(direct, pack_pattern_prefix):
)


# =============================================================================


def main():
parser = argparse.ArgumentParser(
description="Adds needed pack patterns to the architecture file."
Expand All @@ -99,8 +112,18 @@ def main():
if 'name' not in direct.attrib:
continue

top_parent = get_top_pb_type(direct)
if top_parent is not None:
top_name = top_parent.attrib["name"]
else:
top_name = ""

dir_name = direct.attrib['name']

#
# OSERDES
#

# Adding OSERDES via NO_OBUF pack patterns
if IOPAD_OLOGIC_REGEX.match(dir_name) or check_direct(direct, [
('OSERDES', 'OQ'),
Expand All @@ -122,6 +145,8 @@ def main():
]):
add_pack_pattern(direct, 'OSERDES_OBUF')

# TODO: OSERDES via OBUFT

# Adding OSERDES via IOBUF pack patterns
if IOPAD_OLOGIC_REGEX.match(dir_name) or check_direct(direct, [
('OSERDES', 'OQ'),
Expand All @@ -134,17 +159,36 @@ def main():
]):
add_pack_pattern(direct, 'OSERDES_IOBUF')

# Adding OSERDES to differential OBUF pack patterns
if "OQ_to_IOB33M" in dir_name or check_direct(direct, [
('OBUFTDS_M', 'I'),
('OBUFTDS_M', 'O'),
('OSERDES', 'OQ'),
('IOB33M', 'I'),
('IOB33M', 'O'),
]):
add_pack_pattern(direct, 'OSERDES_OBUFTDS_M')

# Adding ISERDES pack patterns
# TODO: OSERDES via OBUFDS

# Adding OSERDES to differential OBUFTDS pack patterns
if "IOPAD_M" in top_name:
if "OQ_to_IOB33M" in dir_name or check_direct(direct, [
('OBUFTDS_M', 'I'),
('OBUFTDS_M', 'O'),
('OSERDES', 'OQ'),
('IOB33M', 'I'),
('IOB33M', 'O'),
]):
add_pack_pattern(direct, 'OSERDES_OBUFTDS_M')

# Adding OSERDES to differential IOBUFDS pack patterns
if "IOPAD_M" in top_name:
if "OQ_to_IOB33M" in dir_name or check_direct(direct, [
('IOBUFDS_M', 'I'),
('IOBUFDS_M', 'IOPAD_$inp'),
('IOBUFDS_M', 'IOPAD_$out'),
('OSERDES', 'OQ'),
('IOB33M', 'I'),
('IOB33M', 'O'),
]):
add_pack_pattern(direct, 'OSERDES_IOBUFDS_M')

#
# ISERDES, no IDELAY
#

# Adding ISERDES via NO_IBUF
if IOPAD_ILOGIC_REGEX.match(dir_name) or check_direct(direct, [
('NO_IBUF', 'I'),
('ISERDES_NO_IDELAY', 'D'),
Expand All @@ -155,21 +199,7 @@ def main():
('IOB33', 'I'),
('IOB33', 'O'),
]):
add_pack_pattern(direct, 'ISERDES')

# Adding ISERDES with IDELAY pack patterns
if 'DATAOUT_to_ILOGICE3' in dir_name or 'I_to_IDELAYE2' in dir_name or check_direct(
direct, [
('NO_IBUF', 'I'),
('ISERDES_IDELAY', 'DDLY'),
('IOB33S', 'I'),
('IOB33S', 'O'),
('IOB33M', 'I'),
('IOB33M', 'O'),
('IOB33', 'I'),
('IOB33', 'O'),
]):
add_pack_pattern(direct, 'ISERDES_IDELAY')
add_pack_pattern(direct, 'ISERDES_NO_IBUF')

# Adding IOSERDES pack patterns (using IOBUF)
if IOPAD_OLOGIC_REGEX.match(dir_name) or IOPAD_ILOGIC_REGEX.match(
Expand All @@ -184,6 +214,36 @@ def main():
]):
add_pack_pattern(direct, 'IOSERDES')

# Adding ISERDES via differential IOBUFDS pack patterns
if "IOPAD_M" in top_name:
if "I_to_ILOGICE3" in dir_name or check_direct(direct, [
('IOBUFDS_M', 'O'),
('IOBUFDS_M', 'IOPAD_$inp'),
('IOBUFDS_M', 'IOPAD_$out'),
('ISERDES_NO_IDELAY', 'D'),
('IOB33M', 'I'),
('IOB33M', 'O'),
]):
add_pack_pattern(direct, 'ISERDES_IOBUFDS_M')

#
# ISERDES + IDELAY
#

# Adding ISERDES+IDELAY via NO_IBUF pack patterns
if 'DATAOUT_to_ILOGICE3' in dir_name or 'I_to_IDELAYE2' in dir_name or check_direct(
direct, [
('NO_IBUF', 'I'),
('ISERDES_IDELAY', 'DDLY'),
('IOB33S', 'I'),
('IOB33S', 'O'),
('IOB33M', 'I'),
('IOB33M', 'O'),
('IOB33', 'I'),
('IOB33', 'O'),
]):
add_pack_pattern(direct, 'ISERDES_IDELAY_NO_IBUF')

# Adding IOSERDES with IDELAY pack patterns (using IOBUF)
if IOPAD_OLOGIC_REGEX.match(
dir_name
Expand All @@ -195,7 +255,26 @@ def main():
('IOB33S', 'I'), ('IOB33S', 'O'), ('IOB33M', 'I'),
('IOB33M', 'O'), ('IOB33', 'I'), ('IOB33', 'O'),
('ISERDES_IDELAY', 'DDLY'), ('OSERDES', 'OQ')]):
add_pack_pattern(direct, 'IOSERDES_IDELAY')
add_pack_pattern(direct, 'ISERDES_IDELAY_IOBUF')

# Adding ISERDES+IDELAY via differential IOBUFDS pack patterns
if "IOPAD_M" in top_name:
if 'DATAOUT_to_ILOGICE3' in dir_name or 'I_to_IDELAYE2' in dir_name or check_direct(
direct, [
('IOBUFDS_M', 'O'),
('IOBUFDS_M', 'IOPAD_$inp'),
('IOBUFDS_M', 'IOPAD_$out'),
('ISERDES_IDELAY', 'DDLY'),
('IOB33M', 'I'),
('IOB33M', 'O'),
]):
add_pack_pattern(direct, 'ISERDES_IDELAY_IOBUFDS_M')

#
# IDELAY only
#

# TODO: Need to change sth in the arch.

print(ET.tostring(arch_xml, pretty_print=True).decode('utf-8'))

Expand Down
4 changes: 3 additions & 1 deletion xc/common/utils/prjxray_edge_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -2108,7 +2108,9 @@ def create_and_insert_edges(
#
# Issue tracking fix:
# https://github.com/SymbiFlow/symbiflow-arch-defs/issues/1033
if 'PADOUT0' in pip.name or 'PADOUT1' in pip.name:
if 'PADOUT0' in pip.name and 'DIFFI_IN1' not in pip.name:
continue
if 'PADOUT1' in pip.name and 'DIFFI_IN0' not in pip.name:
continue

# These edges are used for bringing general interconnect to the
Expand Down
20 changes: 19 additions & 1 deletion xc/common/utils/prjxray_form_channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,25 @@ def classify_nodes(conn, get_switch_timing):
other_site_wire_pkey, other_number_pips = result
assert write_cur.fetchone() is None

if other_site_wire_pkey is not None and other_number_pips == 1:
force_direct = False

write_cur.execute(
"""
SELECT name
FROM pip_in_tile WHERE pkey = ?;
""", (pip_pkey, )
)
pip_name = write_cur.fetchone()[0]

# A solution for:
# https://github.com/SymbiFlow/symbiflow-arch-defs/issues/1033
if "PADOUT0" in pip_name and "DIFFI_IN1" in pip_name:
force_direct = True
if "PADOUT1" in pip_name and "DIFFI_IN0" in pip_name:
force_direct = True

if other_site_wire_pkey is not None and (other_number_pips == 1
or force_direct):
if src_wire_in_tile_pkey == wire_in_tile_pkey:
src_wire_pkey = site_wire_pkey
dest_wire_pkey = other_site_wire_pkey
Expand Down

0 comments on commit 751a444

Please sign in to comment.