aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2016-05-16 09:39:03 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2016-05-16 09:39:03 +0300
commit5c7631ef559c68bd8d75a081237c39d5d147deb6 (patch)
tree603810a62e5304538e288a858a47b7034f39da48
parent9994e1276580164c6a09b66026c645a50367592d (diff)
Ported Cryptech platform to the Alpha board.
-rw-r--r--rtl/alpha_clkmgr.v69
-rw-r--r--rtl/alpha_fmc_top.v82
-rw-r--r--rtl/clkmgr_dcm.v164
-rw-r--r--rtl/clkmgr_mmcm.v179
-rw-r--r--ucf/alpha_fmc.ucf169
5 files changed, 340 insertions, 323 deletions
diff --git a/rtl/alpha_clkmgr.v b/rtl/alpha_clkmgr.v
index 1cc0337..f870a75 100644
--- a/rtl/alpha_clkmgr.v
+++ b/rtl/alpha_clkmgr.v
@@ -7,7 +7,7 @@
//
//
// Author: Pavel Shatov
-// Copyright (c) 2015, NORDUnet A/S All rights reserved.
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
@@ -39,10 +39,7 @@
module alpha_clkmgr
(
- input wire gclk_p, // signal from clock pins
- input wire gclk_n, //
-
- input wire reset_mcu_b, // cpu reset (async, active-low)
+ input wire gclk, // signal from clock pin
output wire sys_clk, // buffered system clock output
output wire sys_rst_n // system reset output (async set, sync clear, active-low)
@@ -52,74 +49,74 @@ module alpha_clkmgr
//
// Parameters
//
- parameter CLK_OUT_MUL = 2;
- parameter CLK_OUT_DIV = 2;
+ parameter CLK_OUT_MUL = 20.0;
+ parameter CLK_OUT_DIV = 20.0;
//
- // Wrapper for Xilinx-specific DCM (Digital Clock Manager) primitive.
+ // Wrapper for Xilinx-specific MMCM (Mixed Mode Clock Manager) primitive.
//
- wire gclk; // buffered input clock
- wire dcm_reset; // dcm reset
- wire dcm_locked; // output clock valid
- wire gclk_missing; // no input clock
+ wire gclk_int; // buffered input clock
+ wire mmcm_reset; // reset input
+ wire mmcm_locked; // output clock valid
+ wire gclk_missing; // input clock stopped
- clkmgr_dcm #
+ clkmgr_mmcm #
(
- .CLK_OUT_MUL (CLK_OUT_MUL),
- .CLK_OUT_DIV (CLK_OUT_DIV)
+ .CLK_OUT_MUL (CLK_OUT_MUL), // 2..64
+ .CLK_OUT_DIV (CLK_OUT_DIV) // 1..128
)
- dcm
+ mmcm
(
- .clk_in_p (gclk_p),
- .clk_in_n (gclk_n),
- .reset_in (dcm_reset),
+ .clk_in (gclk),
+ .reset_in (mmcm_reset),
- .gclk_out (gclk),
+ .gclk_out (gclk_int),
.gclk_missing_out (gclk_missing),
.clk_out (sys_clk),
- .clk_valid_out (dcm_locked)
- );
+ .clk_valid_out (mmcm_locked)
+ );
+
//
- // DCM Reset Logic
+ // MMCM Reset Logic
//
- /* DCM should be reset on power-up, when input clock is stopped or when the
- * CPU gets reset. Note that DCM requires active-high reset, so the shift
- * register is preloaded with 1's and gradually filled with 0's.
+ /* MMCM should be reset on power-up and when the input clock is stopped.
+ * Note that MMCM requires active-high reset, so the shift register is
+ * preloaded with 1's and then gradually filled with 0's.
*/
- reg [15: 0] dcm_rst_shreg = {16{1'b1}}; // 16-bit shift register
+ reg [15: 0] mmcm_rst_shreg = {16{1'b1}}; // 16-bit shift register
- always @(posedge gclk or negedge reset_mcu_b or posedge gclk_missing)
+ always @(posedge gclk_int or posedge gclk_missing)
//
- if ((reset_mcu_b == 1'b0) || (gclk_missing == 1'b1))
- dcm_rst_shreg <= {16{1'b1}};
+ if ((gclk_missing == 1'b1))
+ mmcm_rst_shreg <= {16{1'b1}};
else
- dcm_rst_shreg <= {dcm_rst_shreg[14:0], 1'b0};
+ mmcm_rst_shreg <= {mmcm_rst_shreg[14:0], 1'b0};
- assign dcm_reset = dcm_rst_shreg[15];
+ assign mmcm_reset = mmcm_rst_shreg[15];
//
// System Reset Logic
//
- /* System reset is asserted for 16 cycles whenever DCM aquires lock. Note
+ /* System reset is asserted for 16 cycles whenever MMCM aquires lock. Note
* that system reset is active-low, so the shift register is preloaded with
* 0's and gradually filled with 1's.
*/
reg [15: 0] sys_rst_shreg = {16{1'b0}}; // 16-bit shift register
- always @(posedge sys_clk or negedge reset_mcu_b or posedge gclk_missing or negedge dcm_locked)
+ always @(posedge sys_clk or posedge gclk_missing or negedge mmcm_locked)
//
- if ((reset_mcu_b == 1'b0) || (gclk_missing == 1'b1) || (dcm_locked == 1'b0))
+ if ((gclk_missing == 1'b1) || (mmcm_locked == 1'b0))
sys_rst_shreg <= {16{1'b0}};
- else if (dcm_locked == 1'b1)
+ else if (mmcm_locked == 1'b1)
sys_rst_shreg <= {sys_rst_shreg[14:0], 1'b1};
assign sys_rst_n = sys_rst_shreg[15];
diff --git a/rtl/alpha_fmc_top.v b/rtl/alpha_fmc_top.v
index b5b85f6..e829545 100644
--- a/rtl/alpha_fmc_top.v
+++ b/rtl/alpha_fmc_top.v
@@ -3,12 +3,12 @@
// alpha_top.v
// ------------
// Top module for the Cryptech Alpha FPGA framework. This design
-// allow us to run the EIM interface at one clock and cores including
+// allow us to run the FMC interface at one clock and cores including
// core selector with the always present global clock.
//
//
// Author: Pavel Shatov
-// Copyright (c) 2015, NORDUnet A/S All rights reserved.
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
@@ -42,16 +42,12 @@
module alpha_fmc_top
(
- input wire gclk_p_pin,
- input wire gclk_n_pin,
+ input wire gclk_pin, // 50 MHz
- input wire reset_mcu_b_pin,
-
- // Cryptech avalanche noise board input
- input wire ct_noise,
+ input wire ct_noise, // cryptech avalanche noise circuit
input wire fmc_clk, // clock
- input wire [21: 0] fmc_a, // address
+ input wire [23: 0] fmc_a, // address
inout wire [31: 0] fmc_d, // data
input wire fmc_ne1, // chip select
input wire fmc_noe, // output enable
@@ -59,8 +55,7 @@ module alpha_fmc_top
input wire fmc_nl, // latch enable
output wire fmc_nwait,// wait
- output wire apoptosis_pin,
- output wire led_pin
+ output wire [3: 0] led_pins // {red, yellow, green, blue}
);
@@ -75,24 +70,23 @@ module alpha_fmc_top
alpha_clkmgr #
(
- .CLK_OUT_MUL (2), // 2..32
- .CLK_OUT_DIV (2) // 1..32
+ .CLK_OUT_MUL (20.0), // 2..64
+ .CLK_OUT_DIV (20.0) // 1..128
)
clkmgr
(
- .gclk_p (gclk_p_pin),
- .gclk_n (gclk_n_pin),
-
- .reset_mcu_b (reset_mcu_b_pin),
-
- .sys_clk (sys_clk),
- .sys_rst_n (sys_rst_n)
+ .gclk (gclk_pin),
+
+ .sys_clk (sys_clk),
+ .sys_rst_n (sys_rst_n)
);
- //
+ //----------------------------------------------------------------
// BUFG
//
+ // FMC clock must be routed through the global clocking backbone.
+ // ----------------------------------------------------------------
wire fmc_clk_bug;
BUFG BUFG_fmc_clk
@@ -109,8 +103,9 @@ module alpha_fmc_top
// FMC arbiter handles FMC access and transfers it into
// `sys_clk' clock domain.
//----------------------------------------------------------------
+`define test
- wire [21: 0] sys_fmc_addr; // address
+ wire [23: 0] sys_fmc_addr; // address
wire sys_fmc_wren; // write enable
wire sys_fmc_rden; // read enable
wire [31: 0] sys_fmc_dout; // data output (from STM32 to FPGA)
@@ -122,7 +117,7 @@ module alpha_fmc_top
fmc_arbiter #
(
- .NUM_ADDR_BITS(22) // change to 26 when
+ .NUM_ADDR_BITS(24) // change to 26 when Alpha is alive!
)
fmc
(
@@ -156,7 +151,7 @@ module alpha_fmc_top
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.fmc_active(sys_fmc_wren | sys_fmc_rden),
- .led_out(led_pin)
+ .led_out(led_pins[0])
);
@@ -185,7 +180,20 @@ module alpha_fmc_top
//
//----------------------------------------------------------------
reg [31: 0] test_reg;
-
+
+
+
+ //
+ // Noise Capture Register
+ //
+ reg [31: 0] noise_reg;
+
+ always @(posedge sys_clk)
+ //
+ noise_reg <= {noise_reg[30:0], ct_noise};
+
+
+
always @(posedge sys_clk)
//
if (sys_fmc_wren) begin
@@ -195,13 +203,13 @@ module alpha_fmc_top
// when writing to non-zero address, store _address_
// (padded with zeroes) instead of data
//
- test_reg <= (sys_fmc_addr == {22{1'b0}}) ? sys_fmc_dout : {{10{1'b0}}, sys_fmc_addr};
+ test_reg <= (sys_fmc_addr == {24{1'b0}}) ? sys_fmc_dout : {{8{1'b0}}, sys_fmc_addr};
//
end else if (sys_fmc_rden) begin
//
// always return current value, ignore address
//
- sys_fmc_din <= test_reg;
+ sys_fmc_din <= (sys_fmc_addr == {24{1'b1}}) ? noise_reg : test_reg;
// when reading from address 0, return the current value
// when reading from other addresses, return the address
@@ -230,18 +238,14 @@ module alpha_fmc_top
.noise(ct_noise)
);
-`endif
-
-
- //----------------------------------------------------------------
- // Alpha Patch
- //
- // Patch logic to keep the Alpha board happy.
- // The apoptosis_pin pin must be kept low or the whole board
- // (more exactly the CPU) will be reset after the FPGA has
- // been configured.
- //----------------------------------------------------------------
- assign apoptosis_pin = 1'b0;
+`endif
+
+
+ //
+ // Dummy assignment to bypass unconnected outpins pins check in BitGen
+ //
+
+ assign led_pins[3:1] = 3'b000;
endmodule
diff --git a/rtl/clkmgr_dcm.v b/rtl/clkmgr_dcm.v
deleted file mode 100644
index 141863e..0000000
--- a/rtl/clkmgr_dcm.v
+++ /dev/null
@@ -1,164 +0,0 @@
-//======================================================================
-//
-// clkmgr_dcm.v
-// ---------------
-// Xilinx DCM_SP primitive wrapper to avoid using Clocking Wizard IP core.
-//
-//
-// Author: Pavel Shatov
-// Copyright (c) 2015, NORDUnet A/S All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// - Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// - Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// - Neither the name of the NORDUnet nor the names of its contributors may
-// be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-//======================================================================
-
-module clkmgr_dcm
- (
- input wire clk_in_p,
- input wire clk_in_n,
- input wire reset_in,
-
- output wire gclk_out,
- output wire gclk_missing_out,
-
- output wire clk_out,
- output wire clk_valid_out
- );
-
-
- //
- // Parameters
- //
- parameter CLK_OUT_MUL = 2; // multiply factor for output clock frequency (2..32)
- parameter CLK_OUT_DIV = 2; // divide factor for output clock frequency (1..32)
-
-
- //
- // IBUFGDS
- //
- /* Xilinx-specific primitive to handle LVDS input signal. */
- (* BUFFER_TYPE="NONE" *)
- wire clk_in;
-
- IBUFGDS IBUFGDS_gclk
- (
- .I(clk_in_p),
- .IB(clk_in_n),
- .O(clk_in)
- );
-
- //
- // DCM_SP
- //
- /* Xilinx-specific primitive. */
- wire dcm_clk_0;
- wire dcm_clk_feedback;
- wire dcm_clk_fx;
- wire dcm_locked_int;
- wire [ 7: 0] dcm_status_int;
-
- DCM_SP #
- (
- .STARTUP_WAIT ("FALSE"),
- .DESKEW_ADJUST ("SYSTEM_SYNCHRONOUS"),
- .CLK_FEEDBACK ("1X"),
-
- .PHASE_SHIFT (0),
- .CLKOUT_PHASE_SHIFT ("NONE"),
-
- .CLKIN_PERIOD (20.0), // 50 MHz => 20 ns
- .CLKIN_DIVIDE_BY_2 ("FALSE"),
-
- .CLKDV_DIVIDE (5.000),
- .CLKFX_MULTIPLY (CLK_OUT_MUL),
- .CLKFX_DIVIDE (CLK_OUT_DIV)
- )
- DCM_SP_inst
- (
- .RST (reset_in),
-
- .CLKIN (clk_in),
- .CLKFB (dcm_clk_feedback),
- .CLKDV (),
-
- .CLK0 (dcm_clk_0),
- .CLK90 (),
- .CLK180 (),
- .CLK270 (),
-
- .CLK2X (),
- .CLK2X180 (),
-
- .CLKFX (dcm_clk_fx),
- .CLKFX180 (),
-
- .PSCLK (1'b0),
- .PSEN (1'b0),
- .PSINCDEC (1'b0),
- .PSDONE (),
-
- .LOCKED (dcm_locked_int),
- .STATUS (dcm_status_int),
-
- .DSSEN (1'b0)
- );
-
-
- //
- // Mapping
- //
- assign gclk_out = clk_in;
- assign gclk_missing_out= dcm_status_int[1];
- assign clk_valid_out = dcm_locked_int & ((dcm_status_int[2:1] == 2'b00) ? 1'b1 : 1'b0);
-
-
- //
- // Feedback
- //
- /* DCM_SP requires BUFG primitive in its feedback path. */
- BUFG BUFG_feedback
- (
- .I (dcm_clk_0),
- .O (dcm_clk_feedback)
- );
-
- //
- // Output Buffer
- //
- /* Connect system clock to global clocking network. */
- BUFG BUFG_output
- (
- .I (dcm_clk_fx),
- .O (clk_out)
- );
-
-
-endmodule
-
-//======================================================================
-// EOF clkmgr_dcm.v
-//======================================================================
diff --git a/rtl/clkmgr_mmcm.v b/rtl/clkmgr_mmcm.v
new file mode 100644
index 0000000..852288b
--- /dev/null
+++ b/rtl/clkmgr_mmcm.v
@@ -0,0 +1,179 @@
+//======================================================================
+//
+// clkmgr_mmcm.v
+// ---------------
+// Xilinx MMCM primitive wrapper to avoid using Clocking Wizard IP core.
+//
+//
+// Author: Pavel Shatov
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+module clkmgr_mmcm
+ (
+ input wire clk_in,
+ input wire reset_in,
+
+ output wire gclk_out,
+ output wire gclk_missing_out,
+
+ output wire clk_out,
+ output wire clk_valid_out
+ );
+
+
+ //
+ // Parameters
+ //
+ parameter CLK_OUT_MUL = 20.0; // multiply factor for output clock frequency (2..64)
+ parameter CLK_OUT_DIV = 20.0; // divide factor for output clock frequency (1..128)
+
+
+ //
+ // IBUFG
+ //
+
+ (* BUFFER_TYPE="NONE" *)
+ wire clk_in_ibufg;
+
+ IBUFG IBUFG_gclk
+ (
+ .I (clk_in),
+ .O (clk_in_ibufg)
+ );
+
+
+ //
+ // MMCME2_ADV
+ //
+ wire mmcm_clkout0;
+ wire mmcm_locked;
+ wire mmcm_clkfbout;
+ wire mmcm_clkfbout_bufg;
+
+ MMCME2_ADV #
+ (
+ .CLKIN1_PERIOD (20.000),
+ .REF_JITTER1 (0.010),
+
+ .STARTUP_WAIT ("FALSE"),
+ .BANDWIDTH ("OPTIMIZED"),
+ .COMPENSATION ("ZHOLD"),
+
+ .DIVCLK_DIVIDE (1),
+
+ .CLKFBOUT_MULT_F (CLK_OUT_MUL),
+ .CLKFBOUT_PHASE (0.000),
+ .CLKFBOUT_USE_FINE_PS ("FALSE"),
+
+ .CLKOUT0_DIVIDE_F (CLK_OUT_DIV),
+ .CLKOUT0_PHASE (0.000),
+ .CLKOUT0_USE_FINE_PS ("FALSE"),
+ .CLKOUT0_DUTY_CYCLE (0.500),
+
+ .CLKOUT4_CASCADE ("FALSE")
+ )
+ MMCME2_ADV_inst
+ (
+ .CLKIN1 (clk_in_ibufg),
+ .CLKIN2 (1'b0),
+ .CLKINSEL (1'b1),
+
+ .CLKFBIN (mmcm_clkfbout_bufg),
+ .CLKFBOUT (mmcm_clkfbout),
+ .CLKFBOUTB (),
+
+ .CLKINSTOPPED (gclk_missing_out),
+ .CLKFBSTOPPED (),
+
+ .CLKOUT0 (mmcm_clkout0),
+ .CLKOUT0B (),
+
+ .CLKOUT1 (),
+ .CLKOUT1B (),
+
+ .CLKOUT2 (),
+ .CLKOUT2B (),
+
+ .CLKOUT3 (),
+ .CLKOUT3B (),
+
+ .CLKOUT4 (),
+ .CLKOUT5 (),
+ .CLKOUT6 (),
+
+ .DCLK (1'b0),
+ .DEN (1'b0),
+ .DWE (1'b0),
+ .DADDR (7'd0),
+ .DI (16'h0000),
+ .DO (),
+ .DRDY (),
+
+ .PSCLK (1'b0),
+ .PSEN (1'b0),
+ .PSINCDEC (1'b0),
+ .PSDONE (),
+
+ .LOCKED (mmcm_locked),
+ .PWRDWN (1'b0),
+ .RST (reset_in)
+ );
+
+
+ //
+ // Mapping
+ //
+ assign gclk_out = clk_in_ibufg;
+ assign clk_valid_out = mmcm_locked;
+
+
+ //
+ // BUFGs
+ //
+ BUFG BUFG_gclk
+ (
+ .I (mmcm_clkout0),
+ .O (clk_out)
+ );
+
+ BUFG BUFG_feedback
+ (
+ .I (mmcm_clkfbout),
+ .O (mmcm_clkfbout_bufg)
+ );
+
+
+
+endmodule
+
+//======================================================================
+// EOF clkmgr_mmcm.v
+//======================================================================
diff --git a/ucf/alpha_fmc.ucf b/ucf/alpha_fmc.ucf
index b323104..34b2072 100644
--- a/ucf/alpha_fmc.ucf
+++ b/ucf/alpha_fmc.ucf
@@ -3,11 +3,11 @@
# alpha_fmc.ucf
# -------------------
# Constraint file for implementing the Cryptech Alpha base
-# for the Xilinx Spartan6 LX45 on the Alpha.
+# for the Xilinx Artix-7 200T on the Alpha.
#
#
# Author: Pavel Shatov
-# Copyright (c) 2014, NORDUnet A/S All rights reserved.
+# Copyright (c) 2016, NORDUnet A/S All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -37,15 +37,11 @@
#
#======================================================================
-#-------------------------------------------------------------------------------
-CONFIG VCCAUX = 3.3;
-#-------------------------------------------------------------------------------
-
#--------------------------------------------------------------------------------
# GCLK Timing (fixed at 50 MHz)
#--------------------------------------------------------------------------------
-NET "gclk_p_pin" TNM_NET = TNM_gclk;
+NET "gclk_pin" TNM_NET = TNM_gclk;
TIMESPEC TS_gclk = PERIOD TNM_gclk 20 ns HIGH 50%;
@@ -59,81 +55,86 @@ TIMESPEC TS_fmc_clk = PERIOD TNM_fmc_clk 90 MHz HIGH 50%;
#-------------------------------------------------------------------------------
# FPGA Pinout
#-------------------------------------------------------------------------------
-NET "led_pin" LOC = "A16" | IOSTANDARD = "LVCMOS33" | SLEW = "SLOW" | DRIVE = 8;
-NET "apoptosis_pin" LOC = "K1" | IOSTANDARD = "LVCMOS33" | SLEW = "SLOW" | DRIVE = 8;
-NET "reset_mcu_b_pin" LOC = "F1" | IOSTANDARD = "LVCMOS33" | PULLUP;
-#
-NET "gclk_p_pin" LOC = "H2" | IOSTANDARD = "LVDS_25" | DIFF_TERM = "TRUE";
-NET "gclk_n_pin" LOC = "H1" | IOSTANDARD = "LVDS_25" | DIFF_TERM = "TRUE";
-#
-NET "fmc_clk" LOC = "T8" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_ne1" LOC = "R7" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_noe" LOC = "R8" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_nwe" LOC = "V11" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_nl" LOC = "T7" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_nwait" LOC = "V8" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-#
-NET "fmc_a<0>" LOC = "V7" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<1>" LOC = "M5" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<2>" LOC = "L4" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<3>" LOC = "M3" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<4>" LOC = "L3" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<5>" LOC = "P2" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<6>" LOC = "K3" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<7>" LOC = "K4" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<8>" LOC = "R3" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<9>" LOC = "T3" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<10>" LOC = "V4" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<11>" LOC = "T4" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<12>" LOC = "J3" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<13>" LOC = "J1" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<14>" LOC = "J6" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<15>" LOC = "U16" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<16>" LOC = "M1" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<17>" LOC = "F2" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<18>" LOC = "R11" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<19>" LOC = "V5" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<20>" LOC = "G1" | IOSTANDARD = "LVCMOS33" ;
-NET "fmc_a<21>" LOC = "T2" | IOSTANDARD = "LVCMOS33" ;
-#NET "fmc_a<22>" LOC = " " | IOSTANDARD = "LVCMOS33" ;
-#NET "fmc_a<23>" LOC = " " | IOSTANDARD = "LVCMOS33" ;
-#NET "fmc_a<24>" LOC = " " | IOSTANDARD = "LVCMOS33" ;
-#NET "fmc_a<25>" LOC = " " | IOSTANDARD = "LVCMOS33" ;
-#
-NET "fmc_d<0>" LOC = "K2" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<1>" LOC = "V16" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<2>" LOC = "V9" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<3>" LOC = "T9" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<4>" LOC = "T5" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<5>" LOC = "R5" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<6>" LOC = "T10" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<7>" LOC = "R10" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<8>" LOC = "P6" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<9>" LOC = "N5" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<10>" LOC = "V10" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<11>" LOC = "U10" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<12>" LOC = "L5" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<13>" LOC = "K6" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<14>" LOC = "H4" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<15>" LOC = "H3" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<16>" LOC = "K5" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<17>" LOC = "L2" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<18>" LOC = "L1" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<19>" LOC = "L7" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<20>" LOC = "T11" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<21>" LOC = "T14" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<22>" LOC = "V14" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<23>" LOC = "L6" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<24>" LOC = "U13" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<25>" LOC = "V13" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<26>" LOC = "U11" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<27>" LOC = "U8" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<28>" LOC = "V6" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<29>" LOC = "T6" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<30>" LOC = "U5" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-NET "fmc_d<31>" LOC = "U7" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
-
-NET "ct_noise" LOC = "H7" | IOSTANDARD = "LVCMOS33" ;
+#
+NET "led_pins<0>" LOC = "U3";
+NET "led_pins<1>" LOC = "T1";
+NET "led_pins<2>" LOC = "W22";
+NET "led_pins<3>" LOC = "AA20";
+#
+NET "led_pins<*>" IOSTANDARD = "LVCMOS33";
+NET "led_pins<*>" SLEW = SLOW;
+NET "led_pins<*>" DRIVE = 8;
+#
+NET "gclk_pin" LOC = "D17" | IOSTANDARD = "LVCMOS33" ;
+#
+NET "fmc_clk" LOC = "W11" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_ne1" LOC = "V5" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_noe" LOC = "W16" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_nwe" LOC = "AA6" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_nl" LOC = "W17" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_nwait" LOC = "Y6" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+#
+NET "fmc_a<0>" LOC = "Y17" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<1>" LOC = "AB16" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<2>" LOC = "AA16" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<3>" LOC = "Y16" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<4>" LOC = "AB17" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<5>" LOC = "AA13" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<6>" LOC = "AB13" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<7>" LOC = "AA15" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<8>" LOC = "AB15" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<9>" LOC = "Y13" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<10>" LOC = "AA14" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<11>" LOC = "Y14" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<12>" LOC = "AB10" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<13>" LOC = "V2" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<14>" LOC = "AB12" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<15>" LOC = "AB8" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<16>" LOC = "AA9" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<17>" LOC = "AA8" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<18>" LOC = "Y7" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<19>" LOC = "AB21" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<20>" LOC = "AB22" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<21>" LOC = "AB20" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<22>" LOC = "Y21" | IOSTANDARD = "LVCMOS33" ;
+NET "fmc_a<23>" LOC = "Y22" | IOSTANDARD = "LVCMOS33" ;
+#NET "fmc_a<24>" LOC = "AB18" | IOSTANDARD = "LVCMOS33" ;
+#NET "fmc_a<25>" LOC = "AA19" | IOSTANDARD = "LVCMOS33" ;
+#
+NET "fmc_d<0>" LOC = "AB7" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<1>" LOC = "AB6" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<2>" LOC = "U1" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<3>" LOC = "U2" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<4>" LOC = "AB11" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<5>" LOC = "AA11" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<6>" LOC = "Y11" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<7>" LOC = "Y12" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<8>" LOC = "Y18" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<9>" LOC = "AA21" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<10>" LOC = "W20" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<11>" LOC = "N15" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<12>" LOC = "U20" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<13>" LOC = "AA1" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<14>" LOC = "AB1" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<15>" LOC = "AB2" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<16>" LOC = "AB3" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<17>" LOC = "Y3" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<18>" LOC = "AA3" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<19>" LOC = "AA5" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<20>" LOC = "AB5" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<21>" LOC = "Y4" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<22>" LOC = "AA4" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<23>" LOC = "V4" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<24>" LOC = "W10" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<25>" LOC = "R4" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<26>" LOC = "W12" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<27>" LOC = "W14" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<28>" LOC = "V20" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<29>" LOC = "V18" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<30>" LOC = "R21" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+NET "fmc_d<31>" LOC = "P21" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST" | DRIVE = 8;
+
+NET "ct_noise" LOC = "W19" | IOSTANDARD = "LVCMOS33" ;
#-------------------------------------------------------------------------------
# FMC Input Timing
@@ -143,7 +144,7 @@ NET "ct_noise" LOC = "H7" | IOSTANDARD = "LVCMOS33" ;
# datasheet. Control signals NE1, NL and NWE all have different timing values.
# Instead of writing individual constraints for every control signal, the most
# strict constraint is applied to all control signals. This should not cause
-# any P&R issues, since Spartan-6 can handle 90 MHz easily.
+# any P&R issues, since Spartan-6 (and Artix-7) can handle 90 MHz easily.
#
# NOE signal is not constrained, since it drives "T" input of IOBUF primitive.
#
@@ -174,7 +175,7 @@ TIMEGRP "TNM_FMC_IN_CONTROL" OFFSET = IN 5.0 ns VALID 10.0 ns BEFORE "fmc_clk"
NET "fmc_d<*>" TNM = "TNM_FMC_OUT_DATA" ;
-TIMEGRP "TNM_FMC_OUT_DATA" OFFSET = OUT 11.5 ns AFTER "fmc_clk" FALLING;
+TIMEGRP "TNM_FMC_OUT_DATA" OFFSET = OUT 16.7 ns AFTER "fmc_clk" FALLING;
#-------------------------------------------------------------------------------