XDC: Add PACKAGE_PIN property support

Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
diff --git a/xdc-plugin/tests/Makefile b/xdc-plugin/tests/Makefile
index d603656..714ed73 100644
--- a/xdc-plugin/tests/Makefile
+++ b/xdc-plugin/tests/Makefile
@@ -2,16 +2,19 @@
 # port_indexes - like counter but bus port indices are passes without curly braces
 # io_loc_pairs - test for LOC property being set on IOBUFs as the IO_LOC_PAIRS parameter
 # minilitex_ddr_arty - litex design with more types of IOBUFS including differential
+# package_pins - test for PACKAGE_PIN property being set on IOBUFs as the IO_LOC_PAIRS parameter
 
 TESTS = counter \
 	port_indexes \
 	io_loc_pairs \
-	minilitex_ddr_arty
+	minilitex_ddr_arty \
+	package_pins
 
 counter_verify = $(call compare_json,counter)
 port_indexes_verify = $(call compare_json,port_indexes) && test $$(grep "'unknown' proc command handler" port_indexes/port_indexes.txt | wc -l) -eq 2
 io_loc_pairs_verify = $(call compare_json,io_loc_pairs)
 minilitex_ddr_arty_verify = $(call compare_json,minilitex_ddr_arty)
+package_pins_verify = $(call compare_json,package_pins)
 
 all: $(TESTS)
 
