From 5c7631ef559c68bd8d75a081237c39d5d147deb6 Mon Sep 17 00:00:00 2001 From: "Pavel V. Shatov (Meister)" Date: Mon, 16 May 2016 09:39:03 +0300 Subject: Ported Cryptech platform to the Alpha board. --- rtl/alpha_clkmgr.v | 69 ++++++++++---------- rtl/alpha_fmc_top.v | 82 ++++++++++++------------ rtl/clkmgr_dcm.v | 164 ----------------------------------------------- rtl/clkmgr_mmcm.v | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 255 insertions(+), 239 deletions(-) delete mode 100644 rtl/clkmgr_dcm.v create mode 100644 rtl/clkmgr_mmcm.v (limited to 'rtl') 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 +//====================================================================== -- cgit v1.2.3