aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/rtl/clkmgr_dcm.v147
-rw-r--r--common/rtl/ipcore/clkmgr_dcm.v152
-rw-r--r--common/rtl/novena_clkmgr.v53
-rw-r--r--common/rtl/novena_regs.v6
-rw-r--r--eim/build/Makefile2
-rw-r--r--eim/rtl/novena_eim.v23
-rw-r--r--fmc/build/.gitignore53
-rw-r--r--fmc/build/Makefile70
-rw-r--r--fmc/build/xilinx.mk176
-rw-r--r--fmc/build/xilinx.opt42
-rw-r--r--fmc/rtl/novena_fmc_top.v247
-rw-r--r--fmc/ucf/novena_fmc.ucf198
-rw-r--r--i2c/rtl/novena_i2c.v18
-rw-r--r--sw/cryptech.h4
14 files changed, 996 insertions, 195 deletions
diff --git a/common/rtl/clkmgr_dcm.v b/common/rtl/clkmgr_dcm.v
new file mode 100644
index 0000000..7c851f1
--- /dev/null
+++ b/common/rtl/clkmgr_dcm.v
@@ -0,0 +1,147 @@
+//======================================================================
+//
+// 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,
+ input wire reset_in,
+
+ 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)
+
+
+ //
+ // 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_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/common/rtl/ipcore/clkmgr_dcm.v b/common/rtl/ipcore/clkmgr_dcm.v
deleted file mode 100644
index 6e57c3d..0000000
--- a/common/rtl/ipcore/clkmgr_dcm.v
+++ /dev/null
@@ -1,152 +0,0 @@
-// file: clkmgr_dcm.v
-//
-// (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
-//
-// This file contains confidential and proprietary information
-// of Xilinx, Inc. and is protected under U.S. and
-// international copyright and other intellectual property
-// laws.
-//
-// DISCLAIMER
-// This disclaimer is not a license and does not grant any
-// rights to the materials distributed herewith. Except as
-// otherwise provided in a valid license issued to you by
-// Xilinx, and to the maximum extent permitted by applicable
-// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-// (2) Xilinx shall not be liable (whether in contract or tort,
-// including negligence, or under any other theory of
-// liability) for any loss or damage of any kind or nature
-// related to, arising under or in connection with these
-// materials, including for any direct, or any indirect,
-// special, incidental, or consequential loss or damage
-// (including loss of data, profits, goodwill, or any type of
-// loss or damage suffered as a result of any action brought
-// by a third party) even if such damage or loss was
-// reasonably foreseeable or Xilinx had been advised of the
-// possibility of the same.
-//
-// CRITICAL APPLICATIONS
-// Xilinx products are not designed or intended to be fail-
-// safe, or for use in any application requiring fail-safe
-// performance, such as life-support or safety devices or
-// systems, Class III medical devices, nuclear facilities,
-// applications related to the deployment of airbags, or any
-// other applications that could lead to death, personal
-// injury, or severe property or environmental damage
-// (individually and collectively, "Critical
-// Applications"). Customer assumes the sole risk and
-// liability of any use of Xilinx products in Critical
-// Applications, subject only to applicable laws and
-// regulations governing limitations on product liability.
-//
-// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-// PART OF THIS FILE AT ALL TIMES.
-//
-//----------------------------------------------------------------------------
-// User entered comments
-//----------------------------------------------------------------------------
-// None
-//
-//----------------------------------------------------------------------------
-// "Output Output Phase Duty Pk-to-Pk Phase"
-// "Clock Freq (MHz) (degrees) Cycle (%) Jitter (ps) Error (ps)"
-//----------------------------------------------------------------------------
-// CLK_OUT1____50.000______0.000______50.0______200.000____150.000
-//
-//----------------------------------------------------------------------------
-// "Input Clock Freq (MHz) Input Jitter (UI)"
-//----------------------------------------------------------------------------
-// __primary______________50____________0.010
-
-/*verilator lint_off PINCONNECTEMPTY*/
-/*verilator lint_off UNDRIVEN*/
-/*verilator lint_off UNUSED*/
-
-`timescale 1ps/1ps
-
-(* CORE_GENERATION_INFO = "clkmgr_dcm,clk_wiz_v3_6,{component_name=clkmgr_dcm,use_phase_alignment=true,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,feedback_source=FDBK_AUTO,primtype_sel=DCM_SP,num_out_clk=1,clkin1_period=20.0,clkin2_period=20.0,use_power_down=false,use_reset=true,use_locked=false,use_inclk_stopped=true,use_status=false,use_freeze=false,use_clk_valid=true,feedback_type=SINGLE,clock_mgr_type=MANUAL,manual_override=false}" *)
-module clkmgr_dcm
- (// Clock in ports
- input CLK_IN1,
- // Clock out ports
- output CLK_OUT1,
- // Status and control signals
- input RESET,
- output INPUT_CLK_STOPPED,
- output CLK_VALID
- );
-
- // Input buffering
- //------------------------------------
- assign clkin1 = CLK_IN1;
-
-
- // Clocking primitive
- //------------------------------------
-
- // Instantiation of the DCM primitive
- // * Unused inputs are tied off
- // * Unused outputs are labeled unused
- wire psdone_unused;
- wire locked_int;
- wire [7:0] status_int;
- wire clkfb;
- wire clk0;
-
- DCM_SP
- #(.CLKDV_DIVIDE (2.000),
- .CLKFX_DIVIDE (1),
- .CLKFX_MULTIPLY (4),
- .CLKIN_DIVIDE_BY_2 ("FALSE"),
- .CLKIN_PERIOD (20.0),
- .CLKOUT_PHASE_SHIFT ("NONE"),
- .CLK_FEEDBACK ("1X"),
- .DESKEW_ADJUST ("SYSTEM_SYNCHRONOUS"),
- .PHASE_SHIFT (0),
- .STARTUP_WAIT ("FALSE"))
- dcm_sp_inst
- // Input clock
- (.CLKIN (clkin1),
- .CLKFB (clkfb),
- // Output clocks
- .CLK0 (clk0),
- .CLK90 (),
- .CLK180 (),
- .CLK270 (),
- .CLK2X (),
- .CLK2X180 (),
- .CLKFX (),
- .CLKFX180 (),
- .CLKDV (),
- // Ports for dynamic phase shift
- .PSCLK (1'b0),
- .PSEN (1'b0),
- .PSINCDEC (1'b0),
- .PSDONE (),
- // Other control and status signals
- .LOCKED (locked_int),
- .STATUS (status_int),
-
- .RST (RESET),
- // Unused pin- tie low
- .DSSEN (1'b0));
-
- assign INPUT_CLK_STOPPED = status_int[1];
- assign CLK_VALID = ( ( locked_int == 1'b 1 ) && ( status_int[1] == 1'b 0 ) );
-
- // Output buffering
- //-----------------------------------
- assign clkfb = CLK_OUT1;
-
- BUFG clkout1_buf
- (.O (CLK_OUT1),
- .I (clk0));
-
-
-
-
-endmodule
diff --git a/common/rtl/novena_clkmgr.v b/common/rtl/novena_clkmgr.v
index 97db451..e8ef1bd 100644
--- a/common/rtl/novena_clkmgr.v
+++ b/common/rtl/novena_clkmgr.v
@@ -39,19 +39,21 @@
module novena_clkmgr
(
- input wire gclk_p, // signal from clock pins
- input wire gclk_n, //
+ input wire gclk_p, // signal from clock pins
+ input wire gclk_n, //
- input wire reset_mcu_b, // cpu reset (async)
+ input wire reset_mcu_b, // cpu reset (async, active-low)
- output wire sys_clk, // buffered system clock output
- output wire sys_rst // system reset output (sync)
+ output wire sys_clk, // buffered system clock output
+ output wire sys_rst_n // system reset output (async set, sync clear, active-low)
);
+
//
- // Ports
+ // Parameters
//
-
+ parameter CLK_OUT_MUL = 2;
+ parameter CLK_OUT_DIV = 2;
//
// IBUFGDS
@@ -70,18 +72,23 @@ module novena_clkmgr
//
// DCM
//
- wire dcm_reset; // dcm reset
- wire dcm_locked; // output clock valid
+ wire dcm_reset; // dcm reset
+ wire dcm_locked; // output clock valid
wire gclk_missing; // no input clock
- clkmgr_dcm dcm
+ clkmgr_dcm #
(
- .CLK_IN1(gclk),
- .RESET(dcm_reset),
- .INPUT_CLK_STOPPED(gclk_missing),
+ .CLK_OUT_MUL (CLK_OUT_MUL),
+ .CLK_OUT_DIV (CLK_OUT_DIV)
+ )
+ dcm
+ (
+ .clk_in (gclk),
+ .reset_in (dcm_reset),
+ .gclk_missing_out (gclk_missing),
- .CLK_OUT1(sys_clk),
- .CLK_VALID(dcm_locked)
+ .clk_out (sys_clk),
+ .clk_valid_out (dcm_locked)
);
@@ -90,7 +97,8 @@ module novena_clkmgr
//
/* DCM should be reset on power-up, when input clock is stopped or when the
- * CPU gets reset.
+ * 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.
*/
reg [15: 0] dcm_rst_shreg = {16{1'b1}}; // 16-bit shift register
@@ -109,18 +117,21 @@ module novena_clkmgr
// System Reset Logic
//
- /* System reset is asserted for 16 cycles whenever DCM aquires lock. */
+ /* System reset is asserted for 16 cycles whenever DCM 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'b1}}; // 16-bit shift register
+ 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)
//
if ((reset_mcu_b == 1'b0) || (gclk_missing == 1'b1) || (dcm_locked == 1'b0))
- sys_rst_shreg <= {16{1'b1}};
+ sys_rst_shreg <= {16{1'b0}};
else if (dcm_locked == 1'b1)
- sys_rst_shreg <= {sys_rst_shreg[14:0], 1'b0};
+ sys_rst_shreg <= {sys_rst_shreg[14:0], 1'b1};
- assign sys_rst = sys_rst_shreg[15];
+ assign sys_rst_n = sys_rst_shreg[15];
endmodule
diff --git a/common/rtl/novena_regs.v b/common/rtl/novena_regs.v
index eb89092..4edf028 100644
--- a/common/rtl/novena_regs.v
+++ b/common/rtl/novena_regs.v
@@ -42,7 +42,7 @@ module board_regs
(
// Clock and reset.
input wire clk,
- input wire rst,
+ input wire reset_n,
// Control.
input wire cs,
@@ -96,9 +96,9 @@ module board_regs
//----------------------------------------------------------------
// storage registers for mapping memory to core interface
//----------------------------------------------------------------
- always @ (posedge clk or posedge rst)
+ always @ (posedge clk or negedge reset_n)
begin
- if (rst)
+ if (!reset_n)
begin
reg_dummy <= {32{1'b0}};
end
diff --git a/eim/build/Makefile b/eim/build/Makefile
index 6b251f2..678a2e5 100644
--- a/eim/build/Makefile
+++ b/eim/build/Makefile
@@ -11,7 +11,7 @@ vfiles = \
../rtl/novena_eim.v \
../../common/rtl/novena_regs.v \
../../common/rtl/novena_clkmgr.v \
- ../../common/rtl/ipcore/clkmgr_dcm.v \
+ ../../common/rtl/clkmgr_dcm.v \
../../../common/core_selector/src/rtl/core_selector.v \
../../../common/core_selector/src/rtl/global_selector.v \
../../../common/core_selector/src/rtl/hash_selector.v \
diff --git a/eim/rtl/novena_eim.v b/eim/rtl/novena_eim.v
index 1a1b1f6..23f08aa 100644
--- a/eim/rtl/novena_eim.v
+++ b/eim/rtl/novena_eim.v
@@ -75,18 +75,23 @@ module novena_top
// and implement the reset logic.
// ----------------------------------------------------------------
wire sys_clk;
- wire sys_rst;
+ wire sys_rst_n;
wire eim_bclk_buf;
- novena_clkmgr clkmgr
+ novena_clkmgr #
(
- .gclk_p(gclk_p_pin),
- .gclk_n(gclk_n_pin),
+ .CLK_OUT_MUL (2), // 2..32
+ .CLK_OUT_DIV (2) // 1..32
+ )
+ clkmgr
+ (
+ .gclk_p (gclk_p_pin),
+ .gclk_n (gclk_n_pin),
- .reset_mcu_b(reset_mcu_b_pin),
+ .reset_mcu_b (reset_mcu_b_pin),
- .sys_clk(sys_clk),
- .sys_rst(sys_rst)
+ .sys_clk (sys_clk),
+ .sys_rst_n (sys_rst_n)
);
@@ -123,7 +128,7 @@ module novena_top
.eim_wait_n(eim_wait_n),
.sys_clk(sys_clk),
- .sys_rst(sys_rst),
+ .sys_rst_n(sys_rst_n),
.sys_eim_addr(sys_eim_addr),
.sys_eim_wr(sys_eim_wr),
@@ -148,7 +153,7 @@ module novena_top
core_selector cores
(
.sys_clk(sys_clk),
- .sys_rst(sys_rst),
+ .sys_rst_n(sys_rst_n),
.sys_eim_addr(sys_eim_addr),
.sys_eim_wr(sys_eim_wr),
diff --git a/fmc/build/.gitignore b/fmc/build/.gitignore
new file mode 100644
index 0000000..865bda8
--- /dev/null
+++ b/fmc/build/.gitignore
@@ -0,0 +1,53 @@
+coregen-tmp
+*.xrpt
+novena_fmc.mcs
+novena_fmc.cfi
+novena_fmc.prm
+novena_fmc.bgn
+novena_fmc.bit
+novena_fmc.drc
+novena_fmc_bd.bmm
+novena_fmc_par.ncd
+novena_fmc_par.par
+novena_fmc_par.pad
+novena_fmc_par_pad.csv
+novena_fmc_par_pad.txt
+novena_fmc_par.grf
+novena_fmc_par.ptwx
+novena_fmc_par.unroutes
+novena_fmc_par.xpi
+novena_fmc.ncd
+novena_fmc.pcf
+novena_fmc.ngm
+novena_fmc.mrp
+novena_fmc.map
+smartguide.ncd
+novena_fmc.psr
+novena_fmc_summary.xml
+novena_fmc_usage.xml
+novena_fmc.ngd
+novena_fmc.bld
+xlnx_auto*
+novena_fmc_top.lso
+novena_fmc.srp
+netlist.lst
+xst
+novena_fmc.ngc
+novena_fmc.prj
+novena_fmc.scr
+novena_fmc.post_map.twr
+novena_fmc.post_map.twx
+smartpreview.twr
+novena_fmc.twr
+novena_fmc.twx
+smartpreview.twr
+novena_fmc_err.twr
+novena_fmc_err.twx
+novena_fmc.lso
+novena_fmc_bitgen.xwb
+novena_fmc_bitgen.xwbt
+usage_statistics_webtalk.html
+par_usage_statistics.html
+webtalk.log
+_xmsgs
+default.xreport
diff --git a/fmc/build/Makefile b/fmc/build/Makefile
new file mode 100644
index 0000000..7c73c89
--- /dev/null
+++ b/fmc/build/Makefile
@@ -0,0 +1,70 @@
+project = novena_fmc
+vendor = xilinx
+family = spartan6
+part = xc6slx45csg324-3
+top_module = novena_fmc_top
+isedir = /opt/Xilinx/14.7/ISE_DS
+xil_env = . $(isedir)/settings64.sh
+ucf = ../ucf/$(project).ucf
+
+vfiles = \
+ ../rtl/novena_fmc_top.v \
+ ../../common/rtl/novena_regs.v \
+ ../../common/rtl/novena_clkmgr.v \
+ ../../common/rtl/clkmgr_dcm.v \
+ ../../../common/core_selector/src/rtl/core_selector.v \
+ ../../../common/core_selector/src/rtl/global_selector.v \
+ ../../../common/core_selector/src/rtl/hash_selector.v \
+ ../../../common/core_selector/src/rtl/rng_selector.v \
+ ../../../common/core_selector/src/rtl/cipher_selector.v \
+ ../../../common/core_selector/src/rtl/math_selector.v \
+ ../../../../comm/fmc/src/rtl/cdc_bus_pulse.v \
+ ../../../../comm/fmc/src/rtl/fmc_arbiter_cdc.v \
+ ../../../../comm/fmc/src/rtl/fmc_arbiter.v \
+ ../../../../comm/fmc/src/rtl/fmc_d_phy.v \
+ ../../../../comm/fmc/src/rtl/fmc_indicator.v \
+ ../../../../comm/fmc/src/rtl/fmc_regs.v \
+ ../../../../hash/sha1/src/rtl/sha1.v \
+ ../../../../hash/sha1/src/rtl/sha1_core.v \
+ ../../../../hash/sha1/src/rtl/sha1_w_mem.v \
+ ../../../../hash/sha256/src/rtl/sha256.v \
+ ../../../../hash/sha256/src/rtl/sha256_core.v \
+ ../../../../hash/sha256/src/rtl/sha256_k_constants.v \
+ ../../../../hash/sha256/src/rtl/sha256_w_mem.v \
+ ../../../../hash/sha512/src/rtl/sha512.v \
+ ../../../../hash/sha512/src/rtl/sha512_core.v \
+ ../../../../hash/sha512/src/rtl/sha512_h_constants.v \
+ ../../../../hash/sha512/src/rtl/sha512_k_constants.v \
+ ../../../../hash/sha512/src/rtl/sha512_w_mem.v \
+ ../../../../rng/avalanche_entropy/src/rtl/avalanche_entropy.v \
+ ../../../../rng/avalanche_entropy/src/rtl/avalanche_entropy_core.v \
+ ../../../../rng/rosc_entropy/src/rtl/rosc.v \
+ ../../../../rng/rosc_entropy/src/rtl/rosc_entropy.v \
+ ../../../../rng/rosc_entropy/src/rtl/rosc_entropy_core.v \
+ ../../../../rng/trng/src/rtl/trng.v \
+ ../../../../rng/trng/src/rtl/trng_csprng.v \
+ ../../../../rng/trng/src/rtl/trng_csprng_fifo.v \
+ ../../../../rng/trng/src/rtl/trng_mixer.v \
+ ../../../../cipher/aes/src/rtl/aes.v \
+ ../../../../cipher/aes/src/rtl/aes_core.v \
+ ../../../../cipher/aes/src/rtl/aes_decipher_block.v \
+ ../../../../cipher/aes/src/rtl/aes_encipher_block.v \
+ ../../../../cipher/aes/src/rtl/aes_inv_sbox.v \
+ ../../../../cipher/aes/src/rtl/aes_key_mem.v \
+ ../../../../cipher/aes/src/rtl/aes_sbox.v \
+ ../../../../cipher/chacha/src/rtl/chacha.v \
+ ../../../../cipher/chacha/src/rtl/chacha_core.v \
+ ../../../../cipher/chacha/src/rtl/chacha_qr.v \
+ ../../../../math/modexp/src/rtl/adder.v \
+ ../../../../math/modexp/src/rtl/blockmem1r1w.v \
+ ../../../../math/modexp/src/rtl/blockmem2r1wptr.v \
+ ../../../../math/modexp/src/rtl/blockmem2r1w.v \
+ ../../../../math/modexp/src/rtl/blockmem2rptr1w.v \
+ ../../../../math/modexp/src/rtl/modexp.v \
+ ../../../../math/modexp/src/rtl/modexp_core.v \
+ ../../../../math/modexp/src/rtl/montprod.v \
+ ../../../../math/modexp/src/rtl/residue.v \
+ ../../../../math/modexp/src/rtl/shl.v \
+ ../../../../math/modexp/src/rtl/shr.v
+
+include xilinx.mk
diff --git a/fmc/build/xilinx.mk b/fmc/build/xilinx.mk
new file mode 100644
index 0000000..7a8d9d4
--- /dev/null
+++ b/fmc/build/xilinx.mk
@@ -0,0 +1,176 @@
+# The top level module should define the variables below then include
+# this file. The files listed should be in the same directory as the
+# Makefile.
+#
+# variable description
+# ---------- -------------
+# project project name (top level module should match this name)
+# top_module top level module of the project
+# libdir path to library directory
+# libs library modules used
+# vfiles all local .v files
+# xilinx_cores all local .xco files
+# vendor vendor of FPGA (xilinx, altera, etc.)
+# family FPGA device family (spartan3e)
+# part FPGA part name (xc4vfx12-10-sf363)
+# flashsize size of flash for mcs file (16384)
+# optfile (optional) xst extra opttions file to put in .scr
+# map_opts (optional) options to give to map
+# par_opts (optional) options to give to par
+# intstyle (optional) intstyle option to all tools
+# ucf constraint file, defaults to $(project).ucf
+#
+# Library modules should have a modules.mk in their root directory,
+# namely $(libdir)/<libname>/module.mk, that simply adds to the vfiles
+# and xilinx_cores variable.
+#
+# all the .xco files listed in xilinx_cores will be generated with core, with
+# the resulting .v and .ngc files placed back in the same directory as
+# the .xco file.
+#
+# TODO: .xco files are device dependant, should use a template based system
+
+coregen_work_dir ?= ./coregen-tmp
+#map_opts ?= -timing -ol high -detail -pr b -register_duplication -w -xe n
+# from https://github.com/fpga-logi/logi-hard/blob/master/build_lib/synth/xilinx.mk:
+map_opts ?= -w -logic_opt off -ol high -t 1 -xt 0 -register_duplication off -r 4 -global_opt off -mt off -ir off -pr off -lc off -power off
+par_opts ?= -ol high
+isedir ?= /opt/Xilinx/13.3/ISE_DS
+xil_env ?= . $(isedir)/settings32.sh
+flashsize ?= 8192
+ucf ?= $(project).ucf
+
+libmks = $(patsubst %,$(libdir)/%/module.mk,$(libs))
+mkfiles = $(libmks) xilinx.mk
+include $(libmks)
+
+corengcs = $(foreach core,$(xilinx_cores),$(core:.xco=.ngc))
+local_corengcs = $(foreach ngc,$(corengcs),$(notdir $(ngc)))
+vfiles += $(foreach core,$(xilinx_cores),$(core:.xco=.v))
+junk += $(local_corengcs)
+
+.PHONY: default xilinx_cores clean twr etwr
+default: $(project).bit $(project).mcs
+xilinx_cores: $(corengcs)
+twr: $(project).twr
+etwr: $(project)_err.twr
+
+define cp_template
+$(2): $(1)
+ cp $(1) $(2)
+endef
+$(foreach ngc,$(corengcs),$(eval $(call cp_template,$(ngc),$(notdir $(ngc)))))
+
+%.ngc %.v: %.xco
+ @echo "=== rebuilding $@"
+ if [ -d $(coregen_work_dir) ]; then \
+ rm -rf $(coregen_work_dir)/*; \
+ else \
+ mkdir -p $(coregen_work_dir); \
+ fi
+ cd $(coregen_work_dir); \
+ $(xil_env); \
+ coregen -b $$OLDPWD/$<; \
+ cd -
+ xcodir=`dirname $<`; \
+ basename=`basename $< .xco`; \
+ if [ ! -r $(coregen_work_dir/$$basename.ngc) ]; then \
+ echo "'$@' wasn't created."; \
+ exit 1; \
+ else \
+ cp $(coregen_work_dir)/$$basename.v $(coregen_work_dir)/$$basename.ngc $$xcodir; \
+ fi
+junk += $(coregen_work_dir)
+
+date = $(shell date +%F-%H-%M)
+
+# some common junk
+junk += *.xrpt
+
+programming_files: $(project).bit $(project).mcs
+ mkdir -p $@/$(date)
+ mkdir -p $@/latest
+ for x in .bit .mcs .cfi _bd.bmm; do cp $(project)$$x $@/$(date)/$(project)$$x; cp $(project)$$x $@/latest/$(project)$$x; done
+ $(xil_env); xst -help | head -1 | sed 's/^/#/' | cat - $(project).scr > $@/$(date)/$(project).scr
+
+$(project).mcs: $(project).bit
+ $(xil_env); \
+ promgen -w -s $(flashsize) -p mcs -o $@ -u 0 $^
+junk += $(project).mcs $(project).cfi $(project).prm
+
+$(project).bit: $(project)_par.ncd
+ $(xil_env); \
+ bitgen $(intstyle) -g UnusedPin:Pullnone -g DriveDone:yes -g StartupClk:Cclk -w $(project)_par.ncd $(project).bit
+junk += $(project).bgn $(project).bit $(project).drc $(project)_bd.bmm
+
+
+$(project)_par.ncd: $(project).ncd
+ $(xil_env); \
+ if par $(intstyle) $(par_opts) -w $(project).ncd $(project)_par.ncd; then \
+ :; \
+ else \
+ $(MAKE) etwr; \
+ fi
+junk += $(project)_par.ncd $(project)_par.par $(project)_par.pad
+junk += $(project)_par_pad.csv $(project)_par_pad.txt
+junk += $(project)_par.grf $(project)_par.ptwx
+junk += $(project)_par.unroutes $(project)_par.xpi
+
+$(project).ncd: $(project).ngd
+ if [ -r $(project)_par.ncd ]; then \
+ cp $(project)_par.ncd smartguide.ncd; \
+ smartguide="-smartguide smartguide.ncd"; \
+ else \
+ smartguide=""; \
+ fi; \
+ $(xil_env); \
+ map $(intstyle) $(map_opts) $$smartguide $<
+junk += $(project).ncd $(project).pcf $(project).ngm $(project).mrp $(project).map
+junk += smartguide.ncd $(project).psr
+junk += $(project)_summary.xml $(project)_usage.xml
+
+$(project).ngd: $(project).ngc $(ucf)
+ $(xil_env); ngdbuild $(intstyle) $(project).ngc -uc $(ucf)
+junk += $(project).ngd $(project).bld
+
+$(project).ngc: $(vfiles) $(local_corengcs) $(project).scr $(project).prj
+ $(xil_env); xst $(intstyle) -ifn $(project).scr
+junk += xlnx_auto* $(top_module).lso $(project).srp
+junk += netlist.lst xst $(project).ngc
+
+$(project).prj: $(vfiles) $(mkfiles)
+ for src in $(vfiles); do echo "verilog work $$src" >> $(project).tmpprj; done
+ sort -u $(project).tmpprj > $(project).prj
+ rm -f $(project).tmpprj
+junk += $(project).prj
+
+optfile += $(wildcard $(project).opt)
+top_module ?= $(project)
+$(project).scr: $(optfile) $(mkfiles) ./xilinx.opt
+ echo "run" > $@
+ echo "-p $(part)" >> $@
+ echo "-top $(top_module)" >> $@
+ echo "-ifn $(project).prj" >> $@
+ echo "-ofn $(project).ngc" >> $@
+ cat ./xilinx.opt $(optfile) >> $@
+junk += $(project).scr
+
+$(project).post_map.twr: $(project).ncd
+ $(xil_env); trce -e 10 $< $(project).pcf -o $@
+junk += $(project).post_map.twr $(project).post_map.twx smartpreview.twr
+
+$(project).twr: $(project)_par.ncd
+ $(xil_env); trce $< $(project).pcf -o $(project).twr
+junk += $(project).twr $(project).twx smartpreview.twr
+
+$(project)_err.twr: $(project)_par.ncd
+ $(xil_env); trce -e 10 $< $(project).pcf -o $(project)_err.twr
+junk += $(project)_err.twr $(project)_err.twx
+junk += $(project).lso $(project)_bitgen.xwb $(project)_bitgen.xwbt
+junk += usage_statistics_webtalk.html par_usage_statistics.html webtalk.log _xmsgs default.xreport
+
+.gitignore: $(mkfiles)
+ echo programming_files $(junk) | sed 's, ,\n,g' > .gitignore
+
+clean::
+ rm -rf $(junk)
diff --git a/fmc/build/xilinx.opt b/fmc/build/xilinx.opt
new file mode 100644
index 0000000..7fe9d8b
--- /dev/null
+++ b/fmc/build/xilinx.opt
@@ -0,0 +1,42 @@
+-ifmt mixed
+-ofmt NGC
+-opt_mode speed
+-opt_level 1
+-iuc NO
+-keep_hierarchy no
+-netlist_hierarchy as_optimized
+-rtlview no
+-glob_opt AllClockNets
+-read_cores yes
+-write_timing_constraints NO
+-cross_clock_analysis NO
+-hierarchy_separator /
+-bus_delimiter <>
+-case maintain
+-slice_utilization_ratio 100
+-bram_utilization_ratio 100
+#-dsp_utilization_ratio 100
+-safe_implementation No
+-fsm_extract YES
+-fsm_encoding Auto
+-fsm_style lut
+-ram_extract Yes
+-ram_style Auto
+-rom_extract Yes
+-rom_style Auto
+-shreg_extract YES
+-auto_bram_packing NO
+-resource_sharing YES
+-async_to_sync NO
+#-use_dsp48 auto
+-iobuf YES
+-max_fanout 500
+-register_duplication YES
+-register_balancing No
+-optimize_primitives NO
+-use_clock_enable Auto
+-use_sync_set Auto
+-use_sync_reset Auto
+-iob auto
+-equivalent_register_removal YES
+-slice_utilization_ratio_maxmargin 5
diff --git a/fmc/rtl/novena_fmc_top.v b/fmc/rtl/novena_fmc_top.v
new file mode 100644
index 0000000..37fdc49
--- /dev/null
+++ b/fmc/rtl/novena_fmc_top.v
@@ -0,0 +1,247 @@
+//======================================================================
+//
+// novena_top.v
+// ------------
+// Top module for the Cryptech Novena FPGA framework. This design
+// allow us to run the EIM 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.
+//
+// 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.
+//
+//======================================================================
+
+`timescale 1ns / 1ps
+
+module novena_fmc_top
+ (
+ input wire gclk_p_pin,
+ input wire gclk_n_pin,
+
+ input wire reset_mcu_b_pin,
+
+ // Cryptech avalanche noise board input
+ input wire ct_noise,
+
+ input wire fmc_clk, // clock
+ input wire [21: 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 apoptosis_pin,
+ output wire led_pin
+ );
+
+
+ //----------------------------------------------------------------
+ // Clock Manager
+ //
+ // Clock manager is used to generate SYS_CLK from GCLK
+ // and implement the reset logic.
+ // ----------------------------------------------------------------
+ wire sys_clk;
+ wire sys_rst_n;
+
+ novena_clkmgr #
+ (
+ .CLK_OUT_MUL (2), // 2..32
+ .CLK_OUT_DIV (2) // 1..32
+ )
+ 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)
+ );
+
+
+ //
+ // BUFG
+ //
+ wire fmc_clk_bug;
+
+ BUFG BUFG_fmc_clk
+ (
+ .I (fmc_clk),
+ .O (fmc_clk_bufg)
+ );
+
+
+
+ //----------------------------------------------------------------
+ // FMC Arbiter
+ //
+ // FMC arbiter handles FMC access and transfers it into
+ // `sys_clk' clock domain.
+ //----------------------------------------------------------------
+
+ wire [21: 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)
+`ifdef test
+ reg [31: 0] sys_fmc_din; // data input (from FPGA to STM32)
+`else
+ wire [31: 0] sys_fmc_din; // data input (from FPGA to STM32)
+`endif
+
+ fmc_arbiter #
+ (
+ .NUM_ADDR_BITS(22) // change to 26 when
+ )
+ fmc
+ (
+ .fmc_clk(fmc_clk_bufg),
+ .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 Novena
+ // 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_pin)
+ );
+
+
+`ifdef test
+ //----------------------------------------------------------------
+ // Dummy Register
+ //
+ // General-purpose register to test FMC interface using STM32
+ // demo program instead of core selector logic.
+ //
+ // This register is a bit tricky, but it allows testing of both
+ // data and address buses. Reading from FPGA will always return
+ // value, which is currently stored in the test register,
+ // regardless of read transaction address. Writing to FPGA has
+ // two variants: a) writing to address 0 will store output data
+ // data value in the test register, b) writing to any non-zero
+ // address will store _address_ of write transaction in the test
+ // register.
+ //
+ // To test data bus, write some different patterns to address 0,
+ // then readback from any address and compare.
+ //
+ // To test address bus, write anything to some different non-zero
+ // addresses, then readback from any address and compare returned
+ // value with previously written address.
+ //
+ //----------------------------------------------------------------
+ reg [31: 0] test_reg;
+
+ always @(posedge sys_clk)
+ //
+ if (sys_fmc_wren) begin
+ //
+ // when writing to address 0, store input data value
+ //
+ // 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};
+ //
+ end else if (sys_fmc_rden) begin
+ //
+ // always return current value, ignore address
+ //
+ sys_fmc_din <= test_reg;
+
+ // when reading from address 0, return the current value
+ // when reading from other addresses, return the address
+ //sys_fmc_din <= (sys_fmc_addr == {22{1'b0}}) ? test_reg : {{10{1'b0}}, sys_fmc_addr};
+ //
+ end
+
+`else // !`ifdef test
+ //----------------------------------------------------------------
+ // 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),
+
+ .sys_eim_addr(sys_fmc_addr[16:0]), // XXX parameterize
+ .sys_eim_wr(sys_fmc_wren),
+ .sys_eim_rd(sys_fmc_rden),
+ .sys_write_data(sys_fmc_dout),
+ .sys_read_data(sys_fmc_din),
+
+ .noise(ct_noise)
+ );
+`endif
+
+
+ //----------------------------------------------------------------
+ // Novena Patch
+ //
+ // Patch logic to keep the Novena 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;
+
+
+endmodule
diff --git a/fmc/ucf/novena_fmc.ucf b/fmc/ucf/novena_fmc.ucf
new file mode 100644
index 0000000..bbfd27b
--- /dev/null
+++ b/fmc/ucf/novena_fmc.ucf
@@ -0,0 +1,198 @@
+#======================================================================
+#
+# novena_fmc.ucf
+# -------------------
+# Constraint file for implementing the Cryptech Novena base
+# for the Xilinx Spartan6 LX45 on the Novena.
+#
+#
+# Author: Pavel Shatov
+# Copyright (c) 2014, 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.
+#
+#======================================================================
+
+#-------------------------------------------------------------------------------
+CONFIG VCCAUX = 3.3;
+#-------------------------------------------------------------------------------
+
+
+#--------------------------------------------------------------------------------
+# GCLK Timing (fixed at 50 MHz)
+#--------------------------------------------------------------------------------
+NET "gclk_p_pin" TNM_NET = TNM_gclk;
+TIMESPEC TS_gclk = PERIOD TNM_gclk 20 ns HIGH 50%;
+
+
+#-------------------------------------------------------------------------------
+# FMC_CLK Timing (can be up to 90 MHz)
+#-------------------------------------------------------------------------------
+NET "fmc_clk" TNM_NET = TNM_fmc_clk;
+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" ;
+
+#-------------------------------------------------------------------------------
+# FMC Input Timing
+#-------------------------------------------------------------------------------
+#
+# The following timing values were derived from pages 173-175 of the STM32F429
+# 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.
+#
+# 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
+# more strict. The same approach is used here, i.e. timing for Data bus is
+# applied to Address bus too.
+#
+# Oh, and stupid datasheet doesn't explicitly specify hold time for the data bus!
+#
+
+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 6.0 ns BEFORE "fmc_clk" RISING ;
+TIMEGRP "TNM_FMC_IN_ADDR" OFFSET = IN 3.0 ns VALID 6.0 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
+#-------------------------------------------------------------------------------
+#
+# NWAIT signal is not constrained, since it is polled by STM32.
+#
+
+NET "fmc_d<*>" TNM = "TNM_FMC_OUT_DATA" ;
+
+TIMEGRP "TNM_FMC_OUT_DATA" OFFSET = OUT 11.5 ns AFTER "fmc_clk" FALLING;
+
+
+#-------------------------------------------------------------------------------
+# CDC Paths
+#-------------------------------------------------------------------------------
+INST "fmc/fmc_cdc/cdc_fmc_sys/src_ff" TNM = "TNM_from_fmc_clk";
+INST "fmc/fmc_cdc/cdc_fmc_sys/src_latch*" TNM = "TNM_from_fmc_clk";
+INST "fmc/fmc_cdc/cdc_fmc_sys/ff_sync*" TNM = "TNM_to_sys_clk";
+INST "fmc/fmc_cdc/cdc_fmc_sys/dst_latch*" TNM = "TNM_to_sys_clk";
+
+INST "fmc/fmc_cdc/cdc_sys_fmc/src_ff" TNM = "TNM_from_sys_clk";
+INST "fmc/fmc_cdc/cdc_sys_fmc/src_latch*" TNM = "TNM_from_sys_clk";
+INST "fmc/fmc_cdc/cdc_sys_fmc/ff_sync*" TNM = "TNM_to_fmc_clk";
+INST "fmc/fmc_cdc/cdc_sys_fmc/dst_latch*" TNM = "TNM_to_fmc_clk";
+
+TIMESPEC "TS_fmc_clk_2_sys_clk" = FROM "TNM_from_fmc_clk" TO "TNM_to_sys_clk" TIG;
+TIMESPEC "TS_sys_clk_2_fmc_clk" = FROM "TNM_from_sys_clk" TO "TNM_to_fmc_clk" TIG;
+
+#======================================================================
+# EOF novena_fmc.ucf
+#======================================================================
diff --git a/i2c/rtl/novena_i2c.v b/i2c/rtl/novena_i2c.v
index d1833b2..4ea6f82 100644
--- a/i2c/rtl/novena_i2c.v
+++ b/i2c/rtl/novena_i2c.v
@@ -67,9 +67,14 @@ module novena_top
// and implement the reset logic.
// ----------------------------------------------------------------
wire sys_clk;
- wire sys_rst;
+ wire sys_rst_n;
- novena_clkmgr clkmgr
+ novena_clkmgr #
+ (
+ .CLK_OUT_MUL (2), // 2..32
+ .CLK_OUT_DIV (2) // 1..32
+ )
+ clkmgr
(
.gclk_p(gclk_p_pin),
.gclk_n(gclk_n_pin),
@@ -77,7 +82,7 @@ module novena_top
.reset_mcu_b(reset_mcu_b_pin),
.sys_clk(sys_clk),
- .sys_rst(sys_rst)
+ .sys_rst_n(sys_rst_n)
);
@@ -96,7 +101,6 @@ module novena_top
wire sda_int;
wire clk = sys_clk;
- wire reset_n = ~sys_rst;
// Coretest connections.
wire coretest_reset_n;
@@ -127,7 +131,7 @@ module novena_top
i2c_core i2c_core
(
.clk(clk),
- .reset(sys_rst),
+ .reset(~sys_rst_n), // active-high reset for this third-party module
// External data interface
.SCL(i2c_scl),
@@ -149,7 +153,7 @@ module novena_top
coretest coretest
(
.clk(clk),
- .reset_n(reset_n),
+ .reset_n(sys_rst_n),
.rx_syn(i2c_rxd_syn),
.rx_data(i2c_rxd_data),
@@ -184,7 +188,7 @@ module novena_top
core_selector cores
(
.sys_clk(clk),
- .sys_rst(sys_rst),
+ .sys_rst_n(sys_rst_n),
.sys_eim_addr(sys_eim_addr),
.sys_eim_wr(sys_eim_wr),
diff --git a/sw/cryptech.h b/sw/cryptech.h
index aeafc1b..13088b1 100644
--- a/sw/cryptech.h
+++ b/sw/cryptech.h
@@ -190,7 +190,7 @@ in order to map it into a 16-bit address space.
#define SHA256_NAME0 "sha2"
#define SHA256_NAME1 "-256"
-#define SHA256_VERSION "0.80"
+#define SHA256_VERSION "0.81"
#define SHA512_NAME0 "sha2"
#define SHA512_NAME1 "-512"
@@ -265,7 +265,7 @@ in order to map it into a 16-bit address space.
// current name and version values
#define TRNG_NAME0 "trng"
#define TRNG_NAME1 " "
-#define TRNG_VERSION "0.50"
+#define TRNG_VERSION "0.51"
#define AVALANCHE_ENTROPY_NAME0 "extn"
#define AVALANCHE_ENTROPY_NAME1 "oise"