diff --git a/xdc-plugin/tests/package_pins/package_pins.tcl b/xdc-plugin/tests/package_pins/package_pins.tcl
new file mode 100644
index 0000000..8c0a57c
--- /dev/null
+++ b/xdc-plugin/tests/package_pins/package_pins.tcl
@@ -0,0 +1,14 @@
+yosys -import
+plugin -i xdc
+#Import the commands from the plugins to the tcl interpreter
+yosys -import
+
+# -flatten is used to ensure that the output eblif has only one module.
+# Some of symbiflow expects eblifs with only one module.
+synth_xilinx -vpr -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+#Read the design constraints
+read_xdc -part_json $::env(PART_JSON) $::env(INPUT_XDC_FILE)
+
+# Write the design in JSON format.
+write_json $::env(OUT_JSON)
diff --git a/xdc-plugin/tests/package_pins/package_pins.v b/xdc-plugin/tests/package_pins/package_pins.v
new file mode 100644
index 0000000..c145e5a
--- /dev/null
+++ b/xdc-plugin/tests/package_pins/package_pins.v
@@ -0,0 +1,75 @@
+module top (
+	input  clk,
+	output [3:0] led,
+	inout out_a,
+	output [1:0] out_b,
+	output signal_p,
+	output signal_n
+);
+
+	wire LD6, LD7, LD8, LD9;
+	wire inter_wire, inter_wire_2;
+	localparam BITS = 1;
+	localparam LOG2DELAY = 25;
+
+	reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+	always @(posedge clk) begin
+		counter <= counter + 1;
+	end
+	assign led[1] = inter_wire;
+	assign inter_wire = inter_wire_2;
+	assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+	OBUFTDS OBUFTDS_2(
+		.I(LD6),
+		.O(signal_p),
+		.OB(signal_n),
+		.T(1'b1)
+	);
+	OBUF #(
+		.IOSTANDARD("LVCMOS33"),
+		.SLEW("SLOW")
+	) OBUF_6(.I(LD6), .O(led[0]));
+	OBUF #(
+		.IOSTANDARD("LVCMOS33"),
+		.SLEW("SLOW")
+	) OBUF_7(.I(LD7), .O(inter_wire_2));
+	OBUF #(
+		.IOSTANDARD("LVCMOS33"),
+		.SLEW("SLOW")
+	) OBUF_OUT(.I(LD7), .O(out_a));
+	bottom bottom_inst(.I(LD8), .O(led[2]), .OB(out_b));
+	bottom_intermediate bottom_intermediate_inst(.I(LD9), .O(led[3]));
+endmodule
+
+module bottom_intermediate (
+	input I,
+	output O
+);
+	wire bottom_intermediate_wire;
+	assign O = bottom_intermediate_wire;
+	OBUF #(
+		.IOSTANDARD("LVCMOS33"),
+		.SLEW("SLOW")
+	) OBUF_8(.I(I), .O(bottom_intermediate_wire));
+endmodule
+
+module bottom (
+	input I,
+	output [1:0] OB,
+	output O
+);
+	OBUF #(
+		.IOSTANDARD("LVCMOS33"),
+		.SLEW("SLOW")
+	) OBUF_9(.I(I), .O(O));
+	OBUF #(
+		.IOSTANDARD("LVCMOS33"),
+		.SLEW("SLOW")
+	) OBUF_10(.I(I), .O(OB[0]));
+	OBUF #(
+		.IOSTANDARD("LVCMOS33"),
+		.SLEW("SLOW")
+	) OBUF_11(.I(I), .O(OB[1]));
+endmodule
+
diff --git a/xdc-plugin/tests/package_pins/package_pins.xdc b/xdc-plugin/tests/package_pins/package_pins.xdc
new file mode 100644
index 0000000..543edb0
--- /dev/null
+++ b/xdc-plugin/tests/package_pins/package_pins.xdc
@@ -0,0 +1,36 @@
+#OBUF_6
+set_property PACKAGE_PIN D10 [get_ports {led[0]}]
+set_property DRIVE 12 [get_ports {led[0]}]
+#OBUF_7
+set_property PACKAGE_PIN A9 [get_ports {led[1]}]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports led[1]]
+set_property SLEW FAST [get_ports led[1]]
+set_property IOSTANDARD SSTL135 [get_ports led[1]]
+#OBUF_OUT
+set_property PACKAGE_PIN E3 [get_ports out_a]
+set_property IN_TERM UNTUNED_SPLIT_50 [get_ports out_a]
+set_property SLEW FAST [get_ports out_a]
+set_property IOSTANDARD LVCMOS33 [get_ports out_a]
+#bottom_inst.OBUF_10
+set_property PACKAGE_PIN C2 [get_ports {out_b[0]}]
+set_property SLEW SLOW [get_ports {out_b[0]}]
+set_property IOSTANDARD LVCMOS18 [get_ports {out_b[0]}]
+#bottom_inst.OBUF_11
+set_property PACKAGE_PIN R2 [get_ports {out_b[1]}]
+set_property DRIVE 4 [get_ports {out_b[1]}]
+set_property SLEW FAST [get_ports {out_b[1]}]
+set_property IOSTANDARD LVCMOS25 [get_ports {out_b[1]}]
+#bottom_inst.OBUF_9
+set_property PACKAGE_PIN M6 [get_ports {led[2]}]
+set_property SLEW FAST [get_ports {led[2]}]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports {led[2]}]
+#bottom_intermediate_inst.OBUF_8
+set_property PACKAGE_PIN N4 [get_ports {led[3]}]
+set_property DRIVE 16 [get_ports {led[3]}]
+set_property IOSTANDARD SSTL135 [get_ports {led[3]}]
+#OBUFTDS_2
+set_property PACKAGE_PIN N2 [get_ports signal_p]
+set_property PACKAGE_PIN N1 [get_ports signal_n]
+set_property SLEW FAST [get_ports signal_p]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports signal_p]
+
diff --git a/xdc-plugin/tests/package_pins/package_pins_golden.json b/xdc-plugin/tests/package_pins/package_pins_golden.json
new file mode 100644
index 0000000..2e9102d
--- /dev/null
+++ b/xdc-plugin/tests/package_pins/package_pins_golden.json
@@ -0,0 +1,47 @@
+{
+  "OBUFTDS_2": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "IO_LOC_PAIRS": "signal_p:N2,signal_n:N1",
+    "SLEW": "FAST"
+  },
+  "OBUF_6": {
+    "DRIVE": "12",
+    "IOSTANDARD": "LVCMOS33",
+    "IO_LOC_PAIRS": "led[0]:D10",
+    "SLEW": "SLOW"
+  },
+  "OBUF_7": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "led[1]:A9",
+    "SLEW": "FAST"
+  },
+  "OBUF_OUT": {
+    "IN_TERM": "UNTUNED_SPLIT_50",
+    "IOSTANDARD": "LVCMOS33",
+    "IO_LOC_PAIRS": "out_a:E3",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_10": {
+    "IOSTANDARD": "LVCMOS18",
+    "IO_LOC_PAIRS": "out_b[0]:C2",
+    "SLEW": "SLOW"
+  },
+  "bottom_inst.OBUF_11": {
+    "DRIVE": "4",
+    "IOSTANDARD": "LVCMOS25",
+    "IO_LOC_PAIRS": "out_b[1]:R2",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_9": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "IO_LOC_PAIRS": "led[2]:M6",
+    "SLEW": "FAST"
+  },
+  "bottom_intermediate_inst.OBUF_8": {
+    "DRIVE": "16",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "led[3]:N4",
+    "SLEW": "SLOW"
+  }
+}
\ No newline at end of file
diff --git a/xdc-plugin/xdc.cc b/xdc-plugin/xdc.cc
index 7237565..9a8e5e7 100644
--- a/xdc-plugin/xdc.cc
+++ b/xdc-plugin/xdc.cc
@@ -52,7 +52,8 @@
 	{"SLEW", SetPropertyOptions::SLEW},
 	{"DRIVE", SetPropertyOptions::DRIVE},
 	{"IN_TERM", SetPropertyOptions::IN_TERM},
-	{"LOC", SetPropertyOptions::IO_LOC_PAIRS}
+	{"LOC", SetPropertyOptions::IO_LOC_PAIRS},
+	{"PACKAGE_PIN", SetPropertyOptions::IO_LOC_PAIRS}
 };
 
 const std::unordered_map<std::string, std::vector<std::string>> supported_primitive_parameters  = {