diff options
-rw-r--r-- | common/rtl/clkmgr_dcm.v | 147 | ||||
-rw-r--r-- | common/rtl/ipcore/clkmgr_dcm.v | 152 | ||||
-rw-r--r-- | common/rtl/novena_clkmgr.v | 53 | ||||
-rw-r--r-- | common/rtl/novena_regs.v | 6 | ||||
-rw-r--r-- | eim/build/Makefile | 4 | ||||
-rw-r--r-- | eim/rtl/novena_eim.v | 23 | ||||
-rw-r--r-- | fmc/build/.gitignore | 53 | ||||
-rw-r--r-- | fmc/build/Makefile | 47 | ||||
-rw-r--r-- | fmc/build/xilinx.mk | 176 | ||||
-rw-r--r-- | fmc/build/xilinx.opt | 42 | ||||
-rw-r--r-- | fmc/rtl/novena_fmc_top.v | 247 | ||||
-rw-r--r-- | fmc/ucf/novena_fmc.ucf | 198 | ||||
-rw-r--r-- | i2c/build/Makefile | 102 | ||||
-rw-r--r-- | i2c/rtl/novena_i2c.v | 18 | ||||
-rw-r--r-- | sw/cryptech.h | 4 |
15 files changed, 1012 insertions, 260 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 6b52a80..69c9bd1 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 630faa9..a7eec60 100644 --- a/eim/build/Makefile +++ b/eim/build/Makefile @@ -7,7 +7,7 @@ CORE_TREE := $(abspath ../../../..) WORD_SIZE := $(shell python -c 'from struct import pack; print len(pack("L", 0)) * 8') -# Parameters to xilinkx.mk. +# Parameters to xilinx.mk. project = novena_eim vendor = xilinx @@ -24,7 +24,7 @@ vfiles = \ $(CORE_TREE)/platform/novena/eim/rtl/novena_eim.v \ $(CORE_TREE)/platform/novena/common/rtl/novena_regs.v \ $(CORE_TREE)/platform/novena/common/rtl/novena_clkmgr.v \ - $(CORE_TREE)/platform/novena/common/rtl/ipcore/clkmgr_dcm.v \ + $(CORE_TREE)/platform/novena/common/rtl/clkmgr_dcm.v \ $(CORE_TREE)/platform/novena/config/core_selector.v \ $(CORE_TREE)/comm/eim/src/rtl/cdc_bus_pulse.v \ $(CORE_TREE)/comm/eim/src/rtl/eim_arbiter_cdc.v \ diff --git a/eim/rtl/novena_eim.v b/eim/rtl/novena_eim.v index c774b6c..8feec20 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..81a43d0 --- /dev/null +++ b/fmc/build/Makefile @@ -0,0 +1,47 @@ +# Localize all the relative path awfulness in one variable. + +CORE_TREE := $(abspath ../../../..) + +# Figure out what the native word size is on the build host, because +# the XiLinx tools care for some reason. + +WORD_SIZE := $(shell python -c 'from struct import pack; print len(pack("L", 0)) * 8') + +# Parameters to xilinx.mk. + +project = novena_fmc +vendor = xilinx +family = spartan6 +part = xc6slx45csg324-3 +top_module = novena_top +isedir = /opt/Xilinx/14.7/ISE_DS +xil_env = . $(isedir)/settings$(WORD_SIZE).sh +ucf = ../ucf/$(project).ucf + +# Verilog files that always go with builds on this platform. + +vfiles = \ + $(CORE_TREE)/platform/novena/fmc/rtl/novena_fmc_top.v \ + $(CORE_TREE)/platform/novena/common/rtl/novena_regs.v \ + $(CORE_TREE)/platform/novena/common/rtl/novena_clkmgr.v \ + $(CORE_TREE)/platform/novena/common/rtl/clkmgr_dcm.v \ + $(CORE_TREE)/platform/novena/config/core_selector.v \ + $(CORE_TREE)/comm/fmc/src/rtl/cdc_bus_pulse.v \ + $(CORE_TREE)/comm/fmc/src/rtl/fmc_arbiter_cdc.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 \ + $(CORE_TREE)/comm/fmc/src/rtl/fmc_regs.v + +# Verilog files selected by the core configuration script. + +-include $(CORE_TREE)/platform/novena/config/core_vfiles.mk + +include xilinx.mk + +# Fun extras for running verlator as a linter. + +VERILATOR_FLAGS = --lint-only --top-module novena_top -Wall -Wno-fatal -Wno-DECLFILENAME + +lint: + verilator ${VERILATOR_FLAGS} $(vfiles) $(CORE_TREE)/platform/novena/common/rtl/lint-dummy.v 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/build/Makefile b/i2c/build/Makefile index 1859da3..441b67a 100644 --- a/i2c/build/Makefile +++ b/i2c/build/Makefile @@ -1,70 +1,44 @@ -project = novena_i2c -vendor = xilinx -family = spartan6 -part = xc6slx45csg324-3 -top_module = novena_top -isedir = /opt/Xilinx/14.7/ISE_DS -xil_env = . $(isedir)/settings64.sh -ucf = ../ucf/novena_i2c.ucf +# Localize all the relative path awfulness in one variable. + +CORE_TREE := $(abspath ../../../..) + +# Figure out what the native word size is on the build host, because +# the XiLinx tools care for some reason. + +WORD_SIZE := $(shell python -c 'from struct import pack; print len(pack("L", 0)) * 8') + +# Parameters to xilinx.mk. + +project = novena_eim +vendor = xilinx +family = spartan6 +part = xc6slx45csg324-3 +top_module = novena_top +isedir = /opt/Xilinx/14.7/ISE_DS +xil_env = . $(isedir)/settings$(WORD_SIZE).sh +ucf = ../ucf/$(project).ucf + +# Verilog files that always go with builds on this platform. vfiles = \ - ../rtl/novena_i2c.v \ - ../../common/rtl/novena_regs.v \ - ../../common/rtl/novena_clkmgr.v \ - ../../common/rtl/ipcore/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/i2c/src/rtl/i2c_regs.v \ - ../../../../comm/i2c/src/rtl/i2c_core.v \ - ../../../../comm/coretest/src/rtl/coretest.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/adder32.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/shl32.v \ - ../../../../math/modexp/src/rtl/shr32.v + $(CORE_TREE)/platform/novena/i2c/rtl/novena_i2c.v \ + $(CORE_TREE)/platform/novena/common/rtl/novena_regs.v \ + $(CORE_TREE)/platform/novena/common/rtl/novena_clkmgr.v \ + $(CORE_TREE)/platform/novena/common/rtl/clkmgr_dcm.v \ + $(CORE_TREE)/platform/novena/config/core_selector.v \ + $(CORE_TREE)/comm/i2c/src/rtl/i2c_regs.v \ + $(CORE_TREE)/comm/i2c/src/rtl/i2c_core.v \ + $(CORE_TREE)/comm/coretest/src/rtl/coretest.v + +# Verilog files selected by the core configuration script. + +-include $(CORE_TREE)/platform/novena/config/core_vfiles.mk include xilinx.mk +# Fun extras for running verlator as a linter. + +VERILATOR_FLAGS = --lint-only --top-module novena_top -Wall -Wno-fatal -Wno-DECLFILENAME + lint: - verilator --lint-only --top-module novena_top -Wall -Wno-fatal -Wno-DECLFILENAME $(vfiles) ../../common/rtl/lint-dummy.v + verilator ${VERILATOR_FLAGS} $(vfiles) $(CORE_TREE)/platform/novena/common/rtl/lint-dummy.v diff --git a/i2c/rtl/novena_i2c.v b/i2c/rtl/novena_i2c.v index f6230a0..db2c203 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 5426359..8fbef62 100644 --- a/sw/cryptech.h +++ b/sw/cryptech.h @@ -173,7 +173,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" @@ -243,7 +243,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" |