diff options
-rw-r--r-- | build/Makefile | 10 | ||||
-rw-r--r-- | build/xilinx.opt | 4 | ||||
-rw-r--r-- | rtl/alpha_clkmgr.v | 182 | ||||
-rw-r--r-- | rtl/alpha_fmc_top.v | 272 | ||||
-rw-r--r-- | rtl/alpha_regs.v | 2 | ||||
-rw-r--r-- | rtl/bench/tb_clkmgr.v | 38 | ||||
-rw-r--r-- | rtl/clkmgr_mmcm.v | 241 | ||||
-rw-r--r-- | rtl/clkmgr_mmcm_ctrl.v | 117 | ||||
-rw-r--r-- | rtl/clkmgr_reset_gen.v | 69 | ||||
-rw-r--r-- | ucf/alpha_fmc.ucf | 66 | ||||
-rw-r--r-- | xdc/alpha_fmc_clocks.xdc | 1 | ||||
-rw-r--r-- | xdc/alpha_fmc_pinout.xdc | 100 | ||||
-rw-r--r-- | xdc/alpha_fmc_timing.xdc | 1 |
13 files changed, 712 insertions, 391 deletions
diff --git a/build/Makefile b/build/Makefile index 2fc9fe0..789ab87 100644 --- a/build/Makefile +++ b/build/Makefile @@ -20,7 +20,10 @@ ucf ?= ../ucf/$(project).ucf # Verilog include directories, if needed -vlgincdir = $(CORE_TREE)/lib/lowlevel $(CORE_TREE)/math/ecdsalib/rtl/microcode +vlgincdir = \ + $(CORE_TREE)/lib/lowlevel \ + $(CORE_TREE)/math/ecdsalib/rtl/microcode \ + $(CORE_TREE)/lib/util all: $(project).bit @@ -36,7 +39,7 @@ core_selector.v core_vfiles.mk: # Build some different configurations -bare trng hash mkmif rsa hsm hsm-super keywrap: +bare trng hash mkmif rsa hsm hsm-super hsm_ng hsm_ng_keywrap: $(CONFIG_GEN) -p $@ $(MAKE) project=$(project)_$@ ucf=$(ucf) @@ -47,7 +50,10 @@ vfiles = \ $(CORE_TREE)/platform/alpha/rtl/alpha_regs.v \ $(CORE_TREE)/platform/alpha/rtl/alpha_clkmgr.v \ $(CORE_TREE)/platform/alpha/rtl/clkmgr_mmcm.v \ + $(CORE_TREE)/platform/alpha/rtl/clkmgr_mmcm_ctrl.v \ ./core_selector.v \ + $(CORE_TREE)/platform/alpha/rtl/clkmgr_reset_gen.v \ + $(CORE_TREE)/platform/common/extra/reset_replicator.v \ $(CORE_TREE)/comm/fmc/src/rtl/fmc_arbiter.v \ $(CORE_TREE)/comm/fmc/src/rtl/fmc_d_phy.v \ $(CORE_TREE)/comm/fmc/src/rtl/fmc_indicator.v \ diff --git a/build/xilinx.opt b/build/xilinx.opt index 1ac8957..536725d 100644 --- a/build/xilinx.opt +++ b/build/xilinx.opt @@ -28,7 +28,7 @@ -shreg_extract YES -shreg_min_size 2 -auto_bram_packing NO --resource_sharing YES +-resource_sharing NO -async_to_sync NO -use_dsp48 auto -iobuf YES @@ -43,5 +43,5 @@ -use_sync_set Auto -use_sync_reset Auto -iob auto --equivalent_register_removal YES +-equivalent_register_removal NO -slice_utilization_ratio_maxmargin 5 diff --git a/rtl/alpha_clkmgr.v b/rtl/alpha_clkmgr.v index 5c4099e..0f5f912 100644 --- a/rtl/alpha_clkmgr.v +++ b/rtl/alpha_clkmgr.v @@ -7,7 +7,7 @@ // // // Author: Pavel Shatov -// Copyright (c) 2016, 2018 NORDUnet A/S All rights reserved. +// Copyright (c) 2016, 2018-2019 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 @@ -38,101 +38,101 @@ //====================================================================== module alpha_clkmgr - ( - input wire fmc_clk, // 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) - ); - - - // - // Settings - //
-
- /*
- * fmc_clk is 90 MHz, sys_clk is also 90 MHz routed through an MMCM.
- *
- * VCO frequency is 1080 MHz.
- *
- */ - localparam CLK_OUT_MUL = 12.0; - localparam CLK_OUT_DIV = 12.0;
- localparam CLK_OUT_PHI = 45.0;
+(
+ input wire fmc_clk, // signal from clock pin
+ output wire io_clk, // buffered i/o clock
+ output wire sys_clk, // buffered system clock output
+ output wire sys_rst_n, // system reset output (async set, sync clear, active-low)
+ output wire core_clk // buffered high speed core clock +); - // - // Wrapper for Xilinx-specific MMCM (Mixed Mode Clock Manager) primitive. - // - - wire gclk_int; // buffered input clock - wire mmcm_reset; // reset input - wire mmcm_locked; // output clock valid - wire gclk_missing; // input clock stopped
- - clkmgr_mmcm # - ( - .CLK_OUT_MUL (CLK_OUT_MUL), // 2..64 - .CLK_OUT_DIV (CLK_OUT_DIV), // 1..128
- .CLK_OUT_PHI (CLK_OUT_PHI) // 0.0..360.0
- ) - mmcm - ( - .gclk_in (fmc_clk), - .reset_in (mmcm_reset), - - .gclk_out (gclk_int), - .gclk_missing_out (gclk_missing), - - .clk_out (sys_clk),
- .clk_valid_out (mmcm_locked) - );
- - - - // - // MMCM Reset Logic - // - - /* 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] mmcm_rst_shreg = {16{1'b1}}; // 16-bit shift register - - always @(posedge gclk_int or posedge gclk_missing) - // - if (gclk_missing == 1'b1) - mmcm_rst_shreg <= {16{1'b1}}; - else - mmcm_rst_shreg <= {mmcm_rst_shreg[14:0], 1'b0}; - - assign mmcm_reset = mmcm_rst_shreg[15]; - - - // - // System Reset Logic - // - - /* 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 posedge gclk_missing or negedge mmcm_locked) - // - if ((gclk_missing == 1'b1) || (mmcm_locked == 1'b0)) - sys_rst_shreg <= {16{1'b0}}; - else if (mmcm_locked == 1'b1) - sys_rst_shreg <= {sys_rst_shreg[14:0], 1'b1}; - - assign sys_rst_n = sys_rst_shreg[15]; +
+ //
+ // Parameters
+ //
+ parameter integer CLK_CORE_MULT = 4;
+ +
+ //
+ // STARTUPE2
+ //
+ wire cfg_mclk; // 65 MHz (+/- 50%) internal oscillator
+ wire cfg_eos; // end-of-startup flag
+
+ STARTUPE2 #
+ ( + .SIM_CCLK_FREQ (0.0), // config clock frequency for simulation + .PROG_USR ("FALSE") // only used with encrypted bitstreams + ) + STARTUPE2_inst
+ ( + .CLK (1'b0), // no external clock + .CFGCLK (), // config clock (unused) + .CFGMCLK (cfg_mclk), // config clock
+ .EOS (cfg_eos), // end-of-startup flag +
+ .USRCCLKO (1'b0), // custom clock for configuration memory access (unused) + .USRCCLKTS (1'b0), // UG470 recommends this to be held low + .USRDONEO (1'b1), // custom value to drive onto DONE pin (unused) + .USRDONETS (1'b1), // tri-state DONE pin (unused) +
+ .GSR (1'b0), // UG470 recommends hardwiring this low + .GTS (1'b0), // UG470 recommends this to be tied low + + .PREQ (), // unused when PROG_USR is disabled + .PACK (1'b0), // only used when PROG_USR is enabled
+
+ .KEYCLEARB (1'b1) // unused
+ ); +
+
+ // + // Wrapper for Xilinx-specific MMCM (Mixed Mode Clock Manager) primitive. + // + wire mmcm_reset; // reset input + wire mmcm_locked; // output clock valid + + clkmgr_mmcm #
+ (
+ .CLK_CORE_MULT(CLK_CORE_MULT)
+ )
+ mmcm_inst + ( + .fmc_clk_in (fmc_clk),
+ .rst_in (mmcm_reset), + + .io_clk_out (io_clk),
+ .sys_clk_out (sys_clk),
+ .core_clk_out (core_clk),
+ .locked_out (mmcm_locked) + );
+
+ //
+ // MMCM Controller
+ //
+ clkmgr_mmcm_ctrl mmcm_ctrl_inst + (
+ .clk_in (cfg_mclk), + .reset_n_in (cfg_eos), + .locked_in (mmcm_locked), + .reset_out (mmcm_reset) + );
+
+ + // + // System Reset Logic + //
+ clkmgr_reset_gen #(.SHREG_WIDTH(16)) reset_gen_inst
+ (
+ .clk_in (sys_clk),
+ .locked_in (mmcm_locked),
+ .reset_n_out (sys_rst_n)
+ ); endmodule +
//====================================================================== // EOF alpha_clkmgr.v diff --git a/rtl/alpha_fmc_top.v b/rtl/alpha_fmc_top.v index a07beee..2206a89 100644 --- a/rtl/alpha_fmc_top.v +++ b/rtl/alpha_fmc_top.v @@ -8,7 +8,7 @@ // // // Author: Pavel Shatov -// Copyright (c) 2016, 2018 NORDUnet A/S All rights reserved. +// Copyright (c) 2016, 2018-2019 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 @@ -38,147 +38,139 @@ // //====================================================================== -`timescale 1ns / 1ps - module alpha_fmc_top - ( - input wire gclk_pin, // 50 MHz - - input wire ct_noise, // cryptech avalanche noise circuit - - input wire fmc_clk, // clock - 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 - input wire fmc_nwe, // write enable - input wire fmc_nl, // latch enable - output wire fmc_nwait,// wait - - output wire mkm_sclk, - output wire mkm_cs_n, - input wire mkm_do, - output wire mkm_di, - - output wire [3: 0] led_pins // {red, yellow, green, blue} - ); - - - //---------------------------------------------------------------- - // Clock Manager - // - // Clock manager is used to buffer FMC_CLK and implement reset logic. - // ---------------------------------------------------------------- - wire sys_clk; // system clock (90 MHz) - wire sys_rst_n; // active-low reset - - alpha_clkmgr clkmgr - ( - .fmc_clk (fmc_clk), - - .sys_clk (sys_clk), - .sys_rst_n (sys_rst_n) - ); - - - - //---------------------------------------------------------------- - // FMC Arbiter - // - // FMC arbiter handles FMC accesses. - //---------------------------------------------------------------- - - 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) - wire [31: 0] sys_fmc_din; // data input (from FPGA to STM32) - - fmc_arbiter # - ( - .NUM_ADDR_BITS(24) // change to 26 when Alpha is alive! - ) - fmc - ( - .fmc_a(fmc_a), - .fmc_d(fmc_d), - .fmc_ne1(fmc_ne1), - .fmc_nl(fmc_nl), - .fmc_nwe(fmc_nwe), - .fmc_noe(fmc_noe), - .fmc_nwait(fmc_nwait), - - .sys_clk(sys_clk), - - .sys_addr(sys_fmc_addr), - .sys_wr_en(sys_fmc_wren), - .sys_rd_en(sys_fmc_rden), - .sys_data_out(sys_fmc_dout), - .sys_data_in(sys_fmc_din) - ); - - - //---------------------------------------------------------------- - // LED Driver - // - // A simple utility LED driver that turns on the Alpha - // board LED when the FMC interface is active. - //---------------------------------------------------------------- - fmc_indicator led - ( - .sys_clk(sys_clk), - .sys_rst_n(sys_rst_n), - .fmc_active(sys_fmc_wren | sys_fmc_rden), - .led_out(led_pins[0]) - ); - - - //---------------------------------------------------------------- - // Core Selector - // - // This multiplexer is used to map different types of cores, such as - // hashes, RNGs and ciphers to different regions (segments) of memory. - //---------------------------------------------------------------- - - // A note on byte-swapping: - // STM32 is little-endian, while the register interface here is - // big-endian. The software reads and writes 32-bit integer values, - // which means transmitting the least significant byte first. Up to - // now, we've been doing byte-swapping in software, which is - // inefficient, especially for bulk data transfer. So now we're doing - // the byte-swapping in hardware. - - wire [31:0] write_data; - assign write_data = {sys_fmc_dout[7:0], sys_fmc_dout[15:8], sys_fmc_dout[23:16], sys_fmc_dout[31:24]}; - - wire [31 : 0] read_data; - assign sys_fmc_din = {read_data[7:0], read_data[15:8], read_data[23:16], read_data[31:24]}; - - core_selector cores - ( - .sys_clk(sys_clk), - .sys_rst_n(sys_rst_n), - - .sys_fmc_addr(sys_fmc_addr), - .sys_fmc_wr(sys_fmc_wren), - .sys_fmc_rd(sys_fmc_rden), - .sys_write_data(write_data), - .sys_read_data(read_data), - - .noise(ct_noise), - - .mkm_sclk(mkm_sclk), - .mkm_cs_n(mkm_cs_n), - .mkm_do(mkm_do), - .mkm_di(mkm_di) - ); - - - // - // Dummy assignment to bypass unconnected outpins pins check in BitGen - // +( +// input wire gclk_pin, // 50 MHz + + input wire ct_noise, // cryptech avalanche noise circuit + + input wire fmc_clk, // clock + 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 + input wire fmc_nwe, // write enable + input wire fmc_nl, // latch enable + output wire fmc_nwait,// wait + + output wire mkm_sclk, + output wire mkm_cs_n, + input wire mkm_do, + output wire mkm_di, + + output wire [3: 0] led_pins // {red, yellow, green, blue} +); + + + //---------------------------------------------------------------- + // Clock Manager + // + // Clock manager is used to buffer FMC_CLK and implement reset logic. + // ---------------------------------------------------------------- + wire io_clk; // FMC I/O clock (45 MHz) + wire sys_clk; // system clock (90 MHz) + wire sys_rst_n; // active-low system reset + wire core_clk; // high-speed core clock (45*N MHz) + + alpha_clkmgr #(.CLK_CORE_MULT(2)) clkmgr + ( + .fmc_clk (fmc_clk), + + .io_clk (io_clk), + .sys_clk (sys_clk), + .sys_rst_n (sys_rst_n), + .core_clk (core_clk) + ); + + + + //---------------------------------------------------------------- + // FMC Arbiter + // + // FMC arbiter handles FMC accesses. + //---------------------------------------------------------------- + + 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) + wire [31: 0] sys_fmc_din; // data input (from FPGA to STM32) + + fmc_arbiter # + ( + .NUM_ADDR_BITS(24) // change to 26 when Alpha is alive! + ) + fmc + ( + .fmc_a(fmc_a), + .fmc_d(fmc_d), + .fmc_ne1(fmc_ne1), + .fmc_nl(fmc_nl), + .fmc_nwe(fmc_nwe), + .fmc_noe(fmc_noe), + .fmc_nwait(fmc_nwait), + + .sys_clk(sys_clk), + .io_clk(io_clk), + + .sys_addr(sys_fmc_addr), + .sys_wr_en(sys_fmc_wren), + .sys_rd_en(sys_fmc_rden), + .sys_data_out(sys_fmc_dout), + .sys_data_in(sys_fmc_din) + ); + + + //---------------------------------------------------------------- + // LED Driver + // + // A simple utility LED driver that turns on the Alpha + // board LED when the FMC interface is active. + //---------------------------------------------------------------- + fmc_indicator led + ( + .sys_clk(sys_clk), + .sys_rst_n(sys_rst_n), + .fmc_active(sys_fmc_wren | sys_fmc_rden), + .led_out(led_pins[0]) + ); + + + //---------------------------------------------------------------- + // Core Selector + // + // This multiplexer is used to map different types of cores, such as + // hashes, RNGs and ciphers to different regions (segments) of memory. + //---------------------------------------------------------------- + + core_selector cores + ( + .sys_clk(sys_clk), + .sys_rst_n(sys_rst_n), + .core_clk(core_clk), + + .sys_fmc_addr(sys_fmc_addr), + .sys_fmc_wr(sys_fmc_wren), + .sys_fmc_rd(sys_fmc_rden), + .sys_write_data(sys_fmc_dout), + .sys_read_data(sys_fmc_din), + .sys_error(), + + .noise(ct_noise), + + .mkm_sclk(mkm_sclk), + .mkm_cs_n(mkm_cs_n), + .mkm_do(mkm_do), + .mkm_di(mkm_di), + + .debug() + ); + - assign led_pins[3:1] = 3'b000; + // + // Dummy assignment to get past the unconnected outpins pins check in BitGen + // + assign led_pins[3:1] = 3'b000; endmodule diff --git a/rtl/alpha_regs.v b/rtl/alpha_regs.v index ce17863..31cfbbf 100644 --- a/rtl/alpha_regs.v +++ b/rtl/alpha_regs.v @@ -68,7 +68,7 @@ module board_regs // Core ID constants. localparam CORE_NAME0 = 32'h414c5048; // "ALPH" localparam CORE_NAME1 = 32'h41202020; // "A " - localparam CORE_VERSION = 32'h302e3230; // "0.20" + localparam CORE_VERSION = 32'h302e3330; // "0.30" diff --git a/rtl/bench/tb_clkmgr.v b/rtl/bench/tb_clkmgr.v new file mode 100644 index 0000000..a987e1c --- /dev/null +++ b/rtl/bench/tb_clkmgr.v @@ -0,0 +1,38 @@ +`timescale 1ns / 1ps + +module tb_clkmgr; + + // Input + reg fmc_clk = 1'b0; + + // Clock + always #11.111 fmc_clk = ~fmc_clk; + + // Outputs + wire io_clk; + wire sys_clk; + wire sys_rst_n; + wire core_clk; + + // Internals + reg fmc_clk_inhibit = 1'b0; + + // UUT + alpha_clkmgr uut + ( + .fmc_clk(fmc_clk & ~fmc_clk_inhibit), + .io_clk(io_clk), + .sys_clk(sys_clk), + .sys_rst_n(sys_rst_n), + .core_clk(core_clk) + ); + + // Script + initial begin + #399000; + fmc_clk_inhibit = 1'b1; + #1000; + fmc_clk_inhibit = 1'b0; + end + +endmodule diff --git a/rtl/clkmgr_mmcm.v b/rtl/clkmgr_mmcm.v index 03b0747..afb5716 100644 --- a/rtl/clkmgr_mmcm.v +++ b/rtl/clkmgr_mmcm.v @@ -1,12 +1,12 @@ //====================================================================== // // clkmgr_mmcm.v -// --------------- +// ------------- // Xilinx MMCM primitive wrapper to avoid using Clocking Wizard IP core. // // // Author: Pavel Shatov -// Copyright (c) 2016, 2018, NORDUnet A/S All rights reserved. +// Copyright (c) 2019, 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,144 +37,121 @@ //====================================================================== module clkmgr_mmcm - ( - input wire gclk_in, - input wire reset_in, - - output wire gclk_out, - output wire gclk_missing_out, +(
+ input fmc_clk_in, + input rst_in, + + output io_clk_out, + output sys_clk_out, + output core_clk_out,
+ output locked_out
+); - output wire clk_out,
- output wire clk_valid_out - ); - - - // - // Parameters - // - parameter CLK_OUT_MUL = 12.0; // multiply factor for output clock frequency (2..64) - parameter CLK_OUT_DIV = 12.0; // divide factor for output clock frequency (1..128)
- parameter CLK_OUT_PHI = 45.0; // clock phase shift (0.0..360.0)
- - - // - // IBUFG - // - - (* BUFFER_TYPE="NONE" *) - wire gclk_in_ibufg;
- - IBUFG IBUFG_gclk
- (
- .I (gclk_in),
- .O (gclk_in_ibufg)
- );
- -
- //
- // MMCME2_ADV
- //
- wire mmcm_clkout0;
- wire mmcm_locked;
- wire mmcm_clkfbout;
- wire mmcm_clkfbout_bufg;
-
- MMCME2_ADV #
- (
- .CLKIN1_PERIOD (11.111),
- .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 (CLK_OUT_PHI),
- .CLKOUT0_USE_FINE_PS ("FALSE"),
- .CLKOUT0_DUTY_CYCLE (0.500),
-
- .CLKOUT4_CASCADE ("FALSE")
- )
- MMCME2_ADV_inst
- (
- .CLKIN1 (gclk_in_ibufg),
- .CLKIN2 (1'b0),
- .CLKINSEL (1'b1),
+ parameter integer CLK_CORE_MULT = 4;
- .CLKFBIN (mmcm_clkfbout_bufg),
- .CLKFBOUT (mmcm_clkfbout),
- .CLKFBOUTB (),
-
- .CLKINSTOPPED (gclk_missing_out),
- .CLKFBSTOPPED (),
+ function integer lookup_vco_freq;
+ input integer core_mult;
+ case (core_mult)
+ 2: lookup_vco_freq = 990;
+ 3: lookup_vco_freq = 945;
+ 4: lookup_vco_freq = 1080;
+ 5: lookup_vco_freq = 900;
+ 6: lookup_vco_freq = 1080;
+ 7: lookup_vco_freq = 945;
+ 8: lookup_vco_freq = 1080;
+ endcase
+ endfunction
+ + localparam real FMC_CLK_PERIOD_F = 22.222;
+ localparam real FB_PHASE_F = 45.0;
+ localparam real SYS_FREQ_F = 90.0;
+
+ localparam integer VCO_FREQ = lookup_vco_freq(CLK_CORE_MULT);
+ localparam integer IO_FREQ = 45;
+ localparam integer CORE_FREQ = CLK_CORE_MULT * IO_FREQ;
- .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)
- ); + localparam real VCO_FREQ_F = 1.0 * VCO_FREQ;
+ localparam real FMC_FREQ_F = 1.0 * IO_FREQ;
+
+ localparam real FB_MULT_F = VCO_FREQ_F / FMC_FREQ_F; + localparam real CLK0_DIV_F = VCO_FREQ_F / SYS_FREQ_F;
+
+ localparam integer CLK1_DIV = VCO_FREQ / IO_FREQ;
+ localparam integer CLK2_DIV = VCO_FREQ / CORE_FREQ; + wire fmc_clk_ibufg; + IBUFG IBUFG_fmc_clk + ( + .I(fmc_clk_in), + .O(fmc_clk_ibufg) + ); - // - // Mapping - // - assign gclk_out = gclk_in_ibufg; - assign clk_valid_out = mmcm_locked; -
-
- //
- // BUFGs
- // - BUFG BUFG_gclk
- (
- .I (mmcm_clkout0),
- .O (clk_out)
+ wire mmcm_clkout0;
+ wire mmcm_clkout1;
+ wire mmcm_clkout2; + wire mmcm_clkfbin; + wire mmcm_clkfbout; + MMCME2_BASE # + ( + .CLKIN1_PERIOD (FMC_CLK_PERIOD_F), + .CLKFBOUT_MULT_F (FB_MULT_F),
+ .CLKFBOUT_PHASE (FB_PHASE_F), + .CLKOUT0_DIVIDE_F (CLK0_DIV_F),
+ .CLKOUT1_DIVIDE (CLK1_DIV),
+ .CLKOUT2_DIVIDE (CLK2_DIV) + ) + MMCME2_BASE_io_clk + ( + .CLKIN1 (fmc_clk_ibufg), + .RST (rst_in), + .PWRDWN (1'b0), + + .LOCKED (locked_out), + + + .CLKFBOUT (mmcm_clkfbout), + .CLKFBOUTB (), + .CLKFBIN (mmcm_clkfbin), + + .CLKOUT0 (mmcm_clkout0), + .CLKOUT0B (), + .CLKOUT1 (mmcm_clkout1), + .CLKOUT1B (), + .CLKOUT2 (mmcm_clkout2), + .CLKOUT2B (), + .CLKOUT3 (), + .CLKOUT3B (), + .CLKOUT4 (), + .CLKOUT5 (), + .CLKOUT6 () ); -
- BUFG BUFG_feedback
- (
- .I (mmcm_clkfbout),
- .O (mmcm_clkfbout_bufg)
- );
-
- + + BUFG BUFG_clkfb + ( + .I(mmcm_clkfbout), + .O(mmcm_clkfbin) + ); + + BUFG BUFG_clk_io + ( + .I(mmcm_clkout0), + .O(sys_clk_out) + );
+
+ BUFG BUFG_clk_sys + ( + .I(mmcm_clkout1), + .O(io_clk_out) + );
+
+ BUFG BUFG_clk_core + ( + .I(mmcm_clkout2), + .O(core_clk_out) + );
endmodule //====================================================================== -// EOF clkmgr_mmcm.v +// EOF clkmgr_mmcm_io.v //====================================================================== diff --git a/rtl/clkmgr_mmcm_ctrl.v b/rtl/clkmgr_mmcm_ctrl.v new file mode 100644 index 0000000..6d22291 --- /dev/null +++ b/rtl/clkmgr_mmcm_ctrl.v @@ -0,0 +1,117 @@ +//====================================================================== +// +// clkmgr_mmcm_ctrl.v +// ------------------ +// PLL reset generator and lock monitor. +// +// +// Author: Pavel Shatov +// Copyright (c) 2019, 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_ctrl +( + input clk_in, + input reset_n_in, + input locked_in, + output reset_out +); + + // + // Timer Settings + // + localparam [13:0] tmr_zero = {14{1'b0}}; + localparam [13:0] tmr_last = {14{1'b1}}; + reg [13:0] tmr = tmr_zero; + wire [13:0] tmr_next = tmr + 1'b1; + wire [ 9:0] tmr_msb = tmr[13:4]; + + wire tmr_about_to_wrap = tmr == tmr_last; + wire tmr_msb_is_zero = tmr_msb == 10'd0; + + // + // Lock Counting and Monitoring + // + reg [1:0] pll_seen_locks = 2'd0; + wire [1:0] pll_seen_locks_next = (pll_seen_locks < 2'd3) ? pll_seen_locks + 1'b1 : pll_seen_locks; + + (* SHREG_EXTRACT="NO" *) + (* EQUIVALENT_REGISTER_REMOVAL="NO" *) + reg [3:0] pll_stable_lock_shreg = 4'h0; + wire pll_stable_lock = pll_stable_lock_shreg[3]; + + wire pll_needs_reset = (pll_seen_locks != 2'd1) || !pll_stable_lock; + + // + // Output Register + // + reg reset_out_r = 1'b1; + assign reset_out = reset_out_r; + + // + // Timer Increment/Wrap Logic + // + always @(posedge clk_in or negedge reset_n_in) + // + if (!reset_n_in) tmr <= tmr_zero; + else begin + if (!tmr_about_to_wrap) tmr <= tmr_next; + else if (pll_needs_reset) tmr <= tmr_zero; + end + + // + // Lock Counter + // + always @(posedge locked_in or posedge reset_out) + // + if (reset_out) pll_seen_locks <= 2'd0; + else pll_seen_locks <= pll_seen_locks_next; + + // + // Lock Monitor + // + always @(posedge clk_in or negedge locked_in) + // + if (!locked_in) pll_stable_lock_shreg <= 4'h0; + else pll_stable_lock_shreg <= {pll_stable_lock_shreg[2:0], 1'b1}; + + // + // Reset Generator + // + always @(posedge clk_in or negedge reset_n_in) + // + if (!reset_n_in) reset_out_r <= 1'b1; + else reset_out_r <= tmr_msb_is_zero; + +endmodule + +//====================================================================== +// EOF clkmgr_mmcm_ctrl.v +//====================================================================== diff --git a/rtl/clkmgr_reset_gen.v b/rtl/clkmgr_reset_gen.v new file mode 100644 index 0000000..9cc4401 --- /dev/null +++ b/rtl/clkmgr_reset_gen.v @@ -0,0 +1,69 @@ +//====================================================================== +// +// clkmgr_reset_gen.v +// ------------------ +// System reset generator. +// +// +// Author: Pavel Shatov +// Copyright (c) 2019, 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_reset_gen +( + input clk_in, + input locked_in, + output reset_n_out +); + + // + // Parameter + // + parameter integer SHREG_WIDTH = 16; + + // + // Shift Register + // + (* SHREG_EXTRACT="NO" *) + (* EQUIVALENT_REGISTER_REMOVAL="NO" *) + reg [SHREG_WIDTH-1:0] sys_rst_shreg = {SHREG_WIDTH{1'b0}}; + + always @(posedge clk_in or negedge locked_in) + // + if (!locked_in) sys_rst_shreg <= {SHREG_WIDTH{1'b0}}; + else sys_rst_shreg <= {sys_rst_shreg[SHREG_WIDTH-2:0], 1'b1}; + + assign reset_n_out = sys_rst_shreg[SHREG_WIDTH-1]; + +endmodule + +//====================================================================== +// EOF clkmgr_reset_gen.v +//====================================================================== diff --git a/ucf/alpha_fmc.ucf b/ucf/alpha_fmc.ucf index 7926762..908f9fe 100644 --- a/ucf/alpha_fmc.ucf +++ b/ucf/alpha_fmc.ucf @@ -46,31 +46,28 @@ #------------------------------------------------------------------------------- -# FMC_CLK Timing (can be up to 90 MHz) +# FMC_CLK Timing #------------------------------------------------------------------------------- NET "fmc_clk" TNM_NET = TNM_fmc_clk; -# 90 MHz -#TIMESPEC TS_fmc_clk = PERIOD TNM_fmc_clk 11.111 ns HIGH 50%; - -# 60 MHz -TIMESPEC TS_fmc_clk = PERIOD TNM_fmc_clk 16.667 ns HIGH 50%; +# 45 MHz +TIMESPEC TS_fmc_clk = PERIOD TNM_fmc_clk 22.222 ns HIGH 50%; #------------------------------------------------------------------------------- # FPGA Pinout #------------------------------------------------------------------------------- # -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<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 "led_pins<*>" IOSTANDARD = "LVCMOS33"; +NET "led_pins<*>" SLEW = SLOW; +NET "led_pins<*>" DRIVE = 8; # -NET "gclk_pin" LOC = "D17" | IOSTANDARD = "LVCMOS33" ; +#NET "gclk_pin" LOC = "D17" | IOSTANDARD = "LVCMOS33" ; # NET "fmc_clk" LOC = "W11" | IOSTANDARD = "LVCMOS33" ; NET "fmc_ne1" LOC = "V5" | IOSTANDARD = "LVCMOS33" ; @@ -155,34 +152,57 @@ NET "mkm_do" LOC = "Y1" | IOSTANDARD = "LVCMOS33" ; # MKM_FPGA_MISO # 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 (and Artix-7) can handle 90 MHz easily. +# any P&R issues, since Spartan-6 (and Artix-7) can handle 45 MHz very easily. # # NOE signal is not constrained, since it drives "T" input of IOBUF primitive. # -# Data and Address buses also have different timings, with Data bus timing being +# Data and Address buses also have different timings, with Address bus timing being # more strict. # -# Oh, and the datasheet doesn't explicitly specify hold time for the data bus. +# Oh, and the datasheet doesn't explicitly specify hold time for the data bus. But that +# is not a problem, since it's apparently impossible to specify both OFFSET OUT BEFORE +# and AFTER at the same time :) # +# "ideal" values +#TIMEGRP "TNM_FMC_IN_DATA" OFFSET = IN 8.5 ns VALID 19.5 ns BEFORE "fmc_clk" RISING ; +#TIMEGRP "TNM_FMC_IN_ADDR" OFFSET = IN 11.0 ns VALID 11.0 ns BEFORE "fmc_clk" RISING ; +#TIMEGRP "TNM_FMC_IN_CONTROL" OFFSET = IN 10.5 ns VALID 15.5 ns BEFORE "fmc_clk" RISING ; + +# more realistic ("strict") values with 1 ns subtracted from both sides of the +# valid window +TIMEGRP "TNM_FMC_IN_DATA" OFFSET = IN 7.5 ns VALID 17.5 ns BEFORE "fmc_clk" RISING ; +TIMEGRP "TNM_FMC_IN_ADDR" OFFSET = IN 10.0 ns VALID 9.0 ns BEFORE "fmc_clk" RISING ; +TIMEGRP "TNM_FMC_IN_CONTROL" OFFSET = IN 9.5 ns VALID 13.5 ns BEFORE "fmc_clk" RISING ; + NET "fmc_d<*>" TNM = "TNM_FMC_IN_DATA" ; NET "fmc_a<*>" TNM = "TNM_FMC_IN_ADDR" ; - +# NET "fmc_ne1" TNM = "TNM_FMC_IN_CONTROL" ; NET "fmc_nl" TNM = "TNM_FMC_IN_CONTROL" ; NET "fmc_nwe" TNM = "TNM_FMC_IN_CONTROL" ; -TIMEGRP "TNM_FMC_IN_DATA" OFFSET = IN 3.0 ns VALID 8.5 ns BEFORE "fmc_clk" RISING ; -TIMEGRP "TNM_FMC_IN_ADDR" OFFSET = IN 5.5 ns VALID 5.5 ns BEFORE "fmc_clk" RISING ; -TIMEGRP "TNM_FMC_IN_CONTROL" OFFSET = IN 5.0 ns VALID 10.0 ns BEFORE "fmc_clk" RISING ; - #------------------------------------------------------------------------------- # FMC Output Timing #------------------------------------------------------------------------------- +TIMEGRP "TNM_FMC_OUT_DATA" OFFSET = OUT 6.0 ns BEFORE "fmc_clk" FALLING; #+1ns + NET "fmc_d<*>" TNM = "TNM_FMC_OUT_DATA" ; -TIMEGRP "TNM_FMC_OUT_DATA" OFFSET = OUT 6.0 ns AFTER "fmc_clk" RISING; + +#------------------------------------------------------------------------------- +# Core Selector Multi-Cycle Readback Mux +#------------------------------------------------------------------------------- +NET "cores/reg_read_data_*<*>" TNM_NET = TNM_CORE_SELECTOR_MUX_INPUT ; +NET "cores/addr_core_num_dly2<*>" TNM_NET = TNM_CORE_SELECTOR_MUX_CONTROL ; +NET "cores/pipe_read_data_*<*>" TNM_NET = TNM_CORE_SELECTOR_MUX_OUTPUT ; + +TIMEGRP "TNM_CORE_SELECTOR_MUX_SRC" = "TNM_CORE_SELECTOR_MUX_INPUT" "TNM_CORE_SELECTOR_MUX_CONTROL" ; +TIMEGRP "TNM_CORE_SELECTOR_MUX_DST" = "TNM_CORE_SELECTOR_MUX_OUTPUT" ; + +TIMESPEC TS_core_selector = FROM TNM_CORE_SELECTOR_MUX_SRC TO TNM_CORE_SELECTOR_MUX_DST TS_clkmgr_mmcm_inst_mmcm_clkout0 * 2 ; + #====================================================================== diff --git a/xdc/alpha_fmc_clocks.xdc b/xdc/alpha_fmc_clocks.xdc new file mode 100644 index 0000000..4184ff4 --- /dev/null +++ b/xdc/alpha_fmc_clocks.xdc @@ -0,0 +1 @@ +create_clock -period 22.222 -name clk_fmc -waveform {0.000 11.111} [get_ports fmc_clk] diff --git a/xdc/alpha_fmc_pinout.xdc b/xdc/alpha_fmc_pinout.xdc new file mode 100644 index 0000000..9f4e08a --- /dev/null +++ b/xdc/alpha_fmc_pinout.xdc @@ -0,0 +1,100 @@ +set_property PACKAGE_PIN "U3" [get_ports {led_pins[0]}] +set_property PACKAGE_PIN "T1" [get_ports {led_pins[1]}] +set_property PACKAGE_PIN "W22" [get_ports {led_pins[2]}] +set_property PACKAGE_PIN "AA20" [get_ports {led_pins[3]}] + +set_property PACKAGE_PIN "W11" [get_ports {fmc_clk }] +set_property PACKAGE_PIN "V5" [get_ports {fmc_ne1 }] +set_property PACKAGE_PIN "W16" [get_ports {fmc_noe }] +set_property PACKAGE_PIN "AA6" [get_ports {fmc_nwe }] +set_property PACKAGE_PIN "W17" [get_ports {fmc_nl }] +set_property PACKAGE_PIN "Y6" [get_ports {fmc_nwait }] + +set_property PACKAGE_PIN "Y17" [get_ports {fmc_a[0]}] +set_property PACKAGE_PIN "AB16" [get_ports {fmc_a[1]}] +set_property PACKAGE_PIN "AA16" [get_ports {fmc_a[2]}] +set_property PACKAGE_PIN "Y16" [get_ports {fmc_a[3]}] +set_property PACKAGE_PIN "AB17" [get_ports {fmc_a[4]}] +set_property PACKAGE_PIN "AA13" [get_ports {fmc_a[5]}] +set_property PACKAGE_PIN "AB13" [get_ports {fmc_a[6]}] +set_property PACKAGE_PIN "AA15" [get_ports {fmc_a[7]}] +set_property PACKAGE_PIN "AB15" [get_ports {fmc_a[8]}] +set_property PACKAGE_PIN "Y13" [get_ports {fmc_a[9]}] +set_property PACKAGE_PIN "AA14" [get_ports {fmc_a[10]}] +set_property PACKAGE_PIN "Y14" [get_ports {fmc_a[11]}] +set_property PACKAGE_PIN "AB10" [get_ports {fmc_a[12]}] +set_property PACKAGE_PIN "V2" [get_ports {fmc_a[13]}] +set_property PACKAGE_PIN "AB12" [get_ports {fmc_a[14]}] +set_property PACKAGE_PIN "AB8" [get_ports {fmc_a[15]}] +set_property PACKAGE_PIN "AA9" [get_ports {fmc_a[16]}] +set_property PACKAGE_PIN "AA8" [get_ports {fmc_a[17]}] +set_property PACKAGE_PIN "Y7" [get_ports {fmc_a[18]}] +set_property PACKAGE_PIN "AB21" [get_ports {fmc_a[19]}] +set_property PACKAGE_PIN "AB22" [get_ports {fmc_a[20]}] +set_property PACKAGE_PIN "AB20" [get_ports {fmc_a[21]}] +set_property PACKAGE_PIN "Y21" [get_ports {fmc_a[22]}] +set_property PACKAGE_PIN "Y22" [get_ports {fmc_a[23]}] +#set_property PACKAGE_PIN "AB18" [get_ports {fmc_a[24]}] +#set_property PACKAGE_PIN "AA19" [get_ports {fmc_a[25]}] + +set_property PACKAGE_PIN "AB7" [get_ports {fmc_d[0]}] +set_property PACKAGE_PIN "AB6" [get_ports {fmc_d[1]}] +set_property PACKAGE_PIN "U1" [get_ports {fmc_d[2]}] +set_property PACKAGE_PIN "U2" [get_ports {fmc_d[3]}] +set_property PACKAGE_PIN "AB11" [get_ports {fmc_d[4]}] +set_property PACKAGE_PIN "AA11" [get_ports {fmc_d[5]}] +set_property PACKAGE_PIN "Y11" [get_ports {fmc_d[6]}] +set_property PACKAGE_PIN "Y12" [get_ports {fmc_d[7]}] +set_property PACKAGE_PIN "Y18" [get_ports {fmc_d[8]}] +set_property PACKAGE_PIN "AA21" [get_ports {fmc_d[9]}] +set_property PACKAGE_PIN "W20" [get_ports {fmc_d[10]}] +set_property PACKAGE_PIN "N15" [get_ports {fmc_d[11]}] +set_property PACKAGE_PIN "U20" [get_ports {fmc_d[12]}] +set_property PACKAGE_PIN "AA1" [get_ports {fmc_d[13]}] +set_property PACKAGE_PIN "AB1" [get_ports {fmc_d[14]}] +set_property PACKAGE_PIN "AB2" [get_ports {fmc_d[15]}] +set_property PACKAGE_PIN "AB3" [get_ports {fmc_d[16]}] +set_property PACKAGE_PIN "Y3" [get_ports {fmc_d[17]}] +set_property PACKAGE_PIN "AA3" [get_ports {fmc_d[18]}] +set_property PACKAGE_PIN "AA5" [get_ports {fmc_d[19]}] +set_property PACKAGE_PIN "AB5" [get_ports {fmc_d[20]}] +set_property PACKAGE_PIN "Y4" [get_ports {fmc_d[21]}] +set_property PACKAGE_PIN "AA4" [get_ports {fmc_d[22]}] +set_property PACKAGE_PIN "V4" [get_ports {fmc_d[23]}] +set_property PACKAGE_PIN "W10" [get_ports {fmc_d[24]}] +set_property PACKAGE_PIN "R4" [get_ports {fmc_d[25]}] +set_property PACKAGE_PIN "W12" [get_ports {fmc_d[26]}] +set_property PACKAGE_PIN "W14" [get_ports {fmc_d[27]}] +set_property PACKAGE_PIN "V20" [get_ports {fmc_d[28]}] +set_property PACKAGE_PIN "V18" [get_ports {fmc_d[29]}] +set_property PACKAGE_PIN "R21" [get_ports {fmc_d[30]}] +set_property PACKAGE_PIN "P21" [get_ports {fmc_d[31]}] + +set_property PACKAGE_PIN "W19" [get_ports {ct_noise}] + +set_property PACKAGE_PIN "V3" [get_ports {mkm_sclk}] +set_property PACKAGE_PIN "W2" [get_ports {mkm_cs_n}] +set_property PACKAGE_PIN "W1" [get_ports {mkm_di}] +set_property PACKAGE_PIN "Y1" [get_ports {mkm_do}] + + +set_property IOSTANDARD "LVCMOS33" [get_ports {led_*}] +set_property IOSTANDARD "LVCMOS33" [get_ports {fmc_*}] +set_property IOSTANDARD "LVCMOS33" [get_ports {ct_noise}] +set_property IOSTANDARD "LVCMOS33" [get_ports {mkm_*}] + + +set_property DRIVE 8 [get_ports {led_pins[*]}] +set_property DRIVE 8 [get_ports {fmc_nwait}] +set_property DRIVE 8 [get_ports {fmc_d[*]}] +set_property DRIVE 8 [get_ports {mkm_sclk}] +set_property DRIVE 8 [get_ports {mkm_cs_n}] +set_property DRIVE 8 [get_ports {mkm_di}] + + +set_property SLEW "SLOW" [get_ports {led_pins[*]}] +set_property SLEW "FAST" [get_ports {fmc_nwait}] +set_property SLEW "FAST" [get_ports {fmc_d[*]}] +set_property SLEW "SLOW" [get_ports {mkm_sclk}] +set_property SLEW "SLOW" [get_ports {mkm_cs_n}] +set_property SLEW "SLOW" [get_ports {mkm_di}] diff --git a/xdc/alpha_fmc_timing.xdc b/xdc/alpha_fmc_timing.xdc new file mode 100644 index 0000000..e311270 --- /dev/null +++ b/xdc/alpha_fmc_timing.xdc @@ -0,0 +1 @@ +create_clock -period 22.222 -name clk_fmc -waveform {0.000 11.111} [get_ports clk_fmc] |