diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..25cb179
Binary files /dev/null and b/.DS_Store differ
diff --git a/README.md b/README.md
index 3c58390..befb8c3 100644
--- a/README.md
+++ b/README.md
@@ -4,23 +4,29 @@
[![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg)](https://opensource.org/licenses/BSD-2-Clause)
-
+
+
+
+
- v2.71
-
Copyright 2020 Massachusetts Institute of Technology
+
+
+
+
+The Common Evaluation Platform (CEP) is intended as a surrogate System on a Chip (SoC) that provides users an open-source evaluation platform for the evaluation of custom tools and techniques. An extensive verification environment provided to ensure the underlying functionality is maintained even after modification.
-
+The Logic Locking Key Interface (LLKI) has been provided as a representative means of distributing key / configuration material to LLKI-enabled cores.
-The Common Evaluation Platform (CEP) is intended as a surrogate System on a Chip (SoC) allowing users to test a variety of tools and techniques. Test vectors are provided to ensure the underlying functionality is maintained even after modification.
+For CEP v3.0, the Surrogate Root of Trust (SRoT) and LLKI-enabled AES-192 core has been added. Example test vectors have been with additional LLKI information being available in the comments of files located in ./hdl_cores/llki.
-
+
-Additional information on the objectives of the CEP may be found in [./CEP_SecEvalTargets.pdf](CEP_SecEvalTargets.pdf).
+Additional information on the objectives of the CEP may be found in [./doc/CEP_SecEvalTargets.pdf](CEP_SecEvalTargets.pdf).
The CEP is based on the SiFive U500 Platform which leverages the UCB Rocket Chip. Much of the design is described in Chisel (https://github.com/freechipsproject/chisel3), a domain specific extension to Scala tailored towards constructing hardware. The output of the Chisel generators is synthesizable verilog.
@@ -82,6 +88,8 @@ The RISC-V source code resides in /software/riscv-gnu-toolchain
Begin by installing the dependencies by executing the following:
`sudo apt install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev`
+Now, build the toolchain.
+
Ensure you have write permissions to the directory pointed to by $RISCV and that the current shell has NOT sourced the Xilinx Vivado environment script:
$ cd /software/riscv-gnu-toolchain
@@ -138,7 +146,10 @@ Install the required dependencies by running the following command:
|-- generated_dsp_code/ - Placeholder for the generated DSP code that cannot be
| directly included in the CEP repository due to licensing
| restrictions.
- |-- software/
+ |
+ |-- opentitan/ - Copy of the OpenTitan repository, some components are used by the LLKI.
+ |
+ |-- software/
|
|-- freedom-u-sdk/ - Directory containing an export of the https://github.com/
| mcd500/freedom-u-sdk directory, which is a fork of the
@@ -274,7 +285,7 @@ You should see the following logo/text appear:
./+++++++++++oo+++: +oo++o++++o+o+oo+oo.- `s+++s`-
.--:---:-:-::-::` -::::::::::::::::::. :::::.
- Common Evaluation Platform v2.71
+ Common Evaluation Platform v3.0
Copyright (C) 2020 Massachusetts Institute of Technology
Built upon the SiFive Freedom U500 Platform using
@@ -297,7 +308,7 @@ At the command prompt, you can run the CEP diagnostics by commanding `cep_diag`.
A partial output should be similar to:
```sh
-*** CEP Tag=CEPTest CEP HW VERSION = v2.71 was built on Sep 17 2020 12:01:26 ***
+*** CEP Tag=CEPTest CEP HW VERSION = v3.00 was built on Sep 17 2020 12:01:26 ***
CEP FPGA Physical=0x70000000 -> Virtual=0x00000020004fa000
gSkipInit=0/0
gverbose=0/0
@@ -428,7 +439,7 @@ v2.6 - (18 September 2020)
https://github.com/sifive/sifive-blocks/tree/12bdbe50636b6c57c8dc997e483787fdb5ee540b - Dec 17, 2019
https://github.com/mcd500/freedom-u-sdk/tree/29fe529f8dd8e1974fe1743184b3e13ebb2a21dc - Apr 12, 2019
* riscv-tools (formerly under rocket-chip) now located in ./software/riscv-gnu-toolchain
-7* KNOWN ISSUES:
+* KNOWN ISSUES:
- The iCacheCoherency passes when running bare-metal simulation, but fails when running on the VC-707. There is an issue with
the iCache protocol that the tight-looped iCache coherency test results in one or more of the Rocket Cores (there are 4 in
the CEP) L1 iCache not getting the value associated with the most recent write to instruction memory.
@@ -455,8 +466,11 @@ v2.7 - (28 October 2020)
- isaTests/rv64ud-p-ldst
v2.71 - (2 November 2020)
-* Corrected README.md issues
+* Corrected README.md issue
+v3.0 - (18 December 2020)
+* Initial LLKI release with Surrogate Root of Trust
+* AES core replaced with LLKI-enabled AES core, all other cores remain unchanged
## Licensing
The CEP been developed with a goal of using components with non-viral, open source licensing whenever possible. When not feasible (such as Linux), pointers to reference repositories are given using the [get_external_dependencies.sh](./get_external_dependencies.sh) script.
@@ -466,10 +480,11 @@ Additional licensing information can be found in the [LICENSE](./LICENSE) and [l
## DISTRIBUTION STATEMENT A. Approved for public release: distribution unlimited.
-This material is based upon work supported by the Assistant Secretary of Defense for Research and Engineering under Air Force Contract No. FA8721-05-C-0002 and/or FA8702-15-D-0001. Any opinions, findings, conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the Assistant Secretary of Defense for Research and Engineering.
+© 2020 MASSACHUSETTS INSTITUTE OF TECHNOLOGY
-© 2020 Massachusetts Institute of Technology.
+Subject to FAR 52.227-11 – Patent Rights – Ownership by the Contractor (May 2014)
+SPDX-License-Identifier: BSD-2-Clause
-The software/firmware is provided to you on an as-is basis.
+This material is based upon work supported by the Name of Sponsor under Air Force Contract No. FA8721-05-C-0002 and/or FA8702-15-D-0001. Any opinions, findings, conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the Name of Sponsor.
-Delivered to the U.S. Government with Unlimited Rights, as defined in DFARS Part 252.227-7013 or 7014 (Feb 2014). Notwithstanding any copyright notice, U.S. Government rights in this work are defined by DFARS 252.227-7013 or DFARS 252.227-7014 as detailed above. Use of this work other than as specifically authorized by the U.S. Government may violate any copyrights that exist in this work.
+The software/firmware is provided to you on an As-Is basis
\ No newline at end of file
diff --git a/cep_architecture.jpg b/cep_architecture.jpg
deleted file mode 100644
index 46fc581..0000000
Binary files a/cep_architecture.jpg and /dev/null differ
diff --git a/cosim/README.md b/cosim/README.md
index 9a40fd2..ae71d26 100644
--- a/cosim/README.md
+++ b/cosim/README.md
@@ -452,17 +452,3 @@ make CADENCE=1 <-- run simulation targetting Cadence XCellium on RHEL7
* By default, under each test directory, one file will be created **if and only if** it is not yet there: **vsim.do**. It is used when **vsim** command is called to control the wave capturing.. If there is a need to override, users are free to modify and change it to anyway to fit the needs. Makefile will not overwrite it as long as it is there.
* Under bare metal mode, some of main memory locations are used as mailbox to help RISCV core tracking and printing. See .**../cosim/dvt/cep_adrMap.incl** file. **NOTE**: there is also a file under .../cosim/include/cep_adrMap.h This file is auto-generated from the cep_adrMap.incl mentioned. Therefore, any modification should be made to the cep_adrMap.incl file.
-
-# Food for thought #
-
- * At the time of this writing, running regression is done one test at a time on the same machine, serially. It takes about day+ to run all tests. As more tests are added or moving the platform to support ASIC, there will be hundreds of tests added to verify full coverage of the design before any fabrication attempted. Running serially is not do-able as turn around time is key during physical design and verification process for ASIC. This requires moving to support multiple machines (as on a cloud or grid/networks) where tests can be batched to run concurrently...The Makefile structure already takes that in mind and supports it. The requirements are the grid setup where all the machines on the networks need to be configured identically w.r.t where the tools are, all disks are mounted and visible... Not sure MIT LL support such a thing due to security??
-
- * The environment is also capable of supporting distributed simulation where multiple large blocks (multi corer per board, big large ASIC, etc...) can be spawn off to run on different machines (or physical cores) to speed up simulation. However, this requires more simulation license usages and some manual system splitting during test bench construction.
-
- * The environment also can be expanded to support socket communication instead of shared memory such that the DUT can be run off an emulated system (Amazon FPGA cloud??) to get more performance. This should be able to support booting Linux OS for higher level verification.
-
-
-
-
-
-
diff --git a/cosim/bareMetalTests/Makefile b/cosim/bareMetalTests/Makefile
index 9a651cb..1c93db3 100644
--- a/cosim/bareMetalTests/Makefile
+++ b/cosim/bareMetalTests/Makefile
@@ -56,6 +56,9 @@ BARE_TEST_LIST = \
ddr3 \
cacheCoherence \
idcache_smc \
+ miscTests \
+ lrscOps \
+ atomicOps \
diff --git a/cosim/bareMetalTests/srotTest/Makefile b/cosim/bareMetalTests/srotTest/Makefile
new file mode 100644
index 0000000..4904700
--- /dev/null
+++ b/cosim/bareMetalTests/srotTest/Makefile
@@ -0,0 +1,32 @@
+#//************************************************************************
+#// Copyright (C) 2020 Massachusetts Institute of Technology
+#// SPDX short identifier: BSD-2-Clause
+#//
+#// File Name:
+#// Program: Common Evaluation Platform (CEP)
+#// Description:
+#// Notes:
+#//
+#//************************************************************************
+#
+#
+#
+COSIM_NAME = $(shell cd ../..; basename `pwd`)
+DUT_TOP_DIR = $(shell cd ../../..; pwd | ./${COSIM_NAME}/bin/strip_net.pl )
+BLD_DIR = $(shell cd ..; pwd | ../bin/strip_net.pl )
+TEST_SUITE = $(shell basename ${BLD_DIR})
+TEST_DIR = $(shell cd .; pwd | ../../bin/strip_net.pl )
+TEST_NAME = $(shell basename `pwd`)
+SIM_DIR = ${DUT_TOP_DIR}/${COSIM_NAME}
+
+
+#
+# Top target!!!
+#
+all: .vrun_flag riscv_wrapper.elf
+
+#
+# override anything here before calling the common file
+#
+include ${BLD_DIR}/common.make
+
diff --git a/cosim/bareMetalTests/srotTest/c_dispatch.cc b/cosim/bareMetalTests/srotTest/c_dispatch.cc
new file mode 100644
index 0000000..33c526b
--- /dev/null
+++ b/cosim/bareMetalTests/srotTest/c_dispatch.cc
@@ -0,0 +1,122 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX short identifier: BSD-2-Clause
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+#include
+#include "v2c_cmds.h"
+#include "access.h"
+#include "c_dispatch.h"
+#include "c_module.h"
+#include "cep_apis.h"
+#include "cep_adrMap.h"
+#include "simPio.h"
+/*
+ * main
+ */
+int main(int argc, char *argv[])
+{
+
+ /* ===================================== */
+ /* SETUP SECTION FOR SIMULATION */
+ /* ===================================== */
+ unsigned long seed;
+ sscanf(argv[1],"0x%x",&seed);
+ printf("Seed = 0x%x\n",seed);
+ int errCnt = 0;
+ int verbose = 0x1f;
+
+ /* ===================================== */
+ /* spawn all the paralle threads */
+ /* ===================================== */
+ int activeSlot=0; // only 1 board
+ //
+ // ============================
+ // fork all the tests here
+ // ============================
+ //
+ shPthread thr;
+ //
+ // max number of cores not include the system thread
+ //
+ int maxHost = MAX_CORES; // number of cores/threads
+ //
+ // each bit is to turn on the given core (bit0 = core0, bit1=core1, etc..)
+ //
+ long unsigned int mask = 1 << (seed & 0x3);
+ //
+ // Set the active CPU mask before spawn the threads...
+ //
+ thr.SetActiveMask(mask);
+ //
+ // c_module is the threead to run
+ //
+ for (int i=0;i
+#include "random48.h"
+
+#include "cep_adrMap.h"
+#include "cep_apis.h"
+#include "simdiag_global.h"
+#include "cepregression.h"
+#include "simPio.h"
+
+//
+void *c_module(void *arg) {
+
+
+ // ======================================
+ // Set up
+ // ======================================
+ pthread_parm_t *tParm = (pthread_parm_t *)arg;
+ int errCnt = 0;
+ int slotId = tParm->slotId;
+ int cpuId = tParm->cpuId;
+ int verbose = tParm->verbose;
+ Int32U seed = tParm->seed;
+ int restart = tParm->restart;
+ int offset = GET_OFFSET(slotId,cpuId);
+ GlobalShMemory.getSlotCpuId(offset,&slotId,&cpuId);
+ //printf("offset=%x seed=%x verbose=%x GlobalShMemory=%x\n",offset,seed, verbose,(unsigned long) &GlobalShMemory);
+ // notify I am Alive!!!
+ shIpc *ptr = GlobalShMemory.getIpcPtr(offset);
+ ptr->SetAliveStatus();
+ sleep(1);
+
+ // ======================================
+ // Test is Here
+ // ======================================
+ simPio pio;
+ pio.MaybeAThread(); // chec
+ pio.EnableShIpc(1);
+ pio.SetVerbose(verbose);
+
+ //
+ // ======================================
+ // Test starts here
+ // ======================================
+ // MUST
+ // wait until Calibration is done..
+ //int calibDone = calibrate_ddr3(50);
+ int calibDone = is_program_loaded(50);
+
+ //
+ errCnt += check_bare_status(cpuId,500);
+ //
+ pio.RunClk(100);
+ //
+ // ======================================
+ // Exit
+ // ======================================
+cleanup:
+ if (errCnt != 0) {
+ LOGI("======== TEST FAIL ========== %x\n",errCnt);
+ } else {
+ LOGI("======== TEST PASS ========== \n");
+ }
+ // shIpc *ptr = GlobalShMemory.getIpcPtr(offset);
+ ptr->SetError(errCnt);
+ ptr->SetThreadDone();
+ pthread_exit(NULL);
+ return ((void *)NULL);
+}
+
diff --git a/cosim/bareMetalTests/srotTest/c_module.h b/cosim/bareMetalTests/srotTest/c_module.h
new file mode 100644
index 0000000..92a0535
--- /dev/null
+++ b/cosim/bareMetalTests/srotTest/c_module.h
@@ -0,0 +1,18 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX short identifier: BSD-2-Clause
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+#ifndef c_module_H
+#define c_module_H
+
+#include "shPthread.h"
+
+void *c_module(void *); /* thread routine */
+
+#endif
diff --git a/cosim/bareMetalTests/srotTest/riscv_wrapper.cc b/cosim/bareMetalTests/srotTest/riscv_wrapper.cc
new file mode 100644
index 0000000..de4fc75
--- /dev/null
+++ b/cosim/bareMetalTests/srotTest/riscv_wrapper.cc
@@ -0,0 +1,65 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX short identifier: MIT
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+//
+// For bareMetal mode ONLY
+//
+#ifdef BARE_MODE
+#include "cep_adrMap.h"
+#include "cep_apis.h"
+
+#include "cepSrotTest.h"
+#include "cepregression.h"
+
+
+//#define printf(...) { return 0; }
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//int main(void)
+void thread_entry(int cid, int nc)
+{
+ //
+ int errCnt = 0;
+ int testId[4] = {0x00,0x11,0x22,0x33};
+ int coreId = read_csr(mhartid);
+ //
+ set_printf(0);
+
+ //
+ //
+ set_cur_status(CEP_RUNNING_STATUS);
+ initConfig();
+ if (!errCnt) { errCnt = cepSrotTest_runTest(coreId,0,0); }
+ //
+ //
+ // Done
+ //
+ set_status(errCnt,testId[coreId]);
+ /*
+ if (errCnt) {
+ set_pass();
+ } else {
+ set_fail();
+ }
+ */
+ //
+ // Stuck here forever...
+ //
+ exit(errCnt);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cosim/bfmTests/Makefile b/cosim/bfmTests/Makefile
index e4845f1..8ae2221 100644
--- a/cosim/bfmTests/Makefile
+++ b/cosim/bfmTests/Makefile
@@ -55,6 +55,8 @@ BFM_TEST_LIST = \
ddr3Test \
memPreload \
regression \
+ miscTests \
+
SINGLE_OLD_TESTS = \
aes \
diff --git a/cosim/bfmTests/srotTest/Makefile b/cosim/bfmTests/srotTest/Makefile
new file mode 100644
index 0000000..04ed935
--- /dev/null
+++ b/cosim/bfmTests/srotTest/Makefile
@@ -0,0 +1,31 @@
+#//************************************************************************
+#// Copyright (C) 2020 Massachusetts Institute of Technology
+#// SPDX short identifier: BSD-2-Clause
+#//
+#// File Name:
+#// Program: Common Evaluation Platform (CEP)
+#// Description:
+#// Notes:
+#//
+#//************************************************************************
+#
+#
+#
+COSIM_NAME = $(shell cd ../..; basename `pwd`)
+DUT_TOP_DIR = $(shell cd ../../..; pwd | ./${COSIM_NAME}/bin/strip_net.pl )
+BLD_DIR = $(shell cd ..; pwd | ../bin/strip_net.pl )
+TEST_SUITE = $(shell basename ${BLD_DIR})
+TEST_DIR = $(shell cd .; pwd | ../../bin/strip_net.pl )
+TEST_NAME = $(shell basename `pwd`)
+SIM_DIR = ${DUT_TOP_DIR}/${COSIM_NAME}
+
+#
+# Top target!!!
+#
+all: .vrun_flag
+
+#
+# override anything here before calling the common file
+#
+include ${BLD_DIR}/common.make
+
diff --git a/cosim/bfmTests/srotTest/c_dispatch.cc b/cosim/bfmTests/srotTest/c_dispatch.cc
new file mode 100644
index 0000000..8086bbc
--- /dev/null
+++ b/cosim/bfmTests/srotTest/c_dispatch.cc
@@ -0,0 +1,107 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX short identifier: BSD-2-Clause
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+#include
+#include "v2c_cmds.h"
+#include "access.h"
+#include "c_dispatch.h"
+#include "c_module.h"
+#include "cep_adrMap.h"
+#include "cep_apis.h"
+#include "simPio.h"
+/*
+ * main
+ */
+int main(int argc, char *argv[])
+{
+
+ /* ===================================== */
+ /* SETUP SECTION FOR SIMULATION */
+ /* ===================================== */
+ unsigned long seed;
+ sscanf(argv[1],"0x%x",&seed);
+ printf("Seed = 0x%x\n",seed);
+ int errCnt = 0;
+ int verbose = 0x1f;
+
+ /* ===================================== */
+ /* spawn all the paralle threads */
+ /* ===================================== */
+ int activeSlot=0; // only 1 board
+ //
+ // ============================
+ // fork all the tests here
+ // ============================
+ //
+ shPthread thr;
+ //
+ // max number of cores not include the system thread
+ //
+ int maxHost = MAX_CORES; // number of cores/threads
+ //
+ // each bit is to turn on the given core (bit0 = core0, bit1=core1, etc..)
+ //
+ long unsigned int mask = 0x1 << (seed & 0x3);
+ //
+ // Set the active CPU mask before spawn the threads...
+ //
+ thr.SetActiveMask(mask);
+ //
+ // c_module is the threead to run
+ //
+ for (int i=0;i
+#include "random48.h"
+
+#include "cep_adrMap.h"
+#include "cep_apis.h"
+#include "simdiag_global.h"
+#include "cepSrotTest.h"
+#include "cepregression.h"
+
+//
+void *c_module(void *arg) {
+
+
+ // ======================================
+ // Set up
+ // ======================================
+ pthread_parm_t *tParm = (pthread_parm_t *)arg;
+ int errCnt = 0;
+ int slotId = tParm->slotId;
+ int cpuId = tParm->cpuId;
+ int verbose = tParm->verbose;
+ Int32U seed = tParm->seed;
+ int restart = tParm->restart;
+ int offset = GET_OFFSET(slotId,cpuId);
+ GlobalShMemory.getSlotCpuId(offset,&slotId,&cpuId);
+ //printf("offset=%x seed=%x verbose=%x GlobalShMemory=%x\n",offset,seed, verbose,(unsigned long) &GlobalShMemory);
+ // notify I am Alive!!!
+ shIpc *ptr = GlobalShMemory.getIpcPtr(offset);
+ ptr->SetAliveStatus();
+ sleep(1);
+
+ // ======================================
+ // Test is Here
+ // ======================================
+ simPio pio;
+ pio.MaybeAThread(); // chec
+ pio.EnableShIpc(1);
+ pio.SetVerbose(verbose);
+
+ //
+ // ======================================
+ // Test starts here
+ // ======================================
+ // MUST
+ // wait until Calibration is done..
+ //int calibDone = calibrate_ddr3(50);
+ pio.RunClk(500);
+
+ //
+ initConfig();
+#if 1
+ if (!errCnt) { errCnt = cepSrotTest_runTest(cpuId,seed, verbose); }
+#endif
+ //
+ //
+ pio.RunClk(100);
+ //
+ // ======================================
+ // Exit
+ // ======================================
+cleanup:
+ if (errCnt != 0) {
+ LOGI("======== TEST FAIL ========== %x\n",errCnt);
+ } else {
+ LOGI("======== TEST PASS ========== \n");
+ }
+ // shIpc *ptr = GlobalShMemory.getIpcPtr(offset);
+ ptr->SetError(errCnt);
+ ptr->SetThreadDone();
+ pthread_exit(NULL);
+ return ((void *)NULL);
+}
+
diff --git a/cosim/bfmTests/srotTest/c_module.h b/cosim/bfmTests/srotTest/c_module.h
new file mode 100644
index 0000000..92a0535
--- /dev/null
+++ b/cosim/bfmTests/srotTest/c_module.h
@@ -0,0 +1,18 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX short identifier: BSD-2-Clause
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+#ifndef c_module_H
+#define c_module_H
+
+#include "shPthread.h"
+
+void *c_module(void *); /* thread routine */
+
+#endif
diff --git a/cosim/cep_buildChips.make b/cosim/cep_buildChips.make
index 28d09a1..92ee884 100644
--- a/cosim/cep_buildChips.make
+++ b/cosim/cep_buildChips.make
@@ -150,6 +150,7 @@ endif
DUT_COMMON_FILES = ${DUT_TOP_DIR}/hdl_cores/aes/table.v \
${DUT_TOP_DIR}/hdl_cores/aes/round.v \
${DUT_TOP_DIR}/hdl_cores/aes/aes_192.v \
+ ${DUT_TOP_DIR}/hdl_cores/llki/tlul_err.sv \
$(wildcard ${DUT_TOP_DIR}/generated_dsp_code/*.v) \
${BHV_DIR}/ddr3.v \
@@ -182,7 +183,8 @@ DUT_XILINX_TOP_TB = ${DVT_DIR}/${DUT_XILINX_TOP_MODULE}.v
XILINX_MODELSIM_INI = ${SIM_DIR}/xil_lib/modelsim.ini
XILINX_LIBRARY_LIST = -L unisims_ver -L unimacro_ver -L unifast_ver -L secureip -L xpm
DUT_XILINX_VOPT_ARGS = +acc -64 +nolibcell +nospecify +notimingchecks -modelsimini ${XILINX_MODELSIM_INI} ${WORK_DIR}.glbl ${XILINX_LIBRARY_LIST}
-DUT_XILINX_VLOG_ARGS = +acc -sv -64 -incr +define+MODELSIM +define+RANDOMIZE_MEM_INIT
+DUT_XILINX_VLOG_ARGS = +acc -sv -64 -incr +define+MODELSIM +define+RANDOMIZE_MEM_INIT+RANDOMIZE_REG_INIT+RANDOM="1'b0"
+#DUT_XILINX_VLOG_ARGS = +acc -sv -64 -incr +define+MODELSIM +define+RANDOM="1'b0"
DUT_XILINX_VCOM_ARGS = -64 -93 -modelsimini ${XILINX_MODELSIM_INI}
DUT_XILINX_VSIM_ARGS = -64 -modelsimini ${XILINX_MODELSIM_INI} ${XILINX_LIBRARY_LIST} -warning 3363 -warning 3053 -warning 8630
@@ -245,6 +247,10 @@ SEARCH_DIR_LIST := ${DVT_DIR} \
${DUT_TOP_DIR}/hdl_cores/rsa/rtl \
${DUT_TOP_DIR}/hdl_cores/sha256 \
${DUT_TOP_DIR}/hdl_cores/dsp \
+ ${DUT_TOP_DIR}/hdl_cores/llki \
+ $(DUT_TOP_DIR)/opentitan/hw/ip/tlul/rtl \
+ $(DUT_TOP_DIR)/opentitan/hw/ip/prim/rtl \
+ $(DUT_TOP_DIR)/opentitan/hw/ip/prim_generic/rtl \
${BHV_DIR}
@@ -313,7 +319,7 @@ ${BLD_DIR}/.buildVlog : ${VERILOG_DEFINE_LIST} ${SIM_DIR}/common.make ${SIM_DIR}
@for i in ${INCDIR_LIST}; do \
echo "+incdir+"$${i} >> ${BLD_DIR}/searchPaths_build; \
done
- ${VLOG_CMD} -work ${WORK_DIR} -f ${BLD_DIR}/searchPaths_build +libext+.v ${BLD_DIR}/config.v ${DUT_VLOG_ARGS} ${DUT_VERILOG_FLIST} ${DUT_XILINX_TOP_TB}
+ ${VLOG_CMD} -work ${WORK_DIR} -f ${BLD_DIR}/searchPaths_build +libext+.v +libext+.sv ${BLD_DIR}/config.v ${DUT_VLOG_ARGS} ${DUT_VERILOG_FLIST} ${DUT_XILINX_TOP_TB}
touch $@
#
diff --git a/cosim/drivers/cep_tests/CEP.h b/cosim/drivers/cep_tests/CEP.h
index 9eccb91..ddb3857 100644
--- a/cosim/drivers/cep_tests/CEP.h
+++ b/cosim/drivers/cep_tests/CEP.h
@@ -11,8 +11,8 @@
// CEP Verion String
- const uint8_t CEP_MAJOR_VERSION = 0x02;
- const uint8_t CEP_MINOR_VERSION = 0x50;
+ const uint8_t CEP_MAJOR_VERSION = 0x03;
+ const uint8_t CEP_MINOR_VERSION = 0x00;
// General Constants
const uint32_t BITS_PER_BYTE = 8;
@@ -22,8 +22,6 @@
// Maximum expected name size for the ipCoreData structure
#define MAX_CONFIG_STRING_K 32
- // Defines the total number of cores in the CEP
- #define CEP_TOTAL_CORES 11
// Indexes used to select the desired core
#define AES_BASE_K 0
@@ -37,6 +35,9 @@
#define IIR_BASE_K 8
#define GPS_BASE_K 9
#define CEP_VERSION_REG_K 10
+ #define SROT_BASE_K 11
+ // Defines the total number of cores in the CEP
+ #define CEP_TOTAL_CORES 12
// Structure defining the base address and status
// of the CEP cores
@@ -49,18 +50,18 @@
// Array containing the base addresses and enable status of
// all the CEP cores (indexed by the constants above)
const cep_core_info_t cep_core_info[CEP_TOTAL_CORES] = {
- {"AES", 0x70000000, true}, // AES
- {"MD5", 0x70010000, true}, // MD5
+ {"AES", 0x70000000, true}, // AES
+ {"MD5", 0x70010000, true}, // MD5
{"SHA256", 0x70020000, true}, // SHA256
{"RSA", 0x70030000, true}, // RSA
- {"DES3", 0x70040000, true}, // DES3
+ {"DES3", 0x70040000, true}, // DES3
{"DFT", 0x70050000, true}, // DFT
{"IDFT", 0x70060000, true}, // IDFT
- {"FIR", 0x70070000, true}, // FIR
+ {"FIR", 0x70070000, true}, // FIR
{"IIR", 0x70080000, true}, // IIR
{"GPS", 0x70090000, true}, // GPS
- {"CEP Version", 0x700F0000, true} // CEP Version Register
- };
+ {"CEP Version", 0x700F0000, true}, // CEP Version Register
+ {"SROT", 0x70100000, true}}; // SRoT
// Constants copied from AES.h
const uint32_t AES_KEY_BITS = 192;
@@ -228,6 +229,23 @@
const uint32_t FIR_OUT_ADDR = FIR_IN_DATA + BYTES_PER_WORD;
const uint32_t FIR_OUT_DATA = FIR_OUT_ADDR + BYTES_PER_WORD;
const uint32_t FIR_DONE = 0;
- const uint32_t FIR_RESET = 40;
- const uint32_t FIR_SHIFT = 48;
- const uint32_t FIR_SHIFT2= 56;
+ const uint32_t FIR_RESET = 40;
+ const uint32_t FIR_SHIFT = 48;
+ const uint32_t FIR_SHIFT2 = 56;
+
+ // Constants related to the Surrogate Root of Trust
+ // These constants must be equal to those in llki_pkg.sv
+ const uint32_t SROT_KEYINDEXRAM_ADDR = 0x00000100;
+ const uint32_t SROT_KEYINDEXRAM_SIZE = 0x00000020;
+ const uint32_t SROT_KEYRAM_ADDR = 0x00000120;
+ const uint32_t SROT_KEYRAM_SIZE = 0x00000040;
+
+ // Reminder, data width is 64-bits
+ const uint32_t SROT_CTRLSTS_ADDR = 0x00000000;
+ const uint32_t SROT_CTRLSTS_MODEBIT0_MASK = 0x0000000000000001; // If either mode bit is set, TileLink access to the Key and Key Index RAMs are disabled
+ // These bits are SET ONLY
+ const uint32_t SROT_CTRLSTS_MODEBIT1_MASK = 0x0000000000000002;
+ const uint32_t SROT_CTRLSTS_RESP_WAITING_MASK = 0x0000000000000004;
+
+ const uint32_t SROT_LLKIC2_SENDRECV_ADDR = 0x00000008;
+
diff --git a/cosim/drivers/cep_tests/cep_aes.cc b/cosim/drivers/cep_tests/cep_aes.cc
index dd4a633..d2493db 100644
--- a/cosim/drivers/cep_tests/cep_aes.cc
+++ b/cosim/drivers/cep_tests/cep_aes.cc
@@ -24,6 +24,7 @@
#include
#include "cep_aes.h"
+#include "cepSrotTest.h"
#include "simdiag_global.h"
#include "portable_io.h"
#include "CEP.h"
@@ -184,9 +185,74 @@ int cep_aes::RunAes192Test(int maxLoop) {
uint8_t key0[] = {0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6, 0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c, 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6};
uint8_t pt0[] = {0x32,0x43,0xf6,0xa8,0x88,0x5a,0x30,0x8d, 0x31,0x31,0x98,0xa2,0xe0,0x37,0x07,0x34};
*/
- int outLen=mBlockSize;
+ int outLen=mBlockSize;
+ uint8_t response_status;
//
- for (int i=0;i
-#include "cep_adrMap.h"
+ #include
+ #include "cep_adrMap.h"
-#ifndef PLAYBACK_CMD_H
-#define PLAYBACK_CMD_H
-#define WRITE__CMD 1
-#define RDnCMP_CMD 2
-#define RDSPIN_CMD 3
+ #ifndef PLAYBACK_CMD_H
+ #define PLAYBACK_CMD_H
+ #define WRITE__CMD 1
+ #define RDnCMP_CMD 2
+ #define RDSPIN_CMD 3
-#define WRITE__CMD_SIZE 3
-#define RDnCMP_CMD_SIZE 3
-#define RDSPIN_CMD_SIZE 5
+ #define WRITE__CMD_SIZE 3
+ #define RDnCMP_CMD_SIZE 3
+ #define RDSPIN_CMD_SIZE 5
+ #endif
-#endif
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
-#ifdef __cplusplus
-extern "C" {
-#endif
- /*
- * Function Prototypes
- */
+ //
+ // Function Prototypes
+ //
void dump_wave(int cycle2start, int cycle2capture, int enable);
int calibrate_ddr3(int maxTimeOut);
int is_program_loaded(int maxTimeOut);
@@ -44,13 +44,13 @@ extern "C" {
void set_fail(void);
void set_cur_status(int status);
int check_PassFail_status(int coreMask,int maxTimeOut);
- //
+
void cep_raw_write(uint64_t pAddress, uint64_t pData);
uint64_t cep_raw_read(uint64_t pAddress);
int cep_playback(uint64_t *cmdSeq,
- uint64_t upperAdr, uint64_t lowerAdr,
- int totalCmds, int totalSize,
- int verbose);
+ uint64_t upperAdr, uint64_t lowerAdr,
+ int totalCmds, int totalSize,
+ int verbose);
//
// lock
@@ -62,23 +62,21 @@ extern "C" {
void Set_C2C_Capture(int enable);
int Get_C2C_Capture(void);
void writeDvt(int msb, int lsb, int bits);
-
-//
-// syscalls.c has printf
-//
-#ifdef BARE_MODE
-#undef printf
-#include "encoding.h"
- extern int printf(const char *format, ...);
- extern void set_printf(int enable);
- extern int get_printf(void);
-#endif
-
-// end of extern
-#ifdef __cplusplus
-}
-#endif
+ //
+ // syscalls.c has printf
+ //
+ #ifdef BARE_MODE
+ #undef printf
+ #include "encoding.h"
+ extern int printf(const char *format, ...);
+ extern void set_printf(int enable);
+ extern int get_printf(void);
+ #endif
+
+ // end of extern
+ #ifdef __cplusplus
+ }
+ #endif
-// ===============
-#endif
+#endif // CEP_APIS_H
diff --git a/cosim/drivers/cep_tests/cep_riscv.cc b/cosim/drivers/cep_tests/cep_riscv.cc
index 3b46bcc..4c56ef0 100644
--- a/cosim/drivers/cep_tests/cep_riscv.cc
+++ b/cosim/drivers/cep_tests/cep_riscv.cc
@@ -1,4 +1,4 @@
-//************************************************************************
+// ************************************************************************
// Copyright (C) 2020 Massachusetts Institute of Technology
// SPDX License Identifier: MIT
//
@@ -7,53 +7,56 @@
// Description:
// Notes:
//
-//************************************************************************
+// ************************************************************************
+
//
// for self-modifying code!!!!! look for 0x5A!!!
//
-#if 0
- // *************************
- // This is from native Linux's objdump
- // *************************
+/*
+
+// *************************
+// This is from native Linux's objdump
+// *************************
volatile char get_selfModCodeValue(void) {
- 74: 55 push %rbp
- 75: 48 89 e5 mov %rsp,%rbp
-/home/aduong/CEP/CEP-master/software/freedom-u-sdk/buildroot/package/cep_diag/src/cep_riscv.cc:33
- return (volatile char)0x5A; // this value will be modified to test I-cache coherency
- 78: b8 5a 00 00 00 mov $0x5a,%eax
-/home/aduong/CEP/CEP-master/software/freedom-u-sdk/buildroot/package/cep_diag/src/cep_riscv.cc:34
-}
- 7d: 5d pop %rbp
- 7e: c3 retq
- // *************************
- // This is from RISCV's objdump under Linux
- // *************************
- //
- // from OBJDUMP
- get_selfModCodeValue():
+ 74: 55 push %rbp
+ 75: 48 89 e5 mov %rsp,%rbp
+ /home/aduong/CEP/CEP-master/software/freedom-u-sdk/buildroot/package/cep_diag/src/cep_riscv.cc:33
+ return (volatile char)0x5A; // this value will be modified to test I-cache coherency
+ 78: b8 5a 00 00 00 mov $0x5a,%eax
+ /home/aduong/CEP/CEP-master/software/freedom-u-sdk/buildroot/package/cep_diag/src/cep_riscv.cc:34
+ }
+7d: 5d pop %rbp
+7e: c3 retq
+// *************************
+// This is from RISCV's objdump under Linux
+// *************************
+//
+// from OBJDUMP
+get_selfModCodeValue():
/home/aduong/CEP/CEP-master/software/freedom-u-sdk/buildroot/package/cep_diag/src/cep_exports.cc:321
- char get_selfModCodeValue(void) {
- 14a0: 1141 addi sp,sp,-16
+char get_selfModCodeValue(void) {
+ 14a0: 1141 addi sp,sp,-16
14a2: e422 sd s0,8(sp)
14a4: 0800 addi s0,sp,16
-
- 00000000000014a6 <.L0 >:
- /home/aduong/CEP/CEP-master/software/freedom-u-sdk/buildroot/package/cep_diag/src/cep_exports.cc:322
- return (volatile char)0x5A; // this value will be modified to test I-cache coherency
- 14a6: 05a00793 li a5,90
+
+ 00000000000014a6 <.L0 >:
+ /home/aduong/CEP/CEP-master/software/freedom-u-sdk/buildroot/package/cep_diag/src/cep_exports.cc:322
+ return (volatile char)0x5A; // this value will be modified to test I-cache coherency
+ 14a6: 05a00793 li a5,90
//
// *************************
// This is from RISCV's objdump under BARE mode
// *************************
//
-volatile char get_selfModCodeValue(void) {
- return (volatile char)0x5A; // this value will be modified to test I-cache coherency
-}
- 80001a12: 05a00513 li a0,90
+ volatile char get_selfModCodeValue(void) {
+ return (volatile char)0x5A; // this value will be modified to test I-cache coherency
+ }
+ 80001a12: 05a00513 li a0,90
80001a16: 8082 ret
#endif
+*/
// Only for RISCV
#ifdef RISCV_CPU
@@ -83,6 +86,159 @@ volatile char get_selfModCodeValue(void) {
#endif
+//
+// Atomic
+// return old value before operation
+//
+uint64_t cep_atomic_op(uint64_t *ptr, uint64_t val,int OP) {
+ switch (OP) {
+ case ATOMIC_OP_EXCH : return __atomic_exchange_n(ptr,val,__ATOMIC_SEQ_CST); break;
+ case ATOMIC_OP_ADD : return __atomic_fetch_add(ptr,val,__ATOMIC_SEQ_CST); break;
+ case ATOMIC_OP_AND : return __atomic_fetch_and(ptr,val,__ATOMIC_SEQ_CST); break;
+ case ATOMIC_OP_OR : return __atomic_fetch_or(ptr,val,__ATOMIC_SEQ_CST); break;
+ case ATOMIC_OP_SUB : return __atomic_fetch_sub(ptr,val,__ATOMIC_SEQ_CST); break;
+ case ATOMIC_OP_XOR : return __atomic_fetch_xor(ptr,val,__ATOMIC_SEQ_CST); break;
+ case ATOMIC_OP_LOAD : return __atomic_load_n(ptr,__ATOMIC_SEQ_CST); break;
+ case ATOMIC_OP_STORE : __atomic_store_n(ptr,val,__ATOMIC_SEQ_CST); return 0; break;
+ }
+ return -1;
+}
+//
+// Lock via atomic exchange (load-reserved/store-conditional ONLY on cached region, see Sifive Manual on Atominc Operation)
+//
+int cep_exchAtomicTest(int coreId, uint64_t *ptr, uint64_t mySig, uint64_t partSig, uint64_t incVal, int loop) {
+ //
+ //
+ //
+ int errCnt = 0;
+ int timeOut = 20;
+ int i=1;
+ uint64_t myCurSig = mySig;
+ uint64_t regAdr = reg_base_addr + cep_scratch0_reg + (coreId * 16);
+ //
+ while (i <= loop) {
+ // strong compare
+ // if (__atomic_compare_exchange_n(ptr,&myCurSig,partSig,0,__ATOMIC_SEQ_CST,__ATOMIC_SEQ_CST)) { // next
+ if (__atomic_compare_exchange_n(ptr,&myCurSig,partSig,0,__ATOMIC_ACQ_REL,__ATOMIC_ACQ_REL)) { // next
+ DUT_WRITE32_64(regAdr,mySig);
+ DUT_WRITE32_64(regAdr+8,partSig);
+ timeOut = 20;
+ mySig += incVal;
+ partSig += incVal;
+ i++;
+ //
+ } else {
+ DUT_WRITE32_64(regAdr,myCurSig); // what I got when false!!!
+ DUT_WRITE32_64(regAdr+8,(i << 16) | timeOut);
+ timeOut--;
+ if (timeOut <= 0) {
+ errCnt = i;
+ return errCnt;
+ }
+ }
+ myCurSig = mySig; // reset since myCurSig got exchange!!
+ }
+ return errCnt;
+}
+
+//
+// Simple Atomic test (all ops)
+//
+int cep_runAtomicTest(uint64_t *ptr, uint64_t expVal) {
+ int errCnt = 0;
+ uint64_t actVal, oriVal=expVal;
+
+ //
+ // load the location with expVal
+ //
+ __atomic_store_n(ptr,expVal,__ATOMIC_SEQ_CST);
+ //
+ // readback and check
+ //
+ actVal = __atomic_load_n(ptr,__ATOMIC_SEQ_CST);
+ if (actVal != expVal) {
+ errCnt = 1 << 0;
+ return errCnt;
+ }
+ //
+ // add 1's complement to it to make it all 0xFF...FF
+ //
+ actVal = __atomic_fetch_add(ptr,~expVal,__ATOMIC_SEQ_CST);
+ if (actVal != expVal) {
+ errCnt = 1 << 1;
+ return errCnt;
+ }
+ expVal = (uint64_t)-1;
+ //
+ // Add 1 to get zero
+ //
+ actVal = __atomic_fetch_add(ptr,1,__ATOMIC_SEQ_CST);
+ if (actVal != expVal) {
+ errCnt = 1 << 1;
+ return errCnt;
+ }
+ expVal = 0;
+ //
+ // walk a 1 via OR to make all 0xFF
+ //
+ for (int i=0;i<64;i++) {
+ actVal = __atomic_fetch_or(ptr,((uint64_t)1 << i),__ATOMIC_SEQ_CST);
+ if (actVal != expVal) {
+ errCnt = (i << 16) | (1 << 2);
+ return errCnt;
+ }
+ expVal |= ((uint64_t)1 << i);
+ }
+ //
+ // Subract to get 1's complement
+ //
+ actVal = __atomic_fetch_sub(ptr,oriVal,__ATOMIC_SEQ_CST);
+ if (actVal != expVal) {
+ errCnt = 1 << 3;
+ return errCnt;
+ }
+ expVal = ~oriVal;
+ //
+ // XOR to get all 0xFF...FF
+ //
+ actVal = __atomic_fetch_xor(ptr,~expVal,__ATOMIC_SEQ_CST);
+ if (actVal != expVal) {
+ errCnt = 1 << 4;
+ return errCnt;
+ }
+ expVal = (uint64_t)-1;
+ //
+ // walk a 0 via AND to make all 0
+ //
+ for (int i=0;i<64;i++) {
+ actVal = __atomic_fetch_and(ptr,~((uint64_t)1 << i),__ATOMIC_SEQ_CST);
+ if (actVal != expVal) {
+ errCnt = (i << 16) | (1 << 5);
+ return errCnt;
+ }
+ expVal &= ~((uint64_t)1 << i);
+ }
+ //
+ // Exchange
+ //
+ actVal = __atomic_exchange_n(ptr,oriVal,__ATOMIC_SEQ_CST);
+ if (actVal != expVal) {
+ errCnt = (1 << 6);
+ return errCnt;
+ }
+ expVal = oriVal;
+ //
+ // Final load
+ //
+ actVal = __atomic_load_n(ptr,__ATOMIC_SEQ_CST);
+ if (actVal != expVal) {
+ errCnt = 1 << 7;
+ return errCnt;
+ }
+ //
+ return errCnt;
+}
+
//
// KEEP THIS ONE UNDER 64bytes (cache block) and do not change unless ...
//
diff --git a/cosim/drivers/cep_tests/cep_riscv.h b/cosim/drivers/cep_tests/cep_riscv.h
index 2a15ab0..f6b55d8 100644
--- a/cosim/drivers/cep_tests/cep_riscv.h
+++ b/cosim/drivers/cep_tests/cep_riscv.h
@@ -14,6 +14,16 @@
#include
+#define ATOMIC_OP_EXCH 1
+#define ATOMIC_OP_ADD 2
+#define ATOMIC_OP_AND 3
+#define ATOMIC_OP_OR 4
+#define ATOMIC_OP_SUB 5
+#define ATOMIC_OP_XOR 6
+#define ATOMIC_OP_LOAD 7
+#define ATOMIC_OP_STORE 8
+
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -23,6 +33,10 @@ extern "C" {
volatile char get_selfModCodeValue(void) ;
int set_selfModCodeValue(char newByte, int verbose);
int do_DIcache_SMC(uint64_t *smc_base, int blockCnt, int startVal, int verbose);
+ // Atomic stuffs
+ uint64_t cep_atomic_op(uint64_t *ptr, uint64_t val, int OP) ;
+ int cep_runAtomicTest(uint64_t *ptr, uint64_t expVal);
+ int cep_exchAtomicTest(int coreId, uint64_t *ptr, uint64_t mySig, uint64_t partSig, uint64_t incVal, int loop);
// end of extern
#ifdef __cplusplus
diff --git a/cosim/drivers/cep_tests/cepregression.cc b/cosim/drivers/cep_tests/cepregression.cc
index 2fe72e2..f025001 100644
--- a/cosim/drivers/cep_tests/cepregression.cc
+++ b/cosim/drivers/cep_tests/cepregression.cc
@@ -110,6 +110,20 @@ IpCore_st ipCores[CEP_TOTAL_CORES];
// BEGIN: CEP MMAP Utility Functions
//************************************************************************
// cep_read - Read from a CEP address
+uint32_t cep_read32(int device, uint32_t pAddress) {
+#ifdef BARE_MODE
+ return *(volatile uint32_t*)(ipCores[device].address + pAddress);
+#elif SIM_ENV_ONLY
+ uint32_t d32;
+ DUT_READ32_32( ipCores[device].address + pAddress, d32);
+ return d32;
+#elif LINUX_MODE
+ return lnx_cep_read32(ipCores[device].address + pAddress);
+#else
+ return *(uint32_t*)(&(ipCores[device].mem)[pAddress]);
+#endif
+}
+// 64-bits
uint64_t cep_read(int device, uint32_t pAddress) {
#ifdef BARE_MODE
return *(volatile uint64_t*)(ipCores[device].address + pAddress);
@@ -122,13 +136,27 @@ uint64_t cep_read(int device, uint32_t pAddress) {
#else
return *(uint64_t*)(&(ipCores[device].mem)[pAddress]);
#endif
-
}
+
uint64_t get_physical_adr(int device, uint32_t pAddress) {
return (ipCores[device].address + pAddress);
}
// cep_write - Write to a CEP address
+//
+void cep_write32(int device, uint32_t pAddress, uint32_t pData) {
+#ifdef BARE_MODE
+ *(volatile uint32_t*)(ipCores[device].address + pAddress) = pData;
+#elif SIM_ENV_ONLY
+ DUT_WRITE32_32( ipCores[device].address + pAddress, pData);
+#elif LINUX_MODE
+ return lnx_cep_write32(ipCores[device].address + pAddress, pData);
+#else
+ memcpy(ipCores[device].mem + pAddress, &pData, sizeof(pData));
+#endif
+}
+
+//64-bit
void cep_write(int device, uint32_t pAddress, uint64_t pData) {
#ifdef BARE_MODE
*(volatile uint64_t*)(ipCores[device].address + pAddress) = pData;
@@ -140,6 +168,7 @@ void cep_write(int device, uint32_t pAddress, uint64_t pData) {
memcpy(ipCores[device].mem + pAddress, &pData, sizeof(pData));
#endif
}
+
//************************************************************************
// END: CEP MMAP Utility Functions
//************************************************************************
diff --git a/cosim/drivers/cep_tests/cepregression.h b/cosim/drivers/cep_tests/cepregression.h
index e55f59c..d675d2f 100644
--- a/cosim/drivers/cep_tests/cepregression.h
+++ b/cosim/drivers/cep_tests/cepregression.h
@@ -46,6 +46,10 @@ extern "C" {
int cep_SHA256_test(void);
uint64_t get_physical_adr(int device, uint32_t pAddress);
+ // 32-bits
+ void cep_write32(int device, uint32_t pAddress, uint32_t pData);
+ uint32_t cep_read32(int device, uint32_t pAddress);
+ // 64-bits
void cep_write(int device, uint32_t pAddress, uint64_t pData);
uint64_t cep_read(int device, uint32_t pAddress);
diff --git a/cosim/drivers/diag/cepGpioTest.cc b/cosim/drivers/diag/cepGpioTest.cc
new file mode 100644
index 0000000..9b802c7
--- /dev/null
+++ b/cosim/drivers/diag/cepGpioTest.cc
@@ -0,0 +1,114 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+#include
+
+#include "simdiag_global.h"
+#include "cep_adrMap.h"
+#include "cepGpioTest.h"
+
+#include "cep_apis.h"
+#include "portable_io.h"
+
+#ifdef SIM_ENV_ONLY
+#include "simPio.h"
+#endif
+
+
+#ifdef BARE_MODE
+
+#else
+#include "simPio.h"
+#endif
+
+extern void regBaseTest_Construct(regBaseTest_t *me,
+ int target,
+ int accessSize,
+ int seed,
+ int verbose
+ );
+//
+// Overload functions
+//
+int
+cepGpioTest_WriteEntry(regBaseTest_t *me, uint32_t adr, uint64_t dat)
+{
+ DUT_WRITE32_32(adr,dat);
+ return 0;
+}
+
+uint64_t cepGpioTest_ReadEntry(regBaseTest_t *me, uint32_t adr) {
+ uint32_t d32;
+ DUT_READ32_32(adr,d32);
+ return (uint64_t)d32;
+}
+
+//
+// =============================
+// The test itself
+// =============================
+//
+
+int cepGpioTest_runRegTest(int cpuId, int accessSize,int seed, int verbose) {
+
+ int errCnt = 0;
+ //
+ regBaseTest_t *regp; //
+ //
+ cepGpioTest_CREATE(regp,cpuId, accessSize, seed + (cpuId*100),verbose);
+
+ //
+ // start adding register to test
+ //
+ // only 4 bits
+ //
+ // (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_pin , 0xF);
+ (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_input_en , 0xF);
+ (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_output_en , 0xF);
+ // (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_port_output , 0xF);
+ (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_pue , 0xF);
+ (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_ds , 0xF);
+ (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_rise_ie , 0xF);
+ // (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_rise_ip , 0xF);
+ (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_fall_ie , 0xF);
+ //(*regp->AddAReg_p)(regp, gpio_base_addr + gpio_fall_ip , 0xF);
+ (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_high_ie , 0xF);
+ //(*regp->AddAReg_p)(regp, gpio_base_addr + gpio_high_ip , 0xF);
+ (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_low_ie , 0xF);
+ //(*regp->AddAReg_p)(regp, gpio_base_addr + gpio_low_ip , 0xF);
+ // (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_iof_en , 0xF);
+ //(*regp->AddAReg_p)(regp, gpio_base_addr + gpio_iof_sel , 0xF);
+ (*regp->AddAReg_p)(regp, gpio_base_addr + gpio_out_xor , 0xF);
+ //
+ // now do it
+ errCnt = (*regp->doRegTest_p)(regp);
+ //
+ // Destructors
+ //
+ cepGpioTest_DELETE(regp);
+ //
+ //
+ //
+#ifdef SIM_ENV_ONLY
+ for (int i=0;i<4;i++) {
+ DUT_WRITE_DVT(DVTF_PAT_HI, DVTF_PAT_LO, i);
+ DUT_WRITE_DVT(DVTF_GET_CORE_STATUS, DVTF_GET_CORE_STATUS, 1);
+ uint64_t d64 = DUT_READ_DVT(DVTF_PAT_HI, DVTF_PAT_LO);
+ LOGI("CoreId=%d = 0x%016lx\n",i,d64);
+ }
+#endif
+ return errCnt;
+}
+
+int cepGpioTest_runTest(int cpuId, int seed, int verbose) {
+ int errCnt = 0;
+ if (!errCnt) { errCnt += cepGpioTest_runRegTest(cpuId,32, seed, verbose); }
+ return errCnt;
+}
diff --git a/cosim/drivers/diag/cepGpioTest.h b/cosim/drivers/diag/cepGpioTest.h
new file mode 100644
index 0000000..12935a4
--- /dev/null
+++ b/cosim/drivers/diag/cepGpioTest.h
@@ -0,0 +1,40 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+
+#ifndef cepGpioTest_H
+#define cepGpioTest_H
+
+#include "regBaseTest.h"
+
+//
+// Constructor/Destructor
+//
+#define cepGpioTest_CREATE(me,target,accessSize,seed,verbose) \
+ {REGBASETEST_CREATE(me,target,accessSize,seed,verbose); \
+ me->WriteReg_p = cepGpioTest_WriteEntry; \
+ me->ReadReg_p = cepGpioTest_ReadEntry;}
+
+
+#define cepGpioTest_DELETE(me) REGBASETEST_DELETE(me)
+
+
+//
+// Overload functions
+//
+int cepGpioTest_WriteEntry(regBaseTest_t *me, uint32_t adr, uint64_t dat);
+uint64_t cepGpioTest_ReadEntry(regBaseTest_t *me, uint32_t adr);
+//
+// The test itself
+//
+int cepGpioTest_runTest(int cpuId, int seed, int verbose);
+int cepGpioTest_runRegTest(int cpuId, int accessSize,int seed, int verbose);
+
+#endif
diff --git a/cosim/drivers/diag/cepSpiTest.cc b/cosim/drivers/diag/cepSpiTest.cc
new file mode 100644
index 0000000..be027be
--- /dev/null
+++ b/cosim/drivers/diag/cepSpiTest.cc
@@ -0,0 +1,109 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+#include
+
+#include "simdiag_global.h"
+#include "cep_adrMap.h"
+#include "cepSpiTest.h"
+
+#include "cep_apis.h"
+#include "portable_io.h"
+
+#ifdef SIM_ENV_ONLY
+#include "simPio.h"
+#endif
+
+
+#ifdef BARE_MODE
+
+#else
+#include "simPio.h"
+#endif
+
+extern void regBaseTest_Construct(regBaseTest_t *me,
+ int target,
+ int accessSize,
+ int seed,
+ int verbose
+ );
+//
+// Overload functions
+//
+int
+cepSpiTest_WriteEntry(regBaseTest_t *me, uint32_t adr, uint64_t dat)
+{
+ DUT_WRITE32_32(adr,dat);
+ return 0;
+}
+
+uint64_t cepSpiTest_ReadEntry(regBaseTest_t *me, uint32_t adr) {
+ uint32_t d32;
+ DUT_READ32_32(adr,d32);
+ return (uint64_t)d32;
+}
+
+//
+// =============================
+// The test itself
+// =============================
+//
+
+int cepSpiTest_runRegTest(int cpuId, int accessSize,int seed, int verbose) {
+
+ int errCnt = 0;
+ //
+ regBaseTest_t *regp; //
+ //
+ cepSpiTest_CREATE(regp,cpuId, accessSize, seed + (cpuId*100),verbose);
+
+ //
+ // start adding register to test
+ //
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_sckdiv, 0x00000FFF);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_sckmode, 0x00000003);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_csid, 0x00000001);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_csdef, 0x00000001);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_csmode, 0x00000003);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_dcssck, 0x00FF00FF);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_dintercs, 0x00FF00FF);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_extradel, 0x000000FF);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_sampledel, 0x0000001F);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_fmt, 0x000F000F);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_txmark, 0x00000007);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_rxmark, 0x00000007);
+ (*regp->AddAReg_p)(regp, spi_base_addr + spi_ie, 0x00000003);
+ //(*regp->AddAReg_p)(regp, spi_base_addr + spi_insnmode, 0x00000001);
+ //(*regp->AddAReg_p)(regp, spi_base_addr + spi_insnfmt, 0xFFFF3FFF);
+ // now do it
+ errCnt = (*regp->doRegTest_p)(regp);
+ //
+ // Destructors
+ //
+ cepSpiTest_DELETE(regp);
+ //
+ //
+ //
+#ifdef SIM_ENV_ONLY
+ for (int i=0;i<4;i++) {
+ DUT_WRITE_DVT(DVTF_PAT_HI, DVTF_PAT_LO, i);
+ DUT_WRITE_DVT(DVTF_GET_CORE_STATUS, DVTF_GET_CORE_STATUS, 1);
+ uint64_t d64 = DUT_READ_DVT(DVTF_PAT_HI, DVTF_PAT_LO);
+ LOGI("CoreId=%d = 0x%016lx\n",i,d64);
+ }
+#endif
+ return errCnt;
+}
+
+int cepSpiTest_runTest(int cpuId, int seed, int verbose) {
+ int errCnt = 0;
+ if (!errCnt) { errCnt += cepSpiTest_runRegTest(cpuId,32, seed, verbose); }
+ return errCnt;
+}
diff --git a/cosim/drivers/diag/cepSpiTest.h b/cosim/drivers/diag/cepSpiTest.h
new file mode 100644
index 0000000..4b959b9
--- /dev/null
+++ b/cosim/drivers/diag/cepSpiTest.h
@@ -0,0 +1,40 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+
+#ifndef cepSpiTest_H
+#define cepSpiTest_H
+
+#include "regBaseTest.h"
+
+//
+// Constructor/Destructor
+//
+#define cepSpiTest_CREATE(me,target,accessSize,seed,verbose) \
+ {REGBASETEST_CREATE(me,target,accessSize,seed,verbose); \
+ me->WriteReg_p = cepSpiTest_WriteEntry; \
+ me->ReadReg_p = cepSpiTest_ReadEntry;}
+
+
+#define cepSpiTest_DELETE(me) REGBASETEST_DELETE(me)
+
+
+//
+// Overload functions
+//
+int cepSpiTest_WriteEntry(regBaseTest_t *me, uint32_t adr, uint64_t dat);
+uint64_t cepSpiTest_ReadEntry(regBaseTest_t *me, uint32_t adr);
+//
+// The test itself
+//
+int cepSpiTest_runTest(int cpuId, int seed, int verbose);
+int cepSpiTest_runRegTest(int cpuId, int accessSize,int seed, int verbose);
+
+#endif
diff --git a/cosim/drivers/diag/cepSrotTest.cc b/cosim/drivers/diag/cepSrotTest.cc
new file mode 100644
index 0000000..716225c
--- /dev/null
+++ b/cosim/drivers/diag/cepSrotTest.cc
@@ -0,0 +1,299 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+#include
+
+#include "simdiag_global.h"
+#include "cep_adrMap.h"
+#include "cepSrotTest.h"
+#include "CEP.h"
+#include "cepregression.h"
+#include "random48.h"
+
+#include "cep_apis.h"
+#include "portable_io.h"
+
+#ifdef SIM_ENV_ONLY
+#include "simPio.h"
+#endif
+
+
+#ifdef BARE_MODE
+
+#else
+#include "simPio.h"
+#endif
+
+// Helper function for sending a message to the SRoT and waiting for a response
+// Response status will be returned
+uint8_t send_srot_message(int verbose, uint64_t message) {
+ // Temporarily hold the response message
+ uint64_t response_message;
+
+ // Write a word to the LLKI C2 Send FIFO
+ cep_write(SROT_BASE_K, SROT_LLKIC2_SENDRECV_ADDR, message);
+
+ // Poll the response waiting bit
+ do {;} while (!(cep_read(SROT_BASE_K, SROT_CTRLSTS_ADDR) & SROT_CTRLSTS_RESP_WAITING_MASK));
+
+ // Read the response
+ response_message = cep_read(SROT_BASE_K, SROT_LLKIC2_SENDRECV_ADDR);
+
+ // Return the status
+ return((uint8_t)llkic2_extract_status(response_message));
+} // end send_srot_message
+
+
+// Helper function for parsing LLKIC2 message statu
+int parse_message_status(uint8_t message_status, int verbose) {
+
+ // Parse the status field to see if any error occured
+ switch (message_status) {
+ case LLKI_STATUS_GOOD :
+ if (verbose) {
+ LOGI("\n");
+ LOGI("cepSrotTest_runTest: Good message received!\n");
+ LOGI("\n");
+ }
+ break;
+ case LLKI_STATUS_KEY_PRESENT :
+ LOGI("\n");
+ LOGI("cepSrotTest_runTest: LLKI-KL Key Present\n");
+ LOGI("\n");
+ return 0;
+ break;
+ case LLKI_STATUS_KEY_NOT_PRESENT :
+ LOGI("\n");
+ LOGI("cepSrotTest_runTest: LLKI-KL Key Not Present\n");
+ LOGI("\n");
+ return 0;
+ break;
+ case LLKI_STATUS_BAD_MSG_ID :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: Bad message ID\n");
+ LOGE("\n");
+ return 1;
+ break;
+ case LLKI_STATUS_BAD_MSG_LEN :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: Bad message length\n");
+ LOGE("\n");
+ return 1;
+ break;
+ case LLKI_STATUS_KEY_INDEX_EXCEED :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: Key Index exceeds allowable bounds\n");
+ LOGE("\n");
+ return 1;
+ break;
+ case LLKI_STATUS_KEY_INDEX_INVALID :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: Referenced Key Index is not valid\n");
+ LOGE("\n");
+ return 1;
+ break;
+ case LLKI_STATUS_BAD_POINTER_PAIR :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: Referenced Key Index pointer pair is not valid\n");
+ LOGE("\n");
+ return 1;
+ break;
+ case LLKI_STATUS_BAD_CORE_INDEX :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: Referenced Key Index specifies an out of bounds core index\n");
+ LOGE("\n");
+ return 1;
+ break;
+ case LLKI_STATUS_KL_REQ_BAD_MSG_ID :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: LLKI-KL Request Bad Message ID\n");
+ LOGE("\n");
+ return 1;
+ break;
+ case LLKI_STATUS_KL_REQ_BAD_MSG_LEN :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: LLKI-KL Request Bad Message Length\n");
+ LOGE("\n");
+ return 1;
+ break;
+ case LLKI_STATUS_KL_RESP_BAD_MSG_ID :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: LLKI-KL Response Bad Message ID\n");
+ LOGE("\n");
+ return 1;
+ break;
+ case LLKI_STATUS_KL_TILELINK_ERROR :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: LLKI-KL Tilelink Error\n");
+ LOGE("\n");
+ return 1;
+ break;
+ case LLKI_STATUS_UNKNOWN_ERROR :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: Unknown Error\n");
+ LOGE("\n");
+ return 1;
+ break;
+ default :
+ LOGE("\n");
+ LOGE("cepSrotTest_runTest: Unknown message error\n");
+ LOGE("\n");
+ return 1;
+ break;
+ } // end switch (my_message)
+
+} // end parse_message_status
+
+int cepSrotTest_runTest(int cpuId, int seed, int verbose) {
+
+ uint64_t response_message;
+ uint8_t response_status;
+
+ // Initialize the SRoT Key Index RAM
+ LOGI("\n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("cepSrotTest_runTest: Initializing the Key Index RAM... \n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("\n");
+ for (int i = 0; i < SROT_KEYINDEXRAM_SIZE; i++) {
+ cep_write(SROT_BASE_K, SROT_KEYINDEXRAM_ADDR + (i*8), 0x0000000000000000);
+ }
+
+ LOGI("\n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("cepSrotTest_runTest: Loading a key into the Key RAM... \n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("\n");
+ cep_write(SROT_BASE_K, SROT_KEYRAM_ADDR + 0, AES_MOCK_TSS_KEY_0);
+ cep_write(SROT_BASE_K, SROT_KEYRAM_ADDR + 8, AES_MOCK_TSS_KEY_1);
+
+ LOGI("\n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("cepSrotTest_runTest: Loading a valid key index... \n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("\n");
+ cep_write(SROT_BASE_K, SROT_KEYINDEXRAM_ADDR + 0, key_index_pack( 0x0000, // low pointer
+ 0x0001, // high pointer
+ LLKI_AES_CORE_INDEX, // core index
+ 0x1)); // Valid
+
+ LOGI("\n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("cepSrotTest_runTest: Switching the LLKI from DEBUG to OPERATIONAL mode... \n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("\n");
+ cep_write(SROT_BASE_K, SROT_CTRLSTS_ADDR, SROT_CTRLSTS_MODEBIT0_MASK | SROT_CTRLSTS_MODEBIT1_MASK);
+
+ // Set the desired message values
+ LOGI("\n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("cepSrotTest_runTest: Issuing a Load Key Request to the SRoT and waiting \n");
+ LOGI("cepSrotTest_runTest: for the response... \n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("\n");
+ response_status = send_srot_message(verbose, llkic2_pack( LLKI_MID_C2LOADKEYREQ, // Message ID
+ 0x00, // Status (unused)
+ 0x01, // Message Length
+ 0x00, // Key Index
+ 0xDEADBEEF)); // Reserved Field
+
+ // Parse the message status
+ if (parse_message_status(response_status, verbose)) {
+ return 1;
+ }
+
+ // Set the desired message values
+ LOGI("\n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("cepSrotTest_runTest: Issuing a Key Status Request to the SRoT and waiting \n");
+ LOGI("cepSrotTest_runTest: for the response... \n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("\n");
+ // Write a word to the LLKI C2 Send FIFO
+ response_status = send_srot_message(verbose, llkic2_pack( LLKI_MID_C2KEYSTATUSREQ, // Message ID
+ 0x00, // Status (unused)
+ 0x01, // Message Length
+ 0x00, // Key Index
+ 0xDEADBEEF)); // Reserved Field
+ switch (response_status) {
+ case LLKI_STATUS_KEY_PRESENT :
+ LOGI("\n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("cepSrotTest_runTest: Key is present (as expected) \n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("\n");
+ break;
+ case LLKI_STATUS_KEY_NOT_PRESENT :
+ LOGE("\n");
+ LOGE("----------------------------------------------------------------------------\n");
+ LOGE("cepSrotTest_runTest: Key is NOT present (not expected) \n");
+ LOGE("----------------------------------------------------------------------------\n");
+ LOGE("\n");
+ return 1;
+ default:
+ parse_message_status(response_status, verbose);
+ return 1;
+ }
+
+ // Set the desired message values
+ LOGI("\n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("cepSrotTest_runTest: Issuing a Clear Key Request to the SRoT and waiting \n");
+ LOGI("cepSrotTest_runTest: for the response... \n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("\n");
+ response_status = send_srot_message(verbose, llkic2_pack( LLKI_MID_C2CLEARKEYREQ, // Message ID
+ 0x00, // Status (unused)
+ 0x01, // Message Length
+ 0x00, // Key Index
+ 0xDEADBEEF)); // Reserved Field
+ if (parse_message_status(response_status, verbose)) {
+ return 1;
+ }
+
+
+ // Set the desired message values
+ LOGI("\n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("cepSrotTest_runTest: Issuing a Key Status Request to the SRoT and waiting \n");
+ LOGI("cepSrotTest_runTest: for the response... \n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("\n");
+ response_status = send_srot_message(verbose, llkic2_pack( LLKI_MID_C2KEYSTATUSREQ, // Message ID
+ 0x00, // Status (unused)
+ 0x01, // Message Length
+ 0x00, // Key Index
+ 0xDEADBEEF)); // Reserved Field
+
+ switch (response_status) {
+ case LLKI_STATUS_KEY_NOT_PRESENT :
+ LOGI("\n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("cepSrotTest_runTest: Key is NOT present (as expected) \n");
+ LOGI("----------------------------------------------------------------------------\n");
+ LOGI("\n");
+ break;
+ case LLKI_STATUS_KEY_PRESENT :
+ LOGE("\n");
+ LOGE("----------------------------------------------------------------------------\n");
+ LOGE("cepSrotTest_runTest: Key is present (not expected) \n");
+ LOGE("----------------------------------------------------------------------------\n");
+ LOGE("\n");
+ return 1;
+ default:
+ parse_message_status(response_status, verbose);
+ return 1;
+ }
+
+
+ // Complete the test (successfully)
+ return 0;
+
+}
diff --git a/cosim/drivers/diag/cepSrotTest.h b/cosim/drivers/diag/cepSrotTest.h
new file mode 100644
index 0000000..3cf7633
--- /dev/null
+++ b/cosim/drivers/diag/cepSrotTest.h
@@ -0,0 +1,93 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+
+#ifndef cepSrotTest_H
+#define cepSrotTest_H
+
+#include
+#include
+#include
+
+ // ----------------------------------------------------------------------------
+ // LLKI related constants, structures, and function prototypes
+ // ----------------------------------------------------------------------------
+
+ // LLKI Message ID constants
+ const uint8_t LLKI_MID_C2LOADKEYREQ = 0x00;
+ const uint8_t LLKI_MID_C2CLEARKEYREQ = 0x01;
+ const uint8_t LLKI_MID_C2KEYSTATUSREQ = 0x02;
+ const uint8_t LLKI_MID_C2LOADKEYACK = 0x03;
+ const uint8_t LLKI_MID_C2CLEARKEYACK = 0x04;
+ const uint8_t LLKI_MID_C2KEYSTATUSRESP = 0x05;
+ const uint8_t LLKI_MID_C2ERRORRESP = 0x06;
+
+ // LLKI Status Constants
+ const uint8_t LLKI_STATUS_GOOD = 0x00;
+ const uint8_t LLKI_STATUS_KEY_PRESENT = 0x01;
+ const uint8_t LLKI_STATUS_KEY_NOT_PRESENT = 0x02;
+
+ const uint8_t LLKI_STATUS_BAD_MSG_ID = 0x20;
+ const uint8_t LLKI_STATUS_BAD_MSG_LEN = 0x21;
+ const uint8_t LLKI_STATUS_KEY_INDEX_EXCEED = 0x22; // Specified key index exceeds size
+ // of key index ram
+ const uint8_t LLKI_STATUS_KEY_INDEX_INVALID = 0x23;
+ const uint8_t LLKI_STATUS_BAD_POINTER_PAIR = 0x24;
+ const uint8_t LLKI_STATUS_BAD_CORE_INDEX = 0x25;
+ const uint8_t LLKI_STATUS_KL_REQ_BAD_MSG_ID = 0x26;
+ const uint8_t LLKI_STATUS_KL_REQ_BAD_MSG_LEN = 0x27;
+ const uint8_t LLKI_STATUS_KL_RESP_BAD_MSG_ID = 0x28;
+ const uint8_t LLKI_STATUS_KL_TILELINK_ERROR = 0x29;
+ const uint8_t LLKI_STATUS_KL_LOSS_OF_SYNC = 0x30;
+
+ const uint8_t LLKI_STATUS_UNKNOWN_ERROR = 0xFF;
+
+ // LLKI Core Index Constants
+ const uint8_t LLKI_AES_CORE_INDEX = 0x00;
+ const uint8_t LLKI_INVALID_CORE_INDEX = 0xFF;
+
+ const uint8_t LLKI_KEYINDEX_VALID = 0x80;
+
+ // Packing macro for creating an LLKIC2 message to send to the SRoT
+ #define llkic2_pack(msg_id, status, msg_len, key_index, rsvd1) { \
+ (((uint64_t)msg_id << 0) & 0x00000000000000FF) | \
+ (((uint64_t)status << 8) & 0x000000000000FF00) | \
+ (((uint64_t)msg_len << 16) & 0x0000000000FF0000) | \
+ (((uint64_t)key_index << 24) & 0x00000000FF000000) | \
+ (((uint64_t)rsvd1 << 32) & 0xFFFFFFFF00000000) \
+ }
+
+ // Packing macro for creating a Key Index entry
+ #define key_index_pack(low_pointer, high_pointer, core_index, valid) { \
+ (((uint64_t)low_pointer << 0) & 0x000000000000FFFF) | \
+ (((uint64_t)high_pointer << 16) & 0x00000000FFFF0000) | \
+ (((uint64_t)core_index << 32) & 0x000000FF00000000) | \
+ (((uint64_t)valid << 63) & 0x8000000000000000) \
+ }
+
+ // Helper macros for response message processing
+ #define llkic2_extract_status(message) { \
+ (uint8_t)(((uint64_t)message >> 8) & 0x00000000000000FF) \
+ }
+
+ // LLKI helper functions
+ uint8_t send_srot_message(int verbose, uint64_t message);
+ int parse_message_status(uint8_t message_status, int verbose);
+
+ // Mock TSS Keys
+ const uint64_t AES_MOCK_TSS_KEY_0 = 0x0123456789ABCDEF;
+ const uint64_t AES_MOCK_TSS_KEY_1 = 0xFEDCBA9876543210;
+
+ //
+ // The test itself
+ //
+ int cepSrotTest_runTest(int cpuId, int seed, int verbose);
+
+#endif
diff --git a/cosim/drivers/diag/cepUartTest.cc b/cosim/drivers/diag/cepUartTest.cc
new file mode 100644
index 0000000..b91d7c3
--- /dev/null
+++ b/cosim/drivers/diag/cepUartTest.cc
@@ -0,0 +1,164 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+#include
+
+#include "simdiag_global.h"
+#include "cep_adrMap.h"
+#include "cepUartTest.h"
+
+#include "cep_apis.h"
+#include "portable_io.h"
+
+#ifdef SIM_ENV_ONLY
+#include "simPio.h"
+#endif
+
+
+#ifdef BARE_MODE
+
+#else
+#include "simPio.h"
+#endif
+
+extern void regBaseTest_Construct(regBaseTest_t *me,
+ int target,
+ int accessSize,
+ int seed,
+ int verbose
+ );
+//
+// Overload functions
+//
+int
+cepUartTest_WriteEntry(regBaseTest_t *me, uint32_t adr, uint64_t dat)
+{
+ DUT_WRITE32_32(adr,dat);
+ return 0;
+}
+
+uint64_t cepUartTest_ReadEntry(regBaseTest_t *me, uint32_t adr) {
+ uint32_t d32;
+ DUT_READ32_32(adr,d32);
+ return (uint64_t)d32;
+}
+
+//
+// =============================
+// The test itself
+// =============================
+//
+int cepUartTest_runTxRxTest(int cpuId, int divisor, char *txStr, int txLen, int stopBits, int verbose) {
+ int errCnt = 0;
+ //
+ // write divisor register
+ //
+ if (verbose) {
+ LOGI("%s: div=%d str=%s len=%d stop=%d\n",__FUNCTION__,divisor,txStr,txLen,stopBits);
+ }
+ DUT_WRITE32_32(uart_base_addr + uart_div, divisor);
+ int act;
+ DUT_READ32_32(uart_base_addr + uart_div, act);
+ if (act != divisor) {
+ LOGE("%s: mismatch divisor act=0x%x exp=0x%x\n",__FUNCTION__,act,divisor);
+ errCnt++;
+ return errCnt;
+ } else if (verbose) {
+ LOGI("%s: OK divisor act=0x%x exp=0x%x\n",__FUNCTION__,act,divisor);
+ }
+ // enable tx/rx
+ int dat = ((1 << 0) | // txen
+ ((stopBits & 0x1) << 1) ); // 0=1 stop bit, 1=2 stop bits
+ //
+ DUT_WRITE32_32(uart_base_addr + uart_txctrl,dat);
+ DUT_WRITE32_32(uart_base_addr + uart_rxctrl,dat);
+ //
+ int ti=0, ri=0, tmp;
+ char rxDat;
+ while ((ri < txLen) && (!errCnt)) {
+ // TX?
+ if (ti < txLen) { // still more to TX?? (include NULL)
+ DUT_READ32_32(uart_base_addr + uart_txfifo, tmp);
+ if (((tmp >> 31) & 0x1) == 0) { // not full
+ DUT_WRITE32_32(uart_base_addr + uart_txfifo, (uint32_t)txStr[ti]);
+ ti++;
+ }
+ }
+ // any RX?
+ if (ri < txLen) {
+ DUT_READ32_32(uart_base_addr + uart_rxfifo, tmp);
+ if (((tmp >> 31) & 0x1) == 0) { // something in there
+ rxDat = (char)(tmp & 0xff);
+ // check
+ if (rxDat != txStr[ri]) {
+ LOGE("%s: mismatch char ri=%d act=0x%x exp=0x%x\n",__FUNCTION__,rxDat,txStr[ri]);
+ errCnt++;
+ break;
+ } else if (verbose) {
+ LOGI("%s: OK char ri=%d act=0x%x exp=0x%x\n",__FUNCTION__,ri,rxDat,txStr[ri]);
+ ri++;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ // disable
+ DUT_WRITE32_32(uart_base_addr + uart_txctrl,0);
+ DUT_WRITE32_32(uart_base_addr + uart_rxctrl,0);
+ return errCnt;
+}
+
+int cepUartTest_runRegTest(int cpuId, int accessSize,int seed, int verbose) {
+
+ int errCnt = 0;
+ //
+ regBaseTest_t *regp; //
+ //
+ cepUartTest_CREATE(regp,cpuId, accessSize, seed + (cpuId*100),verbose);
+
+ //
+ // start adding register to test
+ //
+ (*regp->AddAReg_p)(regp, uart_base_addr + uart_txctrl, (0x7 << 16) | 0x3);
+ (*regp->AddAReg_p)(regp, uart_base_addr + uart_rxctrl, (0x7 << 16) | 0x1);
+ (*regp->AddAReg_p)(regp, uart_base_addr + uart_ie, 0x3);
+ // (*regp->AddAReg_p)(regp, uart_base_addr + uart_ie, 0xFFFFFFFF);
+ (*regp->AddAReg_p)(regp, uart_base_addr + uart_div, 0xFFFF);
+
+ // now do it
+ errCnt = (*regp->doRegTest_p)(regp);
+ //
+ // Destructors
+ //
+ cepUartTest_DELETE(regp);
+ //
+ //
+ //
+#ifdef SIM_ENV_ONLY
+ for (int i=0;i<4;i++) {
+ DUT_WRITE_DVT(DVTF_PAT_HI, DVTF_PAT_LO, i);
+ DUT_WRITE_DVT(DVTF_GET_CORE_STATUS, DVTF_GET_CORE_STATUS, 1);
+ uint64_t d64 = DUT_READ_DVT(DVTF_PAT_HI, DVTF_PAT_LO);
+ LOGI("CoreId=%d = 0x%016lx\n",i,d64);
+ }
+#endif
+ return errCnt;
+}
+
+int cepUartTest_runTest(int cpuId, int seed, int verbose) {
+ int errCnt = 0;
+ char txStr[] = "Hello";
+ char txStr2[] = "MIT LL";
+ if (!errCnt) { errCnt += cepUartTest_runTxRxTest(cpuId,16, txStr, strlen(txStr), 0, 1); }
+ if (!errCnt) { errCnt += cepUartTest_runTxRxTest(cpuId,24, txStr2, strlen(txStr2),1, 1); }
+ if (!errCnt) { errCnt += cepUartTest_runRegTest(cpuId,32, seed, verbose); }
+ return errCnt;
+}
diff --git a/cosim/drivers/diag/cepUartTest.h b/cosim/drivers/diag/cepUartTest.h
new file mode 100644
index 0000000..6694243
--- /dev/null
+++ b/cosim/drivers/diag/cepUartTest.h
@@ -0,0 +1,42 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name:
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//
+//************************************************************************
+
+#ifndef cepUartTest_H
+#define cepUartTest_H
+
+#include "regBaseTest.h"
+
+//
+// Constructor/Destructor
+//
+#define cepUartTest_CREATE(me,target,accessSize,seed,verbose) \
+ {REGBASETEST_CREATE(me,target,accessSize,seed,verbose); \
+ me->WriteReg_p = cepUartTest_WriteEntry; \
+ me->ReadReg_p = cepUartTest_ReadEntry;}
+
+
+#define cepUartTest_DELETE(me) REGBASETEST_DELETE(me)
+
+
+//
+// Overload functions
+//
+int cepUartTest_WriteEntry(regBaseTest_t *me, uint32_t adr, uint64_t dat);
+uint64_t cepUartTest_ReadEntry(regBaseTest_t *me, uint32_t adr);
+//
+// The test itself
+//
+int cepUartTest_runTest(int cpuId, int seed, int verbose);
+
+int cepUartTest_runRegTest(int cpuId, int accessSize,int seed, int verbose);
+int cepUartTest_runTxRxTest(int cpuId, int divisor, char *txStr, int txLen, int stopBits, int verbose);
+
+#endif
diff --git a/cosim/drivers/diag/random48.cc b/cosim/drivers/diag/random48.cc
index 6b86576..6428df7 100644
--- a/cosim/drivers/diag/random48.cc
+++ b/cosim/drivers/diag/random48.cc
@@ -3,32 +3,32 @@
//
#include "random48.h"
-static volatile u_long Random48_customDiagRandomNumber= 0;
+static volatile uint64_t Random48_customDiagRandomNumber= 0;
-void Random48_srand48 (u_long seed) {
+void Random48_srand48 (uint64_t seed) {
Random48_customDiagRandomNumber = seed;
}
-u_long Random48_mrand48 (void) {
- u_long a = 48271; // multiplier (see Fishman & Moore)
- u_long m = 2147483647; // modulus = 2^31-1
- u_long q = 44488; // quotient = m div a
- u_long r = 3399; // remainder = m mod a
- u_long divQ = Random48_customDiagRandomNumber/q;
- u_long modQ = Random48_customDiagRandomNumber%q;
- u_long newValue = a*modQ - r*divQ;
- return Random48_customDiagRandomNumber = (newValue > 0)? (u_long)newValue: ((u_long)newValue + m);
+uint64_t Random48_mrand48 (void) {
+ uint64_t a = 48271; // multiplier (see Fishman & Moore)
+ uint64_t m = 2147483647; // modulus = 2^31-1
+ uint64_t q = 44488; // quotient = m div a
+ uint64_t r = 3399; // remainder = m mod a
+ uint64_t divQ = Random48_customDiagRandomNumber/q;
+ uint64_t modQ = Random48_customDiagRandomNumber%q;
+ uint64_t newValue = a*modQ - r*divQ;
+ return Random48_customDiagRandomNumber = (newValue > 0)? (uint64_t)newValue: ((uint64_t)newValue + m);
}
-u_long Random48_mrand48_custom (u_long *Random48_customDiagRandomNumber) {
- u_long a = 48271; // multiplier (see Fishman & Moore)
- u_long m = 2147483647; // modulus = 2^31-1
- u_long q = 44488; // quotient = m div a
- u_long r = 3399; // remainder = m mod a
- u_long divQ = *Random48_customDiagRandomNumber/q;
- u_long modQ = *Random48_customDiagRandomNumber%q;
- u_long newValue = a*modQ - r*divQ;
- return *Random48_customDiagRandomNumber = (newValue > 0)? (u_long)newValue: ((u_long)newValue + m);
+uint64_t Random48_mrand48_custom (uint64_t *Random48_customDiagRandomNumber) {
+ uint64_t a = 48271; // multiplier (see Fishman & Moore)
+ uint64_t m = 2147483647; // modulus = 2^31-1
+ uint64_t q = 44488; // quotient = m div a
+ uint64_t r = 3399; // remainder = m mod a
+ uint64_t divQ = *Random48_customDiagRandomNumber/q;
+ uint64_t modQ = *Random48_customDiagRandomNumber%q;
+ uint64_t newValue = a*modQ - r*divQ;
+ return *Random48_customDiagRandomNumber = (newValue > 0)? (uint64_t)newValue: ((uint64_t)newValue + m);
}
int Random48_rand(void) {
diff --git a/cosim/drivers/diag/random48.h b/cosim/drivers/diag/random48.h
index c6a490f..8fff45f 100644
--- a/cosim/drivers/diag/random48.h
+++ b/cosim/drivers/diag/random48.h
@@ -5,16 +5,18 @@
#include
#include
+#include
+
//#include
#include "simdiag_global.h"
//
// random generator
//
-extern void Random48_srand48(u_long seed);
-extern u_long Random48_mrand48 (void);
+extern void Random48_srand48(uint64_t seed);
+extern uint64_t Random48_mrand48 (void);
extern int Random48_rand(void);
-extern u_long Random48_mrand48_custom (u_long *Random48_customDiagRandomNumber);
+extern uint64_t Random48_mrand48_custom (uint64_t *Random48_customDiagRandomNumber);
#endif // RANDOM48_H
diff --git a/cosim/drivers/linux/cep_diag.cc b/cosim/drivers/linux/cep_diag.cc
index b02358f..d838ec3 100644
--- a/cosim/drivers/linux/cep_diag.cc
+++ b/cosim/drivers/linux/cep_diag.cc
@@ -59,6 +59,7 @@ typedef struct p2vMap {
p2vMap_st _cepMap;
p2vMap_st _ddr3Map;
+p2vMap_st _otherMap; // spi/UART
//
// offs can be full address as well since it will be masked off
@@ -70,6 +71,16 @@ void lnx_cep_write(u_int32_t offs,u_int64_t pData) {
memcpy(_cepMap.mem + (offs & _cepMap.mask) , &pData, sizeof(pData));
}
+//
+// Access to SPI/UART Only
+//
+u_int32_t lnx_cep_read32(u_int32_t offs) {
+ return *(u_int32_t*)(&(_otherMap.mem)[offs & _otherMap.mask]);
+}
+void lnx_cep_write32(u_int32_t offs,u_int32_t pData) {
+ memcpy(_otherMap.mem + (offs & _otherMap.mask) , &pData, sizeof(pData));
+}
+
//
// DDR3
//
@@ -129,6 +140,23 @@ static int do_cep_map() {
}
}
//
+ // SPI/UART
+ //
+ _otherMap.phy_address = other_base_addr;
+ _otherMap.pagesize = other_base_size;
+ _otherMap.mask = _otherMap.pagesize -1;
+ _otherMap.fd = open("/dev/mem",O_RDWR|O_SYNC);
+ if (_otherMap.fd < 0) {
+ printf("ERROR: **** Can't open /dev/mem for OTHER @0x%016lx\n", _otherMap.phy_address);
+ return 1;
+ } else {
+ _otherMap.mem = (unsigned char *)mmap(0, _otherMap.pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, _otherMap.fd, _otherMap.phy_address);
+ if (_otherMap.mem == MAP_FAILED) {
+ printf("ERROR: **** Can't map memory %zu for OTHER\n", _otherMap.phy_address);
+ return 1;
+ }
+ }
+ //
Print_CepBuildDate();
return 0;
}
diff --git a/cosim/drivers/linux/cep_diag.h b/cosim/drivers/linux/cep_diag.h
index 33ed41d..af155fa 100644
--- a/cosim/drivers/linux/cep_diag.h
+++ b/cosim/drivers/linux/cep_diag.h
@@ -38,6 +38,8 @@ extern "C" {
//
u_int64_t lnx_cep_read(u_int32_t offs);
void lnx_cep_write(u_int32_t offs,u_int64_t pData);
+ u_int32_t lnx_cep_read32(u_int32_t offs);
+ void lnx_cep_write32(u_int32_t offs,u_int32_t pData);
//
u_int64_t lnx_mem_read(u_int32_t offs);
void lnx_mem_write(u_int32_t offs,u_int64_t pData);
diff --git a/cosim/dvt/aes_capture.incl b/cosim/dvt/aes_capture.incl
index 036af9b..9d2f973 100644
--- a/cosim/dvt/aes_capture.incl
+++ b/cosim/dvt/aes_capture.incl
@@ -24,10 +24,10 @@ int AES_fd;
always @(posedge c2c_capture_enable[`DVTF_AES_CAPTURE_EN_BIT]) begin
$display("Enable cycle-by-cycle capturing of AES stimulus");
// wait until it gets out of reset
- if (cep_tb.fpga.topDesign.topMod.aes.blackbox.rst)
- @(negedge cep_tb.fpga.topDesign.topMod.aes.blackbox.rst);
+ if (cep_tb.fpga.topDesign.topMod.aesmodule.aes_192_mock_tss_inst.rst)
+ @(negedge cep_tb.fpga.topDesign.topMod.aesmodule.aes_192_mock_tss_inst.rst);
// next clock
- @(posedge cep_tb.fpga.topDesign.topMod.aes.blackbox.clk);
+ @(posedge cep_tb.fpga.topDesign.topMod.aesmodule.aes_192_mock_tss_inst.clk);
CaptureAES_vector=1;
AES_fd=$fopen("../../drivers/vectors/aes_stimulus.txt","w");
captureAES_Stimulus();
@@ -35,7 +35,7 @@ end
always @(negedge c2c_capture_enable[`DVTF_AES_CAPTURE_EN_BIT]) begin
if (CaptureAES_vector) begin
CaptureAES_vector=0;
- repeat (2) @(posedge cep_tb.fpga.topDesign.topMod.aes.blackbox.clk);
+ repeat (2) @(posedge cep_tb.fpga.topDesign.topMod.aesmodule.aes_192_mock_tss_inst.clk);
$display("Stop Capturing AES stimulus");
$fwrite(AES_fd,"};\n");
$fwrite(AES_fd,"`define AES_SAMPLE_COUNT %d\n",AES_sampleNum);
@@ -72,7 +72,7 @@ end
//
// wait until valid in to interleaver
while (CaptureAES_vector) begin
- @(negedge cep_tb.fpga.topDesign.topMod.aes.blackbox.clk);
+ @(negedge cep_tb.fpga.topDesign.topMod.aesmodule.aes_192_mock_tss_inst.clk);
// MUST align to HEX number if _ is used!!!
if (AES_sampleNum>0) begin
$fwrite(AES_fd," ,");
@@ -80,11 +80,11 @@ end
$fwrite(AES_fd," ");
end
$fwrite(AES_fd,"'h%x_%x_%x_%x_%x\n",
- {3'b0,cep_tb.fpga.topDesign.topMod.aes.blackbox.start},
- cep_tb.fpga.topDesign.topMod.aes.blackbox.key[191:0],
- cep_tb.fpga.topDesign.topMod.aes.blackbox.state[127:0],
- {3'b0,cep_tb.fpga.topDesign.topMod.aes.blackbox.out_valid},
- cep_tb.fpga.topDesign.topMod.aes.blackbox.out[127:0]);
+ {3'b0,cep_tb.fpga.topDesign.topMod.aesmodule.aes_192_mock_tss_inst.start},
+ cep_tb.fpga.topDesign.topMod.aesmodule.aes_192_mock_tss_inst.key[191:0],
+ cep_tb.fpga.topDesign.topMod.aesmodule.aes_192_mock_tss_inst.state[127:0],
+ {3'b0,cep_tb.fpga.topDesign.topMod.aesmodule.aes_192_mock_tss_inst.out_valid},
+ cep_tb.fpga.topDesign.topMod.aesmodule.aes_192_mock_tss_inst.out[127:0]);
AES_sampleNum++;
end // while (1)
end
diff --git a/cosim/dvt/behav_models/cep_driver.v b/cosim/dvt/behav_models/cep_driver.v
index 0b98c45..679a04b 100644
--- a/cosim/dvt/behav_models/cep_driver.v
+++ b/cosim/dvt/behav_models/cep_driver.v
@@ -295,6 +295,29 @@ begin
end
endtask // WRITE32_64_TASK
+`define SHIPC_WRITE32_32_TASK WRITE32_32_DPI()
+task WRITE32_32_DPI;
+ reg [63:0] d;
+ reg [7:0] mask;
+begin
+ //`logI("%m a=%x d=%x",a,d);
+ //
+ if (inBox.mAdr[2]) mask = 'hF0;
+ else mask = 'h0F;
+ //
+ d[63:32] = inBox.mPar[0];
+ d[31:0] = inBox.mPar[0];
+`ifdef BFM_MODE
+ case (MY_LOCAL_ID)
+ 0: `CORE0_TL_PATH.tl_a_ul_write_generic(MY_LOCAL_ID & 'h1, inBox.mAdr,d,mask);
+ 1: `CORE1_TL_PATH.tl_a_ul_write_generic(MY_LOCAL_ID & 'h1, inBox.mAdr,d,mask);
+ 2: `CORE2_TL_PATH.tl_a_ul_write_generic(MY_LOCAL_ID & 'h1, inBox.mAdr,d,mask);
+ 3: `CORE3_TL_PATH.tl_a_ul_write_generic(MY_LOCAL_ID & 'h1, inBox.mAdr,d,mask);
+ endcase // case (MY_LOCAL_ID)
+`endif
+end
+endtask // WRITE32_64_TASK
+
`else
// ================= OLD PLI
@@ -317,8 +340,6 @@ begin
3: `CORE3_TL_PATH.tl_x_ul_write(MY_LOCAL_ID & 'h1, a, d);
endcase // case (MY_LOCAL_ID)
end // else: !if(backdoor_enable)
-`else
- cep_tb.write_ddr3_backdoor(a,d);
`endif
end
endtask // WRITE32_64_TASK
@@ -355,6 +376,27 @@ reg [63:0] d;
//`logI("%m a=%x d=%x",a,d);
end
endtask // READ32_64_TASK
+
+`define SHIPC_READ32_32_TASK READ32_32_DPI()
+task READ32_32_DPI;
+ reg [63:0] d;
+ reg [7:0] mask;
+ begin
+ if (inBox.mAdr[2]) mask = 'hF0;
+ else mask = 'h0F;
+`ifdef BFM_MODE
+ case (MY_LOCAL_ID)
+ 0: `CORE0_TL_PATH.tl_x_ul_read_generic(MY_LOCAL_ID & 'h1, inBox.mAdr, mask, d);
+ 1: `CORE1_TL_PATH.tl_x_ul_read_generic(MY_LOCAL_ID & 'h1, inBox.mAdr, mask, d);
+ 2: `CORE2_TL_PATH.tl_x_ul_read_generic(MY_LOCAL_ID & 'h1, inBox.mAdr, mask, d);
+ 3: `CORE3_TL_PATH.tl_x_ul_read_generic(MY_LOCAL_ID & 'h1, inBox.mAdr, mask, d);
+ endcase // case (MY_LOCAL_ID)
+ inBox.mPar[0] = inBox.mAdr[2] ? d[63:32] : d[31:0];
+`endif
+ //`logI("%m a=%x d=%x",a,d);
+end
+endtask // READ32_64_TASK
+
`else
// -------------- OLD PLI
`define SHIPC_READ32_64_TASK READ32_64_TASK(__shIpc_address[31:0],{__shIpc_p0[31:0],__shIpc_p1[31:0]})
@@ -556,11 +598,12 @@ endtask // READ32_64_TASK
force `CORE0_PATH.core.reset =1;
end
end
- assign pcPass = (`CORE0_PC[30:0] === passFail[0][30:0]) ||
- ((`CORE0_PC[30:0] == passFail[2][30:0]) && (passFail[2][30:0] != 0)) ||
- ((`CORE0_PC[30:0] == passFail[3][30:0]) && (passFail[3][30:0] != 0) && checkToHost);
+ assign pcPass = `CORE0_VALID &&
+ ((`CORE0_PC[30:0] === passFail[0][30:0]) ||
+ ((`CORE0_PC[30:0] == passFail[2][30:0]) && (passFail[2][30:0] != 0)) ||
+ ((`CORE0_PC[30:0] == passFail[3][30:0]) && (passFail[3][30:0] != 0) && checkToHost));
- assign pcFail = (`CORE0_PC[30:0] === passFail[1][30:0]);
+ assign pcFail = `CORE0_VALID && (`CORE0_PC[30:0] === passFail[1][30:0]);
end
else if (MY_LOCAL_ID == 1) begin
always @(posedge pcPass or posedge pcFail) begin
@@ -572,10 +615,11 @@ endtask // READ32_64_TASK
force `CORE1_PATH.core.reset =1;
end
end
- assign pcPass = (`CORE1_PC[30:0] === passFail[0][30:0]) ||
- ((`CORE1_PC[30:0] == passFail[2][30:0]) && (passFail[2][30:0] != 0)) ||
- ((`CORE1_PC[30:0] == passFail[3][30:0]) && (passFail[3][30:0] != 0) && checkToHost);
- assign pcFail = (`CORE1_PC[30:0] === passFail[1][30:0]);
+ assign pcPass = `CORE1_VALID &&
+ ((`CORE1_PC[30:0] === passFail[0][30:0]) ||
+ ((`CORE1_PC[30:0] == passFail[2][30:0]) && (passFail[2][30:0] != 0)) ||
+ ((`CORE1_PC[30:0] == passFail[3][30:0]) && (passFail[3][30:0] != 0) && checkToHost));
+ assign pcFail = `CORE1_VALID && (`CORE1_PC[30:0] === passFail[1][30:0]);
end
else if (MY_LOCAL_ID == 2) begin
always @(posedge pcPass or posedge pcFail) begin
@@ -587,10 +631,11 @@ endtask // READ32_64_TASK
force `CORE2_PATH.core.reset =1;
end
end
- assign pcPass = (`CORE2_PC[30:0] === passFail[0][30:0]) ||
- ((`CORE2_PC[30:0] == passFail[2][30:0]) && (passFail[2][30:0] != 0)) ||
- ((`CORE2_PC[30:0] == passFail[3][30:0]) && (passFail[3][30:0] != 0) && checkToHost);
- assign pcFail = (`CORE2_PC[30:0] === passFail[1][30:0]);
+ assign pcPass = `CORE2_VALID &&
+ ((`CORE2_PC[30:0] === passFail[0][30:0]) ||
+ ((`CORE2_PC[30:0] == passFail[2][30:0]) && (passFail[2][30:0] != 0)) ||
+ ((`CORE2_PC[30:0] == passFail[3][30:0]) && (passFail[3][30:0] != 0) && checkToHost));
+ assign pcFail = `CORE2_VALID && (`CORE2_PC[30:0] === passFail[1][30:0]);
end
else if (MY_LOCAL_ID == 3) begin
always @(posedge pcPass or posedge pcFail) begin
@@ -602,10 +647,11 @@ endtask // READ32_64_TASK
force `CORE3_PATH.core.reset =1;
end
end
- assign pcPass = (`CORE3_PC[30:0] === passFail[0][30:0]) ||
- ((`CORE3_PC[30:0] == passFail[3][30:0]) && (passFail[3][30:0] != 0)) |
- ((`CORE3_PC[30:0] == passFail[2][30:0]) && (passFail[2][30:0] != 0) && checkToHost);
- assign pcFail = (`CORE3_PC[30:0] === passFail[1][30:0]);
+ assign pcPass = `CORE3_VALID &&
+ ((`CORE3_PC[30:0] === passFail[0][30:0]) ||
+ ((`CORE3_PC[30:0] == passFail[3][30:0]) && (passFail[3][30:0] != 0)) |
+ ((`CORE3_PC[30:0] == passFail[2][30:0]) && (passFail[2][30:0] != 0) && checkToHost));
+ assign pcFail = `CORE3_VALID && (`CORE3_PC[30:0] === passFail[1][30:0]);
end
endgenerate
`endif // `ifdef RISCV_TESTS
diff --git a/cosim/dvt/behav_models/tl_master_beh.v b/cosim/dvt/behav_models/tl_master_beh.v
index 7da1a81..5cd7f3f 100644
--- a/cosim/dvt/behav_models/tl_master_beh.v
+++ b/cosim/dvt/behav_models/tl_master_beh.v
@@ -280,7 +280,7 @@ module tl_master_beh
if (!tl_err &&
((tl_master_d_bits_opcode != `TL_D_ACCESSACKDATA) ||
(tl_master_d_bits_param != 0) ||
- (tl_master_d_bits_size != 3) ||
+// (tl_master_d_bits_size != 3) ||
(tl_master_d_bits_source != src_id) ||
(tl_master_d_bits_denied) ||
(tl_master_d_bits_corrupt))) begin
@@ -296,6 +296,79 @@ module tl_master_beh
end
endtask
+ task tl_x_ul_read_generic;
+ input [SRC_SIZE-1:0] src_id;
+ input [ADR_WIDTH-1:0] a;
+ input [BUS_SIZE-1:0] mask;
+ output [DATA_WIDTH-1:0] d;
+ //
+ begin
+ checkReset();
+ if (tl_err) disable tl_a_ul_read;
+ //`logI("%m : src=%d a=0x%x %t",src_id,a,$time);
+ //
+ // use negedge to drive output
+ @(posedge clock); `TICK_DELAY;
+ tl_master_a_bits_opcode = `TL_A_GET;
+ tl_master_a_bits_param = 0; // must
+ if (mask == ((1<PrintVerbose("access::Write64_64 mSlotId=%d mLocalId=%d address=%016llx dat=%016llx\n",
+ mSlotId,mLocalId,address,data);
+ }
+ ptr->Write32_32(address,data);
+#endif
+#else
+ *reinterpret_cast(address) = data;
+#endif
+
+}
+
+
void access::Write32_64(u_int32_t address, u_int64_t data) {
#ifdef SIM_ENV_ONLY
#ifdef DLL_SIM
@@ -134,6 +151,18 @@ unsigned access::GetSimClk() {
return dat;
}
+u_int32_t access::Read32_32(u_int32_t address) {
+ u_int32_t data=0;
+#ifdef SIM_ENV_ONLY
+ //shIpc *ptr = GlobalShMemory.getIpcPtr(GetSlotId(),GetLocalId());
+ data = ptr->Read32_32(address);
+ if (0) { // GetVerbose()) {
+ ptr->PrintPostVerbose("access::Read32_32 mSlotId=%d mLocalId=%d address=%08x dat=%016llx\n",mSlotId,mLocalId,address,data);
+ }
+#endif
+ return data;
+}
+
u_int64_t access::Read32_64(u_int32_t address) {
u_int64_t data=0;
#ifdef SIM_ENV_ONLY
diff --git a/cosim/share/access.h b/cosim/share/access.h
index 8919b62..a205b85 100644
--- a/cosim/share/access.h
+++ b/cosim/share/access.h
@@ -85,12 +85,14 @@ class access {
//
// Address is Byte Address
//
+ void Write32_32(u_int32_t address, u_int32_t dat);
void Write32_64(u_int32_t address, u_int64_t dat);
void Write64_64(u_int64_t address, u_int64_t dat);
unsigned GetSimClk();
void SimCheckPoint(char *saveFile);
+ u_int32_t Read32_32(u_int32_t address);
u_int64_t Read32_64(u_int32_t address);
u_int64_t Read64_64(u_int64_t address);
//
diff --git a/cosim/share/portable_io.h b/cosim/share/portable_io.h
index 829492a..3561698 100644
--- a/cosim/share/portable_io.h
+++ b/cosim/share/portable_io.h
@@ -53,6 +53,9 @@
#define DUT_WRITE32_64(a,d) sim_Write64_64(a,d)
#define DUT_READ32_64(a,d) d=sim_Read64_64(a)
+#define DUT_WRITE32_32(a,d) sim_Write32_32(a,d)
+#define DUT_READ32_32(a,d) d=sim_Read32_32(a)
+
#define DDR3_WRITE(a,d) sim_Write64_64(a,d)
#define DDR3_READ(a,d) d=sim_Read64_64(a)
@@ -60,6 +63,9 @@
#define DUT_WRITE32_64(a,d) sim_Write32_64(a,d)
#define DUT_READ32_64(a,d) d=sim_Read32_64(a)
+#define DUT_WRITE32_32(a,d) sim_Write32_32(a,d)
+#define DUT_READ32_32(a,d) d=sim_Read32_32(a)
+
#define DDR3_WRITE(a,d) sim_Write32_64(a,d)
#define DDR3_READ(a,d) d=sim_Read32_64(a)
@@ -93,6 +99,9 @@
#define DUT_WRITE32_64(a,d) lnx_cep_write(a,d)
#define DUT_READ32_64(a,d) { d = lnx_cep_read(a); }
+#define DUT_WRITE32_32(a,d) lnx_cep_write32(a,(int)d)
+#define DUT_READ32_32(a,d) { d = (int)lnx_cep_read32(a); }
+
#define DDR3_WRITE(a,d) *(volatile uint64_t *)((intptr_t)a)=d
#define DDR3_READ(a,d) d=*(volatile uint64_t *)((intptr_t)a)
@@ -125,6 +134,9 @@
#define DUT_WRITE32_64(a,d) *reinterpret_cast(a)=d
#define DUT_READ32_64(a,d) d=*reinterpret_cast(a)
+#define DUT_WRITE32_32(a,d) *reinterpret_cast(a)=d
+#define DUT_READ32_32(a,d) d=*reinterpret_cast(a)
+
#define DDR3_WRITE(a,d) *reinterpret_cast(a)=d
#define DDR3_READ(a,d) d=*reinterpret_cast(a)
diff --git a/cosim/share/shIpc.cc b/cosim/share/shIpc.cc
index 9843876..fed9f09 100644
--- a/cosim/share/shIpc.cc
+++ b/cosim/share/shIpc.cc
@@ -529,6 +529,14 @@ void shIpc::Write12Bytes2Mailbox(int wordPos, u_int32_t *data) {
// 64-bit addeess space
// ==========================================
//
+void shIpc::Write32_32(u_int32_t adr, u_int32_t dat) {
+ mAdr = adr;
+ // Set data stuff
+ mPar[0] = dat;
+ // set cmd
+ SendCmdNwait(SHIPC_WRITE32_32);
+}
+
void shIpc::Write64_64(u_int64_t adr, u_int64_t dat) {
mAdr = adr;
// Set data stuff
@@ -555,6 +563,14 @@ void shIpc::Write64_32(u_int64_t adr, u_int32_t dat) {
SendCmdNwait(SHIPC_WRITE64_32);
}
+u_int32_t shIpc::Read32_32(u_int32_t adr) {
+ mAdr = adr;
+ // set cmd
+ SendCmdNwait(SHIPC_READ32_32);
+ // Set data stuff
+ return mPar[0];
+}
+
u_int64_t shIpc::Read64_64(u_int64_t adr) {
mAdr = adr;
// set cmd
diff --git a/cosim/share/shIpc.h b/cosim/share/shIpc.h
index 82b5f85..3edc0f9 100644
--- a/cosim/share/shIpc.h
+++ b/cosim/share/shIpc.h
@@ -196,9 +196,12 @@ class shIpc {
// 64-bit addeess space
// ==========================================
//
+ void Write32_32(u_int32_t adr, u_int32_t dat) ;
void Write64_32(u_int64_t adr, u_int32_t dat) ;
void Write64_64(u_int64_t adr, u_int64_t dat) ;
- void Write32_64(u_int32_t adr, u_int64_t dat) ;
+ void Write32_64(u_int32_t adr, u_int64_t dat) ;
+
+ u_int32_t Read32_32(u_int32_t adr) ;
u_int32_t Read64_32(u_int64_t adr) ;
u_int64_t Read64_64(u_int64_t adr) ;
u_int64_t Read32_64(u_int32_t adr) ;
diff --git a/cosim/simDiag/simPio.cc b/cosim/simDiag/simPio.cc
index 482b7a6..cc24ff4 100644
--- a/cosim/simDiag/simPio.cc
+++ b/cosim/simDiag/simPio.cc
@@ -28,8 +28,10 @@ u_long curTarget = 0;
simPio gCpu;
void sim_RunClk(int a) { access axc; axc.RunClk(a); }
+u_int32_t sim_Read32_32(u_int32_t adr) { access axc; return axc.Read32_32(adr); }
u_int64_t sim_Read32_64(u_int32_t adr) { access axc; return axc.Read32_64(adr); }
u_int64_t sim_Read64_64(u_int64_t adr) { access axc; return axc.Read64_64(adr); }
+void sim_Write32_32(u_int32_t adr, u_int32_t data) { access axc; axc.Write32_32(adr,data); }
void sim_Write32_64(u_int32_t adr, u_int64_t data) { access axc; axc.Write32_64(adr,data); }
void sim_Write64_64(u_int64_t adr, u_int64_t data) { access axc; axc.Write64_64(adr,data); }
void sim_Framer_RdWr(u_int32_t adr, u_int32_t wrDat, u_int32_t *rdDat) { access axc; axc.Framer_RdWr(adr,wrDat,rdDat); }
diff --git a/cosim/simDiag/simPio.h b/cosim/simDiag/simPio.h
index 6def91e..f0e894b 100644
--- a/cosim/simDiag/simPio.h
+++ b/cosim/simDiag/simPio.h
@@ -38,8 +38,10 @@ extern simPio gCpu;
extern "C" {
void sim_RunClk(int a);
u_int64_t sim_Read32_64(u_int32_t adr);
+ u_int32_t sim_Read32_32(u_int32_t adr);
u_int64_t sim_Read64_64(u_int64_t adr);
void sim_Write32_64(u_int32_t adr, u_int64_t data);
+ void sim_Write32_32(u_int32_t adr, u_int32_t data);
void sim_Write64_64(u_int64_t adr, u_int64_t data);
void sim_WriteDvtFlag(int msb, int lsb, int val) ;
u_int64_t sim_ReadDvtFlag(int msb, int lsb) ;
diff --git a/CEP_SecEvalTargets.pdf b/doc/CEP_SecEvalTargets.pdf
similarity index 100%
rename from CEP_SecEvalTargets.pdf
rename to doc/CEP_SecEvalTargets.pdf
diff --git a/cep_logo.jpg b/doc/cep_logo.jpg
similarity index 100%
rename from cep_logo.jpg
rename to doc/cep_logo.jpg
diff --git a/cep_logo.txt b/doc/cep_logo.txt
similarity index 100%
rename from cep_logo.txt
rename to doc/cep_logo.txt
diff --git a/doc/cep_v3.0_architecture.jpg b/doc/cep_v3.0_architecture.jpg
new file mode 100644
index 0000000..d3315b8
Binary files /dev/null and b/doc/cep_v3.0_architecture.jpg differ
diff --git a/doc/related_logos.jpg b/doc/related_logos.jpg
new file mode 100644
index 0000000..aaf4a0e
Binary files /dev/null and b/doc/related_logos.jpg differ
diff --git a/doc/version.jpg b/doc/version.jpg
new file mode 100644
index 0000000..2a05206
Binary files /dev/null and b/doc/version.jpg differ
diff --git a/get_external_dependencies.sh b/get_external_dependencies.sh
index cac5f27..8b9ddca 100755
--- a/get_external_dependencies.sh
+++ b/get_external_dependencies.sh
@@ -33,7 +33,7 @@ declare -a repo_names=( "#"
"# The following dependencies are related to the Freedom U500 Platform"
"#"
#"GITHUB https://github.com/sifive/freedom f8b917d ./hdl_cores/freedom"
- "GITHUB https://github.com/sifive/fpga-shells 0883312 ./hdl_cores/freedom/fpga-shells"
+ #"GITHUB https://github.com/sifive/fpga-shells 0883312 ./hdl_cores/freedom/fpga-shells"
"GITHUB https://github.com/sifive/sifive-blocks 12bdbe5 ./hdl_cores/freedom/sifive-blocks"
"#"
"# The following dependencies are related to the Rocket Chip"
@@ -45,6 +45,10 @@ declare -a repo_names=( "#"
"GITHUB https://github.com/ucb-bar/riscv-torture 77195ab ./hdl_cores/freedom/rocket-chip/torture"
"GITHUB https://github.com/chipsalliance/api-config-chipsalliance d619ca8 ./hdl_cores/freedom/rocket-chip/api-config-chipsalliance"
"#"
+ "# The following dependencies are related to OpenTitan"
+ "#"
+ "GITHUB https://github.com/lowRISC/opentitan 14b1b20 ./opentitan"
+ "#"
"# The following dependencies are related to the RISC-V GNU Toolchain"
"#"
"GITHUB https://github.com/riscv/riscv-gnu-toolchain 6d2706f ./software/riscv-gnu-toolchain"
diff --git a/hdl_cores/aes/aes_192_mock_tss.sv b/hdl_cores/aes/aes_192_mock_tss.sv
new file mode 100644
index 0000000..4223b3b
--- /dev/null
+++ b/hdl_cores/aes/aes_192_mock_tss.sv
@@ -0,0 +1,251 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name: aes_192_mock_tss.sv
+// Program: Common Evaluation Platform (CEP)
+// Description:
+// Notes:
+//************************************************************************
+`timescale 1ns/1ns
+
+module aes_192_mock_tss import llki_pkg::*; (
+
+ // Clock and Reset
+ input wire clk,
+ input wire rst,
+
+ // Core I/O
+ input wire start,
+ input wire [127:0] state,
+ input wire [191:0] key,
+ output wire [127:0] out,
+ output wire out_valid,
+
+ // LLKI Discrete I/O
+ input [63:0] llkid_key_data,
+ input llkid_key_valid,
+ output reg llkid_key_ready,
+ output reg llkid_key_complete,
+ input llkid_clear_key,
+ output reg llkid_clear_key_ack
+
+);
+
+ reg [127:0] llkid_key_register;
+ wire [127:0] mock_tss_state;
+ reg [7:0] wait_state_counter;
+ MOCKTSS_STATE_TYPE current_state;
+
+ //------------------------------------------------------------------
+ // Mock TSS State Machine
+ //
+ // The Mock TSS introduces artificial wait states to demonstrate
+ // a delay when loading or clearing keys
+ //------------------------------------------------------------------
+ always @(posedge clk or posedge rst)
+ begin
+ if (rst) begin
+ llkid_key_ready <= '1;
+ llkid_key_complete <= '0;
+ llkid_clear_key_ack <= '0;
+ llkid_key_register <= '0;
+ wait_state_counter <= MOCKTSS_WAIT_STATE_COUNTER_INIT;
+ current_state <= ST_MOCKTSS_IDLE;
+ end else begin
+ case (current_state)
+ //------------------------------------------------------------------
+ // Mock TSS - Idle State
+ //------------------------------------------------------------------
+ ST_MOCKTSS_IDLE : begin
+ // Default signal assignments
+ llkid_key_ready <= '1;
+ llkid_key_complete <= '0;
+ llkid_clear_key_ack <= '0;
+ llkid_key_register <= '0;
+ wait_state_counter <= MOCKTSS_WAIT_STATE_COUNTER_INIT;
+ current_state <= ST_MOCKTSS_IDLE;
+
+ // If a clear key is requested while in the IDLE state, the STM
+ // will immediately acknowledge the clearing
+ if (llkid_clear_key) begin
+ llkid_clear_key_ack <= '1;
+ end else if (llkid_key_valid) begin
+ llkid_key_ready <= '0;
+ llkid_key_register[63:0] <= llkid_key_data;
+ current_state <= ST_MOCKTSS_WAIT_STATE0;
+ end // end if (llkid_clear_key)
+
+ end
+ //------------------------------------------------------------------
+ // Mock TSS - Wait State 0
+ //------------------------------------------------------------------
+ ST_MOCKTSS_WAIT_STATE0 : begin
+ // Default signal assignments
+ llkid_key_ready <= '0;
+ llkid_key_complete <= '0;
+ llkid_clear_key_ack <= '0;
+ current_state <= ST_MOCKTSS_WAIT_STATE0;
+
+ // Decrement the wait state counter
+ wait_state_counter <= wait_state_counter - 1;
+
+ // Jump when the wait state counter has reached zero
+ if (wait_state_counter == 0) begin
+ current_state <= ST_MOCKTSS_KEY0_LOADED;
+ end else if (llkid_clear_key) begin
+ current_state <= ST_MOCKTSS_CLEAR_KEY;
+ end // end if (wait_state_counter == 0)
+
+ end // ST_MOCKTSS_WAIT_STATE0
+ //------------------------------------------------------------------
+ // Mock TSS - Key Word 0 has been loaded
+ //------------------------------------------------------------------
+ ST_MOCKTSS_KEY0_LOADED : begin
+ // Default signal assignments
+ llkid_key_ready <= '1;
+ llkid_key_complete <= '0;
+ llkid_clear_key_ack <= '0;
+ wait_state_counter <= MOCKTSS_WAIT_STATE_COUNTER_INIT;
+ current_state <= ST_MOCKTSS_KEY0_LOADED;
+
+ // If a clear key, jump to the clear key state
+ if (llkid_clear_key) begin
+ current_state <= ST_MOCKTSS_CLEAR_KEY;
+ end else if (llkid_key_valid) begin
+ llkid_key_ready <= '0;
+ llkid_key_register[127:64] <= llkid_key_data;
+ current_state <= ST_MOCKTSS_WAIT_STATE1;
+ end // end if (llkid_clear_key)
+ end // ST_MOCKTSS_KEY0_LOADED
+ //------------------------------------------------------------------
+ // Mock TSS - Wait State 1
+ //------------------------------------------------------------------
+ ST_MOCKTSS_WAIT_STATE1 : begin
+ // Default signal assignments
+ llkid_key_ready <= '0;
+ llkid_key_complete <= '0;
+ llkid_clear_key_ack <= '0;
+ current_state <= ST_MOCKTSS_WAIT_STATE1;
+
+ // Decrement the wait state counter
+ wait_state_counter <= wait_state_counter - 1;
+
+ // Jump when the wait state counter has reached zero
+ if (wait_state_counter == 0) begin
+ current_state <= ST_MOCKTSS_KEY1_LOADED;
+ end else if (llkid_clear_key) begin
+ current_state <= ST_MOCKTSS_CLEAR_KEY;
+ end // end if (wait_state_counter == 0)
+
+ end // ST_MOCKTSS_WAIT_STATE1
+ //------------------------------------------------------------------
+ // Mock TSS - Key Word 1 has been loaded. Sit here until
+ // the key is cleared OR an attempt to reload the key occurs.
+ //
+ // Note: Accepting a new key while in this state. Either
+ // this state needs to be able to accept a new key OR care
+ // must be take verify key load state (through a key status
+ // requyest) before loading a new key.
+ //
+ // Additional "robustness" will be explored in future LLKI
+ // releases.
+ //
+ //------------------------------------------------------------------
+ ST_MOCKTSS_KEY1_LOADED : begin
+ // Default signal assignments
+ llkid_key_ready <= '1;
+ llkid_key_complete <= '1;
+ llkid_clear_key_ack <= '0;
+ wait_state_counter <= MOCKTSS_WAIT_STATE_COUNTER_INIT;
+ current_state <= ST_MOCKTSS_KEY1_LOADED;
+
+ // If a clear key, jump to the clear key state.
+ if (llkid_clear_key) begin
+ current_state <= ST_MOCKTSS_CLEAR_KEY;
+ end else if (llkid_key_valid) begin
+ llkid_key_ready <= '0;
+ llkid_key_register[63:0] <= llkid_key_data;
+ current_state <= ST_MOCKTSS_WAIT_STATE0;
+ end // end if (llkid_clear_key)
+ end // ST_MOCKTSS_KEY0_LOADED
+ //------------------------------------------------------------------
+ // Mock TSS - Clear Key State
+ //------------------------------------------------------------------
+ ST_MOCKTSS_CLEAR_KEY : begin
+ // Default signal assignments
+ llkid_key_ready <= '0;
+ llkid_key_complete <= '0;
+ llkid_clear_key_ack <= '0;
+ llkid_key_register <= '0;
+ wait_state_counter <= MOCKTSS_WAIT_STATE_COUNTER_INIT;
+ current_state <= ST_MOCKTSS_WAIT_STATE2;
+ end
+ //------------------------------------------------------------------
+ // Mock TSS - Wait State 2
+ //------------------------------------------------------------------
+ ST_MOCKTSS_WAIT_STATE2 : begin
+ // Default signal assignments
+ llkid_key_ready <= '0;
+ llkid_key_complete <= '0;
+ llkid_clear_key_ack <= '0;
+ current_state <= ST_MOCKTSS_WAIT_STATE2;
+
+ // Decrement the wait state counter
+ wait_state_counter <= wait_state_counter - 1;
+
+ // Jump when the wait state counter has reached zero
+ if (wait_state_counter == 0) begin
+ llkid_clear_key_ack <= '1;
+ current_state <= ST_MOCKTSS_IDLE;
+ end // end if (wait_state_counter == 0)
+
+ end // ST_MOCKTSS_WAIT_STATE1
+ //------------------------------------------------------------------
+ // Mock TSS - Trap State
+ //------------------------------------------------------------------
+ default : begin
+ // Default signal assignments
+ llkid_key_ready <= '1;
+ llkid_key_complete <= '0;
+ llkid_clear_key_ack <= '0;
+ llkid_key_register <= '0;
+ wait_state_counter <= MOCKTSS_WAIT_STATE_COUNTER_INIT;
+ current_state <= ST_MOCKTSS_IDLE;
+ end
+ endcase
+ end // end if (rst)
+ end // end always
+ //------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------
+ // Create the Mock TSS input into the AES core
+ //------------------------------------------------------------------
+ assign mock_tss_state[63:0] = AES_MOCK_TSS_KEY_0 ^
+ llkid_key_register[63:0] ^
+ state[63:0];
+ assign mock_tss_state[127:64] = AES_MOCK_TSS_KEY_1 ^
+ llkid_key_register[127:64] ^
+ state[127:64];
+ //------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------
+ // Instantiate the AES core
+ //------------------------------------------------------------------
+ aes_192 aes_192_inst (
+ .clk (clk),
+ .rst (rst),
+ .start (start),
+ .state (mock_tss_state),
+ .key (key),
+ .out (out),
+ .out_valid (out_valid)
+ );
+ //------------------------------------------------------------------
+
+endmodule
+
diff --git a/hdl_cores/freedom/Makefile.vc707 b/hdl_cores/freedom/Makefile.vc707
index 95a4f9a..d2bbffc 100644
--- a/hdl_cores/freedom/Makefile.vc707
+++ b/hdl_cores/freedom/Makefile.vc707
@@ -1,3 +1,14 @@
+#//************************************************************************
+#// Copyright (C) 2020 Massachusetts Institute of Technology
+#// SPDX short identifier: BSD-2-Clause
+#//
+#// File Name: Makefile.vc707
+#// Program: Common Evaluation Platform (CEP)
+#// Description: CEP Makefile speficially targetted for the VC707
+#// Notes:
+#//
+#//************************************************************************
+
# See LICENSE for license details.
base_dir := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
BUILD_DIR := $(base_dir)/builds/vc707-u500devkit
@@ -14,9 +25,9 @@ sifiveblocks_dir := $(base_dir)/sifive-blocks
VSRCS := \
$(rocketchip_dir)/src/main/resources/vsrc/AsyncResetReg.v \
$(rocketchip_dir)/src/main/resources/vsrc/plusarg_reader.v \
- $(rocketchip_dir)/src/main/resources/vsrc/EICG_wrapper.v \
- $(base_dir)/src/main/resources/vsrc/AnalogToUInt.v \
- $(base_dir)/src/main/resources/vsrc/UIntToAnalog.v \
+ $(rocketchip_dir)/src/main/resources/vsrc/EICG_wrapper.v \
+ $(base_dir)/src/main/resources/vsrc/AnalogToUInt.v \
+ $(base_dir)/src/main/resources/vsrc/UIntToAnalog.v \
$(sifiveblocks_dir)/vsrc/SRLatch.v \
$(FPGA_DIR)/common/vsrc/PowerOnResetFPGAOnly.v \
$(FPGA_DIR)/$(BOARD)/vsrc/sdio.v \
@@ -25,45 +36,65 @@ VSRCS := \
$(BUILD_DIR)/$(CONFIG_PROJECT).$(CONFIG).v \
$(base_dir)/src/main/resources/vsrc/AnalogToUInt.v \
$(base_dir)/src/main/resources/vsrc/UIntToAnalog.v \
- $(base_dir)/../aes/aes_192.v \
- $(base_dir)/../aes/round.v \
- $(base_dir)/../aes/table.v \
- $(base_dir)/../dsp/FIR_filter.v \
- $(base_dir)/../dsp/IIR_filter.v \
- $(base_dir)/../../generated_dsp_code/dft_top.v \
- $(base_dir)/../../generated_dsp_code/idft_top.v \
- $(base_dir)/../des3/des3.v \
- $(base_dir)/../des3/key_sel3.v \
- $(base_dir)/../des3/crp.v \
- $(base_dir)/../des3/sbox1.v \
- $(base_dir)/../des3/sbox2.v \
- $(base_dir)/../des3/sbox3.v \
- $(base_dir)/../des3/sbox4.v \
- $(base_dir)/../des3/sbox5.v \
- $(base_dir)/../des3/sbox6.v \
- $(base_dir)/../des3/sbox7.v \
+ $(base_dir)/../llki/top_pkg.sv \
+ $(base_dir)/../llki/llki_pkg.sv \
+ $(base_dir)/../aes/aes_192_mock_tss.sv \
+ $(base_dir)/../aes/aes_192.v \
+ $(base_dir)/../aes/round.v \
+ $(base_dir)/../aes/table.v \
+ $(base_dir)/../dsp/FIR_filter.v \
+ $(base_dir)/../dsp/IIR_filter.v \
+ $(base_dir)/../../generated_dsp_code/dft_top.v \
+ $(base_dir)/../../generated_dsp_code/idft_top.v \
+ $(base_dir)/../des3/des3.v \
+ $(base_dir)/../des3/key_sel3.v \
+ $(base_dir)/../des3/crp.v \
+ $(base_dir)/../des3/sbox1.v \
+ $(base_dir)/../des3/sbox2.v \
+ $(base_dir)/../des3/sbox3.v \
+ $(base_dir)/../des3/sbox4.v \
+ $(base_dir)/../des3/sbox5.v \
+ $(base_dir)/../des3/sbox6.v \
+ $(base_dir)/../des3/sbox7.v \
$(base_dir)/../des3/sbox8.v \
- $(base_dir)/../md5/md5.v \
- $(base_dir)/../md5/pancham.v \
- $(base_dir)/../md5/pancham_round.v \
- $(base_dir)/../md5/pancham_round.v \
- $(base_dir)/../gps/gps.v \
- $(base_dir)/../gps/gps_clkgen.v \
- $(base_dir)/../gps/cacode.v \
- $(base_dir)/../gps/pcode.v \
- $(base_dir)/../rsa/rtl/modexp_core.v \
- $(base_dir)/../rsa/rtl/montprod.v \
- $(base_dir)/../rsa/rtl/residue.v \
- $(base_dir)/../rsa/rtl/blockmem2r1w.v \
- $(base_dir)/../rsa/rtl/blockmem2r1w.v \
- $(base_dir)/../rsa/rtl/blockmem2r1wptr.v \
- $(base_dir)/../rsa/rtl/blockmem2rptr1w.v \
- $(base_dir)/../rsa/rtl/blockmem1r1w.v \
- $(base_dir)/../rsa/rtl/shr.v \
- $(base_dir)/../rsa/rtl/shl.v \
- $(base_dir)/../rsa/rtl/adder.v \
- $(base_dir)/../sha256/sha256.v \
- $(base_dir)/../sha256/sha256_k_constants.v \
- $(base_dir)/../sha256/sha256_w_mem.v
+ $(base_dir)/../md5/md5.v \
+ $(base_dir)/../md5/pancham.v \
+ $(base_dir)/../md5/pancham_round.v \
+ $(base_dir)/../md5/pancham_round.v \
+ $(base_dir)/../gps/gps.v \
+ $(base_dir)/../gps/gps_clkgen.v \
+ $(base_dir)/../gps/cacode.v \
+ $(base_dir)/../gps/pcode.v \
+ $(base_dir)/../rsa/rtl/modexp_core.v \
+ $(base_dir)/../rsa/rtl/montprod.v \
+ $(base_dir)/../rsa/rtl/residue.v \
+ $(base_dir)/../rsa/rtl/blockmem2r1w.v \
+ $(base_dir)/../rsa/rtl/blockmem2r1w.v \
+ $(base_dir)/../rsa/rtl/blockmem2r1wptr.v \
+ $(base_dir)/../rsa/rtl/blockmem2rptr1w.v \
+ $(base_dir)/../rsa/rtl/blockmem1r1w.v \
+ $(base_dir)/../rsa/rtl/shr.v \
+ $(base_dir)/../rsa/rtl/shl.v \
+ $(base_dir)/../rsa/rtl/adder.v \
+ $(base_dir)/../sha256/sha256.v \
+ $(base_dir)/../sha256/sha256_k_constants.v \
+ $(base_dir)/../sha256/sha256_w_mem.v \
+ $(base_dir)/../../opentitan/hw/ip/prim/rtl/prim_assert.sv \
+ $(base_dir)/../../opentitan/hw/ip/prim/rtl/prim_util_pkg.sv \
+ $(base_dir)/../../opentitan/hw/ip/prim/rtl/prim_fifo_sync.sv \
+ $(base_dir)/../../opentitan/hw/ip/prim_generic/rtl/prim_generic_ram_2p.sv \
+ $(base_dir)/../../opentitan/hw/ip/tlul/rtl/tlul_pkg.sv \
+ $(base_dir)/../../opentitan/hw/ip/tlul/rtl/tlul_adapter_reg.sv \
+ $(base_dir)/../../opentitan/hw/ip/tlul/rtl/tlul_adapter_host.sv \
+ $(base_dir)/../llki/llki_pp_wrapper.sv \
+ $(base_dir)/../llki/srot_wrapper.sv \
+ $(base_dir)/../llki/tlul_err.sv
+
+# Freedom U500 TCL scripts have been expanded to support passing of
+# include directories to synthesis (which is important for SystemVerilog packages)
+# It is unclear why including multiple directories doesn't work as expected
+# (per UG835, v2019.2, pg 1703 creating a list *should* work, although it doesn't seem to)
+INCDIRS := \
+ $(base_dir)/../../opentitan/hw/ip/prim/rtl
include common.mk
diff --git a/hdl_cores/freedom/bootrom/sdboot/sd.c b/hdl_cores/freedom/bootrom/sdboot/sd.c
index 5b34c87..7985845 100644
--- a/hdl_cores/freedom/bootrom/sdboot/sd.c
+++ b/hdl_cores/freedom/bootrom/sdboot/sd.c
@@ -224,7 +224,7 @@ void print_greeting()
kputs(" ./+++++++++++oo+++: +oo++o++++o+o+oo+oo.- `s+++s`- ");
kputs(" .--:---:-:-::-::` -::::::::::::::::::. :::::. ");
kputs(" ");
- kputs(" Common Evaluation Platform v2.71 ");
+ kputs(" Common Evaluation Platform v3.0 ");
kputs(" Copyright (C) 2020 Massachusetts Institute of Technology ");
kputs(" ");
kputs(" Built upon the SiFive Freedom U500 Platform using ");
diff --git a/hdl_cores/freedom/common.mk b/hdl_cores/freedom/common.mk
index b33edd0..61fd14b 100644
--- a/hdl_cores/freedom/common.mk
+++ b/hdl_cores/freedom/common.mk
@@ -32,7 +32,10 @@ SBT ?= java -jar $(rocketchip_dir)/sbt-launch.jar
# Build firrtl.jar and put it where chisel3 can find it.
FIRRTL_JAR ?= $(rocketchip_dir)/firrtl/utils/bin/firrtl.jar
-FIRRTL ?= java -Xmx2G -Xss8M -cp $(FIRRTL_JAR) firrtl.Driver
+#FIRRTL ?= java -Xmx2G -Xss8M -cp $(FIRRTL_JAR) firrtl.Driver
+# 10/27/20 tony d. as recommended from the message
+#
+FIRRTL ?= java -Xmx2G -Xss8M -cp $(FIRRTL_JAR) firrtl.stage.FirrtlMain
$(FIRRTL_JAR): $(shell find $(rocketchip_dir)/firrtl/src/main/scala -iname "*.scala")
$(MAKE) -C $(rocketchip_dir)/firrtl SBT="$(SBT)" root_dir=$(rocketchip_dir)/firrtl build-scala
@@ -76,14 +79,19 @@ f := $(BUILD_DIR)/$(CONFIG_PROJECT).$(CONFIG).vsrcs.F
$(f):
echo $(VSRCS) > $@
+incdirs := $(BUILD_DIR)/$(CONFIG_PROJECT).$(CONFIG).incdirs
+$(incdirs):
+ echo $(INCDIRS) > $@
+
bit := $(BUILD_DIR)/obj/$(MODEL).bit
-$(bit): $(romgen) $(f)
+$(bit): $(romgen) $(f) $(incdirs)
cd $(BUILD_DIR); vivado \
-nojournal -mode batch \
-source $(fpga_common_script_dir)/vivado.tcl \
-tclargs \
-top-module "$(MODEL)" \
-F "$(f)" \
+ -include_dirs "$(incdirs)" \
-ip-vivado-tcls "$(shell find '$(BUILD_DIR)' -name '*.vivado.tcl')" \
-board "$(BOARD)"
diff --git a/hdl_cores/freedom/fpga-shells/.gitignore b/hdl_cores/freedom/fpga-shells/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/hdl_cores/freedom/fpga-shells/README.md b/hdl_cores/freedom/fpga-shells/README.md
new file mode 100644
index 0000000..a65bcda
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/README.md
@@ -0,0 +1,105 @@
+# fpga-shells
+
+An FPGA shell is a Chisel module designed to wrap any SiFive core configuration.
+The goal of the fpga-shell system is to reduce the number of wrappers to have only
+one for each physical device rather than one for every combination of physical device and core configuration.
+
+Each shell consists of Overlays which use dependency injection to create and connect peripheral device interfaces in an FPGADesign to the toplevel shell module.
+
+Most devices already have an overlay defined for them in `src/main/scala/shell[/xilinx]`.
+If you're using a Xilinx device, you'll probably want to use the xilinx-specific overlay
+because it defines a few things that you'd otherwise have to specify yourself.
+
+Generally, you'll want to create a device shell that extends `Series7Shell` or `UltraScaleShell`.
+If you need different functionality (or you're not using a Xilinx device), you can extend `Shell` and implement abstract members.
+Some Microsemi devices are supported by fgpa-shells as well (and can be found in `src/main/scala/shell/microsemi`)
+
+For example:
+
+```Scala
+class DeviceShell()(implicit p: Parameters) extends UltraScaleShell {
+ // create Overlays
+ val myperipheral = Overlay(PeripheralOverlayKey) (new PeripheralOverlay(_,_,_))
+ // ...
+
+ // assign abstract members
+ val pllReset = InModuleBody { Wire(Bool()) }
+ val topDesign = LazyModule(p(DesignKey)(designParameters))
+
+ // ensure clocks are connected
+ designParameters(ClockInputOverlayKey).foreach { unused =>
+ val source = unused(ClockInputOverlayParams())
+ val sink = ClockSinkNode(Seq(ClockSinkParameters()))
+ sink := source
+ }
+
+ // override module implementation to connect reset
+ override lazy val module = new LazyRawModuleImp(this) {
+ val reset = IO(Input(Bool()))
+ pllReset := reset
+ }
+}
+```
+
+Each peripheral device to be added to the shell must define an `Overlay`, which creates the device and connects it to the toplevel shell.
+In addition, in order to access the overlay, the device needs to have a `case class OverlayParams` and a `case object OverlayKey`
+
+```Scala
+case class PeripheralOverlayParams()(implicit val p: Parameters)
+case object PeripheralOverlayKey extends Field[Seq[DesignOverlay[PeripheralOverlayParams, PeripheralDesignOutput]]](Nil)
+```
+
+If the device is parameterizable, then each parameter for the device creation can be passed to the `PeripheralOverlayParams` constructor by adding a field for said parameter.
+Typically, devices are connected to a TileLink bus for processor control, so `PeripheralDesignOutput` can usually be substituted with `TLInwardNode`.
+
+The `Overlay` extends `IOOverlay` which is paramerized by the device's `IO` (in this case `PeripheralDeviceIO` is a subtype of `Data` and is a port specification for the peripheral device)
+and `DesignOutput`.
+
+```Scala
+abstract class AbstractPeripheralOverlay(val params: PeripheralOverlayParams)
+ extends IOOverlay[PeripheralDeviceIO, PeripheralDesignOutput]
+{
+ // assign abstract member p (used to access overlays with their key)
+ // e.g. p(PeripheralOverlayKey) will return a Seq[DesignOverlay[PeripheralOverlayParams, PeripheralDesignOutput]]
+ implicit val p = params.p
+}
+```
+
+Continuing our example with a `DeviceShell` shell, the actual overlay is constructed by extending our abstract `PeripheralOverlay`
+```Scala
+class ConcretePeripheralOverlay(val shell: DeviceShell, val name: String, params: PeripheralOverlayParams)
+ extends AbstractPeripheralOverlay(params)
+{
+ val device = LazyModule(new PeripheralDevice(PeripheralDeviceParams(???))) // if your peripheral device isn't parameterizable, then it'll have an empty constructor
+
+ def ioFactory = new PeripheralDeviceIO // ioFactory defines interface of val io
+ val designOutput = device.node
+
+ // this is where "code-injection" starts
+ val ioSource = BundleBridgeSource(() => device.module.io.cloneType) // create a bridge between device (source) and shell (sink)
+ val ioSink = shell { ioSource.makeSink() }
+
+ InModuleBody { ioSource.bundle <> device.module.io }
+
+ shell { InModuleBody {
+ val port = ioSink.bundle
+
+ io <> port // io is the bundle of shell-level IO as specified by ioFactory
+ } }
+}
+```
+
+The actual device implementation (where the device's functionality is defined) will be something like this:
+```Scala
+case class PeripheralDeviceParams(param1: Param1Type, ???) // only necessary if your device is parameterizable
+class PeripheralDevice(c: PeripheralDeviceParams)(implicit p: Parameters) extends LazyModule {
+
+ val node: PeripheralDesignOutput = ???
+
+ // device implementation
+ lazy val module = new LazyModuleImp(this) {
+ val io = ???
+ ???
+ }
+}
+```
diff --git a/hdl_cores/freedom/fpga-shells/build.wake b/hdl_cores/freedom/fpga-shells/build.wake
new file mode 100644
index 0000000..6149b28
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/build.wake
@@ -0,0 +1,14 @@
+def scalacOpts =
+ "-deprecation",
+ "-feature",
+ "-unchecked",
+ "-language:reflectiveCalls",
+ "-Xsource:2.11",
+ Nil
+
+global def fpgaShellsScalaModule =
+ def scalaVersion = rocketchipScalaModule.getScalaModuleScalaVersion
+ makeScalaModule "fpga-shells" here scalaVersion
+ | setScalaModuleDeps (sifiveBlocksScalaModule, rocketchipScalaModule, Nil)
+ | setScalaModuleScalacOptions scalacOpts
+ | addMacrosParadiseCompilerPlugin
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/common/tcl/libero.tcl b/hdl_cores/freedom/fpga-shells/microsemi/common/tcl/libero.tcl
new file mode 100644
index 0000000..b26894e
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/common/tcl/libero.tcl
@@ -0,0 +1,253 @@
+#==============================================================================
+# Build a Libero project from Chisel generated Verilog and the Libero TCL
+# scriplets generated by each IP block FPGA-Shell.
+#==============================================================================
+
+######### Script arguments #########
+
+if {$argc != 5} {
+ puts "!!! ERROR !!!: This script takes 5 arguments from the Chisel build environment: BUILD_DIR MODEL PROJECT CONFIG BOARD"
+ exit
+}
+
+puts "*****************************************************************"
+puts "******************** Building Libero project ********************"
+puts "*****************************************************************"
+
+set chisel_build_dir [lindex $argv 0]
+set chisel_model [lindex $argv 1]
+set chisel_project [lindex $argv 2]
+set chisel_config [lindex $argv 3]
+set chisel_board [lindex $argv 4]
+
+puts "Number of arguments: $argc"
+puts "Chisel build directory: $chisel_build_dir"
+puts "Chisel model: $chisel_model"
+puts "Chisel project: $chisel_project"
+puts "Chisel config: $chisel_config"
+puts "Chisel board: $chisel_board"
+
+set Prjname "$chisel_model"
+set Proj "./Libero/$Prjname"
+
+set FPExpressDir "$chisel_build_dir/FlashProExpress"
+puts "FlashPro Express folder: $FPExpressDir"
+file mkdir $FPExpressDir
+
+set scriptdir [file dirname [info script]]
+set commondir [file dirname $scriptdir]
+set boarddir [file join [ file dirname $commondir] $chisel_board]
+
+###########################################
+set CoreJTAGDebugver {2.0.100}
+set PF_DDR3ver {2.3.201}
+set PF_DDR4ver {2.3.201}
+set PF_CCCver {1.0.115}
+set PF_INIT_MONITORver {2.0.103}
+set PF_CORERESETPFver {2.1.100}
+set PF_PCIEver {2.0.100}
+set PF_XCVR_REF_CLKver {1.0.103}
+set PF_TX_PLLver {2.0.002}
+
+set use_enhanced_constraint_flow 1
+set tb {testbench}
+file delete -force "$Proj"
+set rootcomp {Top_SD}
+set rootcomp1 Top_SD
+set TOP Top_SD
+
+set SimTime 100us
+set NUM_TX_PLL 1
+set quad 1
+set txpll_refclk_mode "ded"
+set xcvrrefclk_refclk_mode "diff"
+
+#########ORIGINAl SETTINGS#############
+
+#Device Selection
+source [file join $boarddir tcl board.tcl]
+
+#Analysis operating conditions
+set TEMPR {EXT}
+set VOLTR {EXT}
+set IOVOLTR_12 {EXT}
+set IOVOLTR_15 {EXT}
+set IOVOLTR_18 {EXT}
+set IOVOLTR_25 {EXT}
+set IOVOLTR_33 {EXT}
+
+#Design Flow
+set HDL {VERILOG}
+set Block 0
+set SAPI 0
+set vmflow 1
+set synth 1
+set fanout {10}
+
+#########ORIGINAl SETTINGS#############
+
+new_project -ondemand_build_dh 1 -location "$Proj" -name "$Prjname" -project_description {} -block_mode $Block -standalone_peripheral_initialization $SAPI -use_enhanced_constraint_flow $use_enhanced_constraint_flow -hdl $HDL -family $family -die $die -package $package -speed $speed -die_voltage $die_voltage -part_range $part_range -adv_options IO_DEFT_STD:$IOTech -adv_options RESTRICTPROBEPINS:$ResProbe -adv_options RESTRICTSPIPINS:$ResSPI -adv_options TEMPR:$TEMPR -adv_options VCCI_1.2_VOLTR:$IOVOLTR_12 -adv_options VCCI_1.5_VOLTR:$IOVOLTR_15 -adv_options VCCI_1.8_VOLTR:$IOVOLTR_18 -adv_options VCCI_2.5_VOLTR:$IOVOLTR_25 -adv_options VCCI_3.3_VOLTR:$IOVOLTR_33 -adv_options VOLTR:$VOLTR
+
+#
+# Import Chisel generated verilog files into Libero project
+#
+import_files \
+ -convert_EDN_to_HDL 0 \
+ -hdl_source "$chisel_build_dir/$chisel_project.$chisel_config.v" \
+ -hdl_source "../../rocket-chip/vsrc/AsyncResetReg.v" \
+ -hdl_source "../../rocket-chip/vsrc/plusarg_reader.v"
+
+download_latest_cores
+#download_core -vlnv {Actel:DirectCore:COREDES:3.0.106} -vlnv {Actel:DirectCore:COREAHBLTOAXI:2.1.101} -vlnv {Actel:DirectCore:CORE3DES:3.1.104} -vlnv {Actel:DirectCore:COREAHBTOAPB3:3.1.100} -vlnv {Actel:DirectCore:CoreAPB3:4.1.100} -vlnv {Actel:DirectCore:corepwm:4.3.101} -vlnv {Actel:DirectCore:CoreTimer:2.0.103} -vlnv {Actel:DirectCore:CORECORDIC:4.0.102} -vlnv {Actel:DirectCore:CORESPI:5.1.104} -vlnv {Actel:DirectCore:COREAXI4SRAM:2.1.105} -vlnv {Actel:DirectCore:CoreDDRMemCtrlr:0.0.74} -vlnv {Actel:DirectCore:CoreJESD204BTX:3.0.114} -vlnv {Actel:DirectCore:COREUART:5.6.102} -vlnv {Actel:DirectCore:CoreUARTapb:5.6.102} -vlnv {Actel:DirectCore:COREABC:3.7.101} -vlnv {Actel:DirectCore:COREFFT:7.0.104} -vlnv {Actel:DirectCore:CORERSENC:3.5.102} -vlnv {Actel:DirectCore:CORERSDEC:3.6.104} -vlnv {Actel:DirectCore:COREFIFO:2.6.108} -vlnv {Actel:DirectCore:CORE429:3.12.105} -vlnv {Actel:DirectCore:CORE429_APB:3.12.105} -vlnv {Actel:DirectCore:CORETSE:3.1.102} -vlnv {Actel:DirectCore:CORETSE_AHB:3.1.102} -vlnv {Actel:DirectCore:COREFIR_PF:2.0.104} -vlnv {Actel:DirectCore:COREAXI4DMACONTROLLER:2.0.100} -vlnv {Actel:DirectCore:COREBOOTSTRAP:2.0.100} -vlnv {Actel:DirectCore:CoreJESD204BRX:3.0.126} -vlnv {Actel:DirectCore:CORESGMII:3.2.101} -vlnv {Actel:DirectCore:COREAHBL2AHBL_BRIDGE:2.0.108} -vlnv {Actel:DirectCore:CORERISCV_AXI4:2.0.102} -vlnv {Actel:DirectCore:COREJTAGDEBUG:2.0.100} -vlnv {Actel:DirectCore:CoreAXI4Interconnect:2.2.102} -vlnv {Actel:DirectCore:COREMDIO_APB:2.1.100} -vlnv {Actel:DirectCore:CORERMII:3.0.105} -vlnv {Actel:DirectCore:COREDDR_TIP:1.1.124} -vlnv {Actel:DirectCore:COREDDS:3.0.105} -vlnv {Actel:DirectCore:COREI2C:7.2.101} -vlnv {Actel:DirectCore:CoreAHBLite:5.3.101} -vlnv {Actel:DirectCore:CoreGPIO:3.2.102} -vlnv {Actel:DirectCore:COREAXITOAHBL:3.2.104} -vlnv {Actel:DirectCore:COREEDAC:2.10.104} -vlnv {Microsemi:MiV:MIV_RV32IMA_L1_AHB:2.0.100} -vlnv {Microsemi:MiV:MIV_RV32IMAF_L1_AHB:2.0.100} -vlnv {Actel:DirectCore:CorePCS:3.5.106} -vlnv {Actel:DirectCore:COREPCIF:4.1.123} -vlnv {Actel:DirectCore:COREPCIF_AHB:4.1.123} -vlnv {Actel:SystemBuilder:CORESMARTBERT:2.0.106} -vlnv {Actel:DirectCore:CORESYSSERVICES_PF:2.3.116} -vlnv {Actel:DirectCore:CORERESET_PF:2.1.100} -vlnv {Microsemi:SolutionCore:iog_cdr_test_wrapper:1.0.0} -vlnv {Microsemi:SolutionCore:alpha_blend_control:2.0.0} -vlnv {Microsemi:SolutionCore:BayerConversionTop:2.0.0} -vlnv {Microsemi:SolutionCore:ImageEdgeDetection:2.0.0} -vlnv {Microsemi:SolutionCore:ImageSharpenFilter:2.0.0} -vlnv {Microsemi:SolutionCore:RGB2YCbCr:2.0.0} -vlnv {Microsemi:SolutionCore:Scaler:2.0.0} -vlnv {Microsemi:SolutionCore:ddr_memory_arbiter:2.0.0} -vlnv {Microsemi:SolutionCore:YCbCr2RGB:2.0.0} -vlnv {Microsemi:SolutionCore:display_controller:2.0.0} -vlnv {Microsemi:SolutionCore:DisplayEnhancements:2.0.0} -vlnv {Microsemi:SolutionCore:pattern_generator:2.0.0} -vlnv {Actel:DirectCore:CORE10GMAC:2.1.126} -vlnv {Actel:DirectCore:CORECIC:2.1.103} -vlnv {Microsemi:SolutionCore:CPRI:2.0.0} -vlnv {Microsemi:SolutionCore:LiteFast:1.0.3} -vlnv {Microsemi:MiV:MIV_RV32IMA_L1_AXI:2.0.100} -vlnv {Actel:DirectCore:COREAXI4INTERCONNECT:2.5.100} -vlnv {Actel:DirectCore:COREXAUI:2.0.133} -vlnv {Microsemi:SolutionCore:mipi_csi2_tx:2.0.0} -vlnv {Actel:DirectCore:COREQSGMII:2.0.108} -vlnv {Microsemi:SolutionCore:complex_multiplier:1.0.26} -vlnv {Microsemi:SolutionCore:mipicsi2rxdecoderPF:2.1.0} -location {www.actel-ip.com/repositories/DirectCore}
+#download_core -vlnv {Actel:Simulation:CLK_GEN:1.0.1} -vlnv {Actel:Simulation:PULSE_GEN:1.0.1} -vlnv {Actel:Simulation:RESET_GEN:1.0.1} -vlnv {Actel:DirectCore:CoreDDRMemCtrlr:0.0.74} -vlnv {Actel:DirectCore:COREDDR_TIP:1.1.124} -vlnv {Actel:SgCore:PF_CCC:1.0.112} -vlnv {Actel:SgCore:PF_CRYPTO:1.0.101} -vlnv {Actel:SgCore:PF_DPSRAM:1.1.110} -vlnv {Actel:SgCore:PF_DRI:1.0.101} -vlnv {Actel:SgCore:PF_INIT_MONITOR:2.0.101} -vlnv {Actel:SgCore:PF_NGMUX:1.0.101} -vlnv {Actel:SgCore:PF_OSC:1.0.102} -vlnv {Actel:SgCore:PF_TAMPER:1.0.102} -vlnv {Actel:SgCore:PF_TPSRAM:1.1.108} -vlnv {Actel:SgCore:PF_TX_PLL:1.0.109} -vlnv {Actel:SgCore:PF_UPROM:1.0.108} -vlnv {Actel:SgCore:PF_URAM:1.1.107} -vlnv {Actel:SgCore:PF_XCVR:1.0.223} -vlnv {Actel:SgCore:PF_XCVR_REF_CLK:1.0.103} -vlnv {Actel:SystemBuilder:PF_IOD_CDR:1.0.210} -vlnv {Actel:SystemBuilder:PF_IOD_LVDS7_RX:1.0.104} -vlnv {Actel:SystemBuilder:PF_IOD_LVDS7_TX:1.0.104} -vlnv {Actel:SystemBuilder:CORESMARTBERT:2.0.106} -vlnv {Actel:SgCore:PF_CLK_DIV:1.0.102} -vlnv {Actel:SgCore:PF_PCIE:1.0.234} -vlnv {Actel:SystemBuilder:PF_DDR3:2.2.109} -vlnv {Actel:SystemBuilder:PF_DDR4:2.2.109} -vlnv {Actel:SystemBuilder:PF_IOD_GENERIC_RX:1.0.238} -vlnv {Actel:SystemBuilder:PF_IOD_GENERIC_TX:1.0.234} -vlnv {Actel:SystemBuilder:PF_LPDDR3:2.1.111} -vlnv {Actel:SystemBuilder:PF_RGMII_TO_GMII:1.0.208} -vlnv {Actel:SystemBuilder:PF_SRAM_AHBL_AXI:1.1.123} -location {www.actel-ip.com/repositories/SgCore}
+#
+#
+# Execute all design entry scripts generated from Chisel flow.
+#
+set tclfiles [glob -directory $chisel_build_dir $chisel_project.$chisel_config.*.libero.tcl ]
+
+foreach f $tclfiles {
+ puts "---------- Executing Libero TCL script: $f ----------"
+ source $f
+}
+
+#
+# Build design hierarchy and set project root to design's top level
+#
+build_design_hierarchy
+
+#set_root -module {U500PolarFireEvalKitFPGAChip::work}
+set proj_root $chisel_model
+append proj_root "::work"
+puts "project root: $proj_root"
+set_root -module $proj_root
+
+#
+# Import IO, Placement and timing constrainst
+#
+puts "-----------------------------------------------------------------"
+puts "------------------ Applying design constraints ------------------"
+puts "-----------------------------------------------------------------"
+
+set sdc $chisel_project.$chisel_config.shell.sdc
+set io_pdc $chisel_project.$chisel_config.shell.io.pdc
+
+import_files -fp_pdc [file join $boarddir constraints floor_plan.pdc]
+import_files -io_pdc [file join $boarddir constraints pin_constraints.pdc]
+import_files -io_pdc [file join $chisel_build_dir $io_pdc]
+import_files -convert_EDN_to_HDL 0 -sdc [file join $chisel_build_dir $sdc]
+
+organize_tool_files -tool {PLACEROUTE} \
+ -file $Proj/constraint/fp/floor_plan.pdc \
+ -file $Proj/constraint/io/pin_constraints.pdc \
+ -file $Proj/constraint/io/$io_pdc \
+ -file $Proj/constraint/$sdc \
+ -module $proj_root -input_type {constraint}
+
+organize_tool_files -tool {VERIFYTIMING} \
+ -file $Proj/constraint/$sdc \
+ -module $proj_root -input_type {constraint}
+
+run_tool -name {CONSTRAINT_MANAGEMENT}
+derive_constraints_sdc
+
+#
+# Synthesis
+#
+puts "-----------------------------------------------------------------"
+puts "--------------------------- Synthesis ---------------------------"
+puts "-----------------------------------------------------------------"
+run_tool -name {SYNTHESIZE}
+
+#
+# Place and route
+#
+puts "-----------------------------------------------------------------"
+puts "------------------------ Place and Route ------------------------"
+puts "-----------------------------------------------------------------"
+configure_tool -name {PLACEROUTE} -params {EFFORT_LEVEL:true} -params {REPAIR_MIN_DELAY:true} -params {TDPR:true} -params {IOREG_COMBINING:true}
+run_tool -name {PLACEROUTE}
+
+configure_tool -name {VERIFYTIMING} -params {CONSTRAINTS_COVERAGE:1} -params {FORMAT:XML} -params {MAX_TIMING_FAST_HV_LT:1} -params {MAX_TIMING_SLOW_LV_HT:1} -params {MAX_TIMING_SLOW_LV_LT:1} -params {MAX_TIMING_VIOLATIONS_FAST_HV_LT:1} -params {MAX_TIMING_VIOLATIONS_SLOW_LV_HT:1} -params {MAX_TIMING_VIOLATIONS_SLOW_LV_LT:1} -params {MIN_TIMING_FAST_HV_LT:1} -params {MIN_TIMING_SLOW_LV_HT:1} -params {MIN_TIMING_SLOW_LV_LT:1} -params {MIN_TIMING_VIOLATIONS_FAST_HV_LT:1} -params {MIN_TIMING_VIOLATIONS_SLOW_LV_HT:1} -params {MIN_TIMING_VIOLATIONS_SLOW_LV_LT:1}
+run_tool -name {VERIFYTIMING}
+
+#
+# Verify Timing
+#
+puts "-----------------------------------------------------------------"
+puts "------------------------- Verify Timing -------------------------"
+puts "-----------------------------------------------------------------"
+configure_tool -name {VERIFYTIMING} \
+ -params {FORMAT:XML} \
+ -params {CONSTRAINTS_COVERAGE:1} \
+ -params {MAX_TIMING_FAST_HV_LT:1} \
+ -params {MAX_TIMING_SLOW_LV_HT:1} \
+ -params {MAX_TIMING_SLOW_LV_LT:1} \
+ -params {MAX_TIMING_VIOLATIONS_FAST_HV_LT:1} \
+ -params {MAX_TIMING_VIOLATIONS_SLOW_LV_HT:1} \
+ -params {MAX_TIMING_VIOLATIONS_SLOW_LV_LT:1} \
+ -params {MIN_TIMING_FAST_HV_LT:1} \
+ -params {MIN_TIMING_SLOW_LV_HT:1} \
+ -params {MIN_TIMING_SLOW_LV_LT:1} \
+ -params {MIN_TIMING_VIOLATIONS_FAST_HV_LT:1} \
+ -params {MIN_TIMING_VIOLATIONS_SLOW_LV_HT:1} \
+ -params {MIN_TIMING_VIOLATIONS_SLOW_LV_LT:1}
+run_tool -name {VERIFYTIMING}
+
+puts ""
+puts "Checking timing reports"
+
+set reportdir [file join $chisel_build_dir Libero $Prjname designer $Prjname]
+set reports [glob -directory $reportdir [set Prjname]_\{min,max\}_timing_violations_\{fast,slow\}_\{hv,lv\}_\{lt,ht\}.*]
+set ok true
+set eof true
+
+foreach report [lsort $reports] {
+ puts -nonewline " Parsing [file tail ${report}]... "
+ set fp [open $report]
+ while {[gets $fp line] >= 0} {
+ set what [string trim "$line"]
+ set eof false
+ if { "$what" == "This report was not generated" } {
+ puts "empty"
+ break
+ }
+ if { "$what" == "No Path" } {
+ puts "pass"
+ break
+ }
+ if { "$what" == "Path 1" } {
+ puts "failed"
+ set ok false
+ break
+ }
+ set eof true
+ }
+ close $fp
+ if { $eof } {
+ puts "end-of-file"
+ set ok false
+ }
+}
+
+if { !$ok } {
+ puts ""
+ puts "Timing constraints not met!"
+ return -code error "timing failed"
+}
+
+#
+# Generate programming files
+#
+puts "-----------------------------------------------------------------"
+puts "------------------ Generate programming files -------------------"
+puts "-----------------------------------------------------------------"
+run_tool -name {GENERATEPROGRAMMINGDATA}
+
+run_tool -name {GENERATEPROGRAMMINGFILE}
+
+export_prog_job \
+ -job_file_name $chisel_model \
+ -export_dir $FPExpressDir \
+ -bitstream_file_type {TRUSTED_FACILITY} \
+ -bitstream_file_components {}
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_DDR3_fp.pdc b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_DDR3_fp.pdc
new file mode 100644
index 0000000..58c1aef
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_DDR3_fp.pdc
@@ -0,0 +1,34 @@
+# Microsemi Physical design constraints file
+
+# Version: PolarFire v2.0 12.200.0.20
+
+# Design Name: U500PolarFireEvalKitFPGAChip
+
+# Input Netlist Format: EDIF
+
+# Family: PolarFire , Die: MPF300TS_ES , Package: FCG1152 , Speed grade: -1
+
+# Date generated: Mon Jan 8 10:19:51 2018
+
+
+#
+# Local clock constraints
+#
+
+
+#
+# Region constraints
+#
+
+
+#
+# Core cell constraints
+#
+
+set_location -inst_name iofpga/polarfireddr/island/blackbox/DDRPHY_BLK_0/LANE_0_CTRL/I_LANECTRL -fixed true -x 1967 -y 378
+set_location -inst_name iofpga/polarfireddr/island/blackbox/DDRPHY_BLK_0/IOD_BCLK_TRAINING/I_IOD_0 -fixed true -x 2388 -y 378
+set_location -inst_name iofpga/polarfireddr/island/blackbox/DDRPHY_BLK_0/LANE_1_CTRL/I_LANECTRL -fixed true -x 1823 -y 378
+set_location -inst_name iofpga/polarfireddr/island/blackbox/DDRPHY_BLK_0/LANE_1_IOD_READ_TRAINING/I_IOD_0 -fixed true -x 1812 -y 378
+set_location -inst_name iofpga/polarfireddr/island/blackbox/DDRPHY_BLK_0/LANE_0_IOD_READ_TRAINING/I_IOD_0 -fixed true -x 1956 -y 378
+set_location -inst_name iofpga/polarfireddr/island/blackbox/CCC_0/pll_inst_0 -fixed true -x 2460 -y 377
+
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_DDR3_io.pdc b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_DDR3_io.pdc
new file mode 100644
index 0000000..ac3826f
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_DDR3_io.pdc
@@ -0,0 +1,319 @@
+# Microsemi I/O Physical Design Constraints file
+
+# User I/O Constraints file
+
+# Version: PolarFire v2.0 12.200.0.20
+
+# Family: PolarFire , Die: MPF300TS_ES , Package: FCG1152
+
+set_io -port_name {ddr_A[0]} \
+ -pin_name AL27 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[1]} \
+ -pin_name AL26 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[2]} \
+ -pin_name AM27 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[3]} \
+ -pin_name AN27 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[4]} \
+ -pin_name AN26 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[5]} \
+ -pin_name AP25 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[6]} \
+ -pin_name AL25 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[7]} \
+ -pin_name AK25 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[8]} \
+ -pin_name AJ23 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[9]} \
+ -pin_name AH23 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[10]} \
+ -pin_name AJ25 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[11]} \
+ -pin_name AJ24 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[12]} \
+ -pin_name AL22 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[13]} \
+ -pin_name AK23 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[14]} \
+ -pin_name AL24 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_A[15]} \
+ -pin_name AL23 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_BA[0]} \
+ -pin_name AE25 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_BA[1]} \
+ -pin_name AD23 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_BA[2]} \
+ -pin_name AD25 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ddr_CAS_N \
+ -pin_name AF25 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ddr_CK0 \
+ -pin_name AP26 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ddr_CK0_N \
+ -pin_name AP27 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ddr_CKE \
+ -pin_name AF22 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ddr_CS_N \
+ -pin_name AE22 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_DM[0]} \
+ -pin_name AN23 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_DM[1]} \
+ -pin_name AL20 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {ddr_DQS[0]} \
+ -pin_name AP23 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQS[1]} \
+ -pin_name AH22 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQS_N[0]} \
+ -pin_name AP24 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQS_N[1]} \
+ -pin_name AJ21 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[0]} \
+ -pin_name AN22 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[1]} \
+ -pin_name AN21 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[2]} \
+ -pin_name AM24 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[3]} \
+ -pin_name AN24 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[4]} \
+ -pin_name AP21 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[5]} \
+ -pin_name AP20 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[6]} \
+ -pin_name AP19 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[7]} \
+ -pin_name AN19 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[8]} \
+ -pin_name AM21 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[9]} \
+ -pin_name AK22 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[10]} \
+ -pin_name AK21 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[11]} \
+ -pin_name AK20 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[12]} \
+ -pin_name AJ20 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[13]} \
+ -pin_name AH21 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[14]} \
+ -pin_name AG21 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name {ddr_DQ[15]} \
+ -pin_name AM19 \
+ -fixed true \
+ -DIRECTION INOUT
+
+
+set_io -port_name ddr_ODT \
+ -pin_name AF23 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ddr_RAS_N \
+ -pin_name AE23 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ddr_RESET_N \
+ -pin_name AG22 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ddr_SHIELD0 \
+ -pin_name AM22 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ddr_SHIELD1 \
+ -pin_name AM20 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ddr_WE_N \
+ -pin_name AF24 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_PCIe_fp.pdc b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_PCIe_fp.pdc
new file mode 100644
index 0000000..46d891f
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_PCIe_fp.pdc
@@ -0,0 +1,29 @@
+# Microsemi Physical design constraints file
+
+# Version: PolarFire v2.0 12.200.0.20
+
+# Design Name: U500PolarFireEvalKitFPGAChip
+
+# Input Netlist Format: EDIF
+
+# Family: PolarFire , Die: MPF300TS_ES , Package: FCG1152 , Speed grade: -1
+
+# Date generated: Mon Jan 8 10:19:51 2018
+
+
+#
+# Local clock constraints
+#
+
+
+#
+# Region constraints
+#
+
+
+#
+# Core cell constraints
+#
+
+set_location -inst_name pf_xcvr_ref_clk/transceiver_refclk_0/I_IO -fixed true -x 2468 -y 236
+set_location -inst_name pf_tx_pll/transmit_pll_0/txpll_isnt_0 -fixed true -x 2466 -y 239
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_PCIe_io.pdc b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_PCIe_io.pdc
new file mode 100644
index 0000000..f6a68f4
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_PCIe_io.pdc
@@ -0,0 +1,133 @@
+# Microsemi I/O Physical Design Constraints file
+
+# User I/O Constraints file
+
+# Version: PolarFire v2.1 12.200.10.7
+
+# Family: PolarFire , Die: MPF300TS_ES , Package: FCG1152
+
+# Date generated: Fri Feb 9 16:31:44 2018
+
+#
+# User Locked I/O Bank Settings
+#
+
+#
+# Unlocked I/O Bank Settings
+# The I/O Bank Settings can be locked by directly editing this file
+# or by making changes in the I/O Attribute Editor
+#
+
+#
+# User Locked I/O settings
+#
+
+
+
+#
+# Dedicated Peripheral I/O Settings
+#
+
+
+#
+# Unlocked I/O settings
+# The I/Os in this section are unplaced or placed but are not locked
+# the other listed attributes have been applied
+#
+
+
+#
+#Ports using Dedicated Pins
+
+#
+
+set_io -port_name pcie_PCIESS_LANE_RXD0_N \
+ -pin_name V30 \
+ -DIRECTION INPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_RXD0_P \
+ -pin_name V29 \
+ -DIRECTION INPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_RXD1_N \
+ -pin_name W32 \
+ -DIRECTION INPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_RXD1_P \
+ -pin_name W31 \
+ -DIRECTION INPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_RXD2_N \
+ -pin_name Y30 \
+ -DIRECTION INPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_RXD2_P \
+ -pin_name Y29 \
+ -DIRECTION INPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_RXD3_N \
+ -pin_name AB30 \
+ -DIRECTION INPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_RXD3_P \
+ -pin_name AB29 \
+ -DIRECTION INPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_TXD0_N \
+ -pin_name V34 \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_TXD0_P \
+ -pin_name V33 \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_TXD1_N \
+ -pin_name Y34 \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_TXD1_P \
+ -pin_name Y33 \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_TXD2_N \
+ -pin_name AA32 \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_TXD2_P \
+ -pin_name AA31 \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_TXD3_N \
+ -pin_name AB34 \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name pcie_PCIESS_LANE_TXD3_P \
+ -pin_name AB33 \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ref_clk_pad_n \
+ -pin_name W28 \
+ -DIRECTION INPUT
+
+
+set_io -port_name ref_clk_pad_p \
+ -pin_name W27 \
+ -DIRECTION INPUT
+
+
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_base_io.pdc b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_base_io.pdc
new file mode 100644
index 0000000..9466a66
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_base_io.pdc
@@ -0,0 +1,199 @@
+# Microsemi I/O Physical Design Constraints file
+
+#
+# User Locked I/O Bank Settings
+#
+
+#
+# Unlocked I/O Bank Settings
+# The I/O Bank Settings can be locked by directly editing this file
+# or by making changes in the I/O Attribute Editor
+#
+
+#
+# User Locked I/O settings
+#
+
+#set_io -port_name btn_0 \
+# -pin_name B19 \
+# -fixed true \
+# -DIRECTION OUTPUT
+
+
+#set_io -port_name btn_1 \
+# -pin_name C21 \
+# -fixed true \
+# -DIRECTION OUTPUT
+
+
+#set_io -port_name btn_2 \
+# -pin_name A25 \
+# -fixed true \
+# -DIRECTION OUTPUT
+
+
+#set_io -port_name btn_3 \
+# -pin_name B27 \
+# -fixed true \
+# -DIRECTION OUTPUT
+
+
+set_io -port_name led_0 \
+ -pin_name F22 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name led_1 \
+ -pin_name B26 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name led_2 \
+ -pin_name C26 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name led_3 \
+ -pin_name D25 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name led_4 \
+ -pin_name C27 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name led_5 \
+ -pin_name F23 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name led_6 \
+ -pin_name H22 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name led_7 \
+ -pin_name H21 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name ref_clk0 \
+ -pin_name E25 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name pf_user_reset_n \
+ -pin_name K22 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+#set_io -port_name uart_rx \
+# -pin_name H18 \
+# -fixed true \
+# -DIRECTION INPUT
+
+
+set_io -port_name uart_tx \
+ -pin_name G17 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+#
+# SPI flash
+#
+
+set_io -port_name spi_flash_hold \
+ -pin_name A22 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name spi_flash_reset \
+ -pin_name A24 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name spi_flash_sck \
+ -pin_name H19 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+#set_io -port_name spi_flash_sdi \
+# -pin_name C18 \
+# -fixed true \
+# -DIRECTION INPUT
+
+
+set_io -port_name spi_flash_sdo \
+ -pin_name G19 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name spi_flash_ss \
+ -pin_name A20 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name spi_flash_wp \
+ -pin_name A27 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+#
+# Debug
+#
+
+set_io -port_name debug_io1 \
+ -pin_name C17 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name debug_io2 \
+ -pin_name A17 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name debug_io3 \
+ -pin_name B17 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name debug_io4 \
+ -pin_name A18 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+set_io -port_name ddr_CTRLR_READY \
+ -pin_name A19 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name jtag_TDO \
+ -pin_name A3 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+
+
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_fp.pdc b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_fp.pdc
new file mode 100644
index 0000000..e813990
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/PF_EvalKit_fp.pdc
@@ -0,0 +1,3 @@
+
+set_location -inst_name hart_clk_ccc/hart_clk_ccc_0/pll_inst_0 -fixed true -x 2461 -y 377
+set_location -inst_name ddr3_clk_ccc/ddr3_clk_ccc_0/pll_inst_0 -fixed true -x 2460 -y 5
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/chiplink_io.pdc b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/chiplink_io.pdc
new file mode 100644
index 0000000..8b45d2c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/chiplink_io.pdc
@@ -0,0 +1,432 @@
+# Microsemi I/O Physical Design Constraints file
+
+# User I/O Constraints file
+
+# Version: PolarFire v2.0 12.200.0.20
+
+# Family: PolarFire , Die: MPF300TS_ES , Package: FCG1152
+
+#
+# Chiplink IOs
+#
+
+set_io -port_name chiplink_b2c_clk \
+ -pin_name D13 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[0]} \
+ -pin_name H9 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[1]} \
+ -pin_name H8 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[2]} \
+ -pin_name G9 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[3]} \
+ -pin_name F9 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[4]} \
+ -pin_name L19 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[5]} \
+ -pin_name L18 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[6]} \
+ -pin_name H16 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[7]} \
+ -pin_name H17 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[8]} \
+ -pin_name J18 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[9]} \
+ -pin_name J19 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[10]} \
+ -pin_name F14 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[11]} \
+ -pin_name F15 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[12]} \
+ -pin_name G15 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[13]} \
+ -pin_name G16 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[14]} \
+ -pin_name K15 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[15]} \
+ -pin_name J15 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[16]} \
+ -pin_name J14 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[17]} \
+ -pin_name J13 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[18]} \
+ -pin_name L17 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[19]} \
+ -pin_name M17 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[20]} \
+ -pin_name J16 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[21]} \
+ -pin_name K16 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[22]} \
+ -pin_name K18 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[23]} \
+ -pin_name K17 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[24]} \
+ -pin_name F12 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[25]} \
+ -pin_name E12 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[26]} \
+ -pin_name H14 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[27]} \
+ -pin_name G14 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[28]} \
+ -pin_name F13 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[29]} \
+ -pin_name E13 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[30]} \
+ -pin_name A7 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name {chiplink_b2c_data[31]} \
+ -pin_name A8 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name chiplink_b2c_rst \
+ -pin_name D11 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name chiplink_b2c_send \
+ -pin_name D10 \
+ -fixed true \
+ -DIRECTION INPUT
+
+
+set_io -port_name chiplink_c2b_clk \
+ -pin_name C11 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[0]} \
+ -pin_name F8 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[1]} \
+ -pin_name F7 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[2]} \
+ -pin_name G5 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[3]} \
+ -pin_name F5 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[4]} \
+ -pin_name C6 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[5]} \
+ -pin_name B6 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[6]} \
+ -pin_name B9 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[7]} \
+ -pin_name A9 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[8]} \
+ -pin_name H13 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[9]} \
+ -pin_name H12 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[10]} \
+ -pin_name D8 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[11]} \
+ -pin_name C8 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[12]} \
+ -pin_name C7 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[13]} \
+ -pin_name B7 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[14]} \
+ -pin_name E10 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[15]} \
+ -pin_name E11 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[16]} \
+ -pin_name J11 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[17]} \
+ -pin_name H11 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[18]} \
+ -pin_name G12 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[19]} \
+ -pin_name G11 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[20]} \
+ -pin_name E6 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[21]} \
+ -pin_name D6 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[22]} \
+ -pin_name D9 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[23]} \
+ -pin_name C9 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[24]} \
+ -pin_name B10 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[25]} \
+ -pin_name A10 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[26]} \
+ -pin_name G10 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[27]} \
+ -pin_name F10 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[28]} \
+ -pin_name E7 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[29]} \
+ -pin_name E8 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[30]} \
+ -pin_name E1 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name {chiplink_c2b_data[31]} \
+ -pin_name D1 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name chiplink_c2b_rst \
+ -pin_name G7 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
+set_io -port_name chiplink_c2b_send \
+ -pin_name H7 \
+ -fixed true \
+ -DIRECTION OUTPUT
+
+
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/clock_groups.sdc b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/clock_groups.sdc
new file mode 100644
index 0000000..77ebb48
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/polarfireevalkit/constraints/clock_groups.sdc
@@ -0,0 +1,5 @@
+#set_clock_groups -name {Coreplex} -logically_exclusive -group [ get_clocks { hart_clk_ccc/hart_clk_ccc_0/pll_inst_0/OUT0 } ]
+set_clock_groups -name {PCIe_AXI} -logically_exclusive -group [ get_clocks { hart_clk_ccc/hart_clk_ccc_0/pll_inst_0/OUT1 } ]
+set_clock_groups -name {DDR_subsystem} -logically_exclusive -group [ get_clocks { iofpga/polarfireddr/island/blackbox/CCC_0/pll_inst_0/OUT1 } ]
+
+
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/vera/constraints/false_paths.sdc b/hdl_cores/freedom/fpga-shells/microsemi/vera/constraints/false_paths.sdc
new file mode 100644
index 0000000..4aed0fe
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/vera/constraints/false_paths.sdc
@@ -0,0 +1,41 @@
+set_false_path -from [ get_ports { ereset_n }]
+create_clock -name {chiplink_b2c_clk} -period 8 [ get_ports { chiplink_b2c_clk } ]
+
+# The c2b_clk comes from a phase-shifted output of the PLL
+create_generated_clock -name {chiplink_c2b_clk} \
+ -divide_by 1 -phase 0 \
+ -source [ get_pins { hart_clk_ccc/hart_clk_ccc_0/pll_inst_0/OUT2 } ] \
+ [ get_ports { chiplink_c2b_clk } ]
+
+set_clock_groups -asynchronous \
+ -group [ get_clocks { chiplink_b2c_clk \
+ iofpga/chiplink_rx_pll/chiplink_rx_pll_0/pll_inst_0/OUT1 } ] \
+ -group [ get_clocks { ref_clk0 \
+ hart_clk_ccc/hart_clk_ccc_0/pll_inst_0/OUT1 \
+ hart_clk_ccc/hart_clk_ccc_0/pll_inst_0/OUT2 \
+ chiplink_c2b_clk } ] \
+ -group [ get_clocks { osc_rc160mhz } ] \
+ -group [ get_clocks { ref_clk_pad_p } ] \
+ -group [ get_clocks { iofpga/pf_ddr4/island/blackbox/CCC_0/pll_inst_0/OUT1 } ]
+
+# RX side: want to latch almost anywhere except on the rising edge of the clock
+# The data signals coming from Aloe have: clock - 1.2 <= transition <= clock + 0.8
+# HFU500 Expansion board has 200mil delta between clock and data
+# Let's add 0.1ns of safety for trace jitter+skew on both sides:
+# min = hold = -1.2 - 0.1
+# max = period - setup = 0.8 + 0.1
+set_input_delay -min -1.3 -clock {chiplink_b2c_clk} [ get_ports { chiplink_b2c_data* chiplink_b2c_rst chiplink_b2c_send } ]
+set_input_delay -max 0.9 -clock {chiplink_b2c_clk} [ get_ports { chiplink_b2c_data* chiplink_b2c_rst chiplink_b2c_send } ]
+
+# TX side: want to transition almost anywhere except on the rising edge of the clock
+# The data signals going to Aloe must have: clock - 1.85 <= NO transition <= clock + 0.65
+# Let's add 0.6ns of safey for trace jitter+skew on both sides:
+# min = -hold = -0.65 - 0.6
+# max = setup = 1.85 + 0.6
+set_output_delay -min -1.25 -clock {chiplink_c2b_clk} [ get_ports { chiplink_c2b_data* chiplink_c2b_rst chiplink_c2b_send } ]
+set_output_delay -max 2.45 -clock {chiplink_c2b_clk} [ get_ports { chiplink_c2b_data* chiplink_c2b_rst chiplink_c2b_send } ]
+# phase = 31.5 -> 0.55ns setup slack, 0.45ns hold slack
+
+#retiming is required
+set_false_path -from [ get_pins { iofpga/link/ResetCatchAndSync_d3_1/AsyncResetSynchronizerShiftReg_w1_d3_i0/sync_2/reg_0/q/CLK } ] -to [ get_ports { chiplink_c2b_rst } ]
+set_false_path -from [ get_ports { chiplink_b2c_rst } ] -to [ get_pins { iofpga/link/AsyncResetReg/q/D } ]
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/vera/constraints/floor_plan.pdc b/hdl_cores/freedom/fpga-shells/microsemi/vera/constraints/floor_plan.pdc
new file mode 100644
index 0000000..68f37ef
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/vera/constraints/floor_plan.pdc
@@ -0,0 +1,4 @@
+# Constraints
+
+set_location -inst_name corePLL/corePLL_0/pll_inst_0 -fixed true -x 1 -y 377
+set_location -inst_name rxPLL/rxPLL_0/pll_inst_0 -fixed true -x 0 -y 377
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/vera/constraints/pin_constraints.pdc b/hdl_cores/freedom/fpga-shells/microsemi/vera/constraints/pin_constraints.pdc
new file mode 100644
index 0000000..673fd31
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/vera/constraints/pin_constraints.pdc
@@ -0,0 +1,11 @@
+#
+# User Locked I/O Bank Settings
+#
+
+set_iobank -bank_name Bank0 -vcci 1.80 -fixed true
+set_iobank -bank_name Bank1 -vcci 1.20 -fixed true
+set_iobank -bank_name Bank2 -vcci 3.30 -fixed true
+set_iobank -bank_name Bank4 -vcci 1.80 -fixed true
+set_iobank -bank_name Bank5 -vcci 3.30 -fixed true
+set_iobank -bank_name Bank6 -vcci 1.80 -fixed true
+set_iobank -bank_name Bank7 -vcci 1.80 -fixed true
diff --git a/hdl_cores/freedom/fpga-shells/microsemi/vera/tcl/board.tcl b/hdl_cores/freedom/fpga-shells/microsemi/vera/tcl/board.tcl
new file mode 100644
index 0000000..6c743fd
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/microsemi/vera/tcl/board.tcl
@@ -0,0 +1,12 @@
+#Device Selection
+set family {PolarFire}
+set die {MPF300TS_ES}
+set package {FCG1152}
+set speed {-1}
+set die_voltage {1.0}
+set part_range {EXT}
+
+#Device Settings
+set IOTech {LVCMOS 1.8V}
+set ResProbe {1}
+set ResSPI {0}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/Bundles.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/Bundles.scala
new file mode 100644
index 0000000..7fa93bd
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/Bundles.scala
@@ -0,0 +1,17 @@
+// See LICENSE.SiFive for license details.
+package sifive.fpgashells.clocks
+
+import Chisel._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.util._
+
+class ClockBundle(params: ClockBundleParameters) extends GenericParameterizedBundle(params)
+{
+ val clock = Clock()
+ val reset = Bool()
+}
+
+class ClockGroupBundle(params: ClockGroupBundleParameters) extends GenericParameterizedBundle(params)
+{
+ val member = HeterogeneousBag(params.members.map(p => new ClockBundle(p)))
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/ClockGroup.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/ClockGroup.scala
new file mode 100644
index 0000000..aa09e02
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/ClockGroup.scala
@@ -0,0 +1,33 @@
+// See LICENSE.SiFive for license details.
+package sifive.fpgashells.clocks
+
+import Chisel._
+import chisel3.internal.sourceinfo.SourceInfo
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.diplomacy._
+
+case class ClockGroupNode(groupName: String)(implicit valName: ValName)
+ extends MixedNexusNode(ClockGroupImp, ClockImp)(
+ dFn = { _ => ClockSourceParameters() },
+ uFn = { seq => ClockGroupSinkParameters(name = groupName, members = seq) })
+
+class ClockGroup(groupName: String)(implicit p: Parameters) extends LazyModule
+{
+ val node = ClockGroupNode(groupName)
+
+ lazy val module = new LazyModuleImp(this) {
+ val (in, _) = node.in(0)
+ val (out, _) = node.out.unzip
+
+ require (node.in.size == 1)
+ require (in.member.size == out.size)
+
+ (in.member zip out) foreach { case (i, o) => o := i }
+ }
+}
+
+object ClockGroup
+{
+ def apply()(implicit p: Parameters, valName: ValName) =
+ LazyModule(new ClockGroup(valName.name)).node
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/Nodes.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/Nodes.scala
new file mode 100644
index 0000000..2593bf5
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/Nodes.scala
@@ -0,0 +1,70 @@
+// See LICENSE.SiFive for license details.
+package sifive.fpgashells.clocks
+
+import Chisel._
+import chisel3.internal.sourceinfo.SourceInfo
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.diplomacy._
+
+object ClockImp extends SimpleNodeImp[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle]
+{
+ def edge(pd: ClockSourceParameters, pu: ClockSinkParameters, p: Parameters, sourceInfo: SourceInfo) = ClockEdgeParameters(pd, pu, p, sourceInfo)
+ def bundle(e: ClockEdgeParameters) = new ClockBundle(e.bundle)
+ def render(e: ClockEdgeParameters) = RenderedEdge(colour = "#00cc00" /* green */)
+}
+
+case class ClockSourceNode(val portParams: Seq[ClockSourceParameters])(implicit valName: ValName) extends SourceNode(ClockImp)(portParams)
+case class ClockSinkNode(val portParams: Seq[ClockSinkParameters])(implicit valName: ValName) extends SinkNode(ClockImp)(portParams)
+case class ClockAdapterNode(
+ sourceFn: ClockSourceParameters => ClockSourceParameters = { m => m },
+ sinkFn: ClockSinkParameters => ClockSinkParameters = { s => s })(
+ implicit valName: ValName)
+ extends AdapterNode(ClockImp)(sourceFn, sinkFn)
+case class ClockIdentityNode()(implicit valName: ValName) extends IdentityNode(ClockImp)()
+
+object ClockSinkNode
+{
+ def apply(
+ freqMHz: Double,
+ dutyCycle: Double = 50,
+ phaseDeg: Double = 0,
+ // Create SDC/TCL constraints that the clock matches these requirements:
+ phaseErrorDeg: Double = 5,
+ freqErrorPPM: Double = 10000,
+ jitterPS: Double = 300)(implicit valName: ValName): ClockSinkNode =
+ ClockSinkNode(Seq(ClockSinkParameters(
+ phaseDeg = phaseDeg,
+ phaseErrorDeg = phaseErrorDeg,
+ freqErrorPPM = freqErrorPPM,
+ jitterPS = jitterPS,
+ take = Some(ClockParameters(
+ freqMHz = freqMHz,
+ dutyCycle = dutyCycle)))))
+}
+
+object ClockSourceNode
+{
+ def apply(
+ freqMHz: Double,
+ dutyCycle: Double = 50,
+ jitterPS: Double = 300)(implicit valName: ValName): ClockSourceNode =
+ ClockSourceNode(Seq(ClockSourceParameters(
+ jitterPS = Some(jitterPS),
+ give = Some(ClockParameters(
+ freqMHz = freqMHz,
+ dutyCycle = dutyCycle)))))
+}
+
+object ClockGroupImp extends SimpleNodeImp[ClockGroupSourceParameters, ClockGroupSinkParameters, ClockGroupEdgeParameters, ClockGroupBundle]
+{
+ def edge(pd: ClockGroupSourceParameters, pu: ClockGroupSinkParameters, p: Parameters, sourceInfo: SourceInfo) = ClockGroupEdgeParameters(pd, pu, p, sourceInfo)
+ def bundle(e: ClockGroupEdgeParameters) = new ClockGroupBundle(e.bundle)
+ def render(e: ClockGroupEdgeParameters) = RenderedEdge(colour = "#00cc00" /* green */)
+}
+
+case class ClockGroupAdapterNode(
+ sourceFn: ClockGroupSourceParameters => ClockGroupSourceParameters = { m => m },
+ sinkFn: ClockGroupSinkParameters => ClockGroupSinkParameters = { s => s })(
+ implicit valName: ValName)
+ extends AdapterNode(ClockGroupImp)(sourceFn, sinkFn)
+case class ClockGroupIdentityNode()(implicit valName: ValName) extends IdentityNode(ClockGroupImp)()
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/PLLFactory.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/PLLFactory.scala
new file mode 100644
index 0000000..7f76285
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/PLLFactory.scala
@@ -0,0 +1,98 @@
+// See LICENSE for license details.
+package sifive.fpgashells.clocks
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import scala.collection.immutable.ListMap
+
+case class PLLNode(val feedback: Boolean)(implicit valName: ValName)
+ extends MixedNexusNode(ClockImp, ClockGroupImp)(
+ dFn = { _ => ClockGroupSourceParameters() },
+ uFn = { _ => ClockSinkParameters() })
+
+case class PLLInClockParameters(
+ freqMHz: Double,
+ jitter: Double = 50,
+ feedback: Boolean = false)
+
+case class PLLOutClockParameters(
+ freqMHz: Double,
+ phaseDeg: Double = 0,
+ dutyCycle: Double = 50, // in percent
+ // used to create constraints:
+ jitterPS: Double = 300,
+ freqErrorPPM: Double = 10000,
+ phaseErrorDeg: Double = 5)
+
+case class PLLParameters(
+ name: String,
+ input: PLLInClockParameters,
+ req: Seq[PLLOutClockParameters])
+
+trait PLLInstance {
+ def getInput: Clock
+ def getReset: Option[Bool]
+ def getLocked: Bool
+ def getClocks: Seq[Clock]
+ def getClockNames: Seq[String]
+}
+
+case object PLLFactoryKey extends Field[PLLFactory]
+class PLLFactory(scope: IOShell, maxOutputs: Int, gen: PLLParameters => PLLInstance)
+{
+ private var pllNodes: Seq[PLLNode] = Nil
+
+ def apply(feedback: Boolean = false)(implicit valName: ValName, p: Parameters): PLLNode = {
+ val node = scope { PLLNode(feedback) }
+ pllNodes = node +: pllNodes
+ node
+ }
+
+ val plls: ModuleValue[Seq[(PLLInstance, PLLNode)]] = scope { InModuleBody {
+ val plls = pllNodes.flatMap { case node =>
+ require (node.in.size == 1)
+ val (in, edgeIn) = node.in(0)
+ val (out, edgeOut) = node.out.unzip
+
+ val params = PLLParameters(
+ name = node.valName.name,
+ input = PLLInClockParameters(
+ freqMHz = edgeIn.clock.freqMHz,
+ jitter = edgeIn.source.jitterPS.getOrElse(50),
+ feedback = node.feedback),
+ req = edgeOut.flatMap(_.members).map { e =>
+ PLLOutClockParameters(
+ freqMHz = e.clock.freqMHz,
+ phaseDeg = e.sink.phaseDeg,
+ dutyCycle = e.clock.dutyCycle,
+ jitterPS = e.sink.jitterPS,
+ freqErrorPPM = e.sink.freqErrorPPM,
+ phaseErrorDeg = e.sink.phaseErrorDeg)})
+
+ val pll = gen(params)
+ pll.getInput := in.clock
+ pll.getReset.foreach { _ := in.reset }
+ (out.flatMap(_.member) zip pll.getClocks) foreach { case (o, i) =>
+ o.clock := i
+ o.reset := !pll.getLocked || in.reset
+ }
+ Some((pll, node))
+ }
+
+ // Require all clock group names to be distinct
+ val sdcGroups = Map() ++ plls.flatMap { case tuple =>
+ val (pll, node) = tuple
+ val (out, edgeOut) = node.out.unzip
+ val groupLabels = edgeOut.flatMap(e => Seq.fill(e.members.size) { e.sink.name })
+ groupLabels zip pll.getClocks.map(x => IOPin(x))
+ }.groupBy(_._1).mapValues(_.map(_._2))
+
+ // Ensure there are no clock groups with the same name
+ require (sdcGroups.size == pllNodes.map(_.edges.out.size).sum)
+ sdcGroups.foreach { case (_, clockPins) => scope.sdc.addGroup(pins = clockPins) }
+
+ plls
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/Parameters.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/Parameters.scala
new file mode 100644
index 0000000..80477d4
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/Parameters.scala
@@ -0,0 +1,77 @@
+// See LICENSE.SiFive for license details.
+package sifive.fpgashells.clocks
+
+import Chisel._
+import chisel3.internal.sourceinfo.SourceInfo
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.diplomacy._
+import scala.math.max
+
+// All Clock parameters specify only the PLL values required at power-on
+// Dynamic control of the PLL from software can take the values out-of-range
+
+case class ClockParameters(
+ freqMHz: Double,
+ dutyCycle: Double = 50) //in percent
+{
+ require (freqMHz > 0)
+ require (0 < dutyCycle)
+ require (dutyCycle < 100)
+}
+
+case class ClockSourceParameters(
+ jitterPS: Option[Double] = None, // if known at chisel elaboration
+ give: Option[ClockParameters] = None)
+
+case class ClockSinkParameters(
+ phaseDeg: Double = 0,
+ // Create SDC/TCL constraints that the clock matches these requirements:
+ phaseErrorDeg: Double = 5,
+ freqErrorPPM: Double = 10000,
+ jitterPS: Double = 200,
+ take: Option[ClockParameters] = None)
+{
+ require (phaseErrorDeg >= 0)
+ require (freqErrorPPM >= 0)
+}
+
+case class ClockBundleParameters()
+
+case class ClockEdgeParameters(
+ source: ClockSourceParameters,
+ sink: ClockSinkParameters,
+ params: Parameters,
+ sourceInfo: SourceInfo)
+{
+ // Unify the given+taken ClockParameters
+ require (!source.give.isEmpty || !sink.take.isEmpty)
+ val clock = source.give.orElse(sink.take).get
+ source.give.foreach { x => require (clock == x) }
+ sink.take.foreach { x => require (clock == x) }
+
+ val bundle = ClockBundleParameters()
+}
+
+// ClockGroups exist as the output of a PLL
+
+case class ClockGroupSourceParameters()
+case class ClockGroupSinkParameters(
+ name: String,
+ members: Seq[ClockSinkParameters])
+
+case class ClockGroupBundleParameters(
+ members: Seq[ClockBundleParameters])
+
+case class ClockGroupEdgeParameters(
+ source: ClockGroupSourceParameters,
+ sink: ClockGroupSinkParameters,
+ params: Parameters,
+ sourceInfo: SourceInfo)
+{
+ val sourceParameters = ClockSourceParameters()
+ val members = sink.members.map { s =>
+ ClockEdgeParameters(sourceParameters, s, params, sourceInfo)
+ }
+
+ val bundle = ClockGroupBundleParameters(members.map(_.bundle))
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/ResetWrangler.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/ResetWrangler.scala
new file mode 100644
index 0000000..2e7f4b4
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/clocks/ResetWrangler.scala
@@ -0,0 +1,43 @@
+// See LICENSE for license details.
+package sifive.fpgashells.clocks
+
+import chisel3._
+import chisel3.util._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.util._
+
+class ResetWrangler(debounceNs: Double = 100000)(implicit p: Parameters) extends LazyModule
+{
+ val node = ClockAdapterNode()
+
+ lazy val module = new LazyRawModuleImp(this) {
+ val (in, _) = node.in.unzip
+ val (out, _) = node.out.unzip
+
+ val status = IO(Output(UInt(in.size.W)))
+ status := Cat(in.map(_.reset).reverse)
+
+ val causes = in.map(_.reset).foldLeft(false.B)(_ || _)
+ val (slowIn, slowEdge) = node.in.minBy(_._2.clock.freqMHz)
+ val slowPeriodNs = 1000 / slowEdge.clock.freqMHz
+ val slowTicks = math.ceil(debounceNs/slowPeriodNs).toInt max 7
+ val slowBits = log2Ceil(slowTicks+1)
+
+ // debounce
+ val increment = Wire(Bool())
+ val incremented = Wire(UInt(slowBits.W))
+ val debounced = withClockAndReset(slowIn.clock, causes) {
+ AsyncResetReg(incremented, 0, increment, Some("debounce"))
+ }
+ increment := debounced =/= slowTicks.U
+ incremented := debounced + 1.U
+ val deglitched = AsyncResetReg(increment, slowIn.clock, causes, true, Some("deglitch"))
+
+ // catch and sync increment to each domain
+ (in zip out) foreach { case (i, o) =>
+ o.clock := i.clock
+ o.reset := ResetCatchAndSync(o.clock, deglitched)
+ }
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr3/MicrosemiPolarFireDDR3.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr3/MicrosemiPolarFireDDR3.scala
new file mode 100644
index 0000000..0cd535c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr3/MicrosemiPolarFireDDR3.scala
@@ -0,0 +1,165 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.microsemi.polarfireddr3
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.config.Parameters
+//import freechips.rocketchip.coreplex._
+import freechips.rocketchip.subsystem._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import sifive.fpgashells.ip.microsemi.polarfireddr3.{PolarFireEvalKitDDR3IOClocksReset, PolarFireEvalKitDDR3IODDR, DDR3_Subsys}
+
+case class PolarFireEvalKitDDR3Params(
+ address : Seq[AddressSet]
+)
+
+class PolarFireEvalKitDDR3Pads(depth : BigInt) extends PolarFireEvalKitDDR3IODDR(depth) {
+ def this(c : PolarFireEvalKitDDR3Params) {
+ this(AddressRange.fromSets(c.address).head.size)
+ }
+}
+
+class PolarFireEvalKitDDR3IO(depth : BigInt) extends PolarFireEvalKitDDR3IODDR(depth) with PolarFireEvalKitDDR3IOClocksReset
+
+class PolarFireEvalKitDDR3Island(c : PolarFireEvalKitDDR3Params)(implicit p: Parameters) extends LazyModule with CrossesToOnlyOneClockDomain {
+ val ranges = AddressRange.fromSets(c.address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val offset = ranges.head.base
+ val depth = ranges.head.size
+ val crossing = AsynchronousCrossing(8)
+
+ require((depth<=0x100000000L),"PolarFire Evaluation Kit supports upto 4GB depth configuraton")
+
+ val device = new MemoryDevice
+ val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = c.address,
+ resources = device.reg,
+ regionType = RegionType.UNCACHED,
+ executable = true,
+ supportsWrite = TransferSizes(1, 256*8),
+ supportsRead = TransferSizes(1, 256*8))),
+ beatBytes = 8)))
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new PolarFireEvalKitDDR3IO(depth)
+ })
+
+ //MIG black box instantiation
+ val blackbox = Module(new DDR3_Subsys(depth))
+ val (axi_async, _) = node.in(0)
+
+ //pins to top level
+
+ //inouts
+ attach(io.port.DQ,blackbox.io.DQ)
+ attach(io.port.DQS_N,blackbox.io.DQS_N)
+ attach(io.port.DQS,blackbox.io.DQS)
+
+ //outputs
+ io.port.A := blackbox.io.A
+ io.port.BA := blackbox.io.BA
+ io.port.RAS_N := blackbox.io.RAS_N
+ io.port.CAS_N := blackbox.io.CAS_N
+ io.port.WE_N := blackbox.io.WE_N
+ io.port.RESET_N := blackbox.io.RESET_N
+ io.port.CK0 := blackbox.io.CK0
+ io.port.CK0_N := blackbox.io.CK0_N
+ io.port.CKE := blackbox.io.CKE
+ io.port.CS_N := blackbox.io.CS_N
+ io.port.DM := blackbox.io.DM
+ io.port.ODT := blackbox.io.ODT
+
+ io.port.CTRLR_READY := blackbox.io.CTRLR_READY
+ io.port.SHIELD0 := blackbox.io.SHIELD0
+ io.port.SHIELD1 := blackbox.io.SHIELD1
+
+ //inputs
+ val awaddr = axi_async.aw.bits.addr - UInt(offset)
+ val araddr = axi_async.ar.bits.addr - UInt(offset)
+
+ //slave AXI interface write address ports
+ blackbox.io.axi0_awid := axi_async.aw.bits.id
+ blackbox.io.axi0_awaddr := awaddr //truncated
+ blackbox.io.axi0_awlen := axi_async.aw.bits.len
+ blackbox.io.axi0_awsize := axi_async.aw.bits.size
+ blackbox.io.axi0_awburst := axi_async.aw.bits.burst
+ blackbox.io.axi0_awlock := axi_async.aw.bits.lock
+ blackbox.io.axi0_awcache := UInt("b0011")
+ blackbox.io.axi0_awprot := axi_async.aw.bits.prot
+ blackbox.io.axi0_awvalid := axi_async.aw.valid
+ axi_async.aw.ready := blackbox.io.axi0_awready
+
+ //slave interface write data ports
+ blackbox.io.axi0_wdata := axi_async.w.bits.data
+ blackbox.io.axi0_wstrb := axi_async.w.bits.strb
+ blackbox.io.axi0_wlast := axi_async.w.bits.last
+ blackbox.io.axi0_wvalid := axi_async.w.valid
+ axi_async.w.ready := blackbox.io.axi0_wready
+
+ //slave interface write response
+ blackbox.io.axi0_bready := axi_async.b.ready
+ axi_async.b.bits.id := blackbox.io.axi0_bid
+ axi_async.b.bits.resp := blackbox.io.axi0_bresp
+ axi_async.b.valid := blackbox.io.axi0_bvalid
+
+ //slave AXI interface read address ports
+ blackbox.io.axi0_arid := axi_async.ar.bits.id
+ blackbox.io.axi0_araddr := araddr // truncated
+ blackbox.io.axi0_arlen := axi_async.ar.bits.len
+ blackbox.io.axi0_arsize := axi_async.ar.bits.size
+ blackbox.io.axi0_arburst := axi_async.ar.bits.burst
+ blackbox.io.axi0_arlock := axi_async.ar.bits.lock
+ blackbox.io.axi0_arcache := UInt("b0011")
+ blackbox.io.axi0_arprot := axi_async.ar.bits.prot
+ blackbox.io.axi0_arvalid := axi_async.ar.valid
+ axi_async.ar.ready := blackbox.io.axi0_arready
+
+ //slace AXI interface read data ports
+ blackbox.io.axi0_rready := axi_async.r.ready
+ axi_async.r.bits.id := blackbox.io.axi0_rid
+ axi_async.r.bits.data := blackbox.io.axi0_rdata
+ axi_async.r.bits.resp := blackbox.io.axi0_rresp
+ axi_async.r.bits.last := blackbox.io.axi0_rlast
+ axi_async.r.valid := blackbox.io.axi0_rvalid
+
+ //misc
+ blackbox.io.AXI0_AWUSERTAG := UInt("b0000")
+ blackbox.io.SYS_RESET_N :=io.port.SYS_RESET_N
+ blackbox.io.PLL_REF_CLK :=io.port.PLL_REF_CLK
+
+ io.port.SYS_CLK := blackbox.io.SYS_CLK
+ io.port.PLL_LOCK := blackbox.io.PLL_LOCK
+ }
+}
+
+class PolarFireEvalKitDDR3(c : PolarFireEvalKitDDR3Params)(implicit p: Parameters) extends LazyModule {
+ val ranges = AddressRange.fromSets(c.address)
+ val depth = ranges.head.size
+
+ val buffer = LazyModule(new TLBuffer)
+ val toaxi4 = LazyModule(new TLToAXI4(adapterName = Some("mem"), stripBits = 1))
+ val indexer = LazyModule(new AXI4IdIndexer(idBits = 4))
+ val deint = LazyModule(new AXI4Deinterleaver(p(CacheBlockBytes)))
+ val yank = LazyModule(new AXI4UserYanker)
+ val island = LazyModule(new PolarFireEvalKitDDR3Island(c))
+
+ val node: TLInwardNode =
+ island.crossAXI4In(island.node) := yank.node := deint.node := indexer.node := toaxi4.node := buffer.node
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new PolarFireEvalKitDDR3IO(depth)
+ })
+
+ io.port <> island.module.io.port
+
+ // Shove the island
+ island.module.clock := io.port.SYS_CLK
+ island.module.reset := !io.port.CTRLR_READY
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr3/MicrosemiPolarFireDDR3Periphery.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr3/MicrosemiPolarFireDDR3Periphery.scala
new file mode 100644
index 0000000..476218e
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr3/MicrosemiPolarFireDDR3Periphery.scala
@@ -0,0 +1,37 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.microsemi.polarfireddr3
+
+import Chisel._
+import freechips.rocketchip.config._
+//import freechips.rocketchip.coreplex.HasMemoryBus
+import freechips.rocketchip.subsystem.BaseSubsystem
+import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressRange}
+
+case object MemoryMicrosemiDDR3Key extends Field[PolarFireEvalKitDDR3Params]
+
+//trait HasMemoryPolarFireEvalKitDDR3 extends HasMemoryBus {
+trait HasMemoryPolarFireEvalKitDDR3 { this: BaseSubsystem =>
+ val module: HasMemoryPolarFireEvalKitDDR3ModuleImp
+
+ val polarfireddrsubsys = LazyModule(new PolarFireEvalKitDDR3(p(MemoryMicrosemiDDR3Key)))
+
+ polarfireddrsubsys.node := mbus.toDRAMController(Some("PolarFireDDR"))()
+}
+
+trait HasMemoryPolarFireEvalKitDDR3Bundle {
+ val polarfireddrsubsys: PolarFireEvalKitDDR3IO
+ def connectPolarFireEValKitDDR3ToPads(pads: PolarFireEvalKitDDR3Pads) {
+ pads <> polarfireddrsubsys
+ }
+}
+
+trait HasMemoryPolarFireEvalKitDDR3ModuleImp extends LazyModuleImp
+ with HasMemoryPolarFireEvalKitDDR3Bundle {
+ val outer: HasMemoryPolarFireEvalKitDDR3
+ val ranges = AddressRange.fromSets(p(MemoryMicrosemiDDR3Key).address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val depth = ranges.head.size
+ val polarfireddrsubsys = IO(new PolarFireEvalKitDDR3IO(depth))
+
+ polarfireddrsubsys <> outer.polarfireddrsubsys.module.io.port
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr4/MicrosemiPolarFireDDR4.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr4/MicrosemiPolarFireDDR4.scala
new file mode 100644
index 0000000..1274d29
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr4/MicrosemiPolarFireDDR4.scala
@@ -0,0 +1,166 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.microsemi.polarfireddr4
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.subsystem._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import sifive.fpgashells.ip.microsemi.polarfireddr4.{PolarFireEvalKitDDR4IOClocksReset, PolarFireEvalKitDDR4IODDR, DDR4_Subsys}
+
+case class PolarFireEvalKitDDR4Params(
+ address : Seq[AddressSet]
+)
+
+class PolarFireEvalKitDDR4Pads(depth : BigInt) extends PolarFireEvalKitDDR4IODDR(depth) {
+ def this(c : PolarFireEvalKitDDR4Params) {
+ this(AddressRange.fromSets(c.address).head.size)
+ }
+}
+
+class PolarFireEvalKitDDR4IO(depth : BigInt) extends PolarFireEvalKitDDR4IODDR(depth) with PolarFireEvalKitDDR4IOClocksReset
+
+class PolarFireEvalKitDDR4Island(c : PolarFireEvalKitDDR4Params)(implicit p: Parameters) extends LazyModule with HasCrossing {
+ val ranges = AddressRange.fromSets(c.address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val offset = ranges.head.base
+ val depth = ranges.head.size
+ val crossing = AsynchronousCrossing(8)
+ require((depth<=0x100000000L),"PF Eval Kit supports upto 4GB depth configuraton")
+
+ val device = new MemoryDevice
+ val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = c.address,
+ resources = device.reg,
+ regionType = RegionType.UNCACHED,
+ executable = true,
+ supportsWrite = TransferSizes(1, 128),
+ supportsRead = TransferSizes(1, 128))),
+ beatBytes = 8)))
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new PolarFireEvalKitDDR4IO(depth)
+ })
+
+ // DDR block black box instantiation
+ val blackbox = Module(new DDR4_Subsys(depth))
+ val (axi_async, _) = node.in(0)
+
+ //pins to top level
+
+ //inouts
+ attach(io.port.DQ,blackbox.io.DQ)
+ attach(io.port.DQS_N,blackbox.io.DQS_N)
+ attach(io.port.DQS,blackbox.io.DQS)
+
+ //outputs
+ io.port.A := blackbox.io.A
+ io.port.ACT_N := blackbox.io.ACT_N
+ io.port.BA := blackbox.io.BA
+ io.port.BG := blackbox.io.BG
+ io.port.RAS_N := blackbox.io.RAS_N
+ io.port.CAS_N := blackbox.io.CAS_N
+ io.port.WE_N := blackbox.io.WE_N
+ io.port.RESET_N := blackbox.io.RESET_N
+ io.port.CK0 := blackbox.io.CK0
+ io.port.CK0_N := blackbox.io.CK0_N
+ io.port.CKE := blackbox.io.CKE
+ io.port.CS_N := blackbox.io.CS_N
+ io.port.DM_N := blackbox.io.DM_N
+ io.port.ODT := blackbox.io.ODT
+
+ io.port.CTRLR_READY := blackbox.io.CTRLR_READY
+ io.port.SHIELD0 := blackbox.io.SHIELD0
+ io.port.SHIELD1 := blackbox.io.SHIELD1
+
+ //inputs
+ val awaddr = axi_async.aw.bits.addr - UInt(offset)
+ val araddr = axi_async.ar.bits.addr - UInt(offset)
+
+ //slave AXI interface write address ports
+ blackbox.io.axi0_awid := axi_async.aw.bits.id
+ blackbox.io.axi0_awaddr := awaddr //truncated
+ blackbox.io.axi0_awlen := axi_async.aw.bits.len
+ blackbox.io.axi0_awsize := axi_async.aw.bits.size
+ blackbox.io.axi0_awburst := axi_async.aw.bits.burst
+ blackbox.io.axi0_awlock := axi_async.aw.bits.lock
+ blackbox.io.axi0_awcache := UInt("b0011")
+ blackbox.io.axi0_awprot := axi_async.aw.bits.prot
+ blackbox.io.axi0_awvalid := axi_async.aw.valid
+ axi_async.aw.ready := blackbox.io.axi0_awready
+
+ //slave interface write data ports
+ blackbox.io.axi0_wdata := axi_async.w.bits.data
+ blackbox.io.axi0_wstrb := axi_async.w.bits.strb
+ blackbox.io.axi0_wlast := axi_async.w.bits.last
+ blackbox.io.axi0_wvalid := axi_async.w.valid
+ axi_async.w.ready := blackbox.io.axi0_wready
+
+ //slave interface write response
+ blackbox.io.axi0_bready := axi_async.b.ready
+ axi_async.b.bits.id := blackbox.io.axi0_bid
+ axi_async.b.bits.resp := blackbox.io.axi0_bresp
+ axi_async.b.valid := blackbox.io.axi0_bvalid
+
+ //slave AXI interface read address ports
+ blackbox.io.axi0_arid := axi_async.ar.bits.id
+ blackbox.io.axi0_araddr := araddr
+ blackbox.io.axi0_arlen := axi_async.ar.bits.len
+ blackbox.io.axi0_arsize := axi_async.ar.bits.size
+ blackbox.io.axi0_arburst := axi_async.ar.bits.burst
+ blackbox.io.axi0_arlock := axi_async.ar.bits.lock
+ blackbox.io.axi0_arcache := UInt("b0011")
+ blackbox.io.axi0_arprot := axi_async.ar.bits.prot
+ blackbox.io.axi0_arvalid := axi_async.ar.valid
+ axi_async.ar.ready := blackbox.io.axi0_arready
+
+ //slace AXI interface read data ports
+ blackbox.io.axi0_rready := axi_async.r.ready
+ axi_async.r.bits.id := blackbox.io.axi0_rid
+ axi_async.r.bits.data := blackbox.io.axi0_rdata
+ axi_async.r.bits.resp := blackbox.io.axi0_rresp
+ axi_async.r.bits.last := blackbox.io.axi0_rlast
+ axi_async.r.valid := blackbox.io.axi0_rvalid
+
+ //misc
+ //blackbox.io.AXI0_AWUSERTAG := UInt("b0000")
+ blackbox.io.SYS_RESET_N :=io.port.SYS_RESET_N
+ blackbox.io.PLL_REF_CLK :=io.port.PLL_REF_CLK
+
+ io.port.SYS_CLK := blackbox.io.SYS_CLK
+ io.port.RESET_N := blackbox.io.RESET_N
+ io.port.PLL_LOCK := blackbox.io.PLL_LOCK
+ }
+}
+
+class PolarFireEvalKitDDR4(c : PolarFireEvalKitDDR4Params)(implicit p: Parameters) extends LazyModule {
+ val ranges = AddressRange.fromSets(c.address)
+ val depth = ranges.head.size
+
+ val buffer = LazyModule(new TLBuffer)
+ val toaxi4 = LazyModule(new TLToAXI4(adapterName = Some("mem"), stripBits = 1))
+ val indexer = LazyModule(new AXI4IdIndexer(idBits = 4))
+ val deint = LazyModule(new AXI4Deinterleaver(p(CacheBlockBytes)))
+ val yank = LazyModule(new AXI4UserYanker)
+ val island = LazyModule(new PolarFireEvalKitDDR4Island(c))
+
+ val node: TLInwardNode =
+ island.crossAXI4In(island.node) := yank.node := deint.node := indexer.node := toaxi4.node := buffer.node
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new PolarFireEvalKitDDR4IO(depth)
+ })
+
+ io.port <> island.module.io.port
+
+ // Shove the island
+ island.module.clock := io.port.SYS_CLK
+ island.module.reset := !io.port.CTRLR_READY
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr4/MicrosemiPolarFireDDR4Periphery.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr4/MicrosemiPolarFireDDR4Periphery.scala
new file mode 100644
index 0000000..6a95c4c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_ddr4/MicrosemiPolarFireDDR4Periphery.scala
@@ -0,0 +1,37 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.microsemi.polarfireddr4
+
+import Chisel._
+import freechips.rocketchip.config._
+//import freechips.rocketchip.coreplex.HasMemoryBus
+import freechips.rocketchip.subsystem.BaseSubsystem
+import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressRange}
+
+case object MemoryMicrosemiDDR4Key extends Field[PolarFireEvalKitDDR4Params]
+
+//trait HasMemoryPolarFireEvalKitDDR4 extends HasMemoryBus {
+trait HasMemoryPolarFireEvalKitDDR4 { this: BaseSubsystem =>
+ val module: HasMemoryPolarFireEvalKitDDR4ModuleImp
+
+ val polarfireddrsubsys = LazyModule(new PolarFireEvalKitDDR4(p(MemoryMicrosemiDDR4Key)))
+
+ polarfireddrsubsys.node := mbus.toDRAMController(Some("PolarFireDDR"))()
+}
+
+trait HasMemoryPolarFireEvalKitDDR4Bundle {
+ val polarfireddrsubsys: PolarFireEvalKitDDR4IO
+ def connectPolarFireEValKitDDR4ToPads(pads: PolarFireEvalKitDDR4Pads) {
+ pads <> polarfireddrsubsys
+ }
+}
+
+trait HasMemoryPolarFireEvalKitDDR4ModuleImp extends LazyModuleImp
+ with HasMemoryPolarFireEvalKitDDR4Bundle {
+ val outer: HasMemoryPolarFireEvalKitDDR4
+ val ranges = AddressRange.fromSets(p(MemoryMicrosemiDDR4Key).address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val depth = ranges.head.size
+ val polarfireddrsubsys = IO(new PolarFireEvalKitDDR4IO(depth))
+
+ polarfireddrsubsys <> outer.polarfireddrsubsys.module.io.port
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_pcie/PolarFireEvalKitPCIeX4.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_pcie/PolarFireEvalKitPCIeX4.scala
new file mode 100644
index 0000000..2bae837
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_pcie/PolarFireEvalKitPCIeX4.scala
@@ -0,0 +1,75 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.microsemi.polarfireevalkitpciex4
+
+import Chisel._
+import freechips.rocketchip.amba.axi4._
+//import freechips.rocketchip.coreplex.CacheBlockBytes
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import freechips.rocketchip.util._
+import freechips.rocketchip.subsystem.{HasCrossing, CacheBlockBytes}
+
+import sifive.fpgashells.ip.microsemi.polarfirepcierootport._
+
+trait PolarFireEvalKitPCIeRefClk extends Bundle{
+//TODO: bring reference clock connection in here
+ val REFCLK_rxp = Bool(INPUT)
+ val REFCLK_rxn = Bool(INPUT)
+}
+
+class PolarFireEvalKitPCIeX4Pads extends Bundle
+ with PolarFirePCIeIOSerial
+ with PolarFireEvalKitPCIeRefClk
+
+class PolarFireEvalKitPCIeX4IO extends Bundle
+ with PolarFireEvalKitPCIeRefClk
+ with PolarFirePCIeIOSerial
+ with PolarFirePCIeIODebug
+ with PolarFirePCIeIOClocksReset {
+ val axi_ctl_aresetn = Bool(INPUT)
+}
+
+class PolarFireEvalKitPCIeX4(implicit p: Parameters) extends LazyModule with HasCrossing {
+ val crossing = SynchronousCrossing()
+ val axi_to_pcie = LazyModule(new PolarFirePCIeX4)
+
+ val slave: TLInwardNode =
+ (axi_to_pcie.slave
+ := AXI4Buffer()
+ := AXI4UserYanker()
+ := AXI4Deinterleaver(p(CacheBlockBytes))
+ := AXI4IdIndexer(idBits=4)
+ := TLToAXI4(adapterName = Some("pcie-slave")))
+
+ val control: TLInwardNode =
+ (axi_to_pcie.control
+ := TLToAPB(false)
+ := TLBuffer()
+ := TLFragmenter(4, p(CacheBlockBytes)))
+
+ val master: TLOutwardNode =
+ (TLWidthWidget(8)
+ := AXI4ToTL()
+ := AXI4UserYanker(capMaxFlight=Some(8))
+ := AXI4Fragmenter()
+ := AXI4IdIndexer(idBits=2)
+ := AXI4Buffer()
+ := axi_to_pcie.master)
+
+ val TLScope = LazyModule(new SimpleLazyModule with LazyScope)
+ val intnode: IntOutwardNode = IntSyncCrossingSink() := TLScope {
+ IntSyncCrossingSource(alreadyRegistered = true) := axi_to_pcie.intnode
+ }
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new PolarFireEvalKitPCIeX4IO
+ })
+
+ io.port <> axi_to_pcie.module.io.port
+ TLScope.module.clock := io.port.PCIE_1_TL_CLK_125MHz
+ TLScope.module.reset := ResetCatchAndSync(io.port.PCIE_1_TL_CLK_125MHz, reset)
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_pcie/PolarFireEvalKitPCIeX4Periphery.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_pcie/PolarFireEvalKitPCIeX4Periphery.scala
new file mode 100644
index 0000000..4131d35
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/microsemi/polarfire_pcie/PolarFireEvalKitPCIeX4Periphery.scala
@@ -0,0 +1,35 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.microsemi.polarfireevalkitpciex4
+
+import Chisel._
+//import freechips.rocketchip.coreplex.{HasInterruptBus, HasSystemBus}
+import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, BufferParams}
+import freechips.rocketchip.subsystem.BaseSubsystem
+import freechips.rocketchip.tilelink._
+
+//trait HasSystemPolarFireEvalKitPCIeX4 extends HasSystemBus with HasInterruptBus {
+trait HasSystemPolarFireEvalKitPCIeX4 { this: BaseSubsystem =>
+ val pf_eval_kit_pcie = LazyModule(new PolarFireEvalKitPCIeX4)
+ private val cname = "polarfirepcie"
+ sbus.coupleFrom(s"master_named_$cname") { _ :=* TLFIFOFixer(TLFIFOFixer.all) :=* pf_eval_kit_pcie.crossTLOut(pf_eval_kit_pcie.master) }
+ sbus.coupleTo(s"slave_named_$cname") { pf_eval_kit_pcie.crossTLIn(pf_eval_kit_pcie.slave) :*= TLWidthWidget(sbus.beatBytes) :*= _ }
+ sbus.coupleTo(s"controller_named_$cname") { pf_eval_kit_pcie.crossTLIn(pf_eval_kit_pcie.control) :*= TLWidthWidget(sbus.beatBytes) :*= _ }
+ ibus.fromSync := pf_eval_kit_pcie.crossIntOut(pf_eval_kit_pcie.intnode)
+}
+
+trait HasSystemPolarFireEvalKitPCIeX4Bundle {
+ val pf_eval_kit_pcie: PolarFireEvalKitPCIeX4IO
+ def connectPolarFireEvalKitPCIeX4ToPads(pads: PolarFireEvalKitPCIeX4Pads) {
+ pads <> pf_eval_kit_pcie
+ }
+}
+
+trait HasSystemPolarFireEvalKitPCIeX4ModuleImp extends LazyModuleImp
+ with HasSystemPolarFireEvalKitPCIeX4Bundle {
+ val outer: HasSystemPolarFireEvalKitPCIeX4
+ val pf_eval_kit_pcie = IO(new PolarFireEvalKitPCIeX4IO)
+
+ pf_eval_kit_pcie <> outer.pf_eval_kit_pcie.module.io.port
+
+ outer.pf_eval_kit_pcie.module.clock := outer.pf_eval_kit_pcie.module.io.port.AXI_CLK
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/ethernet/ethernet.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/ethernet/ethernet.scala
new file mode 100644
index 0000000..9bc195a
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/ethernet/ethernet.scala
@@ -0,0 +1,125 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.ethernet
+
+import chisel3._
+import chisel3.util._
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.regmapper._
+import freechips.rocketchip.util._
+import freechips.rocketchip.subsystem.CacheBlockBytes
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx.xxv_ethernet._
+
+class EthernetMACIO extends Bundle {
+ val pcs = Flipped(new EthernetPCS)
+}
+
+class EtherBeat extends Bundle {
+ val data = UInt(64.W)
+ val last = Bool()
+}
+
+abstract class EthernetMAC(busWidthBytes: Int, base: BigInt)(implicit p: Parameters) extends IORegisterRouter(
+ RegisterRouterParams(
+ name = "ethernet",
+ compat = Seq("sifive,ethernet0"),
+ base = base,
+ beatBytes = busWidthBytes),
+ new EthernetMACIO)
+{
+ lazy val module = new LazyModuleImp(this) {
+ val mac = Module(new nfmac10g)
+ port.pcs.tx_d := mac.io.xgmii_txd
+ port.pcs.tx_c := mac.io.xgmii_txc
+ mac.io.xgmii_rxd := port.pcs.rx_d
+ mac.io.xgmii_rxc := port.pcs.rx_c
+
+ mac.io.tx_clk0 := port.pcs.tx_clock
+ mac.io.rx_clk0 := port.pcs.rx_clock
+ mac.io.reset := reset // combined with locked to reset MAC RX/TX FSMs
+ mac.io.tx_dcm_locked := !port.pcs.tx_reset
+ mac.io.rx_dcm_locked := !port.pcs.rx_reset
+ mac.io.tx_axis_aresetn := !ResetCatchAndSync(port.pcs.tx_clock, reset.asBool)
+ mac.io.rx_axis_aresetn := !ResetCatchAndSync(port.pcs.rx_clock, reset.asBool)
+
+ // FIFO interface
+ val txen = RegInit(false.B)
+ val rxen = RegInit(false.B)
+ val loop = RegInit(0.U(3.W))
+ val skip = RegInit(false.B)
+ val last = RegInit(true.B)
+ val rxQ = Module(new AsyncQueue(new EtherBeat, params=AsyncQueueParams(depth=16)))
+ val txQ = Module(new AsyncQueue(new EtherBeat, params=AsyncQueueParams(depth=16)))
+ val txO = withClockAndReset(port.pcs.tx_clock, port.pcs.tx_reset) { Queue(txQ.io.deq, 2) }
+ val rxI = withClockAndReset(port.pcs.rx_clock, port.pcs.rx_reset) {
+ val w = Wire(chiselTypeOf(rxQ.io.enq))
+ rxQ.io.enq <> Queue(w, 2)
+ w
+ }
+
+ // TX AXIS / RX AXIS
+ rxQ.io.enq_clock := port.pcs.rx_clock
+ rxQ.io.enq_reset := port.pcs.rx_reset
+ rxQ.io.deq_clock := clock
+ rxQ.io.deq_reset := reset
+ txQ.io.enq_clock := clock
+ txQ.io.enq_reset := reset
+ txQ.io.deq_clock := port.pcs.tx_clock
+ txQ.io.deq_reset := port.pcs.tx_reset
+
+ port.pcs.loopback := loop
+
+ regmap(
+ 0 -> RegFieldGroup("control", Some("Control Registers"), Seq(
+ RegField(1, txen, RegFieldDesc("tx_en", "TX Enable", reset=Some(0))),
+ RegField(1, rxen, RegFieldDesc("rx_en", "RX Enable", reset=Some(0))),
+ RegField(1),
+ RegField(1, last, RegFieldDesc("last", "Last frame", reset=Some(1))),
+ RegField(3, loop, RegFieldDesc("loop", "TX-RX PCS Loopback", reset=Some(0))),
+ RegField(1, skip, RegFieldDesc("skip", "Bypass RX-TX directly", reset=Some(0))),
+ RegField(8),
+ RegField.r(1, txQ.io.enq.ready, RegFieldDesc("tx_ready", "TX Ready")),
+ RegField.r(1, rxQ.io.deq.valid, RegFieldDesc("rx_valid", "RX Valid")),
+ RegField.r(1, port.pcs.tx_reset, RegFieldDesc("tx_reset", "TX Reset")),
+ RegField.r(1, port.pcs.rx_reset, RegFieldDesc("rx_reset", "RX Reset")),
+ RegField.r(1, mac.io.tx_axis_tready, RegFieldDesc("mac_ready", "MAC Ready")),
+// RegField.r(1, port.pcs.rx_lock, RegFieldDesc("rx_lock", "RX Lock")),
+ RegField.r(1, port.pcs.sfp_detect, RegFieldDesc("sfp_detect", "SFP Detect")))),
+ 16 -> RegFieldGroup("tx", Some("TX Data Queue"), Seq(RegField.w(64, RegWriteFn((valid, data) => {
+ txQ.io.enq.valid := valid;
+ txQ.io.enq.bits.data := data
+ txQ.io.enq.bits.last := last
+ txQ.io.enq.ready })))),
+ 24 -> RegFieldGroup("rx", Some("RX Data Queue"), Seq(RegField.r(64, RegReadFn(ready => {
+ rxQ.io.deq.ready := ready
+ (rxQ.io.deq.valid, rxQ.io.deq.bits.data)}))))) // discards last
+
+ val tx_txen = withClockAndReset(port.pcs.tx_clock, port.pcs.tx_reset) { RegNext(RegNext(txen)) }
+ txO.ready := mac.io.tx_axis_tready && tx_txen
+ mac.io.tx_axis_tvalid := txO.valid && tx_txen
+ mac.io.tx_axis_tdata := txO.bits.data
+ mac.io.tx_axis_tlast := txO.bits.last
+ mac.io.tx_axis_tkeep := 0xff.U
+ mac.io.tx_axis_tuser := 0.U
+
+ // rxQ.io ready is ignored; loss of packets can happen
+ val rx_rxen = withClockAndReset(port.pcs.rx_clock, port.pcs.rx_reset) { RegNext(RegNext(rxen)) }
+ rxI.valid := mac.io.rx_axis_tvalid && rx_rxen
+ rxI.bits.data := mac.io.rx_axis_tdata
+ rxI.bits.last := mac.io.rx_axis_tlast
+ // ignore tkeep/tuser
+
+ when (withClockAndReset(port.pcs.tx_clock, port.pcs.tx_reset) { RegNext(RegNext(skip)) } ) {
+ txO.ready := rxI.ready
+ rxI.valid := txO.valid
+ rxI.bits := txO.bits
+ }
+ }
+}
+
+class TLEthernetMAC(busWidthBytes: Int, c: BigInt)(implicit p: Parameters)
+ extends EthernetMAC(busWidthBytes, c) with HasTLControlRegMap
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xdma/XDMA.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xdma/XDMA.scala
new file mode 100644
index 0000000..d5c4a16
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xdma/XDMA.scala
@@ -0,0 +1,52 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xdma
+
+import chisel3._
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import freechips.rocketchip.subsystem.{CrossesToOnlyOneClockDomain, CacheBlockBytes}
+import sifive.fpgashells.ip.xilinx.xdma._
+
+class XDMA(c: XDMAParams)(implicit p: Parameters, val crossing: ClockCrossingType = AsynchronousCrossing(8))
+ extends LazyModule with CrossesToOnlyOneClockDomain
+{
+ val imp = LazyModule(new DiplomaticXDMA(c))
+
+ val slave: TLInwardNode =
+ (imp.slave
+ := AXI4Buffer()
+ := AXI4UserYanker()
+ := AXI4Deinterleaver(p(CacheBlockBytes))
+ := AXI4IdIndexer(idBits=c.sIDBits)
+ := TLToAXI4(adapterName = Some("pcie-slave")))
+
+ val control: TLInwardNode =
+ (imp.control
+ := AXI4Buffer()
+ := AXI4UserYanker(capMaxFlight = Some(2))
+ := TLToAXI4()
+ := TLFragmenter(4, p(CacheBlockBytes), holdFirstDeny = true))
+
+ val master: TLOutwardNode =
+ (TLWidthWidget(c.busBytes)
+ := AXI4ToTL()
+ := AXI4UserYanker(capMaxFlight=Some(16))
+ := AXI4Fragmenter()
+ := AXI4IdIndexer(idBits=2)
+ := imp.master)
+
+ val intnode: IntOutwardNode = imp.intnode
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val pads = new XDMAPads(c.lanes)
+ val clocks = new XDMAClocks
+ })
+
+ io.pads <> imp.module.io.pads
+ io.clocks <> imp.module.io.clocks
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xdma/package.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xdma/package.scala
new file mode 100644
index 0000000..97df7e0
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xdma/package.scala
@@ -0,0 +1,10 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx
+
+package object xdma
+{
+ type XDMAPads = sifive.fpgashells.ip.xilinx.xdma.XDMAPads
+ type XDMAClocks = sifive.fpgashells.ip.xilinx.xdma.XDMAClocks
+ type XDMAParams = sifive.fpgashells.ip.xilinx.xdma.XDMAParams
+ val XDMAParams = sifive.fpgashells.ip.xilinx.xdma.XDMAParams
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxarty100tmig/XilinxArty100TMIG.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxarty100tmig/XilinxArty100TMIG.scala
new file mode 100644
index 0000000..5b72ebf
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxarty100tmig/XilinxArty100TMIG.scala
@@ -0,0 +1,171 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxarty100tmig
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.subsystem._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import sifive.fpgashells.ip.xilinx.arty100tmig.{Arty100TMIGIOClocksReset, Arty100TMIGIODDR, arty100tmig}
+
+case class XilinxArty100TMIGParams(
+ address : Seq[AddressSet]
+)
+
+class XilinxArty100TMIGPads(depth : BigInt) extends Arty100TMIGIODDR(depth) {
+ def this(c : XilinxArty100TMIGParams) {
+ this(AddressRange.fromSets(c.address).head.size)
+ }
+}
+
+class XilinxArty100TMIGIO(depth : BigInt) extends Arty100TMIGIODDR(depth) with Arty100TMIGIOClocksReset
+
+class XilinxArty100TMIGIsland(c : XilinxArty100TMIGParams, val crossing: ClockCrossingType = AsynchronousCrossing(8))(implicit p: Parameters) extends LazyModule with CrossesToOnlyOneClockDomain {
+ val ranges = AddressRange.fromSets(c.address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val offset = ranges.head.base
+ val depth = ranges.head.size
+ require((depth<=0x10000000L),"artymig supports upto 256 MB depth configuraton")
+
+ val device = new MemoryDevice
+ val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = c.address,
+ resources = device.reg,
+ regionType = RegionType.UNCACHED,
+ executable = true,
+ supportsWrite = TransferSizes(1, 64),
+ supportsRead = TransferSizes(1, 64))),
+ beatBytes = 8)))
+
+ lazy val module = new LazyRawModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new XilinxArty100TMIGIO(depth)
+ })
+
+ childClock := io.port.ui_clk
+ childReset := io.port.ui_clk_sync_rst
+
+ //MIG black box instantiation
+ val blackbox = Module(new arty100tmig(depth))
+ val (axi_async, _) = node.in(0)
+
+ //pins to top level
+
+ //inouts
+ attach(io.port.ddr3_dq,blackbox.io.ddr3_dq)
+ attach(io.port.ddr3_dqs_n,blackbox.io.ddr3_dqs_n)
+ attach(io.port.ddr3_dqs_p,blackbox.io.ddr3_dqs_p)
+
+ //outputs
+ io.port.ddr3_addr := blackbox.io.ddr3_addr
+ io.port.ddr3_ba := blackbox.io.ddr3_ba
+ io.port.ddr3_ras_n := blackbox.io.ddr3_ras_n
+ io.port.ddr3_cas_n := blackbox.io.ddr3_cas_n
+ io.port.ddr3_we_n := blackbox.io.ddr3_we_n
+ io.port.ddr3_reset_n := blackbox.io.ddr3_reset_n
+ io.port.ddr3_ck_p := blackbox.io.ddr3_ck_p
+ io.port.ddr3_ck_n := blackbox.io.ddr3_ck_n
+ io.port.ddr3_cke := blackbox.io.ddr3_cke
+ io.port.ddr3_cs_n := blackbox.io.ddr3_cs_n
+ io.port.ddr3_dm := blackbox.io.ddr3_dm
+ io.port.ddr3_odt := blackbox.io.ddr3_odt
+
+ //inputs
+ //NO_BUFFER clock
+ blackbox.io.sys_clk_i := io.port.sys_clk_i
+ blackbox.io.clk_ref_i := io.port.clk_ref_i
+
+ io.port.ui_clk := blackbox.io.ui_clk
+ io.port.ui_clk_sync_rst := blackbox.io.ui_clk_sync_rst
+ io.port.mmcm_locked := blackbox.io.mmcm_locked
+ blackbox.io.aresetn := io.port.aresetn
+ blackbox.io.app_sr_req := Bool(false)
+ blackbox.io.app_ref_req := Bool(false)
+ blackbox.io.app_zq_req := Bool(false)
+ //app_sr_active := unconnected
+ //app_ref_ack := unconnected
+ //app_zq_ack := unconnected
+
+ val awaddr = axi_async.aw.bits.addr - UInt(offset)
+ val araddr = axi_async.ar.bits.addr - UInt(offset)
+
+ //slave AXI interface write address ports
+ blackbox.io.s_axi_awid := axi_async.aw.bits.id
+ blackbox.io.s_axi_awaddr := awaddr //truncated
+ blackbox.io.s_axi_awlen := axi_async.aw.bits.len
+ blackbox.io.s_axi_awsize := axi_async.aw.bits.size
+ blackbox.io.s_axi_awburst := axi_async.aw.bits.burst
+ blackbox.io.s_axi_awlock := axi_async.aw.bits.lock
+ blackbox.io.s_axi_awcache := UInt("b0011")
+ blackbox.io.s_axi_awprot := axi_async.aw.bits.prot
+ blackbox.io.s_axi_awqos := axi_async.aw.bits.qos
+ blackbox.io.s_axi_awvalid := axi_async.aw.valid
+ axi_async.aw.ready := blackbox.io.s_axi_awready
+
+ //slave interface write data ports
+ blackbox.io.s_axi_wdata := axi_async.w.bits.data
+ blackbox.io.s_axi_wstrb := axi_async.w.bits.strb
+ blackbox.io.s_axi_wlast := axi_async.w.bits.last
+ blackbox.io.s_axi_wvalid := axi_async.w.valid
+ axi_async.w.ready := blackbox.io.s_axi_wready
+
+ //slave interface write response
+ blackbox.io.s_axi_bready := axi_async.b.ready
+ axi_async.b.bits.id := blackbox.io.s_axi_bid
+ axi_async.b.bits.resp := blackbox.io.s_axi_bresp
+ axi_async.b.valid := blackbox.io.s_axi_bvalid
+
+ //slave AXI interface read address ports
+ blackbox.io.s_axi_arid := axi_async.ar.bits.id
+ blackbox.io.s_axi_araddr := araddr // truncated
+ blackbox.io.s_axi_arlen := axi_async.ar.bits.len
+ blackbox.io.s_axi_arsize := axi_async.ar.bits.size
+ blackbox.io.s_axi_arburst := axi_async.ar.bits.burst
+ blackbox.io.s_axi_arlock := axi_async.ar.bits.lock
+ blackbox.io.s_axi_arcache := UInt("b0011")
+ blackbox.io.s_axi_arprot := axi_async.ar.bits.prot
+ blackbox.io.s_axi_arqos := axi_async.ar.bits.qos
+ blackbox.io.s_axi_arvalid := axi_async.ar.valid
+ axi_async.ar.ready := blackbox.io.s_axi_arready
+
+ //slace AXI interface read data ports
+ blackbox.io.s_axi_rready := axi_async.r.ready
+ axi_async.r.bits.id := blackbox.io.s_axi_rid
+ axi_async.r.bits.data := blackbox.io.s_axi_rdata
+ axi_async.r.bits.resp := blackbox.io.s_axi_rresp
+ axi_async.r.bits.last := blackbox.io.s_axi_rlast
+ axi_async.r.valid := blackbox.io.s_axi_rvalid
+
+ //misc
+ io.port.init_calib_complete := blackbox.io.init_calib_complete
+ blackbox.io.sys_rst :=io.port.sys_rst
+ //mig.device_temp :- unconnceted
+ }
+}
+
+class XilinxArty100TMIG(c : XilinxArty100TMIGParams, crossing: ClockCrossingType = AsynchronousCrossing(8))(implicit p: Parameters) extends LazyModule {
+ val ranges = AddressRange.fromSets(c.address)
+ val depth = ranges.head.size
+
+ val buffer = LazyModule(new TLBuffer)
+ val toaxi4 = LazyModule(new TLToAXI4(adapterName = Some("mem")))
+ val indexer = LazyModule(new AXI4IdIndexer(idBits = 4))
+ val deint = LazyModule(new AXI4Deinterleaver(p(CacheBlockBytes)))
+ val yank = LazyModule(new AXI4UserYanker)
+ val island = LazyModule(new XilinxArty100TMIGIsland(c, crossing))
+
+ val node: TLInwardNode =
+ island.crossAXI4In(island.node) := yank.node := deint.node := indexer.node := toaxi4.node := buffer.node
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new XilinxArty100TMIGIO(depth)
+ })
+
+ io.port <> island.module.io.port
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIG.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIG.scala
new file mode 100644
index 0000000..0b287f6
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIG.scala
@@ -0,0 +1,170 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxvc707mig
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.subsystem._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import sifive.fpgashells.ip.xilinx.vc707mig.{VC707MIGIOClocksReset, VC707MIGIODDR, vc707mig}
+
+case class XilinxVC707MIGParams(
+ address : Seq[AddressSet]
+)
+
+class XilinxVC707MIGPads(depth : BigInt) extends VC707MIGIODDR(depth) {
+ def this(c : XilinxVC707MIGParams) {
+ this(AddressRange.fromSets(c.address).head.size)
+ }
+}
+
+class XilinxVC707MIGIO(depth : BigInt) extends VC707MIGIODDR(depth) with VC707MIGIOClocksReset
+
+class XilinxVC707MIGIsland(c : XilinxVC707MIGParams, val crossing: ClockCrossingType = AsynchronousCrossing(8))(implicit p: Parameters) extends LazyModule with CrossesToOnlyOneClockDomain {
+ val ranges = AddressRange.fromSets(c.address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val offset = ranges.head.base
+ val depth = ranges.head.size
+ require((depth<=0x100000000L),"vc707mig supports upto 4GB depth configuraton")
+
+ val device = new MemoryDevice
+ val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = c.address,
+ resources = device.reg,
+ regionType = RegionType.UNCACHED,
+ executable = true,
+ supportsWrite = TransferSizes(1, 128),
+ supportsRead = TransferSizes(1, 128))),
+ beatBytes = 8)))
+
+ lazy val module = new LazyRawModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new XilinxVC707MIGIO(depth)
+ })
+
+ childClock := io.port.ui_clk
+ childReset := io.port.ui_clk_sync_rst
+
+ //MIG black box instantiation
+ val blackbox = Module(new vc707mig(depth))
+ val (axi_async, _) = node.in(0)
+
+ //pins to top level
+
+ //inouts
+ attach(io.port.ddr3_dq,blackbox.io.ddr3_dq)
+ attach(io.port.ddr3_dqs_n,blackbox.io.ddr3_dqs_n)
+ attach(io.port.ddr3_dqs_p,blackbox.io.ddr3_dqs_p)
+
+ //outputs
+ io.port.ddr3_addr := blackbox.io.ddr3_addr
+ io.port.ddr3_ba := blackbox.io.ddr3_ba
+ io.port.ddr3_ras_n := blackbox.io.ddr3_ras_n
+ io.port.ddr3_cas_n := blackbox.io.ddr3_cas_n
+ io.port.ddr3_we_n := blackbox.io.ddr3_we_n
+ io.port.ddr3_reset_n := blackbox.io.ddr3_reset_n
+ io.port.ddr3_ck_p := blackbox.io.ddr3_ck_p
+ io.port.ddr3_ck_n := blackbox.io.ddr3_ck_n
+ io.port.ddr3_cke := blackbox.io.ddr3_cke
+ io.port.ddr3_cs_n := blackbox.io.ddr3_cs_n
+ io.port.ddr3_dm := blackbox.io.ddr3_dm
+ io.port.ddr3_odt := blackbox.io.ddr3_odt
+
+ //inputs
+ //NO_BUFFER clock
+ blackbox.io.sys_clk_i := io.port.sys_clk_i
+
+ io.port.ui_clk := blackbox.io.ui_clk
+ io.port.ui_clk_sync_rst := blackbox.io.ui_clk_sync_rst
+ io.port.mmcm_locked := blackbox.io.mmcm_locked
+ blackbox.io.aresetn := io.port.aresetn
+ blackbox.io.app_sr_req := Bool(false)
+ blackbox.io.app_ref_req := Bool(false)
+ blackbox.io.app_zq_req := Bool(false)
+ //app_sr_active := unconnected
+ //app_ref_ack := unconnected
+ //app_zq_ack := unconnected
+
+ val awaddr = axi_async.aw.bits.addr - UInt(offset)
+ val araddr = axi_async.ar.bits.addr - UInt(offset)
+
+ //slave AXI interface write address ports
+ blackbox.io.s_axi_awid := axi_async.aw.bits.id
+ blackbox.io.s_axi_awaddr := awaddr //truncated
+ blackbox.io.s_axi_awlen := axi_async.aw.bits.len
+ blackbox.io.s_axi_awsize := axi_async.aw.bits.size
+ blackbox.io.s_axi_awburst := axi_async.aw.bits.burst
+ blackbox.io.s_axi_awlock := axi_async.aw.bits.lock
+ blackbox.io.s_axi_awcache := UInt("b0011")
+ blackbox.io.s_axi_awprot := axi_async.aw.bits.prot
+ blackbox.io.s_axi_awqos := axi_async.aw.bits.qos
+ blackbox.io.s_axi_awvalid := axi_async.aw.valid
+ axi_async.aw.ready := blackbox.io.s_axi_awready
+
+ //slave interface write data ports
+ blackbox.io.s_axi_wdata := axi_async.w.bits.data
+ blackbox.io.s_axi_wstrb := axi_async.w.bits.strb
+ blackbox.io.s_axi_wlast := axi_async.w.bits.last
+ blackbox.io.s_axi_wvalid := axi_async.w.valid
+ axi_async.w.ready := blackbox.io.s_axi_wready
+
+ //slave interface write response
+ blackbox.io.s_axi_bready := axi_async.b.ready
+ axi_async.b.bits.id := blackbox.io.s_axi_bid
+ axi_async.b.bits.resp := blackbox.io.s_axi_bresp
+ axi_async.b.valid := blackbox.io.s_axi_bvalid
+
+ //slave AXI interface read address ports
+ blackbox.io.s_axi_arid := axi_async.ar.bits.id
+ blackbox.io.s_axi_araddr := araddr // truncated
+ blackbox.io.s_axi_arlen := axi_async.ar.bits.len
+ blackbox.io.s_axi_arsize := axi_async.ar.bits.size
+ blackbox.io.s_axi_arburst := axi_async.ar.bits.burst
+ blackbox.io.s_axi_arlock := axi_async.ar.bits.lock
+ blackbox.io.s_axi_arcache := UInt("b0011")
+ blackbox.io.s_axi_arprot := axi_async.ar.bits.prot
+ blackbox.io.s_axi_arqos := axi_async.ar.bits.qos
+ blackbox.io.s_axi_arvalid := axi_async.ar.valid
+ axi_async.ar.ready := blackbox.io.s_axi_arready
+
+ //slace AXI interface read data ports
+ blackbox.io.s_axi_rready := axi_async.r.ready
+ axi_async.r.bits.id := blackbox.io.s_axi_rid
+ axi_async.r.bits.data := blackbox.io.s_axi_rdata
+ axi_async.r.bits.resp := blackbox.io.s_axi_rresp
+ axi_async.r.bits.last := blackbox.io.s_axi_rlast
+ axi_async.r.valid := blackbox.io.s_axi_rvalid
+
+ //misc
+ io.port.init_calib_complete := blackbox.io.init_calib_complete
+ blackbox.io.sys_rst :=io.port.sys_rst
+ //mig.device_temp :- unconnceted
+ }
+}
+
+class XilinxVC707MIG(c : XilinxVC707MIGParams, crossing: ClockCrossingType = AsynchronousCrossing(8))(implicit p: Parameters) extends LazyModule {
+ val ranges = AddressRange.fromSets(c.address)
+ val depth = ranges.head.size
+
+ val buffer = LazyModule(new TLBuffer)
+ val toaxi4 = LazyModule(new TLToAXI4(adapterName = Some("mem"), stripBits = 1))
+ val indexer = LazyModule(new AXI4IdIndexer(idBits = 4))
+ val deint = LazyModule(new AXI4Deinterleaver(p(CacheBlockBytes)))
+ val yank = LazyModule(new AXI4UserYanker)
+ val island = LazyModule(new XilinxVC707MIGIsland(c, crossing))
+
+ val node: TLInwardNode =
+ island.crossAXI4In(island.node) := yank.node := deint.node := indexer.node := toaxi4.node := buffer.node
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new XilinxVC707MIGIO(depth)
+ })
+
+ io.port <> island.module.io.port
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIGPeriphery.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIGPeriphery.scala
new file mode 100644
index 0000000..933c986
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIGPeriphery.scala
@@ -0,0 +1,35 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxvc707mig
+
+import Chisel._
+import freechips.rocketchip.config._
+import freechips.rocketchip.subsystem.BaseSubsystem
+import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressRange}
+
+case object MemoryXilinxDDRKey extends Field[XilinxVC707MIGParams]
+
+trait HasMemoryXilinxVC707MIG { this: BaseSubsystem =>
+ val module: HasMemoryXilinxVC707MIGModuleImp
+
+ val xilinxvc707mig = LazyModule(new XilinxVC707MIG(p(MemoryXilinxDDRKey)))
+
+ xilinxvc707mig.node := mbus.toDRAMController(Some("xilinxvc707mig"))()
+}
+
+trait HasMemoryXilinxVC707MIGBundle {
+ val xilinxvc707mig: XilinxVC707MIGIO
+ def connectXilinxVC707MIGToPads(pads: XilinxVC707MIGPads) {
+ pads <> xilinxvc707mig
+ }
+}
+
+trait HasMemoryXilinxVC707MIGModuleImp extends LazyModuleImp
+ with HasMemoryXilinxVC707MIGBundle {
+ val outer: HasMemoryXilinxVC707MIG
+ val ranges = AddressRange.fromSets(p(MemoryXilinxDDRKey).address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val depth = ranges.head.size
+ val xilinxvc707mig = IO(new XilinxVC707MIGIO(depth))
+
+ xilinxvc707mig <> outer.xilinxvc707mig.module.io.port
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1.scala
new file mode 100644
index 0000000..851d85e
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1.scala
@@ -0,0 +1,76 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxvc707pciex1
+
+import Chisel._
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import freechips.rocketchip.subsystem.{CrossesToOnlyOneClockDomain, CacheBlockBytes}
+import sifive.fpgashells.ip.xilinx.vc707axi_to_pcie_x1.{VC707AXIToPCIeX1, VC707AXIToPCIeX1IOClocksReset, VC707AXIToPCIeX1IOSerial}
+import sifive.fpgashells.ip.xilinx.ibufds_gte2.IBUFDS_GTE2
+
+trait VC707AXIToPCIeRefClk extends Bundle{
+ val REFCLK_rxp = Bool(INPUT)
+ val REFCLK_rxn = Bool(INPUT)
+}
+
+class XilinxVC707PCIeX1Pads extends Bundle
+ with VC707AXIToPCIeX1IOSerial
+ with VC707AXIToPCIeRefClk
+
+class XilinxVC707PCIeX1IO extends Bundle
+ with VC707AXIToPCIeRefClk
+ with VC707AXIToPCIeX1IOSerial
+ with VC707AXIToPCIeX1IOClocksReset {
+ val axi_ctl_aresetn = Bool(INPUT)
+}
+
+class XilinxVC707PCIeX1(implicit p: Parameters, val crossing: ClockCrossingType = AsynchronousCrossing(8))
+ extends LazyModule with CrossesToOnlyOneClockDomain
+{
+ val axi_to_pcie_x1 = LazyModule(new VC707AXIToPCIeX1)
+
+ val slave: TLInwardNode =
+ (axi_to_pcie_x1.slave
+ := AXI4Buffer()
+ := AXI4UserYanker()
+ := AXI4Deinterleaver(p(CacheBlockBytes))
+ := AXI4IdIndexer(idBits=4)
+ := TLToAXI4(adapterName = Some("pcie-slave")))
+
+ val control: TLInwardNode =
+ (axi_to_pcie_x1.control
+ := AXI4Buffer()
+ := AXI4UserYanker(capMaxFlight = Some(2))
+ := TLToAXI4()
+ := TLFragmenter(4, p(CacheBlockBytes), holdFirstDeny = true))
+
+ val master: TLOutwardNode =
+ (TLWidthWidget(8)
+ := AXI4ToTL()
+ := AXI4UserYanker(capMaxFlight=Some(8))
+ := AXI4Fragmenter()
+ := axi_to_pcie_x1.master)
+
+ val intnode: IntOutwardNode = axi_to_pcie_x1.intnode
+
+ lazy val module = new LazyRawModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new XilinxVC707PCIeX1IO
+ })
+
+ childClock := io.port.axi_aclk_out
+ childReset := ~io.port.axi_aresetn
+
+ io.port <> axi_to_pcie_x1.module.io.port
+
+ //PCIe Reference Clock
+ val ibufds_gte2 = Module(new IBUFDS_GTE2)
+ axi_to_pcie_x1.module.io.REFCLK := ibufds_gte2.io.O
+ ibufds_gte2.io.CEB := UInt(0)
+ ibufds_gte2.io.I := io.port.REFCLK_rxp
+ ibufds_gte2.io.IB := io.port.REFCLK_rxn
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1Periphery.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1Periphery.scala
new file mode 100644
index 0000000..caf570b
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1Periphery.scala
@@ -0,0 +1,32 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxvc707pciex1
+
+import Chisel._
+import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, BufferParams}
+import freechips.rocketchip.subsystem.BaseSubsystem
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts.IntSyncCrossingSink
+
+trait HasSystemXilinxVC707PCIeX1 { this: BaseSubsystem =>
+ val xilinxvc707pcie = LazyModule(new XilinxVC707PCIeX1)
+ private val cname = "xilinxvc707pcie"
+ sbus.coupleFrom(s"master_named_$cname") { _ :=* TLFIFOFixer(TLFIFOFixer.all) :=* xilinxvc707pcie.crossTLOut(xilinxvc707pcie.master) }
+ sbus.coupleTo(s"slave_named_$cname") { xilinxvc707pcie.crossTLIn(xilinxvc707pcie.slave) :*= TLWidthWidget(sbus.beatBytes) :*= _ }
+ sbus.coupleTo(s"controller_named_$cname") { xilinxvc707pcie.crossTLIn(xilinxvc707pcie.control) :*= TLWidthWidget(sbus.beatBytes) :*= _ }
+ ibus.fromSync := xilinxvc707pcie.crossIntOut(xilinxvc707pcie.intnode)
+}
+
+trait HasSystemXilinxVC707PCIeX1Bundle {
+ val xilinxvc707pcie: XilinxVC707PCIeX1IO
+ def connectXilinxVC707PCIeX1ToPads(pads: XilinxVC707PCIeX1Pads) {
+ pads <> xilinxvc707pcie
+ }
+}
+
+trait HasSystemXilinxVC707PCIeX1ModuleImp extends LazyModuleImp
+ with HasSystemXilinxVC707PCIeX1Bundle {
+ val outer: HasSystemXilinxVC707PCIeX1
+ val xilinxvc707pcie = IO(new XilinxVC707PCIeX1IO)
+
+ xilinxvc707pcie <> outer.xilinxvc707pcie.module.io.port
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvcu118mig/XilinxVCU118MIG.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvcu118mig/XilinxVCU118MIG.scala
new file mode 100644
index 0000000..9141126
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvcu118mig/XilinxVCU118MIG.scala
@@ -0,0 +1,163 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxvcu118mig
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.subsystem._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import sifive.fpgashells.ip.xilinx.vcu118mig.{VCU118MIGIOClocksReset, VCU118MIGIODDR, vcu118mig}
+
+case class XilinxVCU118MIGParams(
+ address : Seq[AddressSet]
+)
+
+class XilinxVCU118MIGPads(depth : BigInt) extends VCU118MIGIODDR(depth) {
+ def this(c : XilinxVCU118MIGParams) {
+ this(AddressRange.fromSets(c.address).head.size)
+ }
+}
+
+class XilinxVCU118MIGIO(depth : BigInt) extends VCU118MIGIODDR(depth) with VCU118MIGIOClocksReset
+
+class XilinxVCU118MIGIsland(c : XilinxVCU118MIGParams)(implicit p: Parameters) extends LazyModule with CrossesToOnlyOneClockDomain {
+ val ranges = AddressRange.fromSets(c.address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val offset = ranges.head.base
+ val depth = ranges.head.size
+ val crossing = AsynchronousCrossing(8)
+ require((depth<=0x80000000L),"vcu118mig supports upto 2GB depth configuraton")
+
+ val device = new MemoryDevice
+ val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = c.address,
+ resources = device.reg,
+ regionType = RegionType.UNCACHED,
+ executable = true,
+ supportsWrite = TransferSizes(1, 256*8),
+ supportsRead = TransferSizes(1, 256*8))),
+ beatBytes = 8)))
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new XilinxVCU118MIGIO(depth)
+ })
+
+ //MIG black box instantiation
+ val blackbox = Module(new vcu118mig(depth))
+ val (axi_async, _) = node.in(0)
+
+ //pins to top level
+
+ //inouts
+ attach(io.port.c0_ddr4_dq,blackbox.io.c0_ddr4_dq)
+ attach(io.port.c0_ddr4_dqs_c,blackbox.io.c0_ddr4_dqs_c)
+ attach(io.port.c0_ddr4_dqs_t,blackbox.io.c0_ddr4_dqs_t)
+ attach(io.port.c0_ddr4_dm_dbi_n,blackbox.io.c0_ddr4_dm_dbi_n)
+
+ //outputs
+ io.port.c0_ddr4_adr := blackbox.io.c0_ddr4_adr
+ io.port.c0_ddr4_bg := blackbox.io.c0_ddr4_bg
+ io.port.c0_ddr4_ba := blackbox.io.c0_ddr4_ba
+ io.port.c0_ddr4_reset_n := blackbox.io.c0_ddr4_reset_n
+ io.port.c0_ddr4_act_n := blackbox.io.c0_ddr4_act_n
+ io.port.c0_ddr4_ck_c := blackbox.io.c0_ddr4_ck_c
+ io.port.c0_ddr4_ck_t := blackbox.io.c0_ddr4_ck_t
+ io.port.c0_ddr4_cke := blackbox.io.c0_ddr4_cke
+ io.port.c0_ddr4_cs_n := blackbox.io.c0_ddr4_cs_n
+ io.port.c0_ddr4_odt := blackbox.io.c0_ddr4_odt
+
+ //inputs
+ //NO_BUFFER clock
+ blackbox.io.c0_sys_clk_i := io.port.c0_sys_clk_i
+
+ io.port.c0_ddr4_ui_clk := blackbox.io.c0_ddr4_ui_clk
+ io.port.c0_ddr4_ui_clk_sync_rst := blackbox.io.c0_ddr4_ui_clk_sync_rst
+ blackbox.io.c0_ddr4_aresetn := io.port.c0_ddr4_aresetn
+
+ val awaddr = axi_async.aw.bits.addr - UInt(offset)
+ val araddr = axi_async.ar.bits.addr - UInt(offset)
+
+ //slave AXI interface write address ports
+ blackbox.io.c0_ddr4_s_axi_awid := axi_async.aw.bits.id
+ blackbox.io.c0_ddr4_s_axi_awaddr := awaddr //truncated
+ blackbox.io.c0_ddr4_s_axi_awlen := axi_async.aw.bits.len
+ blackbox.io.c0_ddr4_s_axi_awsize := axi_async.aw.bits.size
+ blackbox.io.c0_ddr4_s_axi_awburst := axi_async.aw.bits.burst
+ blackbox.io.c0_ddr4_s_axi_awlock := axi_async.aw.bits.lock
+ blackbox.io.c0_ddr4_s_axi_awcache := UInt("b0011")
+ blackbox.io.c0_ddr4_s_axi_awprot := axi_async.aw.bits.prot
+ blackbox.io.c0_ddr4_s_axi_awqos := axi_async.aw.bits.qos
+ blackbox.io.c0_ddr4_s_axi_awvalid := axi_async.aw.valid
+ axi_async.aw.ready := blackbox.io.c0_ddr4_s_axi_awready
+
+ //slave interface write data ports
+ blackbox.io.c0_ddr4_s_axi_wdata := axi_async.w.bits.data
+ blackbox.io.c0_ddr4_s_axi_wstrb := axi_async.w.bits.strb
+ blackbox.io.c0_ddr4_s_axi_wlast := axi_async.w.bits.last
+ blackbox.io.c0_ddr4_s_axi_wvalid := axi_async.w.valid
+ axi_async.w.ready := blackbox.io.c0_ddr4_s_axi_wready
+
+ //slave interface write response
+ blackbox.io.c0_ddr4_s_axi_bready := axi_async.b.ready
+ axi_async.b.bits.id := blackbox.io.c0_ddr4_s_axi_bid
+ axi_async.b.bits.resp := blackbox.io.c0_ddr4_s_axi_bresp
+ axi_async.b.valid := blackbox.io.c0_ddr4_s_axi_bvalid
+
+ //slave AXI interface read address ports
+ blackbox.io.c0_ddr4_s_axi_arid := axi_async.ar.bits.id
+ blackbox.io.c0_ddr4_s_axi_araddr := araddr // truncated
+ blackbox.io.c0_ddr4_s_axi_arlen := axi_async.ar.bits.len
+ blackbox.io.c0_ddr4_s_axi_arsize := axi_async.ar.bits.size
+ blackbox.io.c0_ddr4_s_axi_arburst := axi_async.ar.bits.burst
+ blackbox.io.c0_ddr4_s_axi_arlock := axi_async.ar.bits.lock
+ blackbox.io.c0_ddr4_s_axi_arcache := UInt("b0011")
+ blackbox.io.c0_ddr4_s_axi_arprot := axi_async.ar.bits.prot
+ blackbox.io.c0_ddr4_s_axi_arqos := axi_async.ar.bits.qos
+ blackbox.io.c0_ddr4_s_axi_arvalid := axi_async.ar.valid
+ axi_async.ar.ready := blackbox.io.c0_ddr4_s_axi_arready
+
+ //slace AXI interface read data ports
+ blackbox.io.c0_ddr4_s_axi_rready := axi_async.r.ready
+ axi_async.r.bits.id := blackbox.io.c0_ddr4_s_axi_rid
+ axi_async.r.bits.data := blackbox.io.c0_ddr4_s_axi_rdata
+ axi_async.r.bits.resp := blackbox.io.c0_ddr4_s_axi_rresp
+ axi_async.r.bits.last := blackbox.io.c0_ddr4_s_axi_rlast
+ axi_async.r.valid := blackbox.io.c0_ddr4_s_axi_rvalid
+
+ //misc
+ io.port.c0_init_calib_complete := blackbox.io.c0_init_calib_complete
+ blackbox.io.sys_rst :=io.port.sys_rst
+ }
+}
+
+class XilinxVCU118MIG(c : XilinxVCU118MIGParams)(implicit p: Parameters) extends LazyModule {
+ val ranges = AddressRange.fromSets(c.address)
+ val depth = ranges.head.size
+
+ val buffer = LazyModule(new TLBuffer)
+ val toaxi4 = LazyModule(new TLToAXI4(adapterName = Some("mem"), stripBits = 1))
+ val indexer = LazyModule(new AXI4IdIndexer(idBits = 4))
+ val deint = LazyModule(new AXI4Deinterleaver(p(CacheBlockBytes)))
+ val yank = LazyModule(new AXI4UserYanker)
+ val island = LazyModule(new XilinxVCU118MIGIsland(c))
+
+ val node: TLInwardNode =
+ island.crossAXI4In(island.node) := yank.node := deint.node := indexer.node := toaxi4.node := buffer.node
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new XilinxVCU118MIGIO(depth)
+ })
+
+ io.port <> island.module.io.port
+
+ // Shove the island
+ island.module.clock := io.port.c0_ddr4_ui_clk
+ island.module.reset := io.port.c0_ddr4_ui_clk_sync_rst
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvcu118mig/XilinxVCU118MIGPeriphery.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvcu118mig/XilinxVCU118MIGPeriphery.scala
new file mode 100644
index 0000000..bde5149
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/devices/xilinx/xilinxvcu118mig/XilinxVCU118MIGPeriphery.scala
@@ -0,0 +1,35 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxvcu118mig
+
+import Chisel._
+import freechips.rocketchip.config._
+import freechips.rocketchip.subsystem.BaseSubsystem
+import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressRange}
+
+case object MemoryXilinxDDRKey extends Field[XilinxVCU118MIGParams]
+
+trait HasMemoryXilinxVCU118MIG { this: BaseSubsystem =>
+ val module: HasMemoryXilinxVCU118MIGModuleImp
+
+ val xilinxvcu118mig = LazyModule(new XilinxVCU118MIG(p(MemoryXilinxDDRKey)))
+
+ xilinxvcu118mig.node := mbus.toDRAMController(Some("xilinxvcu118mig"))()
+}
+
+trait HasMemoryXilinxVCU118MIGBundle {
+ val xilinxvcu118mig: XilinxVCU118MIGIO
+ def connectXilinxVCU118MIGToPads(pads: XilinxVCU118MIGPads) {
+ pads <> xilinxvcu118mig
+ }
+}
+
+trait HasMemoryXilinxVCU118MIGModuleImp extends LazyModuleImp
+ with HasMemoryXilinxVCU118MIGBundle {
+ val outer: HasMemoryXilinxVCU118MIG
+ val ranges = AddressRange.fromSets(p(MemoryXilinxDDRKey).address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val depth = ranges.head.size
+ val xilinxvcu118mig = IO(new XilinxVCU118MIGIO(depth))
+
+ xilinxvcu118mig <> outer.xilinxvcu118mig.module.io.port
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/corejtagdebug/corejtagdebug.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/corejtagdebug/corejtagdebug.scala
new file mode 100644
index 0000000..3c7feb0
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/corejtagdebug/corejtagdebug.scala
@@ -0,0 +1,71 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.corejtagdebug
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box for Microsemi DirectCore IP block Actel:DirectCore:COREJTAGDEBUG:2.0.100
+
+trait CoreJtagDebugIOJTAGPads extends Bundle {
+
+ val TCK = Clock(INPUT)
+ val TDI = Bool(INPUT)
+ val TMS = Bool(INPUT)
+ val TRSTB = Bool(INPUT)
+ val TDO = Bool(OUTPUT)
+}
+
+trait CoreJtagDebugIOTarget extends Bundle {
+
+ val TGT_TCK = Clock(OUTPUT)
+ val TGT_TDI = Bool(OUTPUT)
+ val TGT_TMS = Bool(OUTPUT)
+ val TGT_TRST = Bool(OUTPUT)
+ val TGT_TDO = Bool(INPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class CoreJtagDebugBlock(implicit val p:Parameters) extends BlackBox
+{
+ override def desiredName = "corejtagdebug_wrapper"
+
+ val io = new CoreJtagDebugIOJTAGPads with CoreJtagDebugIOTarget {
+ // chain inputs
+ val UTDO_IN_0 = Bool(INPUT)
+ val UTDO_IN_1 = Bool(INPUT)
+ val UTDO_IN_2 = Bool(INPUT)
+ val UTDO_IN_3 = Bool(INPUT)
+ val UTDODRV_0 = Bool(INPUT)
+ val UTDODRV_1 = Bool(INPUT)
+ val UTDODRV_2 = Bool(INPUT)
+ val UTDODRV_3 = Bool(INPUT)
+
+ // chain outputs
+ val UTDI_OUT = Bool(OUTPUT)
+ val URSTB_OUT = Bool(OUTPUT)
+ val UIREG_OUT = Bits(OUTPUT,8)
+ val UDRUPD_OUT = Bool(OUTPUT)
+ val UDRSH_OUT = Bool(OUTPUT)
+ val UDRCK_OUT = Bool(OUTPUT)
+ val UDRCAP_OUT = Bool(OUTPUT)
+ }
+
+ ElaborationArtefacts.add(
+ "Libero.corejtagdebug.tcl",
+ """
+create_design -id Actel:DirectCore:COREJTAGDEBUG:2.0.100 -design_name {corejtagdebug_wrapper} -config_file {} -params {} -inhibit_configurator 0
+open_smartdesign -design {corejtagdebug_wrapper}
+configure_design -component {corejtagdebug_wrapper} -library {}
+configure_vlnv_instance -component {corejtagdebug_wrapper} -library {} -name {corejtagdebug_wrapper_0} -params {"IR_CODE:0x55" "ACTIVE_HIGH_TGT_RESET:1"} -validate_rules 0
+fix_vlnv_instance -component {corejtagdebug_wrapper} -library {} -name {corejtagdebug_wrapper_0}
+open_smartdesign -design {corejtagdebug_wrapper}
+configure_design -component {corejtagdebug_wrapper} -library {}
+"""
+ )
+
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire.scala
new file mode 100644
index 0000000..edd6aa0
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire.scala
@@ -0,0 +1,40 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi
+
+import Chisel._
+import chisel3.{Input, Output}
+import chisel3.experimental.{Analog, attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+
+
+//========================================================================
+// This file contains common devices for Microsemi PolarFire FPGAs.
+//========================================================================
+
+//-------------------------------------------------------------------------
+// Clock network macro
+//-------------------------------------------------------------------------
+
+class CLKBUF() extends BlackBox
+{
+ val io = new Bundle{
+ val PAD = Clock(INPUT)
+ val Y = Clock(OUTPUT)
+ }
+}
+
+class CLKINT() extends BlackBox
+{
+ val io = new Bundle{
+ val A = Clock(INPUT)
+ val Y = Clock(OUTPUT)
+ }
+}
+
+class ICB_CLKINT() extends BlackBox
+{
+ val io = new Bundle{
+ val A = Clock(INPUT)
+ val Y = Clock(OUTPUT)
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_ccc/PolarFireCCC.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_ccc/PolarFireCCC.scala
new file mode 100644
index 0000000..a5d6ff3
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_ccc/PolarFireCCC.scala
@@ -0,0 +1,81 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfireccc
+
+import Chisel._
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.config._
+
+import sifive.fpgashells.clocks._
+
+case class PolarFireCCCParameters(
+ name: String,
+ pll_in_freq: Double = 50,
+ gl0Enabled: Boolean = false,
+ gl1Enabled: Boolean = false,
+ gl2Enabled: Boolean = false,
+ gl3Enabled: Boolean = false,
+ gl0_0_out_freq: Double = 111.111,
+ gl1_0_out_freq: Double = 111.111,
+ gl2_0_out_freq: Double = 111.111,
+ gl3_0_out_freq: Double = 111.111,
+ gl0_0_pll_phase: Double = 0,
+ gl1_0_pll_phase: Double = 0,
+ gl2_0_pll_phase: Double = 0,
+ gl3_0_pll_phase: Double = 0,
+ feedback: Boolean = false
+)
+
+// Black Box for Microsemi PolarFire Clock Conditioning Circuit (CCC) Actel:SgCore:PF_CCC:1.0.112
+class PolarFireCCCIOPads(c : PLLParameters) extends Bundle {
+ val REF_CLK_0 = Clock(INPUT)
+ val OUT0_FABCLK_0 = if (c.req.size >= 1) Some(Clock(OUTPUT)) else None
+ val OUT1_FABCLK_0 = if (c.req.size >= 2) Some(Clock(OUTPUT)) else None
+ val OUT2_FABCLK_0 = if (c.req.size >= 3) Some(Clock(OUTPUT)) else None
+ val OUT3_FABCLK_0 = if (c.req.size >= 4) Some(Clock(OUTPUT)) else None
+ val PLL_LOCK_0 = Bool(OUTPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class PolarFireCCC(c : PLLParameters) extends BlackBox with PLLInstance {
+ val moduleName = c.name
+ override def desiredName = c.name
+
+ val io = new PolarFireCCCIOPads(c)
+ def getInput = io.REF_CLK_0
+ def getReset = None
+ def getLocked = io.PLL_LOCK_0
+ def getClocks = Seq() ++ io.OUT0_FABCLK_0 ++ io.OUT1_FABCLK_0 ++
+ io.OUT2_FABCLK_0 ++ io.OUT3_FABCLK_0
+
+ def getClockNames = Seq.tabulate (c.req.size) { i =>
+ s"${c.name}/${c.name}_0/pll_inst_0/OUT${i}"
+ }
+
+ val used = Seq.tabulate(4) { i =>
+ s" GL${i}_0_IS_USED:${i < c.req.size} \\\n"
+ }.mkString
+
+ val outputs = c.req.zipWithIndex.map { case (req, i) =>
+ s""" GL${i}_0_OUT_FREQ:${req.freqMHz} \\
+ | GL${i}_0_PLL_PHASE:${req.phaseDeg} \\
+ |""".stripMargin
+ }.mkString
+
+ // !!! work-around libero bug
+ // val feedback = if (c.input.feedback) "External" else "Post-VCO"
+ val feedback = "Post-VCO"
+
+ ElaborationArtefacts.add(s"${moduleName}.libero.tcl",
+ s"""create_design -id Actel:SgCore:PF_CCC:1.0.115 -design_name {${moduleName}} -config_file {} -params {} -inhibit_configurator 0
+ |open_smartdesign -design {${moduleName}}
+ |configure_design -component {${moduleName}} -library {}
+ |configure_vlnv_instance -component {${moduleName}} -library {} -name {${moduleName}_0} -validate_rules 0 -params { \\
+ | PLL_IN_FREQ_0:${c.input.freqMHz} \\
+ | PLL_FEEDBACK_MODE_0:${feedback} \\
+ |${used}${outputs}}
+ |fix_vlnv_instance -component {${moduleName}} -library {} -name {${moduleName}_0}
+ |open_smartdesign -design {${moduleName}}
+ |configure_design -component {${moduleName}} -library {}
+ |""".stripMargin)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_clock_divider/PolarFireClockDivider.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_clock_divider/PolarFireClockDivider.scala
new file mode 100644
index 0000000..0dba06b
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_clock_divider/PolarFireClockDivider.scala
@@ -0,0 +1,40 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfireclockdivider
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box for Actel:SgCore:PF_CLK_DIV:1.0.101
+
+trait PolarFireClockDividerIOPads extends Bundle {
+
+ val CLK_OUT = Clock(OUTPUT)
+ val CLK_IN = Clock(INPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class PolarFireClockDivider(implicit val p:Parameters) extends BlackBox
+{
+ override def desiredName = "pf_clk_divider"
+
+ val io = new PolarFireClockDividerIOPads {
+ }
+
+ ElaborationArtefacts.add(
+ "Libero.polarfire_clock_divider.libero.tcl",
+ """
+create_design -id Actel:SgCore:PF_CLK_DIV:1.0.101 -design_name {pf_clk_divider} -config_file {} -params {} -inhibit_configurator 0
+open_smartdesign -design {pf_clk_divider}
+configure_design -component {pf_clk_divider} -library {}
+configure_vlnv_instance -component {pf_clk_divider} -library {} -name {pf_clk_divider_0} -params {"DIVIDER:2"} -validate_rules 0
+fix_vlnv_instance -component {pf_clk_divider} -library {} -name {pf_clk_divider_0}
+open_smartdesign -design {pf_clk_divider}
+configure_design -component {pf_clk_divider} -library {}
+"""
+ )
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_ddr3/PolarFireDDR3.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_ddr3/PolarFireDDR3.scala
new file mode 100644
index 0000000..e8b2a6a
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_ddr3/PolarFireDDR3.scala
@@ -0,0 +1,129 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfireddr3
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box for Microsemi PolarFire DDR3 controller version 2.1.101
+
+class PolarFireEvalKitDDR3IODDR(depth : BigInt) extends GenericParameterizedBundle(depth) {
+
+ val A = Bits(OUTPUT,16)
+ val BA = Bits(OUTPUT,3)
+ val RAS_N = Bool(OUTPUT)
+ val CAS_N = Bool(OUTPUT)
+ val WE_N = Bool(OUTPUT)
+ val CTRLR_READY = Bool(OUTPUT)
+ val SHIELD0 = Bool(OUTPUT)
+ val SHIELD1 = Bool(OUTPUT)
+ val CK0 = Bits(OUTPUT,1)
+ val CK0_N = Bits(OUTPUT,1)
+ val CKE = Bits(OUTPUT,1)
+ val CS_N = Bits(OUTPUT,1)
+ val DM = Bits(OUTPUT,2)
+ val ODT = Bits(OUTPUT,1)
+ val RESET_N = Bool(OUTPUT)
+
+ val DQ = Analog(16.W)
+ val DQS = Analog(2.W)
+ val DQS_N = Analog(2.W)
+}
+
+trait PolarFireEvalKitDDR3IOClocksReset extends Bundle {
+
+ val SYS_RESET_N = Bool(INPUT)
+ val PLL_REF_CLK = Clock(INPUT)
+
+ val SYS_CLK = Clock(OUTPUT)
+ val PLL_LOCK = Bool(OUTPUT)
+
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class DDR3_Subsys(depth : BigInt)(implicit val p:Parameters) extends BlackBox
+{
+ override def desiredName = "pf_ddr"
+
+ val io = new PolarFireEvalKitDDR3IODDR(depth) with PolarFireEvalKitDDR3IOClocksReset {
+ //axi slave interface
+ //slave interface write address ports
+ val axi0_awid = Bits(INPUT,4)
+ val axi0_awaddr = Bits(INPUT,32)
+ val axi0_awlen = Bits(INPUT,8)
+ val axi0_awsize = Bits(INPUT,3)
+ val axi0_awburst = Bits(INPUT,2)
+ val axi0_awlock = Bits(INPUT,2)
+ val axi0_awcache = Bits(INPUT,4)
+ val axi0_awprot = Bits(INPUT,3)
+ val axi0_awvalid = Bool(INPUT)
+ val axi0_awready = Bool(OUTPUT)
+ //slave interface write data ports
+ val axi0_wdata = Bits(INPUT,64)
+ val axi0_wstrb = Bits(INPUT,8)
+ val axi0_wlast = Bool(INPUT)
+ val axi0_wvalid = Bool(INPUT)
+ val axi0_wready = Bool(OUTPUT)
+ //slave interface write response ports
+ val axi0_bready = Bool(INPUT)
+ val axi0_bid = Bits(OUTPUT,4)
+ val axi0_bresp = Bits(OUTPUT,2)
+ val axi0_bvalid = Bool(OUTPUT)
+ //slave interface read address ports
+ val axi0_arid = Bits(INPUT,4)
+ val axi0_araddr = Bits(INPUT,32)
+ val axi0_arlen = Bits(INPUT,8)
+ val axi0_arsize = Bits(INPUT,3)
+ val axi0_arburst = Bits(INPUT,2)
+ val axi0_arlock = Bits(INPUT,2)
+ val axi0_arcache = Bits(INPUT,4)
+ val axi0_arprot = Bits(INPUT,3)
+ val axi0_arvalid = Bool(INPUT)
+ val axi0_arready = Bool(OUTPUT)
+ //slave interface read data ports
+ val axi0_rready = Bool(INPUT)
+ val axi0_rid = Bits(OUTPUT,4)
+ val axi0_rdata = Bits(OUTPUT,64)
+ val axi0_rresp = Bits(OUTPUT,2)
+ val axi0_rlast = Bool(OUTPUT)
+ val axi0_rvalid = Bool(OUTPUT)
+ //misc
+ val AXI0_AWUSERTAG = Bits(INPUT,4)
+ val AXI0_BUSERTAG = Bits(OUTPUT,4)
+ }
+
+ ElaborationArtefacts.add(
+ "AddIPInstance.polarfire_ddr3.libero.tcl",
+ """
+create_design -id Actel:SystemBuilder:PF_DDR3:2.2.109 -design_name {pf_ddr} -config_file {} -params {} -inhibit_configurator 0
+open_smartdesign -design pf_ddr
+sysbld_configure_page -component pf_ddr -page PF_DDR3_UI -param WIDTH:16 \
+ -param CLOCK_DDR:666.666 \
+ -param CLOCK_PLL_REFERENCE:111.111 \
+ -param CCC_PLL_CLOCK_MULTIPLIER:6 \
+ -param ROW_ADDR_WIDTH:16 \
+ -param CAS_LATENCY:9 \
+ -param RTT_NOM:RZQ6 \
+ -param CAS_WRITE_LATENCY:7 \
+ -param OUTPUT_DRIVE_STRENGTH:RZQ7 \
+ -param TIMING_RAS:36 \
+ -param TIMING_RCD:13.5 \
+ -param TIMING_RP:13.5 \
+ -param TIMING_RC:49.5 \
+ -param TIMING_WR:15 \
+ -param TIMING_FAW:30 \
+ -param TIMING_WTR:5 \
+ -param TIMING_RRD:7.5 \
+ -param TIMING_RTP:7.5 \
+ -param TIMING_RFC:350 \
+ -param AXI_ID_WIDTH:6
+save_design -component pf_ddr -library {} -file {}
+generate_design -component pf_ddr -library {} -file {} -generator {} -recursive 1
+close_design -component pf_ddr
+"""
+ )
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_ddr4/PolarFireDDR4.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_ddr4/PolarFireDDR4.scala
new file mode 100644
index 0000000..a4af0e9
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_ddr4/PolarFireDDR4.scala
@@ -0,0 +1,132 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfireddr4
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box
+
+class PolarFireEvalKitDDR4IODDR(depth : BigInt) extends GenericParameterizedBundle(depth) {
+
+ val A = Bits(OUTPUT,14)
+ val ACT_N = Bool(OUTPUT)
+ val BA = Bits(OUTPUT,2)
+ val BG = Bits(OUTPUT,2)
+ val RAS_N = Bool(OUTPUT)
+ val CAS_N = Bool(OUTPUT)
+ val WE_N = Bool(OUTPUT)
+ val SHIELD0 = Bool(OUTPUT)
+ val SHIELD1 = Bool(OUTPUT)
+ val CK0 = Bits(OUTPUT,1)
+ val CK0_N = Bits(OUTPUT,1)
+ val CKE = Bits(OUTPUT,1)
+ val CS_N = Bits(OUTPUT,1)
+ val DM_N = Bits(OUTPUT,2)
+ val ODT = Bits(OUTPUT,1)
+
+ val DQ = Analog(16.W)
+ val DQS = Analog(2.W)
+ val DQS_N = Analog(2.W)
+
+ val RESET_N = Bool(OUTPUT)
+}
+
+trait PolarFireEvalKitDDR4IOClocksReset extends Bundle {
+
+ val SYS_RESET_N = Bool(INPUT)
+ val PLL_REF_CLK = Clock(INPUT)
+
+ val SYS_CLK = Clock(OUTPUT)
+ val PLL_LOCK = Bool(OUTPUT)
+ val CTRLR_READY = Bool(OUTPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class DDR4_Subsys(depth : BigInt)(implicit val p:Parameters) extends BlackBox
+{
+ override def desiredName = "pf_ddr"
+
+ val io = new PolarFireEvalKitDDR4IODDR(depth) with PolarFireEvalKitDDR4IOClocksReset {
+ //axi slave interface
+ //slave interface write address ports
+ val axi0_awid = Bits(INPUT,6)
+ val axi0_awaddr = Bits(INPUT,32)
+ val axi0_awlen = Bits(INPUT,8)
+ val axi0_awsize = Bits(INPUT,3)
+ val axi0_awburst = Bits(INPUT,2)
+ val axi0_awlock = Bits(INPUT,2)
+ val axi0_awcache = Bits(INPUT,4)
+ val axi0_awprot = Bits(INPUT,3)
+ val axi0_awvalid = Bool(INPUT)
+ val axi0_awready = Bool(OUTPUT)
+ //slave interface write data ports
+ val axi0_wdata = Bits(INPUT,64)
+ val axi0_wstrb = Bits(INPUT,8)
+ val axi0_wlast = Bool(INPUT)
+ val axi0_wvalid = Bool(INPUT)
+ val axi0_wready = Bool(OUTPUT)
+ //slave interface write response ports
+ val axi0_bready = Bool(INPUT)
+ val axi0_bid = Bits(OUTPUT,6)
+ val axi0_bresp = Bits(OUTPUT,2)
+ val axi0_bvalid = Bool(OUTPUT)
+ //slave interface read address ports
+ val axi0_arid = Bits(INPUT,6)
+ val axi0_araddr = Bits(INPUT,32)
+ val axi0_arlen = Bits(INPUT,8)
+ val axi0_arsize = Bits(INPUT,3)
+ val axi0_arburst = Bits(INPUT,2)
+ val axi0_arlock = Bits(INPUT,2)
+ val axi0_arcache = Bits(INPUT,4)
+ val axi0_arprot = Bits(INPUT,3)
+ val axi0_arvalid = Bool(INPUT)
+ val axi0_arready = Bool(OUTPUT)
+ //slave interface read data ports
+ val axi0_rready = Bool(INPUT)
+ val axi0_rid = Bits(OUTPUT,6)
+ val axi0_rdata = Bits(OUTPUT,64)
+ val axi0_rresp = Bits(OUTPUT,2)
+ val axi0_rlast = Bool(OUTPUT)
+ val axi0_rvalid = Bool(OUTPUT)
+ //misc
+ //val AXI0_AWUSERTAG = Bits(INPUT,4)
+ //val AXI0_BUSERTAG = Bits(OUTPUT,4)
+ }
+
+ ElaborationArtefacts.add(
+ "AddIPInstance.ddr4.libero.tcl",
+ """
+create_design -id Actel:SystemBuilder:PF_DDR4:2.3.201 -design_name {pf_ddr} -config_file {} -params {} -inhibit_configurator 0
+open_smartdesign -design pf_ddr
+
+sysbld_configure_page -component pf_ddr -page PF_DDR4_UI -param WIDTH:16 \
+ -param MEMCTRLR_INST_NO:0 \
+ -param ENABLE_ECC:false \
+ -param AXI_WIDTH:64 \
+ -param FABRIC_INTERFACE:AXI4 \
+ -param CLOCK_DDR:800 \
+ -param CLOCK_PLL_REFERENCE:200 \
+ -param ROW_ADDR_WIDTH:15 \
+ -param CCC_PLL_CLOCK_MULTIPLIER:16 \
+ -param RTT_NOM:RZQ6 \
+ -param READ_PREAMBLE:1 \
+ -param TIMING_RAS:34 \
+ -param TIMING_RCD:13.92 \
+ -param TIMING_RP:13.92 \
+ -param TIMING_RC:47.92 \
+ -param TIMING_RFC:350 \
+ -param TIMING_FAW:20 \
+ -param AXI_ID_WIDTH:6
+
+save_design -component pf_ddr -library {} -file {}
+
+generate_design -component pf_ddr -library {} -file {} -generator {} -recursive 1
+
+close_design -component pf_ddr""")
+
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_dll/PolarFireDLL.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_dll/PolarFireDLL.scala
new file mode 100644
index 0000000..4a4c0ee
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_dll/PolarFireDLL.scala
@@ -0,0 +1,46 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfiredll
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box for Microsemi PolarFire Delay Locked Loop (DLL) Actel:SgCore:PF_CCC:1.0.112
+
+class PolarFireDLLIOPads extends Bundle {
+
+ val DLL_FB_CLK = Clock(INPUT)
+ val DLL_REF_CLK = Clock(INPUT)
+ val DLL_CLK_0_FABCLK = Clock(OUTPUT)
+ val DLL_LOCK = Bool(OUTPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class PolarFireDLL(name: String)(implicit val p:Parameters) extends BlackBox
+{
+ val modulename = name
+ override def desiredName = name
+
+ val io = new PolarFireDLLIOPads
+
+ ElaborationArtefacts.add(
+ "AddIPInstance." ++ modulename ++".libero.tcl",
+ """
+create_design -id Actel:SgCore:PF_CCC:1.0.115 -design_name {""" ++ modulename ++"""} -config_file {} -params {} -inhibit_configurator 0
+open_smartdesign -design {""" ++ modulename ++"""}
+configure_design -component {""" ++ modulename ++"""} -library {}
+configure_vlnv_instance -component {""" ++ modulename ++"""} -library {} -name {""" ++ modulename ++"""_0} \
+ -params {"DLL_ONLY_EN:true" \
+ "DLL_IN:125" \
+ "DLL_MODE:INJECTION_REM_MODE" \
+ "DLL_CLK_0_FABCLK_EN:true" \
+ } -validate_rules 0
+fix_vlnv_instance -component {""" ++ modulename ++"""} -library {} -name {""" ++ modulename ++"""_0}
+open_smartdesign -design {""" ++ modulename ++"""}
+configure_design -component {""" ++ modulename ++"""} -library {}"""
+ )
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_glitchless_mux/PolarFireGlitchlessMux.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_glitchless_mux/PolarFireGlitchlessMux.scala
new file mode 100644
index 0000000..9905780
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_glitchless_mux/PolarFireGlitchlessMux.scala
@@ -0,0 +1,41 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfireglitchlessmux
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box forMicrosemi PolarFire glitchless mux Actel:SgCore:PF_NGMUX:1.0.101
+
+trait PolarFireGlitchlessMuxIOPads extends Bundle {
+
+ val CLK_OUT = Clock(OUTPUT)
+ val CLK0 = Clock(INPUT)
+ val CLK1 = Clock(INPUT)
+ val SEL = Bool(INPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class PolarFireGlitchlessMux(implicit val p:Parameters) extends BlackBox
+{
+ override def desiredName = "pf_glitchless_mux"
+
+ val io = new PolarFireGlitchlessMuxIOPads {
+ }
+
+ ElaborationArtefacts.add(
+ "Libero.polarfire_glitchless_mux.libero.tcl",
+ """
+create_design -id Actel:SgCore:PF_NGMUX:1.0.101 -design_name {pf_glitchless_mux} -config_file {} -params {} -inhibit_configurator 0
+open_smartdesign -design {pf_glitchless_mux}
+configure_design -component {pf_glitchless_mux} -library {}
+fix_vlnv_instance -component {pf_glitchless_mux} -library {} -name {pf_glitchless_mux_0}
+open_smartdesign -design {pf_glitchless_mux}
+configure_design -component {pf_glitchless_mux} -library {}
+"""
+ )
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_init_monitor/PolarFireInitMonitor.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_init_monitor/PolarFireInitMonitor.scala
new file mode 100644
index 0000000..33d1797
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_init_monitor/PolarFireInitMonitor.scala
@@ -0,0 +1,32 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfireinitmonitor
+
+import Chisel._
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.config._
+
+// Black Box for Microsemi PolarFire Clock Conditioning Circuit (CCC) Actel:SgCore:PF_INIT_MONITOR:2.0.103
+
+trait PolarFireInitMonitorIOPads {
+ val DEVICE_INIT_DONE = Bool(OUTPUT)
+ val FABRIC_POR_N = Bool(OUTPUT)
+ val PCIE_INIT_DONE = Bool(OUTPUT)
+ val SRAM_INIT_DONE = Bool(OUTPUT)
+ val USRAM_INIT_DONE = Bool(OUTPUT)
+}
+
+class PolarFireInitMonitor(implicit val p:Parameters) extends BlackBox
+{
+ override def desiredName = "polarfire_init_monitor"
+
+ val io = new Bundle with PolarFireInitMonitorIOPads
+
+ ElaborationArtefacts.add(s"${desiredName}.libero.tcl",
+ s"""create_design -id Actel:SgCore:PF_INIT_MONITOR:2.0.103 -design_name {polarfire_init_monitor} -config_file {} -params {} -inhibit_configurator 0
+ |open_smartdesign -design {polarfire_init_monitor}
+ |configure_design -component {polarfire_init_monitor} -library {}
+ |fix_vlnv_instance -component {polarfire_init_monitor} -library {} -name {polarfire_init_monitor_0}
+ |open_smartdesign -design {polarfire_init_monitor}
+ |configure_design -component {polarfire_init_monitor} -library {}
+ |""".stripMargin)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_oscillator/PolarFireOscillator.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_oscillator/PolarFireOscillator.scala
new file mode 100644
index 0000000..d3c32f7
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_oscillator/PolarFireOscillator.scala
@@ -0,0 +1,37 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfire_oscillator
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box for Microsemi PolarFire internal oscillator Actel:SgCore:PF_OSC:1.0.102
+
+trait PolarFireOscillatorIOPads extends Bundle {
+
+ val RCOSC_160MHZ_GL = Clock(OUTPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class PolarFireOscillator(implicit val p:Parameters) extends BlackBox
+{
+ override def desiredName = "pf_oscillator"
+
+ val io = new PolarFireOscillatorIOPads {
+ }
+
+ ElaborationArtefacts.add(
+ "Libero.polarfire_oscillator.libero.tcl",
+ """
+create_design -id Actel:SgCore:PF_OSC:1.0.102 -design_name {pf_oscillator} -config_file {} -params {} -inhibit_configurator 0
+open_smartdesign -design {pf_oscillator}
+configure_design -component {pf_oscillator} -library {}
+fix_vlnv_instance -component {pf_oscillator} -library {} -name {pf_oscillator_0}
+open_smartdesign -design {pf_oscillator}
+configure_design -component {pf_oscillator} -library {} """
+ )
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_pcie_rootport/PolarFirePCIeRootPort.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_pcie_rootport/PolarFirePCIeRootPort.scala
new file mode 100644
index 0000000..24dd7e7
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_pcie_rootport/PolarFirePCIeRootPort.scala
@@ -0,0 +1,608 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfirepcierootport
+
+import Chisel._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.amba.apb._
+import freechips.rocketchip.interrupts._
+import freechips.rocketchip.util.{ElaborationArtefacts}
+
+
+import chisel3.{Input, Output}
+import chisel3.experimental.attach
+
+// Black Box for Microsemi PolarFire PCIe root port
+
+trait PolarFirePCIeIOSerial extends Bundle {
+ //serial external pins
+ val PCIESS_LANE_TXD0_N = Bool(OUTPUT)
+ val PCIESS_LANE_TXD0_P = Bool(OUTPUT)
+ val PCIESS_LANE_TXD1_N = Bool(OUTPUT)
+ val PCIESS_LANE_TXD1_P = Bool(OUTPUT)
+ val PCIESS_LANE_TXD2_N = Bool(OUTPUT)
+ val PCIESS_LANE_TXD2_P = Bool(OUTPUT)
+ val PCIESS_LANE_TXD3_N = Bool(OUTPUT)
+ val PCIESS_LANE_TXD3_P = Bool(OUTPUT)
+
+ val PCIESS_LANE_RXD0_N = Bool(INPUT)
+ val PCIESS_LANE_RXD0_P = Bool(INPUT)
+ val PCIESS_LANE_RXD1_N = Bool(INPUT)
+ val PCIESS_LANE_RXD1_P = Bool(INPUT)
+ val PCIESS_LANE_RXD2_N = Bool(INPUT)
+ val PCIESS_LANE_RXD2_P = Bool(INPUT)
+ val PCIESS_LANE_RXD3_N = Bool(INPUT)
+ val PCIESS_LANE_RXD3_P = Bool(INPUT)
+}
+
+trait PolarFirePCIeIOClocksReset extends Bundle {
+ //clock, reset, control
+ val APB_S_PCLK = Clock(INPUT)
+ val APB_S_PRESET_N = Bool(INPUT)
+
+ val AXI_CLK = Clock(INPUT)
+ val AXI_CLK_STABLE = Bool(INPUT)
+
+ val PCIE_1_TL_CLK_125MHz = Clock(INPUT)
+ val PCIE_1_TX_BIT_CLK = Clock(INPUT)
+ val PCIE_1_TX_PLL_REF_CLK = Clock(INPUT)
+ val PCIE_1_TX_PLL_LOCK = Bool(INPUT)
+
+ val PCIESS_LANE0_CDR_REF_CLK_0 = Clock(INPUT)
+ val PCIESS_LANE1_CDR_REF_CLK_0 = Clock(INPUT)
+ val PCIESS_LANE2_CDR_REF_CLK_0 = Clock(INPUT)
+ val PCIESS_LANE3_CDR_REF_CLK_0 = Clock(INPUT)
+}
+
+trait PolarFirePCIeIODebug extends Bundle {
+
+ val debug_pclk = Output(Clock())
+ val debug_preset = Output(Bool())
+ val debug_penable = Output(Bool())
+ val debug_psel = Output(Bool())
+ val debug_paddr2 = Output(Bool())
+ val debug_paddr3 = Output(Bool())
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class polarfire_pcie_rp() extends BlackBox
+{
+ val io = new Bundle with PolarFirePCIeIOSerial
+ with PolarFirePCIeIOClocksReset {
+
+ // APB control interface
+ val APB_S_PADDR = Bits(INPUT,26)
+ val APB_S_PENABLE = Bool(INPUT)
+ val APB_S_PSEL = Bool(INPUT)
+ val APB_S_PWDATA = Bits(INPUT,32)
+ val APB_S_PWRITE = Bool(INPUT)
+ val APB_S_PRDATA = Bits(OUTPUT,32)
+ val APB_S_PREADY = Bool(OUTPUT)
+ val APB_S_PSLVERR = Bool(OUTPUT)
+
+ //axi slave
+ val PCIESS_AXI_1_S_ARREADY = Bool(OUTPUT)
+ val PCIESS_AXI_1_S_AWREADY = Bool(OUTPUT)
+ val PCIESS_AXI_1_S_BID = Bits(OUTPUT,4)
+ val PCIESS_AXI_1_S_BRESP = Bits(OUTPUT,2)
+ val PCIESS_AXI_1_S_BVALID = Bool(OUTPUT)
+ val PCIESS_AXI_1_S_RDATA = Bits(OUTPUT,64)
+ val PCIESS_AXI_1_S_RID = Bits(OUTPUT,4)
+ val PCIESS_AXI_1_S_RLAST = Bool(OUTPUT)
+ val PCIESS_AXI_1_S_RRESP = Bits(OUTPUT,2)
+ val PCIESS_AXI_1_S_RVALID = Bool(OUTPUT)
+ val PCIESS_AXI_1_S_WREADY = Bool(OUTPUT)
+
+ val PCIESS_AXI_1_S_ARADDR = Bits(INPUT,32)
+ val PCIESS_AXI_1_S_ARBURST = Bits(INPUT,2)
+ val PCIESS_AXI_1_S_ARID = Bits(INPUT,4)
+ val PCIESS_AXI_1_S_ARLEN = Bits(INPUT,8)
+ val PCIESS_AXI_1_S_ARSIZE = Bits(INPUT,2)
+ val PCIESS_AXI_1_S_ARVALID = Bool(INPUT)
+ val PCIESS_AXI_1_S_AWADDR = Bits(INPUT,32)
+ val PCIESS_AXI_1_S_AWBURST = Bits(INPUT,2)
+ val PCIESS_AXI_1_S_AWID = Bits(INPUT,4)
+ val PCIESS_AXI_1_S_AWLEN = Bits(INPUT,8)
+ val PCIESS_AXI_1_S_AWSIZE = Bits(INPUT,2)
+ val PCIESS_AXI_1_S_AWVALID = Bool(INPUT)
+ val PCIESS_AXI_1_S_BREADY = Bool(INPUT)
+ val PCIESS_AXI_1_S_RREADY = Bool(INPUT)
+ val PCIESS_AXI_1_S_WDATA = Bits(INPUT,64)
+ val PCIESS_AXI_1_S_WLAST = Bool(INPUT)
+ val PCIESS_AXI_1_S_WSTRB = Bits(INPUT,8)
+ val PCIESS_AXI_1_S_WVALID = Bool(INPUT)
+
+ //axi master
+ val PCIESS_AXI_1_M_ARADDR = Bits(OUTPUT,32)
+ val PCIESS_AXI_1_M_ARBURST = Bits(OUTPUT,2)
+ val PCIESS_AXI_1_M_ARID = Bits(OUTPUT,4)
+ val PCIESS_AXI_1_M_ARLEN = Bits(OUTPUT,8)
+ val PCIESS_AXI_1_M_ARSIZE = Bits(OUTPUT,2)
+ val PCIESS_AXI_1_M_ARVALID = Bool(OUTPUT)
+ val PCIESS_AXI_1_M_AWADDR = Bits(OUTPUT,32)
+ val PCIESS_AXI_1_M_AWBURST = Bits(OUTPUT,2)
+ val PCIESS_AXI_1_M_AWID = Bits(OUTPUT,4)
+ val PCIESS_AXI_1_M_AWLEN = Bits(OUTPUT,8)
+ val PCIESS_AXI_1_M_AWSIZE = Bits(OUTPUT,2)
+ val PCIESS_AXI_1_M_AWVALID = Bool(OUTPUT)
+ val PCIESS_AXI_1_M_BREADY = Bool(OUTPUT)
+ val PCIESS_AXI_1_M_RREADY = Bool(OUTPUT)
+ val PCIESS_AXI_1_M_WDATA = Bits(OUTPUT,64)
+ val PCIESS_AXI_1_M_WLAST = Bool(OUTPUT)
+ val PCIESS_AXI_1_M_WSTRB = Bits(OUTPUT,8)
+ val PCIESS_AXI_1_M_WVALID = Bool(OUTPUT)
+
+ val PCIESS_AXI_1_M_ARREADY = Bool(INPUT)
+ val PCIESS_AXI_1_M_AWREADY = Bool(INPUT)
+ val PCIESS_AXI_1_M_BID = Bits(INPUT,4)
+ val PCIESS_AXI_1_M_BRESP = Bits(INPUT,2)
+ val PCIESS_AXI_1_M_BVALID = Bool(INPUT)
+ val PCIESS_AXI_1_M_RDATA = Bits(INPUT,64)
+ val PCIESS_AXI_1_M_RID = Bits(INPUT,4)
+ val PCIESS_AXI_1_M_RLAST = Bool(INPUT)
+ val PCIESS_AXI_1_M_RRESP = Bits(INPUT,2)
+ val PCIESS_AXI_1_M_RVALID = Bool(INPUT)
+ val PCIESS_AXI_1_M_WREADY = Bool(INPUT)
+
+ // Misc
+ //val DLL_OUT = Bool(OUTPUT)
+ val PCIE_1_DLUP_EXIT = Bool(OUTPUT)
+ val PCIE_1_HOT_RST_EXIT = Bool(OUTPUT)
+ val PCIE_1_INTERRUPT_OUT = Bool(OUTPUT)
+ val PCIE_1_L2_EXIT = Bool(OUTPUT)
+ val PCIE_1_LTSSM = Bits(OUTPUT,5)
+ val PCIE_1_M_WDERR = Bool(OUTPUT)
+ val PCIE_1_S_RDERR = Bool(OUTPUT)
+
+ val PCIE_1_INTERRUPT = Bits(INPUT,8)
+ val PCIE_1_M_RDERR = Bool(INPUT)
+ val PCIE_1_S_WDERR = Bool(INPUT)
+ }
+}
+//scalastyle:off
+
+class PolarFirePCIeX4(implicit p:Parameters) extends LazyModule
+{
+ val device = new SimpleDevice("pci", Seq("plda,axi-pcie-root-port-1.00")) {
+ override def describe(resources: ResourceBindings): Description = {
+ val Description(name, mapping) = super.describe(resources)
+ val intc = "pcie_intc"
+ def ofInt(x: Int) = Seq(ResourceInt(BigInt(x)))
+ def ofMap(x: Int) = Seq(0, 0, 0, x).flatMap(ofInt) ++ Seq(ResourceReference(intc)) ++ ofInt(x)
+ val extra = Map(
+ "#address-cells" -> ofInt(3),
+ "#size-cells" -> ofInt(2),
+ "#interrupt-cells" -> ofInt(1),
+ "device_type" -> Seq(ResourceString("pci")),
+ "interrupt-map-mask" -> Seq(0, 0, 0, 7).flatMap(ofInt),
+ "interrupt-map" -> Seq(1, 2, 3, 4).flatMap(ofMap),
+ "ranges" -> resources("ranges").map{ case Binding(_, ResourceAddress(address, perms)) =>
+ ResourceMapping(address, BigInt(0x02000000) << 64, perms) },
+ "interrupt-controller" -> Seq(ResourceMap(labels = Seq(intc), value = Map(
+ "interrupt-controller" -> Nil,
+ "#address-cells" -> ofInt(0),
+ "#interrupt-cells" -> ofInt(1)))))
+ Description(name, mapping ++ extra)
+ }
+ }
+
+ val slave = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = List(AddressSet(0x40000000L, 0x1fffffffL),AddressSet(0x2030000000L, 0x0fffffffL)),
+ resources = Seq(Resource(device, "ranges")),
+ executable = true,
+ supportsWrite = TransferSizes(1, 128),
+ supportsRead = TransferSizes(1, 128))),
+ beatBytes = 8)))
+
+ val control = APBSlaveNode(Seq(APBSlavePortParameters(
+ slaves = Seq(APBSlaveParameters(
+ address = List(AddressSet(0x2000000000L, 0x03ffffffL)),
+ resources = device.reg("control"),
+ supportsWrite = TransferSizes(1, 4),
+ supportsRead = TransferSizes(1, 4))),
+ beatBytes = 4)))
+
+
+ val master = AXI4MasterNode(Seq(AXI4MasterPortParameters(
+ masters = Seq(AXI4MasterParameters(
+ name = "PolarFire PCIe",
+ id = IdRange(0, 16),
+ aligned = false)))))
+
+ val intnode = IntSourceNode(IntSourcePortSimple(resources = device.int))
+
+ lazy val module = new LazyModuleImp(this) {
+ // Must have exactly the right number of idBits
+ require (slave.edges.in(0).bundle.idBits == 4)
+ require (master.edges.out(0).bundle.dataBits == 64)
+
+ class PolarFirePCIeX4IOBundle extends Bundle with PolarFirePCIeIOSerial
+ with PolarFirePCIeIODebug
+ with PolarFirePCIeIOClocksReset;
+
+ val io = IO(new Bundle {
+ val port = new PolarFirePCIeX4IOBundle
+ val REFCLK = Bool(INPUT)
+ })
+
+ val blackbox = Module(new polarfire_pcie_rp)
+
+ val (s, _) = slave.in(0)
+ val (c, _) = control.in(0)
+ val (m, _) = master.out(0)
+ val (i, _) = intnode.out(0)
+
+ //to top level
+ i(0) := blackbox.io.PCIE_1_INTERRUPT_OUT
+ blackbox.io.APB_S_PCLK := io.port.APB_S_PCLK
+ blackbox.io.APB_S_PRESET_N := io.port.APB_S_PRESET_N
+
+ blackbox.io.AXI_CLK := io.port.AXI_CLK
+ blackbox.io.AXI_CLK_STABLE := io.port.AXI_CLK_STABLE
+
+ blackbox.io.PCIE_1_TL_CLK_125MHz := io.port.PCIE_1_TL_CLK_125MHz
+ blackbox.io.PCIE_1_TX_BIT_CLK := io.port.PCIE_1_TX_BIT_CLK
+ blackbox.io.PCIE_1_TX_PLL_REF_CLK := io.port.PCIE_1_TX_PLL_REF_CLK
+ blackbox.io.PCIE_1_TX_PLL_LOCK := io.port.PCIE_1_TX_PLL_LOCK
+ blackbox.io.PCIESS_LANE0_CDR_REF_CLK_0 := io.port.PCIESS_LANE0_CDR_REF_CLK_0
+ blackbox.io.PCIESS_LANE1_CDR_REF_CLK_0 := io.port.PCIESS_LANE1_CDR_REF_CLK_0
+ blackbox.io.PCIESS_LANE2_CDR_REF_CLK_0 := io.port.PCIESS_LANE2_CDR_REF_CLK_0
+ blackbox.io.PCIESS_LANE3_CDR_REF_CLK_0 := io.port.PCIESS_LANE3_CDR_REF_CLK_0
+
+ io.port.PCIESS_LANE_TXD0_N := blackbox.io.PCIESS_LANE_TXD0_N
+ io.port.PCIESS_LANE_TXD0_P := blackbox.io.PCIESS_LANE_TXD0_P
+ io.port.PCIESS_LANE_TXD1_N := blackbox.io.PCIESS_LANE_TXD1_N
+ io.port.PCIESS_LANE_TXD1_P := blackbox.io.PCIESS_LANE_TXD1_P
+ io.port.PCIESS_LANE_TXD2_N := blackbox.io.PCIESS_LANE_TXD2_N
+ io.port.PCIESS_LANE_TXD2_P := blackbox.io.PCIESS_LANE_TXD2_P
+ io.port.PCIESS_LANE_TXD3_N := blackbox.io.PCIESS_LANE_TXD3_N
+ io.port.PCIESS_LANE_TXD3_P := blackbox.io.PCIESS_LANE_TXD3_P
+
+ blackbox.io.PCIESS_LANE_RXD0_N := io.port.PCIESS_LANE_RXD0_N
+ blackbox.io.PCIESS_LANE_RXD0_P := io.port.PCIESS_LANE_RXD0_P
+ blackbox.io.PCIESS_LANE_RXD1_N := io.port.PCIESS_LANE_RXD1_N
+ blackbox.io.PCIESS_LANE_RXD1_P := io.port.PCIESS_LANE_RXD1_P
+ blackbox.io.PCIESS_LANE_RXD2_N := io.port.PCIESS_LANE_RXD2_N
+ blackbox.io.PCIESS_LANE_RXD2_P := io.port.PCIESS_LANE_RXD2_P
+ blackbox.io.PCIESS_LANE_RXD3_N := io.port.PCIESS_LANE_RXD3_N
+ blackbox.io.PCIESS_LANE_RXD3_P := io.port.PCIESS_LANE_RXD3_P
+
+ //s
+ //slave interface
+ blackbox.io.PCIESS_AXI_1_S_AWID := s.aw.bits.id
+ blackbox.io.PCIESS_AXI_1_S_AWADDR := s.aw.bits.addr
+ blackbox.io.PCIESS_AXI_1_S_AWLEN := s.aw.bits.len
+ blackbox.io.PCIESS_AXI_1_S_AWSIZE := s.aw.bits.size
+ blackbox.io.PCIESS_AXI_1_S_AWBURST := s.aw.bits.burst
+ blackbox.io.PCIESS_AXI_1_S_AWVALID := s.aw.valid
+ s.aw.ready := blackbox.io.PCIESS_AXI_1_S_AWREADY
+
+ blackbox.io.PCIESS_AXI_1_S_WDATA := s.w.bits.data
+ blackbox.io.PCIESS_AXI_1_S_WSTRB := s.w.bits.strb
+ blackbox.io.PCIESS_AXI_1_S_WLAST := s.w.bits.last
+ blackbox.io.PCIESS_AXI_1_S_WVALID := s.w.valid
+ s.w.ready := blackbox.io.PCIESS_AXI_1_S_WREADY
+
+ s.b.bits.id := blackbox.io.PCIESS_AXI_1_S_BID
+ s.b.bits.resp := blackbox.io.PCIESS_AXI_1_S_BRESP
+ s.b.valid := blackbox.io.PCIESS_AXI_1_S_BVALID
+ blackbox.io.PCIESS_AXI_1_S_BREADY := s.b.ready
+
+ blackbox.io.PCIESS_AXI_1_S_ARID := s.ar.bits.id
+ blackbox.io.PCIESS_AXI_1_S_ARADDR := s.ar.bits.addr
+ blackbox.io.PCIESS_AXI_1_S_ARLEN := s.ar.bits.len
+ blackbox.io.PCIESS_AXI_1_S_ARSIZE := s.ar.bits.size
+ blackbox.io.PCIESS_AXI_1_S_ARBURST := s.ar.bits.burst
+ blackbox.io.PCIESS_AXI_1_S_ARVALID := s.ar.valid
+ s.ar.ready := blackbox.io.PCIESS_AXI_1_S_ARREADY
+
+ s.r.bits.id := blackbox.io.PCIESS_AXI_1_S_RID
+ s.r.bits.data := blackbox.io.PCIESS_AXI_1_S_RDATA
+ s.r.bits.resp := blackbox.io.PCIESS_AXI_1_S_RRESP
+ s.r.bits.last := blackbox.io.PCIESS_AXI_1_S_RLAST
+ s.r.valid := blackbox.io.PCIESS_AXI_1_S_RVALID
+ blackbox.io.PCIESS_AXI_1_S_RREADY := s.r.ready
+
+ blackbox.io.PCIE_1_INTERRUPT := UInt(0)
+ blackbox.io.PCIE_1_M_RDERR := Bool(false)
+ blackbox.io.PCIE_1_S_WDERR := Bool(false)
+
+ //ctl
+ blackbox.io.APB_S_PADDR := c.paddr
+ blackbox.io.APB_S_PENABLE := c.penable
+ blackbox.io.APB_S_PSEL := c.psel
+ blackbox.io.APB_S_PWDATA := c.pwdata
+ blackbox.io.APB_S_PWRITE := c.pwrite
+ c.prdata := blackbox.io.APB_S_PRDATA
+ c.pready := blackbox.io.APB_S_PREADY
+ c.pslverr := blackbox.io.APB_S_PSLVERR
+
+
+ // debug
+ io.port.debug_pclk := io.port.APB_S_PCLK
+ io.port.debug_preset := io.port.APB_S_PRESET_N
+ io.port.debug_penable := c.penable
+ io.port.debug_psel := c.psel
+ io.port.debug_paddr2 := c.paddr(2)
+ io.port.debug_paddr3 := c.paddr(3)
+
+ //m
+ m.aw.bits.cache := UInt(0)
+ m.aw.bits.prot := AXI4Parameters.PROT_PRIVILEDGED
+ m.aw.bits.qos := UInt(0)
+
+ m.aw.bits.id := blackbox.io.PCIESS_AXI_1_M_AWID
+ m.aw.bits.addr := blackbox.io.PCIESS_AXI_1_M_AWADDR
+ m.aw.bits.len := blackbox.io.PCIESS_AXI_1_M_AWLEN
+ m.aw.bits.size := blackbox.io.PCIESS_AXI_1_M_AWSIZE
+ m.aw.bits.burst := blackbox.io.PCIESS_AXI_1_M_AWBURST
+ m.aw.bits.id := blackbox.io.PCIESS_AXI_1_M_AWID
+ m.aw.valid := blackbox.io.PCIESS_AXI_1_M_AWVALID
+ blackbox.io.PCIESS_AXI_1_M_AWREADY := m.aw.ready
+
+ m.w.bits.data := blackbox.io.PCIESS_AXI_1_M_WDATA
+ m.w.bits.strb := blackbox.io.PCIESS_AXI_1_M_WSTRB
+ m.w.bits.last := blackbox.io.PCIESS_AXI_1_M_WLAST
+ m.w.valid := blackbox.io.PCIESS_AXI_1_M_WVALID
+ blackbox.io.PCIESS_AXI_1_M_WREADY := m.w.ready
+
+ blackbox.io.PCIESS_AXI_1_M_BID := m.b.bits.id
+ blackbox.io.PCIESS_AXI_1_M_BRESP := m.b.bits.resp
+ blackbox.io.PCIESS_AXI_1_M_BVALID := m.b.valid
+ m.b.ready := blackbox.io.PCIESS_AXI_1_M_BREADY
+
+ m.ar.bits.cache := UInt(0)
+ m.ar.bits.prot := AXI4Parameters.PROT_PRIVILEDGED
+ m.ar.bits.qos := UInt(0)
+
+ m.ar.bits.id := blackbox.io.PCIESS_AXI_1_M_ARID
+ m.ar.bits.addr := blackbox.io.PCIESS_AXI_1_M_ARADDR
+ m.ar.bits.len := blackbox.io.PCIESS_AXI_1_M_ARLEN
+ m.ar.bits.size := blackbox.io.PCIESS_AXI_1_M_ARSIZE
+ m.ar.bits.burst := blackbox.io.PCIESS_AXI_1_M_ARBURST
+ m.ar.valid := blackbox.io.PCIESS_AXI_1_M_ARVALID
+ m.ar.bits.id := blackbox.io.PCIESS_AXI_1_M_ARID
+ blackbox.io.PCIESS_AXI_1_M_ARREADY := m.ar.ready
+
+ blackbox.io.PCIESS_AXI_1_M_RID := m.r.bits.id
+ blackbox.io.PCIESS_AXI_1_M_RDATA := m.r.bits.data
+ blackbox.io.PCIESS_AXI_1_M_RRESP := m.r.bits.resp
+ blackbox.io.PCIESS_AXI_1_M_RLAST := m.r.bits.last
+ blackbox.io.PCIESS_AXI_1_M_RVALID := m.r.valid
+ m.r.ready := blackbox.io.PCIESS_AXI_1_M_RREADY
+ }
+
+ ElaborationArtefacts.add(
+ "Libero.polarfire_pcie_root_port.libero.tcl",
+ """
+new_file -type {SmartDesign} -name polarfire_pcie_rp
+add_vlnv_instance -component {polarfire_pcie_rp} -library {} -vendor {Actel} -lib {SgCore} -name {PF_PCIE} -version {2.0.100} -instance_name {PF_PCIE_0} -promote_all 0 -file_name {}
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_IS_CONFIGURED:true"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_SIMULATION_LEVEL:RTL"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIESS_LANE0_IS_USED:true"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIESS_LANE1_IS_USED:false"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIESS_LANE2_IS_USED:false"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIESS_LANE3_IS_USED:false"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_GPSS1_LANE0_IS_USED:false"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_GPSS1_LANE1_IS_USED:false"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_GPSS1_LANE2_IS_USED:false"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_GPSS1_LANE3_IS_USED:false"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PROTOCOL_PRESET_USED:PCIe"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_TX_CLK_DIV_FACTOR:1"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_CONTROLLER_ENABLED:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_NUMBER_OF_LANES:x1"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_LANE_RATE:Gen1 (2.5 Gbps)"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_REF_CLK_FREQ:100"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_PORT_TYPE:End Point"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_CDR_REF_CLK_SOURCE:Dedicated"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_CDR_REF_CLK_NUMBER:1"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_CONTROLLER_ENABLED:Enabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_NUMBER_OF_LANES:x4"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_LANE_RATE:Gen2 (5.0 Gbps)"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_REF_CLK_FREQ:100"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_PORT_TYPE:Root Port"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_CDR_REF_CLK_SOURCE:Dedicated"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_CDR_REF_CLK_NUMBER:1"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_VENDOR_ID:0x11AA"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SUB_VENDOR_ID:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_REVISION_ID:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_DEVICE_ID:0x1556"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SUB_SYSTEM_ID:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_CLASS_CODE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_VENDOR_ID:0x11AA"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SUB_VENDOR_ID:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_REVISION_ID:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_DEVICE_ID:0x1556"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SUB_SYSTEM_ID:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_CLASS_CODE:0x060400"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_BAR_MODE:Custom"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_PHY_REF_CLK_SLOT:Slot"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_INTERRUPTS:INTx"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_DE_EMPHASIS:-3.5 dB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_EXPOSE_WAKE_SIG:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_TRANSMIT_SWING:Full Swing"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_BAR_MODE:Custom"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_PHY_REF_CLK_SLOT:Slot"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_INTERRUPTS:MSI4"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_DE_EMPHASIS:-3.5 dB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_EXPOSE_WAKE_SIG:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_TRANSMIT_SWING:Full Swing"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_NUM_FTS:63"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_L0_ACC_LATENCY:No limit"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_L0_EXIT_LATENCY:64 ns to less than 128 ns"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_L1_ENABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_L1_ACC_LATENCY:No limit"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_L1_EXIT_LATENCY:16 us to less than 32 us"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_NUM_FTS:63"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_L0_ACC_LATENCY:No limit"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_L0_EXIT_LATENCY:64 ns to less than 128 ns"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_L1_ENABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_L1_ACC_LATENCY:No limit"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_L1_EXIT_LATENCY:16 us to less than 32 us"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TYPE_BAR_0_TABLE:64-bit prefetchable memory"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SIZE_BAR_0_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TABLE_SIZE_BAR_0_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SOURCE_ADDRESS_BAR_0_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TRANS_ADDRESS_BAR_0_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TYPE_BAR_0_TABLE:64-bit prefetchable memory"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SIZE_BAR_0_TABLE:2 GB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TABLE_SIZE_BAR_0_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SOURCE_ADDRESS_BAR_0_TABLE:0x100000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TRANS_ADDRESS_BAR_0_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TYPE_BAR_1_TABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SIZE_BAR_1_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TABLE_SIZE_BAR_1_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SOURCE_ADDRESS_BAR_1_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TRANS_ADDRESS_BAR_1_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TYPE_BAR_1_TABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SIZE_BAR_1_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TABLE_SIZE_BAR_1_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SOURCE_ADDRESS_BAR_1_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TRANS_ADDRESS_BAR_1_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TYPE_BAR_2_TABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SIZE_BAR_2_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TABLE_SIZE_BAR_2_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SOURCE_ADDRESS_BAR_2_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TRANS_ADDRESS_BAR_2_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TYPE_BAR_2_TABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SIZE_BAR_2_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TABLE_SIZE_BAR_2_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SOURCE_ADDRESS_BAR_2_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TRANS_ADDRESS_BAR_2_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TYPE_BAR_3_TABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SIZE_BAR_3_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TABLE_SIZE_BAR_3_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SOURCE_ADDRESS_BAR_3_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TRANS_ADDRESS_BAR_3_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TYPE_BAR_3_TABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SIZE_BAR_3_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TABLE_SIZE_BAR_3_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SOURCE_ADDRESS_BAR_3_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TRANS_ADDRESS_BAR_3_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TYPE_BAR_4_TABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SIZE_BAR_4_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TABLE_SIZE_BAR_4_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SOURCE_ADDRESS_BAR_4_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TRANS_ADDRESS_BAR_4_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TYPE_BAR_4_TABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SIZE_BAR_4_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TABLE_SIZE_BAR_4_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SOURCE_ADDRESS_BAR_4_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TRANS_ADDRESS_BAR_4_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TYPE_BAR_5_TABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SIZE_BAR_5_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TABLE_SIZE_BAR_5_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_SOURCE_ADDRESS_BAR_5_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_MASTER_TRANS_ADDRESS_BAR_5_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TYPE_BAR_5_TABLE:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SIZE_BAR_5_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TABLE_SIZE_BAR_5_TABLE:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_SOURCE_ADDRESS_BAR_5_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_MASTER_TRANS_ADDRESS_BAR_5_TABLE:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_STATE_TABLE_0:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SIZE_TABLE_0:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SOURCE_ADDRESS_TABLE_0:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_TRANS_ADDRESS_TABLE_0:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_STATE_TABLE_0:Enabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SIZE_TABLE_0:256 MB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SOURCE_ADDRESS_TABLE_0:0x30000000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_TRANS_ADDRESS_TABLE_0:0x30000000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_STATE_TABLE_1:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SIZE_TABLE_1:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SOURCE_ADDRESS_TABLE_1:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_TRANS_ADDRESS_TABLE_1:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_STATE_TABLE_1:Enabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SIZE_TABLE_1:512 MB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SOURCE_ADDRESS_TABLE_1:0x40000000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_TRANS_ADDRESS_TABLE_1:0x40000000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_STATE_TABLE_2:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SIZE_TABLE_2:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SOURCE_ADDRESS_TABLE_2:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_TRANS_ADDRESS_TABLE_2:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_STATE_TABLE_2:Enabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SIZE_TABLE_2:2 GB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SOURCE_ADDRESS_TABLE_2:0x80000000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_TRANS_ADDRESS_TABLE_2:0x2080000000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_STATE_TABLE_3:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SIZE_TABLE_3:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SOURCE_ADDRESS_TABLE_3:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_TRANS_ADDRESS_TABLE_3:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_STATE_TABLE_3:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SIZE_TABLE_3:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SOURCE_ADDRESS_TABLE_3:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_TRANS_ADDRESS_TABLE_3:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_STATE_TABLE_4:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SIZE_TABLE_4:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SOURCE_ADDRESS_TABLE_4:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_TRANS_ADDRESS_TABLE_4:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_STATE_TABLE_4:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SIZE_TABLE_4:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SOURCE_ADDRESS_TABLE_4:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_TRANS_ADDRESS_TABLE_4:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_STATE_TABLE_5:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SIZE_TABLE_5:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SOURCE_ADDRESS_TABLE_5:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_TRANS_ADDRESS_TABLE_5:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_STATE_TABLE_5:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SIZE_TABLE_5:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SOURCE_ADDRESS_TABLE_5:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_TRANS_ADDRESS_TABLE_5:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_STATE_TABLE_6:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SIZE_TABLE_6:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SOURCE_ADDRESS_TABLE_6:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_TRANS_ADDRESS_TABLE_6:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_STATE_TABLE_6:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SIZE_TABLE_6:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SOURCE_ADDRESS_TABLE_6:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_TRANS_ADDRESS_TABLE_6:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_STATE_TABLE_7:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SIZE_TABLE_7:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_SOURCE_ADDRESS_TABLE_7:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_0_SLAVE_TRANS_ADDRESS_TABLE_7:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_STATE_TABLE_7:Disabled"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SIZE_TABLE_7:4 KB"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_SOURCE_ADDRESS_TABLE_7:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_PCIE_1_SLAVE_TRANS_ADDRESS_TABLE_7:0x0000"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_EXPOSE_LANE_DRI_PORTS:false"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"UI_EXPOSE_PCIE_APBLINK_PORTS:true"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"SD_EXPORT_HIDDEN_PORTS:false"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"EXPOSE_ALL_DEBUG_PORTS:false"} -validate_rules 0
+configure_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0} -params {"XT_ES_DEVICE:true"} -validate_rules 0
+fix_vlnv_instance -component {polarfire_pcie_rp} -library {} -name {PF_PCIE_0}
+
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:AXI_CLK} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:AXI_CLK_STABLE} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIESS_LANE0_CDR_REF_CLK_0} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIESS_LANE1_CDR_REF_CLK_0} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIESS_LANE2_CDR_REF_CLK_0} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIESS_LANE3_CDR_REF_CLK_0} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_TL_CLK_125MHZ} -pin_create_new {}
+
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_INTERRUPT} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_S_WDERR} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_M_RDERR} -pin_create_new {}
+
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_DLUP_EXIT} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_HOT_RST_EXIT} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_INTERRUPT_OUT} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_L2_EXIT} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_LTSSM} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_M_WDERR} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_1_S_RDERR} -pin_create_new {}
+
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:APB_S_PCLK} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:APB_S_PRESET_N} -pin_create_new {}
+
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:AXI_1_SLAVE} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:PCIE_APB_SLAVE} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:CLKS_FROM_TXPLL_TO_PCIE_1} -pin_create_new {}
+promote_pin_to_top -component {polarfire_pcie_rp} -library {} -pin {PF_PCIE_0:AXI_1_MASTER} -pin_create_new {}
+
+generate_design -component {polarfire_pcie_rp} -library {} -generator {} -recursive 1
+"""
+ )
+
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_reset/PolarFireReset.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_reset/PolarFireReset.scala
new file mode 100644
index 0000000..6972075
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_reset/PolarFireReset.scala
@@ -0,0 +1,44 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfirereset
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box for Microsemi PolarFire IP block Actel:DirectCore:CORERESET_PF:2.1.100
+
+trait PolarFireResetIOPads extends Bundle {
+
+ val CLK = Clock(INPUT)
+ val EXT_RST_N = Bool(INPUT)
+ val FF_US_RESTORE = Bool(INPUT)
+ val INIT_DONE = Bool(INPUT)
+ val PLL_LOCK = Bool(INPUT)
+ val SS_BUSY = Bool(INPUT)
+ val FABRIC_RESET_N = Bool(OUTPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class PolarFireReset(implicit val p:Parameters) extends BlackBox
+{
+ override def desiredName = "polarfire_reset"
+
+ val io = new PolarFireResetIOPads {
+ }
+
+
+ ElaborationArtefacts.add(
+ "Libero.polarfire_reset.libero.tcl",
+ """
+create_design -id Actel:DirectCore:CORERESET_PF:2.1.100 -design_name {polarfire_reset} -config_file {} -params {} -inhibit_configurator 0
+open_smartdesign -design {polarfire_reset}
+configure_design -component {polarfire_reset} -library {}
+fix_vlnv_instance -component {polarfire_reset} -library {} -name {polarfire_reset_0}
+open_smartdesign -design {polarfire_reset}
+configure_design -component {polarfire_reset} -library {}"""
+ )
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_tx_pll/PolarFireTxPLL.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_tx_pll/PolarFireTxPLL.scala
new file mode 100644
index 0000000..a8e2079
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_tx_pll/PolarFireTxPLL.scala
@@ -0,0 +1,45 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfiretxpll
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box for Microsemi:SgCore:PF_TX_PLL:1.0.109
+
+trait PolarFireTxPLLIOPads extends Bundle {
+
+ val REF_CLK = Clock(INPUT)
+ val BIT_CLK = Clock(OUTPUT)
+ val CLK_125 = Clock(OUTPUT)
+ val REF_CLK_TO_LANE = Clock(OUTPUT)
+ val LOCK = Bool(OUTPUT)
+ val PLL_LOCK = Bool(OUTPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class PolarFireTxPLL(implicit val p:Parameters) extends BlackBox
+{
+ override def desiredName = "transmit_pll"
+
+ val io = new PolarFireTxPLLIOPads {
+ }
+
+ ElaborationArtefacts.add(
+ "Libero.polarfire_tx_pll.libero.tcl",
+ """
+create_design -id Actel:SgCore:PF_TX_PLL:2.0.002 -design_name {transmit_pll} -config_file {} -params {} -inhibit_configurator 0
+open_smartdesign -design {transmit_pll}
+configure_design -component {transmit_pll} -library {}
+configure_vlnv_instance -component {transmit_pll} -library {} -name {transmit_pll_0} -params {"TxPLL_REF:100" "TxPLL_OUT:2500"} -validate_rules 0
+fix_vlnv_instance -component {transmit_pll} -library {} -name {transmit_pll_0}
+open_smartdesign -design {transmit_pll}
+configure_design -component {transmit_pll} -library {}
+"""
+ )
+
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_xcvr_refclk/PolarFireTransceiverRefClk.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_xcvr_refclk/PolarFireTransceiverRefClk.scala
new file mode 100644
index 0000000..9b69680
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/microsemi/polarfire_xcvr_refclk/PolarFireTransceiverRefClk.scala
@@ -0,0 +1,46 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.microsemi.polarfirexcvrrefclk
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box for Microsemi:SgCore:PF_XCVR_REF_CLK:1.0.103
+
+trait PolarFireTransceiverRefClkIOPads extends Bundle {
+
+ val REF_CLK_PAD_P = Bool(INPUT)
+ val REF_CLK_PAD_N = Bool(INPUT)
+ val REF_CLK = Clock(OUTPUT)
+ val FAB_REF_CLK = Clock(OUTPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class PolarFireTransceiverRefClk(implicit val p:Parameters) extends BlackBox
+{
+ override def desiredName = "transceiver_refclk"
+
+ val io = new PolarFireTransceiverRefClkIOPads {
+ }
+
+ ElaborationArtefacts.add(
+ "Libero.polarfire_xcvr_refclk.libero.tcl",
+ """
+create_design -id Actel:SgCore:PF_XCVR_REF_CLK:1.0.103 -design_name {transceiver_refclk} -config_file {} -params {} -inhibit_configurator 0
+open_smartdesign -design {transceiver_refclk}
+configure_design -component {transceiver_refclk} -library {}
+configure_vlnv_instance -component {transceiver_refclk} -library {} -name {transceiver_refclk_0} \
+ -params {"ENABLE_FAB_CLK_0:1" \
+ } -validate_rules 0
+
+fix_vlnv_instance -component {transceiver_refclk} -library {} -name {transceiver_refclk_0}
+open_smartdesign -design {transceiver_refclk}
+configure_design -component {transceiver_refclk} -library {}
+"""
+ )
+
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/Unisim.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/Unisim.scala
new file mode 100644
index 0000000..87e72dc
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/Unisim.scala
@@ -0,0 +1,370 @@
+// See LICENSE for license details.
+
+package sifive.fpgashells.ip.xilinx
+import Chisel._
+import chisel3.{Input, Output}
+import chisel3.experimental.{Analog, attach, StringParam, RawParam, IntParam, DoubleParam}
+
+import sifive.blocks.devices.pinctrl.{BasePin}
+
+object booleanToVerilogVectorParam extends (Boolean => RawParam) {
+ def apply(b : Boolean) : RawParam = if(b) RawParam("1") else RawParam("0")
+}
+
+object booleanToVerilogStringParam extends (Boolean => StringParam) {
+ def apply(b : Boolean) : StringParam = if(b) StringParam("""TRUE""") else StringParam("""FALSE""")
+}
+
+
+/** IBUFDS -- SelectIO Differential Input */
+
+class IBUFDS(
+ CAPACITANCE : String = "DONT_CARE",
+ DIFF_TERM : Boolean = false,
+ DQS_BIAS : Boolean = false,
+ IBUF_DELAY_VALUE : Int = 0,
+ IBUF_LOW_PWR : Boolean = true,
+ IFD_DELAY_VALUE : String = "AUTO",
+ IOSTANDARD : String = "DEFAULT"
+)
+extends BlackBox(
+ Map(
+ "CAPACITANCE" -> StringParam(CAPACITANCE),
+ "DIFF_TERM" -> booleanToVerilogStringParam(DIFF_TERM),
+ "DQS_BIAS" -> booleanToVerilogStringParam(DQS_BIAS),
+ "IBUF_DELAY_VALUE" -> IntParam(IBUF_DELAY_VALUE),
+ "IBUF_LOW_PWR" -> booleanToVerilogStringParam(IBUF_LOW_PWR),
+ "IFD_DELAY_VALUE" -> StringParam(IFD_DELAY_VALUE),
+ "IOSTANDARD" -> StringParam(IOSTANDARD)
+ )
+) {
+ val io = IO(new Bundle {
+ val O = Output(Clock())
+ val I = Input(Clock())
+ val IB = Input(Clock())
+ })
+}
+
+/** IBUFG -- Clock Input Buffer */
+
+class IBUFG extends BlackBox {
+ val io = IO(new Bundle {
+ val O = Output(Clock())
+ val I = Input(Clock())
+ })
+}
+
+object IBUFG {
+ def apply (pin: Clock): Clock = {
+ val pad = Module (new IBUFG())
+ pad.io.I := pin
+ pad.io.O
+ }
+}
+
+/** IBUF -- Input Buffer */
+
+class IBUF extends BlackBox {
+ val io = IO(new Bundle {
+ val O = Output(Bool())
+ val I = Input(Bool())
+ })
+}
+
+object IBUF {
+ def apply(pin: Bool): Bool = {
+ val pad = Module (new IBUF)
+ pad.io.I := pin
+ pad.io.O
+ }
+}
+
+/** IBUFDS_GTE2 -- Differential Signaling Input Buffer */
+
+class IBUFDS_GTE2(
+ CLKCM_CFG : Boolean = true,
+ CLKRCV_TRST : Boolean = true,
+ CLKSWING_CFG : Int = 3
+)
+extends BlackBox(
+ Map(
+ "CLKCM_CFG" -> booleanToVerilogStringParam(CLKCM_CFG),
+ "CLKRCV_TRST" -> booleanToVerilogStringParam(CLKCM_CFG),
+ "CLKSWING_CFG" -> IntParam(CLKSWING_CFG)
+ )
+) {
+ val io = IO(new Bundle {
+ val O = Bool(OUTPUT)
+ val ODIV2 = Bool(OUTPUT)
+ val CEB = Bool(INPUT)
+ val I = Bool(INPUT)
+ val IB = Bool(INPUT)
+ })
+}
+
+class IBUFDS_GTE4(
+ REFCLK_EN_TX_PATH: Int = 0,
+ REFCLK_HROW_CK_SEL: Int = 0,
+ REFCLK_ICNTL_RX: Int = 0)
+ extends BlackBox(Map(
+ "REFCLK_EN_TX_PATH" -> IntParam(REFCLK_EN_TX_PATH),
+ "REFCLK_HROW_CK_SEL" -> IntParam(REFCLK_HROW_CK_SEL),
+ "REFCLK_ICNTL_RX" -> IntParam(REFCLK_ICNTL_RX)))
+{
+ val io = IO(new Bundle {
+ val O = Clock(OUTPUT)
+ val ODIV2 = Clock(OUTPUT)
+ val CEB = Bool(INPUT)
+ val I = Clock(INPUT)
+ val IB = Clock(INPUT)
+ })
+}
+
+/** IDDR - 7 Series SelectIO DDR flop */
+
+class IDDR(
+ DDR_CLK_EDGE : String = "OPPOSITE_EDGE",
+ INIT_Q1 : Boolean = false,
+ INIT_Q2 : Boolean = false,
+ IS_C_INVERTED : Boolean = false,
+ IS_D_INVERTED : Boolean = false,
+ SRTYPE : String = "SYNC"
+)
+extends BlackBox(
+ Map(
+ "DDR_CLK_EDGE" -> StringParam(DDR_CLK_EDGE),
+ "INIT_Q1" -> booleanToVerilogVectorParam(INIT_Q1),
+ "INIT_Q2" -> booleanToVerilogVectorParam(INIT_Q2),
+ "IS_C_INVERTED" -> booleanToVerilogVectorParam(IS_C_INVERTED),
+ "IS_D_INVERTED" -> booleanToVerilogVectorParam(IS_D_INVERTED),
+ "SRTYPE" -> StringParam(SRTYPE)
+ )
+) {
+ val io = IO(new Bundle {
+ val Q1 = Output(Bool())
+ val Q2 = Output(Bool())
+ val C = Input(Bool())
+ val CE = Input(Bool())
+ val D = Input(Bool())
+ val R = Input(Bool())
+ val S = Input(Bool())
+ })
+}
+
+/** IDELAYCTRL - 7 Series SelectIO */
+
+class IDELAYCTRL(
+ sim_device : String = "7SERIES"
+)
+extends BlackBox(
+ Map(
+ "SIM_DEVICE" -> StringParam(sim_device)
+ )
+) {
+ val io = IO(new Bundle {
+ val RDY = Output(Bool())
+ val REFCLK = Input(Bool())
+ val RST = Input(Bool())
+ })
+}
+
+
+/** IDELAYE2 -- 7 Series SelectIO ILogic programmable delay. */
+
+class IDELAYE2(
+ CINVCTRL_SEL : Boolean = false,
+ DELAY_SRC : String = "IDATAIN",
+ HIGH_PERFORMANCE_MODE : Boolean = false,
+ IDELAY_TYPE : String = "FIXED",
+ IDELAY_VALUE : Int = 0,
+ IS_C_INVERTED : Boolean = false,
+ IS_DATAIN_INVERTED : Boolean = false,
+ IS_IDATAIN_INVERTED : Boolean = false,
+ PIPE_SEL : Boolean = false,
+ REFCLK_FREQUENCY : Double = 200.0,
+ SIGNAL_PATTERN : String = "DATA",
+ SIM_DELAY_D : Int = 0
+)
+extends BlackBox(
+ Map(
+ "CINVCTRL_SEL" -> booleanToVerilogStringParam(CINVCTRL_SEL),
+ "DELAY_SRC" -> StringParam(DELAY_SRC),
+ "HIGH_PERFORMANCE_MODE" -> booleanToVerilogStringParam(HIGH_PERFORMANCE_MODE),
+ "IDELAY_TYPE" -> StringParam(IDELAY_TYPE),
+ "IS_C_INVERTED" -> booleanToVerilogVectorParam(IS_C_INVERTED),
+ "IS_DATAIN_INVERTED" -> booleanToVerilogVectorParam(IS_DATAIN_INVERTED),
+ "IS_IDATAIN_INVERTED" -> booleanToVerilogVectorParam(IS_IDATAIN_INVERTED),
+ "PIPE_SEL" -> booleanToVerilogStringParam(PIPE_SEL),
+ "REFCLK_FREQUENCY" -> DoubleParam(REFCLK_FREQUENCY),
+ "SIGNAL_PATTERN" -> StringParam(SIGNAL_PATTERN),
+ "SIM_DELAY_D" -> IntParam(SIM_DELAY_D)
+ )
+) {
+ val io = IO(new Bundle {
+ val DATAOUT = Output(Bool())
+ val CNTVALUEOUT = Output(UInt(5.W))
+ val C = Input(Bool())
+ val CE = Input(Bool())
+ val CINVCTRL = Input(Bool())
+ val DATAIN = Input(Bool())
+ val IDATAIN = Input(Bool())
+ val INC = Input(Bool())
+ val LD = Input(Bool())
+ val LDPIPEEN = Input(Bool())
+ val REGRST = Input(Bool())
+ val CNTVALUEIN = Input(UInt(5.W))
+ })
+}
+
+/** IOBUF -- Bidirectional IO Buffer. */
+
+//Cannot convert to BlackBox because of line
+//val IO = IO(Analog(1.W))
+//is illegal
+
+class IOBUF extends BlackBox {
+
+ val io = new Bundle {
+ val O = Output(Bool())
+ val IO = Analog(1.W)
+ val I = Input(Bool())
+ val T = Input(Bool())
+ }
+}
+
+object IOBUF {
+
+ def apply (pin: Analog, ctrl: BasePin): Bool = {
+ val pad = Module(new IOBUF())
+ pad.io.I := ctrl.o.oval
+ pad.io.T := ~ctrl.o.oe
+ ctrl.i.ival := pad.io.O & ctrl.o.ie
+ attach(pad.io.IO, pin)
+ pad.io.O & ctrl.o.ie
+ }
+
+ // Creates an output IOBUF
+ def apply (pin: Analog, in: Bool): Unit = {
+ val pad = Module(new IOBUF())
+ pad.io.I := in
+ pad.io.T := false.B
+ attach(pad.io.IO, pin)
+ }
+
+ // Creates an input IOBUF
+ def apply (pin: Analog): Bool = {
+ val pad = Module(new IOBUF())
+ pad.io.I := false.B
+ pad.io.T := true.B
+ attach(pad.io.IO, pin)
+ pad.io.O
+ }
+
+}
+
+/** ODDR - 7 Series SelectIO DDR flop */
+
+class ODDR(
+ DDR_CLK_EDGE : String = "OPPOSITE_EDGE",
+ INIT : Boolean = false,
+ IS_C_INVERTED : Boolean = false,
+ IS_D1_INVERTED : Boolean = false,
+ IS_D2_INVERTED : Boolean = false,
+ SRTYPE : String = "SYNC"
+)
+extends BlackBox(
+ Map(
+ "DDR_CLK_EDGE" -> StringParam(DDR_CLK_EDGE),
+ "INIT" -> booleanToVerilogVectorParam(INIT),
+ "IS_C_INVERTED" -> booleanToVerilogVectorParam(IS_C_INVERTED),
+ "IS_D1_INVERTED" -> booleanToVerilogVectorParam(IS_D1_INVERTED),
+ "IS_D2_INVERTED" -> booleanToVerilogVectorParam(IS_D2_INVERTED),
+ "SRTYPE" -> StringParam(SRTYPE)
+ )
+) {
+ val io = IO(new Bundle {
+ val Q = Output(Bool())
+ val C = Input(Clock())
+ val CE = Input(Bool())
+ val D1 = Input(Bool())
+ val D2 = Input(Bool())
+ val R = Input(Bool())
+ val S = Input(Bool())
+ })
+}
+
+/** ODELAYE2 -- 7 Series SelectIO OLogic programmable delay. */
+
+class ODELAYE2(
+ CINVCTRL_SEL : Boolean = false,
+ DELAY_SRC : String = "ODATAIN",
+ HIGH_PERFORMANCE_MODE : Boolean = false,
+ IS_C_INVERTED : Boolean = false,
+ IS_ODATAIN_INVERTED : Boolean = false,
+ ODELAY_TYPE : String = "FIXED",
+ ODELAY_VALUE : Int = 0,
+ PIPE_SEL : Boolean = false,
+ REFCLK_FREQUENCY : Double = 200.0,
+ SIGNAL_PATTERN : String = "DATA",
+ SIM_DELAY_D : Int = 0
+)
+extends BlackBox(
+ Map(
+ "CINVCTRL_SEL" -> booleanToVerilogStringParam(CINVCTRL_SEL),
+ "DELAY_SRC" -> StringParam(DELAY_SRC),
+ "HIGH_PERFORMANCE_MODE" -> booleanToVerilogStringParam(HIGH_PERFORMANCE_MODE),
+ "IS_C_INVERTED" -> booleanToVerilogVectorParam(IS_C_INVERTED),
+ "IS_ODATAIN_INVERTED" -> booleanToVerilogVectorParam(IS_ODATAIN_INVERTED),
+ "ODELAY_TYPE" -> StringParam(ODELAY_TYPE),
+ "PIPE_SEL" -> booleanToVerilogStringParam(PIPE_SEL),
+ "REFCLK_FREQUENCY" -> DoubleParam(REFCLK_FREQUENCY),
+ "SIGNAL_PATTERN" -> StringParam(SIGNAL_PATTERN),
+ "SIM_DELAY_D" -> IntParam(SIM_DELAY_D)
+ )
+) {
+ val io = IO(new Bundle {
+ val DATAOUT = Output(Bool())
+ val CNTVALUEOUT = Output(UInt(5.W))
+ val C = Input(Bool())
+ val CE = Input(Bool())
+ val CINVCTRL = Input(Bool())
+ val CLKIN = Input(Bool())
+ val INC = Input(Bool())
+ val LD = Input(Bool())
+ val LDPIPEEN = Input(Bool())
+ val ODATAIN = Input(Bool())
+ val REGRST = Input(Bool())
+ val CNTVALUEIN = Input(UInt(5.W))
+ })
+}
+
+/** PULLUP : can be applied to Input to add a Pullup. */
+
+class PULLUP extends BlackBox {
+ val io = IO(new Bundle {
+ val O = Analog(1.W)
+ })
+}
+
+object PULLUP {
+ def apply (pin: Analog): Unit = {
+ val pullup = Module(new PULLUP())
+ attach(pullup.io.O, pin)
+ }
+}
+
+/** KEEPER : can be applied to I/O to hold its last value since driven. */
+
+class KEEPER extends BlackBox {
+ val io = IO(new Bundle {
+ val O = Analog(1.W)
+ })
+}
+
+object KEEPER {
+ def apply (pin: Analog): Unit = {
+ val pullup = Module(new KEEPER())
+ attach(pullup.io.O, pin)
+ }
+}
+
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/Xilinx.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/Xilinx.scala
new file mode 100644
index 0000000..adb2fcc
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/Xilinx.scala
@@ -0,0 +1,490 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.xilinx
+
+import Chisel._
+import chisel3.{Input, Output}
+import chisel3.experimental.{Analog, attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+
+import sifive.blocks.devices.pinctrl.{BasePin}
+import sifive.fpgashells.clocks._
+import freechips.rocketchip.diplomacy.LazyModule
+
+class JTAGTUNNEL extends BlackBox {
+ val io = new Bundle {
+ val jtag_tck = Output(Bool())
+ val jtag_tms = Output(Bool())
+ val jtag_tdi = Output(Bool())
+ val jtag_tdo = Input(Bool())
+ val jtag_tdo_en = Input(Bool())
+ }
+ //setInline("JTAGTUNNEL.v",
+ // s"""
+ ElaborationArtefacts.add("JTAGTUNNEL.v",
+ """
+ |module JTAGTUNNEL(
+ | output jtag_tck,
+ | output jtag_tms,
+ | output jtag_tdi,
+ | input jtag_tdo,
+ | input jtag_tdo_en
+ |);
+ |
+ |parameter USER_CHAIN=4;
+ |wire CAPTURE;
+ |wire DRCK;
+ |wire RESET;
+ |wire SEL;
+ |wire SHIFT;
+ |wire UPDATE;
+ |wire RUNTEST;
+ |
+ |wire jtag_tck;
+ |reg jtag_tms;
+ |wire jtag_tdi;
+ |wire jtag_tdo;
+ |wire jtag_tdo_en;
+ |wire TDO;
+ |wire reset;
+ |wire start_tck;
+ |reg [6:0] shiftreg_cnt;
+ |reg [7:0] counter_neg;
+ |reg [7:0] counter_pos;
+ |reg TDI_REG;
+ |
+ |BSCANE2 #(
+ | .JTAG_CHAIN(USER_CHAIN) // Value for USER command.
+ |)
+ |BSCANE2_inst (
+ | .CAPTURE(CAPTURE), // 1-bit output: CAPTURE output from TAP controller.
+ | .DRCK(DRCK), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or
+ | // SHIFT are asserted.
+ | .RESET(RESET), // 1-bit output: Reset output for TAP controller.
+ | .RUNTEST(RUNTEST), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state.
+ | .SEL(SEL), // 1-bit output: USER instruction active output.
+ | .SHIFT(SHIFT), // 1-bit output: SHIFT output from TAP controller.
+ | .TCK(TCK), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin.
+ | .TDI(TDI), // 1-bit output: Test Data Input (TDI) output from TAP controller.
+ | .TMS(TMS), // 1-bit output: Test Mode Select output. Fabric connection to TAP.
+ | .UPDATE(UPDATE), // 1-bit output: UPDATE output from TAP controller
+ | .TDO(TDO) // 1-bit input: Test Data Output (TDO) input for USER function.
+ | );
+ |//
+ |BUFGCE BUFGCE_JTAG (
+ | .O(jtag_tck), // 1-bit output: Clock output
+ | .CE(start_tck), // 1-bit input: Clock enable input for I0
+ | .I(TCK) // 1-bit input: Primary clock
+ |);
+ |
+ |
+ |assign start_tck = SEL;
+ |assign jtag_tdi = TDI;
+ |assign TDO = jtag_tdo_en ? jtag_tdo : 1'b1;
+ |
+ |always@(*) begin
+ | if (counter_neg == 8'h04) begin
+ | jtag_tms = TDI_REG;
+ | end else if (counter_neg == 8'h05) begin
+ | jtag_tms = 1'b1;
+ | end else if ((counter_neg == (8'h08 + shiftreg_cnt)) || (counter_neg == (8'h08 + shiftreg_cnt - 8'h01))) begin
+ | jtag_tms = 1'b1;
+ | end else begin
+ | jtag_tms = 1'b0;
+ | end
+ |end
+ |
+ |always@(posedge TCK) begin
+ | if (~SHIFT) begin
+ | shiftreg_cnt <= 7'b0000000;
+ | end else if ((counter_pos >= 8'h01) && (counter_pos <= 8'h07)) begin
+ | shiftreg_cnt <= {{TDI, shiftreg_cnt[6:1]}};
+ | end else begin
+ | shiftreg_cnt <= shiftreg_cnt;
+ | end
+ |end
+ |
+ |always@(posedge TCK) begin
+ | if (~SHIFT) begin
+ | TDI_REG <= 1'b0;
+ | end else if (counter_pos == 8'h00) begin
+ | TDI_REG <= ~TDI;
+ | end else begin
+ | TDI_REG <= TDI_REG;
+ | end
+ |end
+ |
+ |always@(negedge TCK) begin
+ | if (~SHIFT) begin
+ | counter_neg <= 8'b00000000;
+ | end else begin
+ | counter_neg <= counter_neg + 1;
+ | end
+ |end
+ |
+ |always@(posedge TCK) begin
+ | if (~SHIFT) begin
+ | counter_pos <= 8'b00000000;
+ | end else begin
+ | counter_pos <= counter_pos + 1;
+ | end
+ |end
+ |endmodule
+ """.stripMargin)
+}
+
+object JTAGTUNNEL {
+
+ def apply (DUT_TCK: Bool, DUT_TMS: Bool, DUT_TDI: Bool, DUT_TDO:Bool, DUT_TDO_en: Bool): Unit = {
+ val inst_jtag_tunnel = Module(new JTAGTUNNEL())
+ DUT_TCK := inst_jtag_tunnel.io.jtag_tck
+ DUT_TMS := inst_jtag_tunnel.io.jtag_tms
+ DUT_TDI := inst_jtag_tunnel.io.jtag_tdi
+ inst_jtag_tunnel.io.jtag_tdo := DUT_TDO
+ inst_jtag_tunnel.io.jtag_tdo_en := DUT_TDO_en
+ }
+}
+
+//========================================================================
+// This file contains common devices used by our Xilinx FPGA flows and some
+// BlackBox modules used in the Xilinx FPGA flows
+//========================================================================
+
+//-------------------------------------------------------------------------
+// mmcm
+//-------------------------------------------------------------------------
+/** mmcm: This is generated by the Xilinx IP Generation Scripts */
+
+class mmcm extends BlackBox {
+ val io = new Bundle {
+ val clk_in1 = Input(Clock())
+ val clk_out1 = Output(Clock())
+ val clk_out2 = Output(Clock())
+ val clk_out3 = Output(Clock())
+ val resetn = Input(Bool())
+ val locked = Output(Bool())
+ }
+}
+
+//-------------------------------------------------------------------------
+// reset_sys
+//-------------------------------------------------------------------------
+/** reset_sys: This is generated by the Xilinx IP Generation Scripts */
+
+class reset_sys extends BlackBox {
+ val io = new Bundle {
+ val slowest_sync_clk = Input(Clock())
+ val ext_reset_in = Input(Bool())
+ val aux_reset_in = Input(Bool())
+ val mb_debug_sys_rst = Input(Bool())
+ val dcm_locked = Input(Bool())
+ val mb_reset = Output(Bool())
+ val bus_struct_reset = Output(Bool())
+ val peripheral_reset = Output(Bool())
+ val interconnect_aresetn = Output(Bool())
+ val peripheral_aresetn = Output(Bool())
+ }
+}
+
+//-------------------------------------------------------------------------
+// reset_mig
+//-------------------------------------------------------------------------
+/** reset_mig: This is generated by the Xilinx IP Generation Scripts */
+
+class reset_mig extends BlackBox {
+ val io = new Bundle {
+ val slowest_sync_clk = Input(Clock())
+ val ext_reset_in = Input(Bool())
+ val aux_reset_in = Input(Bool())
+ val mb_debug_sys_rst = Input(Bool())
+ val dcm_locked = Input(Bool())
+ val mb_reset = Output(Bool())
+ val bus_struct_reset = Output(Bool())
+ val peripheral_reset = Output(Bool())
+ val interconnect_aresetn = Output(Bool())
+ val peripheral_aresetn = Output(Bool())
+ }
+}
+
+//-------------------------------------------------------------------------
+// PowerOnResetFPGAOnly
+//-------------------------------------------------------------------------
+/** PowerOnResetFPGAOnly -- this generates a power_on_reset signal using
+ * initial blocks. It is synthesizable on FPGA flows only.
+ */
+
+// This is a FPGA-Only construct, which uses
+// 'initial' constructions
+class PowerOnResetFPGAOnly extends BlackBox {
+ val io = new Bundle {
+ val clock = Input(Clock())
+ val power_on_reset = Output(Bool())
+ }
+}
+
+object PowerOnResetFPGAOnly {
+ def apply (clk: Clock, name: String): Bool = {
+ val por = Module(new PowerOnResetFPGAOnly())
+ por.suggestName(name)
+ por.io.clock := clk
+ por.io.power_on_reset
+ }
+ def apply (clk: Clock): Bool = apply(clk, "fpga_power_on")
+}
+
+
+//-------------------------------------------------------------------------
+// vc707_sys_clock_mmcm
+//-------------------------------------------------------------------------
+//IP : xilinx mmcm with "NO_BUFFER" input clock
+class Series7MMCM(c : PLLParameters) extends BlackBox with PLLInstance {
+ val io = new Bundle {
+ val clk_in1 = Clock(INPUT)
+ val clk_out1 = if (c.req.size >= 1) Some(Clock(OUTPUT)) else None
+ val clk_out2 = if (c.req.size >= 2) Some(Clock(OUTPUT)) else None
+ val clk_out3 = if (c.req.size >= 3) Some(Clock(OUTPUT)) else None
+ val clk_out4 = if (c.req.size >= 4) Some(Clock(OUTPUT)) else None
+ val clk_out5 = if (c.req.size >= 5) Some(Clock(OUTPUT)) else None
+ val clk_out6 = if (c.req.size >= 6) Some(Clock(OUTPUT)) else None
+ val clk_out7 = if (c.req.size >= 7) Some(Clock(OUTPUT)) else None
+ val reset = Bool(INPUT)
+ val locked = Bool(OUTPUT)
+ }
+
+ val moduleName = c.name
+ override def desiredName = c.name
+
+ def getClocks = Seq() ++ io.clk_out1 ++ io.clk_out2 ++
+ io.clk_out3 ++ io.clk_out4 ++
+ io.clk_out5 ++ io.clk_out6 ++
+ io.clk_out7
+ def getInput = io.clk_in1
+ def getReset = Some(io.reset)
+ def getLocked = io.locked
+ def getClockNames = Seq.tabulate (c.req.size) { i =>
+ s"${c.name}/inst/mmcm_adv_inst/CLKOUT${i}"
+ }
+
+ val used = Seq.tabulate(7) { i =>
+ s" CONFIG.CLKOUT${i+1}_USED {${i < c.req.size}} \\\n"
+ }.mkString
+
+ val outputs = c.req.zipWithIndex.map { case (r, i) =>
+ s""" CONFIG.CLKOUT${i+1}_REQUESTED_OUT_FREQ {${r.freqMHz}} \\
+ | CONFIG.CLKOUT${i+1}_REQUESTED_PHASE {${r.phaseDeg}} \\
+ | CONFIG.CLKOUT${i+1}_REQUESTED_DUTY_CYCLE {${r.dutyCycle}} \\
+ |""".stripMargin
+ }.mkString
+
+ val checks = c.req.zipWithIndex.map { case (r, i) =>
+ val f = if (i == 0) "_F" else ""
+ val phaseMin = r.phaseDeg - r.phaseErrorDeg
+ val phaseMax = r.phaseDeg + r.phaseErrorDeg
+ val freqMin = r.freqMHz * (1 - r.freqErrorPPM / 1000000)
+ val freqMax = r.freqMHz * (1 + r.freqErrorPPM / 1000000)
+ s"""set jitter [get_property CONFIG.CLKOUT${i+1}_JITTER [get_ips ${moduleName}]]
+ |if {$$jitter > ${r.jitterPS}} {
+ | puts "Output jitter $$jitter ps exceeds required limit of ${r.jitterPS}"
+ | exit 1
+ |}
+ |set phase [get_property CONFIG.MMCM_CLKOUT${i}_PHASE [get_ips ${moduleName}]]
+ |if {$$phase < ${phaseMin} || $$phase > ${phaseMax}} {
+ | puts "Achieved phase $$phase degrees is outside tolerated range ${phaseMin}-${phaseMax}"
+ | exit 1
+ |}
+ |set div2 [get_property CONFIG.MMCM_CLKOUT${i}_DIVIDE${f} [get_ips ${moduleName}]]
+ |set freq [expr { ${c.input.freqMHz} * $$mult / $$div1 / $$div2 }]
+ |if {$$freq < ${freqMin} || $$freq > ${freqMax}} {
+ | puts "Achieved frequency $$freq MHz is outside tolerated range ${freqMin}-${freqMax}"
+ | exit 1
+ |}
+ |puts "Achieve frequency $$freq MHz phase $$phase degrees jitter $$jitter ps"
+ |""".stripMargin
+ }.mkString
+
+
+ val aligned = if (c.input.feedback) " CONFIG.USE_PHASE_ALIGNMENT {true} \\\n" else ""
+
+ ElaborationArtefacts.add(s"${moduleName}.vivado.tcl",
+ s"""create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name \\
+ | ${moduleName} -dir $$ipdir -force
+ |set_property -dict [list \\
+ | CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \\
+ | CONFIG.PRIM_SOURCE {No_buffer} \\
+ | CONFIG.NUM_OUT_CLKS {${c.req.size.toString}} \\
+ | CONFIG.PRIM_IN_FREQ {${c.input.freqMHz.toString}} \\
+ | CONFIG.CLKIN1_JITTER_PS {${c.input.jitter}} \\
+ |${used}${aligned}${outputs}] [get_ips ${moduleName}]
+ |set mult [get_property CONFIG.MMCM_CLKFBOUT_MULT_F [get_ips ${moduleName}]]
+ |set div1 [get_property CONFIG.MMCM_DIVCLK_DIVIDE [get_ips ${moduleName}]]
+ |${checks}""".stripMargin)
+}
+
+//-------------------------------------------------------------------------
+// vc707reset
+//-------------------------------------------------------------------------
+
+class vc707reset() extends BlackBox
+{
+ val io = new Bundle{
+ val areset = Bool(INPUT)
+ val clock1 = Clock(INPUT)
+ val reset1 = Bool(OUTPUT)
+ val clock2 = Clock(INPUT)
+ val reset2 = Bool(OUTPUT)
+ val clock3 = Clock(INPUT)
+ val reset3 = Bool(OUTPUT)
+ val clock4 = Clock(INPUT)
+ val reset4 = Bool(OUTPUT)
+ }
+}
+
+//-------------------------------------------------------------------------
+// vcu118_sys_clock_mmcm
+//-------------------------------------------------------------------------
+//IP : xilinx mmcm with "NO_BUFFER" input clock
+
+class vcu118_sys_clock_mmcm0 extends BlackBox {
+ val io = new Bundle {
+ val clk_in1 = Bool(INPUT)
+ val clk_out1 = Clock(OUTPUT)
+ val clk_out2 = Clock(OUTPUT)
+ val clk_out3 = Clock(OUTPUT)
+ val clk_out4 = Clock(OUTPUT)
+ val clk_out5 = Clock(OUTPUT)
+ val clk_out6 = Clock(OUTPUT)
+ val clk_out7 = Clock(OUTPUT)
+ val reset = Bool(INPUT)
+ val locked = Bool(OUTPUT)
+ }
+
+ ElaborationArtefacts.add(
+ "vcu118_sys_clock_mmcm0.vivado.tcl",
+ """create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name vcu118_sys_clock_mmcm0 -dir $ipdir -force
+ set_property -dict [list \
+ CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \
+ CONFIG.PRIM_SOURCE {No_buffer} \
+ CONFIG.CLKOUT2_USED {true} \
+ CONFIG.CLKOUT3_USED {true} \
+ CONFIG.CLKOUT4_USED {true} \
+ CONFIG.CLKOUT5_USED {true} \
+ CONFIG.CLKOUT6_USED {true} \
+ CONFIG.CLKOUT7_USED {true} \
+ CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {12.5} \
+ CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {25} \
+ CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {37.5} \
+ CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {50} \
+ CONFIG.CLKOUT5_REQUESTED_OUT_FREQ {100} \
+ CONFIG.CLKOUT6_REQUESTED_OUT_FREQ {150.000} \
+ CONFIG.CLKOUT7_REQUESTED_OUT_FREQ {75} \
+ CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \
+ CONFIG.PRIM_IN_FREQ {250.000} \
+ CONFIG.CLKIN1_JITTER_PS {50.0} \
+ CONFIG.MMCM_DIVCLK_DIVIDE {5} \
+ CONFIG.MMCM_CLKFBOUT_MULT_F {24.000} \
+ CONFIG.MMCM_CLKIN1_PERIOD {4.000} \
+ CONFIG.MMCM_CLKOUT0_DIVIDE_F {96.000} \
+ CONFIG.MMCM_CLKOUT1_DIVIDE {48} \
+ CONFIG.MMCM_CLKOUT2_DIVIDE {32} \
+ CONFIG.MMCM_CLKOUT3_DIVIDE {24} \
+ CONFIG.MMCM_CLKOUT4_DIVIDE {12} \
+ CONFIG.MMCM_CLKOUT5_DIVIDE {8} \
+ CONFIG.MMCM_CLKOUT6_DIVIDE {16} \
+ CONFIG.NUM_OUT_CLKS {7} \
+ CONFIG.CLKOUT1_JITTER {213.008} \
+ CONFIG.CLKOUT1_PHASE_ERROR {154.678} \
+ CONFIG.CLKOUT2_JITTER {179.547} \
+ CONFIG.CLKOUT2_PHASE_ERROR {154.678} \
+ CONFIG.CLKOUT3_JITTER {164.187} \
+ CONFIG.CLKOUT3_PHASE_ERROR {154.678} \
+ CONFIG.CLKOUT4_JITTER {154.688} \
+ CONFIG.CLKOUT4_PHASE_ERROR {154.678} \
+ CONFIG.CLKOUT5_JITTER {135.165} \
+ CONFIG.CLKOUT5_PHASE_ERROR {154.678} \
+ CONFIG.CLKOUT6_JITTER {126.046} \
+ CONFIG.CLKOUT6_PHASE_ERROR {154.678} \
+ CONFIG.CLKOUT7_JITTER {142.781} \
+ CONFIG.CLKOUT7_PHASE_ERROR {154.678}] [get_ips vcu118_sys_clock_mmcm0] """
+ )
+}
+
+class vcu118_sys_clock_mmcm1 extends BlackBox {
+ val io = new Bundle {
+ val clk_in1 = Bool(INPUT)
+ val clk_out1 = Clock(OUTPUT)
+ val clk_out2 = Clock(OUTPUT)
+ val reset = Bool(INPUT)
+ val locked = Bool(OUTPUT)
+ }
+
+ ElaborationArtefacts.add(
+ "vcu118_sys_clock_mmcm1.vivado.tcl",
+ """create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name vcu118_sys_clock_mmcm1 -dir $ipdir -force
+ set_property -dict [list \
+ CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \
+ CONFIG.PRIM_SOURCE {No_buffer} \
+ CONFIG.CLKOUT2_USED {true} \
+ CONFIG.CLKOUT3_USED {false} \
+ CONFIG.CLKOUT4_USED {false} \
+ CONFIG.CLKOUT5_USED {false} \
+ CONFIG.CLKOUT6_USED {false} \
+ CONFIG.CLKOUT7_USED {false} \
+ CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {32.5} \
+ CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {65} \
+ CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \
+ CONFIG.PRIM_IN_FREQ {250.000} \
+ CONFIG.CLKIN1_JITTER_PS {50.0} \
+ CONFIG.MMCM_DIVCLK_DIVIDE {25} \
+ CONFIG.MMCM_CLKFBOUT_MULT_F {117.000} \
+ CONFIG.MMCM_CLKIN1_PERIOD {4.000} \
+ CONFIG.MMCM_CLKOUT0_DIVIDE_F {36.000} \
+ CONFIG.MMCM_CLKOUT1_DIVIDE {18} \
+ CONFIG.MMCM_CLKOUT2_DIVIDE {1} \
+ CONFIG.MMCM_CLKOUT3_DIVIDE {1} \
+ CONFIG.MMCM_CLKOUT4_DIVIDE {1} \
+ CONFIG.MMCM_CLKOUT5_DIVIDE {1} \
+ CONFIG.MMCM_CLKOUT6_DIVIDE {1} \
+ CONFIG.NUM_OUT_CLKS {2} \
+ CONFIG.CLKOUT1_JITTER {257.594} \
+ CONFIG.CLKOUT1_PHASE_ERROR {366.693} \
+ CONFIG.CLKOUT2_JITTER {232.023} \
+ CONFIG.CLKOUT2_PHASE_ERROR {366.693}] \
+ [get_ips vcu118_sys_clock_mmcm1] """
+ )
+}
+
+//-------------------------------------------------------------------------
+// vcu118reset
+//-------------------------------------------------------------------------
+
+class vcu118reset() extends BlackBox
+{
+ val io = new Bundle{
+ val areset = Bool(INPUT)
+ val clock1 = Clock(INPUT)
+ val reset1 = Bool(OUTPUT)
+ val clock2 = Clock(INPUT)
+ val reset2 = Bool(OUTPUT)
+ val clock3 = Clock(INPUT)
+ val reset3 = Bool(OUTPUT)
+ val clock4 = Clock(INPUT)
+ val reset4 = Bool(OUTPUT)
+ }
+}
+
+//-------------------------------------------------------------------------
+// sdio_spi_bridge
+//-------------------------------------------------------------------------
+
+class sdio_spi_bridge() extends BlackBox
+{
+ val io = new Bundle{
+ val clk = Clock(INPUT)
+ val reset = Bool(INPUT)
+ val sd_cmd = Analog(1.W)
+ val sd_dat = Analog(4.W)
+ val spi_sck = Bool(INPUT)
+ val spi_cs = Bool(INPUT)
+ val spi_dq_o = Bits(INPUT,4)
+ val spi_dq_i = Bits(OUTPUT,4)
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/arty100tmig/arty100tmig.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/arty100tmig/arty100tmig.scala
new file mode 100644
index 0000000..a507664
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/arty100tmig/arty100tmig.scala
@@ -0,0 +1,263 @@
+package sifive.fpgashells.ip.xilinx.arty100tmig
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// Black Box
+
+class Arty100TMIGIODDR(depth : BigInt) extends GenericParameterizedBundle(depth) {
+ require((depth<=0x10000000L),"Arty100TMIGIODDR supports upto 256 MB depth configuraton")
+ val ddr3_addr = Bits(OUTPUT,14)
+ val ddr3_ba = Bits(OUTPUT,3)
+ val ddr3_ras_n = Bool(OUTPUT)
+ val ddr3_cas_n = Bool(OUTPUT)
+ val ddr3_we_n = Bool(OUTPUT)
+ val ddr3_reset_n = Bool(OUTPUT)
+ val ddr3_ck_p = Bits(OUTPUT,1)
+ val ddr3_ck_n = Bits(OUTPUT,1)
+ val ddr3_cke = Bits(OUTPUT,1)
+ val ddr3_cs_n = Bits(OUTPUT,1)
+ val ddr3_dm = Bits(OUTPUT,2)
+ val ddr3_odt = Bits(OUTPUT,1)
+
+ val ddr3_dq = Analog(16.W)
+ val ddr3_dqs_n = Analog(2.W)
+ val ddr3_dqs_p = Analog(2.W)
+}
+
+trait Arty100TMIGIOClocksReset extends Bundle {
+ //inputs
+ //"NO_BUFFER" clock source (must be connected to IBUF outside of IP)
+ val sys_clk_i = Bool(INPUT)
+ val clk_ref_i = Bool(INPUT)
+ //user interface signals
+ val ui_clk = Clock(OUTPUT)
+ val ui_clk_sync_rst = Bool(OUTPUT)
+ val mmcm_locked = Bool(OUTPUT)
+ val aresetn = Bool(INPUT)
+ //misc
+ val init_calib_complete = Bool(OUTPUT)
+ val sys_rst = Bool(INPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class arty100tmig(depth : BigInt)(implicit val p:Parameters) extends BlackBox
+{
+ require((depth<=0x10000000L),"arty100tmig supports upto 256 MB depth configuraton")
+
+ val io = new Arty100TMIGIODDR(depth) with Arty100TMIGIOClocksReset {
+ // User interface signals
+ val app_sr_req = Bool(INPUT)
+ val app_ref_req = Bool(INPUT)
+ val app_zq_req = Bool(INPUT)
+ val app_sr_active = Bool(OUTPUT)
+ val app_ref_ack = Bool(OUTPUT)
+ val app_zq_ack = Bool(OUTPUT)
+ //axi_s
+ //slave interface write address ports
+ val s_axi_awid = Bits(INPUT,4)
+ val s_axi_awaddr = Bits(INPUT,if(depth<=0x40000000) 30 else 32)
+ val s_axi_awlen = Bits(INPUT,8)
+ val s_axi_awsize = Bits(INPUT,3)
+ val s_axi_awburst = Bits(INPUT,2)
+ val s_axi_awlock = Bits(INPUT,1)
+ val s_axi_awcache = Bits(INPUT,4)
+ val s_axi_awprot = Bits(INPUT,3)
+ val s_axi_awqos = Bits(INPUT,4)
+ val s_axi_awvalid = Bool(INPUT)
+ val s_axi_awready = Bool(OUTPUT)
+ //slave interface write data ports
+ val s_axi_wdata = Bits(INPUT,64)
+ val s_axi_wstrb = Bits(INPUT,8)
+ val s_axi_wlast = Bool(INPUT)
+ val s_axi_wvalid = Bool(INPUT)
+ val s_axi_wready = Bool(OUTPUT)
+ //slave interface write response ports
+ val s_axi_bready = Bool(INPUT)
+ val s_axi_bid = Bits(OUTPUT,4)
+ val s_axi_bresp = Bits(OUTPUT,2)
+ val s_axi_bvalid = Bool(OUTPUT)
+ //slave interface read address ports
+ val s_axi_arid = Bits(INPUT,4)
+ val s_axi_araddr = Bits(INPUT,if(depth<=0x40000000) 30 else 32)
+ val s_axi_arlen = Bits(INPUT,8)
+ val s_axi_arsize = Bits(INPUT,3)
+ val s_axi_arburst = Bits(INPUT,2)
+ val s_axi_arlock = Bits(INPUT,1)
+ val s_axi_arcache = Bits(INPUT,4)
+ val s_axi_arprot = Bits(INPUT,3)
+ val s_axi_arqos = Bits(INPUT,4)
+ val s_axi_arvalid = Bool(INPUT)
+ val s_axi_arready = Bool(OUTPUT)
+ //slave interface read data ports
+ val s_axi_rready = Bool(INPUT)
+ val s_axi_rid = Bits(OUTPUT,4)
+ val s_axi_rdata = Bits(OUTPUT,64)
+ val s_axi_rresp = Bits(OUTPUT,2)
+ val s_axi_rlast = Bool(OUTPUT)
+ val s_axi_rvalid = Bool(OUTPUT)
+ //misc
+ val device_temp = Bits(OUTPUT,12)
+ }
+
+
+ val migprj = """{
+
+
+ design_1_mig_7series_0_0
+ 1
+ 1
+ OFF
+ 1024
+ ON
+ Enabled
+ xc7a100t-csg324/-1
+ 4.1
+ No Buffer
+ No Buffer
+ ACTIVE HIGH
+ FALSE
+ 1
+ 50 Ohms
+ 0
+
+ DDR3_SDRAM/Components/MT41K128M16XX-15E
+ 3000
+ 1.8V
+ 4:1
+ 166.666
+ 0
+ 666
+ 1.000
+ 1
+ 1
+ 1
+ 1
+ 16
+ 1
+ 1
+ Disabled
+ Normal
+ 8
+ FALSE
+
+ 14
+ 10
+ 3
+ 1.35V
+ 268435456
+ BANK_ROW_COLUMN
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 8 - Fixed
+ Sequential
+ 5
+ Normal
+ No
+ Slow Exit
+ Enable
+ RZQ/6
+ Disable
+ Enable
+ RZQ/6
+ 0
+ Disabled
+ Enabled
+ Output Buffer Enabled
+ Full Array
+ 5
+ Enabled
+ Normal
+ Dynamic ODT off
+ AXI
+
+ RD_PRI_REG
+ 28
+ 64
+ 4
+ 0
+
+
+
+ } """
+
+
+
+
+ val migprjname = """{/arty100tmig.prj}"""
+ val modulename = """arty100tmig"""
+
+ ElaborationArtefacts.add(
+ modulename++".vivado.tcl",
+ """set migprj """++migprj++"""
+ set migprjfile """++migprjname++"""
+ set migprjfilepath $ipdir$migprjfile
+ set fp [open $migprjfilepath w+]
+ puts $fp $migprj
+ close $fp
+ create_ip -vendor xilinx.com -library ip -name mig_7series -module_name """ ++ modulename ++ """ -dir $ipdir -force
+ set_property CONFIG.XML_INPUT_FILE $migprjfilepath [get_ips """ ++ modulename ++ """] """
+ )
+
+
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/ibufds_gte2/ibufds_gte2.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/ibufds_gte2/ibufds_gte2.scala
new file mode 100644
index 0000000..90f58f5
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/ibufds_gte2/ibufds_gte2.scala
@@ -0,0 +1,18 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.xilinx.ibufds_gte2
+
+import Chisel._
+
+//IP : xilinx unisim IBUFDS_GTE2
+//Differential Signaling Input Buffer
+//unparameterized
+
+class IBUFDS_GTE2 extends BlackBox {
+ val io = new Bundle {
+ val O = Bool(OUTPUT)
+ val ODIV2 = Bool(OUTPUT)
+ val CEB = Bool(INPUT)
+ val I = Bool(INPUT)
+ val IB = Bool(INPUT)
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/vc707axi_to_pcie_x1/vc707axi_to_pcie_x1.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/vc707axi_to_pcie_x1/vc707axi_to_pcie_x1.scala
new file mode 100644
index 0000000..1884238
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/vc707axi_to_pcie_x1/vc707axi_to_pcie_x1.scala
@@ -0,0 +1,491 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.xilinx.vc707axi_to_pcie_x1
+
+import Chisel._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.interrupts._
+import freechips.rocketchip.util.{ElaborationArtefacts}
+
+// IP VLNV: xilinx.com:customize_ip:vc707pcietoaxi:1.0
+// Black Box
+// Signals named _exactly_ as per Vivado generated verilog
+// s : -{lock, cache, prot, qos}
+
+trait VC707AXIToPCIeX1IOSerial extends Bundle {
+ //serial external pins
+ val pci_exp_txp = Bool(OUTPUT)
+ val pci_exp_txn = Bool(OUTPUT)
+ val pci_exp_rxp = Bool(INPUT)
+ val pci_exp_rxn = Bool(INPUT)
+}
+
+trait VC707AXIToPCIeX1IOClocksReset extends Bundle {
+ //clock, reset, control
+ val axi_aresetn = Bool(INPUT)
+ val axi_aclk_out = Clock(OUTPUT)
+ val axi_ctl_aclk_out = Clock(OUTPUT)
+ val mmcm_lock = Bool(OUTPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class vc707axi_to_pcie_x1() extends BlackBox
+{
+ val io = new Bundle with VC707AXIToPCIeX1IOSerial
+ with VC707AXIToPCIeX1IOClocksReset {
+ //refclk
+ val REFCLK = Bool(INPUT)
+
+ //clock, reset, control
+ val INTX_MSI_Request = Bool(INPUT)
+ val INTX_MSI_Grant = Bool(OUTPUT)
+ val MSI_enable = Bool(OUTPUT)
+ val MSI_Vector_Num = Bits(INPUT,5)
+ val MSI_Vector_Width = Bits(OUTPUT,3)
+
+ //interrupt
+ val interrupt_out = Bool(OUTPUT)
+
+ //axi slave
+ //-{lock, cache, prot, qos}
+ //slave interface write address
+ val s_axi_awid = Bits(INPUT,4)
+ val s_axi_awaddr = Bits(INPUT,32)
+ val s_axi_awregion = Bits(INPUT,4)
+ val s_axi_awlen = Bits(INPUT,8)
+ val s_axi_awsize = Bits(INPUT,3)
+ val s_axi_awburst = Bits(INPUT,2)
+ //val s_axi_awlock = Bool(INPUT)
+ //val s_axi_awcache = Bits(INPUT,4)
+ //val s_axi_awprot = Bits(INPUT,3)
+ //val s_axi_awqos = Bits(INPUT,4)
+ val s_axi_awvalid = Bool(INPUT)
+ val s_axi_awready = Bool(OUTPUT)
+ //slave interface write data
+ val s_axi_wdata = Bits(INPUT,64)
+ val s_axi_wstrb = Bits(INPUT,8)
+ val s_axi_wlast = Bool(INPUT)
+ val s_axi_wvalid = Bool(INPUT)
+ val s_axi_wready = Bool(OUTPUT)
+ //slave interface write response
+ val s_axi_bready = Bool(INPUT)
+ val s_axi_bid = Bits(OUTPUT,4)
+ val s_axi_bresp = Bits(OUTPUT,2)
+ val s_axi_bvalid = Bool(OUTPUT)
+ //slave interface read address
+ val s_axi_arid = Bits(INPUT,4)
+ val s_axi_araddr = Bits(INPUT,32)
+ val s_axi_arregion = Bits(INPUT,4)
+ val s_axi_arlen = Bits(INPUT,8)
+ val s_axi_arsize = Bits(INPUT,3)
+ val s_axi_arburst = Bits(INPUT,2)
+ //val s_axi_arlock = Bits(INPUT,1)
+ //val s_axi_arcache = Bits(INPUT,4)
+ //val s_axi_arprot = Bits(INPUT,3)
+ //val s_axi_arqos = Bits(INPUT,4)
+ val s_axi_arvalid = Bool(INPUT)
+ val s_axi_arready = Bool(OUTPUT)
+ //slave interface read data
+ val s_axi_rready = Bool(INPUT)
+ val s_axi_rid = Bits(OUTPUT,4)
+ val s_axi_rdata = Bits(OUTPUT,64)
+ val s_axi_rresp = Bits(OUTPUT,2)
+ val s_axi_rlast = Bool(OUTPUT)
+ val s_axi_rvalid = Bool(OUTPUT)
+
+ //axi master
+ //-{id,region,qos}
+ //slave interface write address ports
+ //val m_axi_awid = Bits(OUTPUT,4)
+ val m_axi_awaddr = Bits(OUTPUT,32)
+ //val m_axi_awregion = Bits(OUTPUT,4)
+ val m_axi_awlen = Bits(OUTPUT,8)
+ val m_axi_awsize = Bits(OUTPUT,3)
+ val m_axi_awburst = Bits(OUTPUT,2)
+ val m_axi_awlock = Bool(OUTPUT)
+ val m_axi_awcache = Bits(OUTPUT,4)
+ val m_axi_awprot = Bits(OUTPUT,3)
+ //val m_axi_awqos = Bits(OUTPUT,4)
+ val m_axi_awvalid = Bool(OUTPUT)
+ val m_axi_awready = Bool(INPUT)
+ //slave interface write data ports
+ val m_axi_wdata = Bits(OUTPUT,64)
+ val m_axi_wstrb = Bits(OUTPUT,8)
+ val m_axi_wlast = Bool(OUTPUT)
+ val m_axi_wvalid = Bool(OUTPUT)
+ val m_axi_wready = Bool(INPUT)
+ //slave interface write response ports
+ val m_axi_bready = Bool(OUTPUT)
+ //val m_axi_bid = Bits(INPUT,4)
+ val m_axi_bresp = Bits(INPUT,2)
+ val m_axi_bvalid = Bool(INPUT)
+ //slave interface read address ports
+ //val m_axi_arid = Bits(OUTPUT,4)
+ val m_axi_araddr = Bits(OUTPUT,32)
+ //val m_axi_arregion = Bits(OUTPUT,4)
+ val m_axi_arlen = Bits(OUTPUT,8)
+ val m_axi_arsize = Bits(OUTPUT,3)
+ val m_axi_arburst = Bits(OUTPUT,2)
+ val m_axi_arlock = Bits(OUTPUT,1)
+ val m_axi_arcache = Bits(OUTPUT,4)
+ val m_axi_arprot = Bits(OUTPUT,3)
+ //val m_axi_arqos = Bits(OUTPUT,4)
+ val m_axi_arvalid = Bool(OUTPUT)
+ val m_axi_arready = Bool(INPUT)
+ //slave interface read data ports
+ val m_axi_rready = Bool(OUTPUT)
+ //val m_axi_rid = Bits(INPUT,4)
+ val m_axi_rdata = Bits(INPUT,64)
+ val m_axi_rresp = Bits(INPUT,2)
+ val m_axi_rlast = Bool(INPUT)
+ val m_axi_rvalid = Bool(INPUT)
+
+ //axi lite slave for control
+ val s_axi_ctl_awaddr = Bits(INPUT,32)
+ val s_axi_ctl_awvalid = Bool(INPUT)
+ val s_axi_ctl_awready = Bool(OUTPUT)
+ val s_axi_ctl_wdata = Bits(INPUT,32)
+ val s_axi_ctl_wstrb = Bits(INPUT,4)
+ val s_axi_ctl_wvalid = Bool(INPUT)
+ val s_axi_ctl_wready = Bool(OUTPUT)
+ val s_axi_ctl_bresp = Bits(OUTPUT,2)
+ val s_axi_ctl_bvalid = Bool(OUTPUT)
+ val s_axi_ctl_bready = Bool(INPUT)
+ val s_axi_ctl_araddr = Bits(INPUT,32)
+ val s_axi_ctl_arvalid = Bool(INPUT)
+ val s_axi_ctl_arready = Bool(OUTPUT)
+ val s_axi_ctl_rdata = Bits(OUTPUT,32)
+ val s_axi_ctl_rresp = Bits(OUTPUT,2)
+ val s_axi_ctl_rvalid = Bool(OUTPUT)
+ val s_axi_ctl_rready = Bool(INPUT)
+ }
+}
+//scalastyle:off
+
+//wrap vc707_axi_to_pcie_x1 black box in Nasti Bundles
+
+class VC707AXIToPCIeX1(implicit p:Parameters) extends LazyModule
+{
+ val device = new SimpleDevice("pci", Seq("xlnx,axi-pcie-host-1.00.a")) {
+ override def describe(resources: ResourceBindings): Description = {
+ val Description(name, mapping) = super.describe(resources)
+ val intc = "pcie_intc"
+ def ofInt(x: Int) = Seq(ResourceInt(BigInt(x)))
+ def ofMap(x: Int) = Seq(0, 0, 0, x).flatMap(ofInt) ++ Seq(ResourceReference(intc)) ++ ofInt(x)
+ val extra = Map(
+ "#address-cells" -> ofInt(3),
+ "#size-cells" -> ofInt(2),
+ "#interrupt-cells" -> ofInt(1),
+ "device_type" -> Seq(ResourceString("pci")),
+ "interrupt-map-mask" -> Seq(0, 0, 0, 7).flatMap(ofInt),
+ "interrupt-map" -> Seq(1, 2, 3, 4).flatMap(ofMap),
+ "ranges" -> resources("ranges").map(x =>
+ (x: @unchecked) match { case Binding(_, ResourceAddress(address, perms)) =>
+ ResourceMapping(address, BigInt(0x02000000) << 64, perms) }),
+ "interrupt-controller" -> Seq(ResourceMap(labels = Seq(intc), value = Map(
+ "interrupt-controller" -> Nil,
+ "#address-cells" -> ofInt(0),
+ "#interrupt-cells" -> ofInt(1)))))
+ Description(name, mapping ++ extra)
+ }
+ }
+
+ val slave = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = List(AddressSet(0x40000000L, 0x1fffffffL)),
+ resources = Seq(Resource(device, "ranges")),
+ executable = true,
+ supportsWrite = TransferSizes(1, 128),
+ supportsRead = TransferSizes(1, 128))),
+ beatBytes = 8)))
+
+ val control = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = List(AddressSet(0x2000000000L, 0x3ffffffL)), // when truncated to 32-bits, is 0
+ resources = device.reg("control"),
+ supportsWrite = TransferSizes(1, 4),
+ supportsRead = TransferSizes(1, 4),
+ interleavedId = Some(0))), // AXI4-Lite never interleaves responses
+ beatBytes = 4)))
+
+ val master = AXI4MasterNode(Seq(AXI4MasterPortParameters(
+ masters = Seq(AXI4MasterParameters(
+ name = "VC707 PCIe",
+ id = IdRange(0, 1),
+ aligned = false)))))
+
+ val intnode = IntSourceNode(IntSourcePortSimple(resources = device.int))
+
+ lazy val module = new LazyModuleImp(this) {
+ // The master on the control port must be AXI-lite
+ require (control.edges.in(0).master.endId == 1)
+ // Must have exactly the right number of idBits
+ require (slave.edges.in(0).bundle.idBits == 4)
+
+ class VC707AXIToPCIeX1IOBundle extends Bundle with VC707AXIToPCIeX1IOSerial
+ with VC707AXIToPCIeX1IOClocksReset;
+
+ val io = IO(new Bundle {
+ val port = new VC707AXIToPCIeX1IOBundle
+ val REFCLK = Bool(INPUT)
+ })
+
+ val blackbox = Module(new vc707axi_to_pcie_x1)
+
+ val (s, _) = slave.in(0)
+ val (c, _) = control.in(0)
+ val (m, _) = master.out(0)
+ val (i, _) = intnode.out(0)
+
+ //to top level
+ blackbox.io.axi_aresetn := io.port.axi_aresetn
+ io.port.axi_aclk_out := blackbox.io.axi_aclk_out
+ io.port.axi_ctl_aclk_out := blackbox.io.axi_ctl_aclk_out
+ io.port.mmcm_lock := blackbox.io.mmcm_lock
+ io.port.pci_exp_txp := blackbox.io.pci_exp_txp
+ io.port.pci_exp_txn := blackbox.io.pci_exp_txn
+ blackbox.io.pci_exp_rxp := io.port.pci_exp_rxp
+ blackbox.io.pci_exp_rxn := io.port.pci_exp_rxn
+ i(0) := blackbox.io.interrupt_out
+ blackbox.io.REFCLK := io.REFCLK
+
+ //s
+ //AXI4 signals ordered as per AXI4 Specification (Release D) Section A.2
+ //-{lock, cache, prot, qos}
+ //-{aclk, aresetn, awuser, wid, wuser, buser, ruser}
+ //global signals
+ //aclk :=
+ //aresetn :=
+ //slave interface write address
+ blackbox.io.s_axi_awid := s.aw.bits.id
+ blackbox.io.s_axi_awaddr := s.aw.bits.addr
+ blackbox.io.s_axi_awlen := s.aw.bits.len
+ blackbox.io.s_axi_awsize := s.aw.bits.size
+ blackbox.io.s_axi_awburst := s.aw.bits.burst
+ //blackbox.io.s_axi_awlock := s.aw.bits.lock
+ //blackbox.io.s_axi_awcache := s.aw.bits.cache
+ //blackbox.io.s_axi_awprot := s.aw.bits.prot
+ //blackbox.io.s_axi_awqos := s.aw.bits.qos
+ blackbox.io.s_axi_awregion := UInt(0)
+ //blackbox.io.awuser := s.aw.bits.user
+ blackbox.io.s_axi_awvalid := s.aw.valid
+ s.aw.ready := blackbox.io.s_axi_awready
+ //slave interface write data ports
+ //blackbox.io.s_axi_wid := s.w.bits.id
+ blackbox.io.s_axi_wdata := s.w.bits.data
+ blackbox.io.s_axi_wstrb := s.w.bits.strb
+ blackbox.io.s_axi_wlast := s.w.bits.last
+ //blackbox.io.s_axi_wuser := s.w.bits.user
+ blackbox.io.s_axi_wvalid := s.w.valid
+ s.w.ready := blackbox.io.s_axi_wready
+ //slave interface write response
+ s.b.bits.id := blackbox.io.s_axi_bid
+ s.b.bits.resp := blackbox.io.s_axi_bresp
+ //s.b.bits.user := blackbox.io.s_axi_buser
+ s.b.valid := blackbox.io.s_axi_bvalid
+ blackbox.io.s_axi_bready := s.b.ready
+ //slave AXI interface read address ports
+ blackbox.io.s_axi_arid := s.ar.bits.id
+ blackbox.io.s_axi_araddr := s.ar.bits.addr
+ blackbox.io.s_axi_arlen := s.ar.bits.len
+ blackbox.io.s_axi_arsize := s.ar.bits.size
+ blackbox.io.s_axi_arburst := s.ar.bits.burst
+ //blackbox.io.s_axi_arlock := s.ar.bits.lock
+ //blackbox.io.s_axi_arcache := s.ar.bits.cache
+ //blackbox.io.s_axi_arprot := s.ar.bits.prot
+ //blackbox.io.s_axi_arqos := s.ar.bits.qos
+ blackbox.io.s_axi_arregion := UInt(0)
+ //blackbox.io.s_axi_aruser := s.ar.bits.user
+ blackbox.io.s_axi_arvalid := s.ar.valid
+ s.ar.ready := blackbox.io.s_axi_arready
+ //slave AXI interface read data ports
+ s.r.bits.id := blackbox.io.s_axi_rid
+ s.r.bits.data := blackbox.io.s_axi_rdata
+ s.r.bits.resp := blackbox.io.s_axi_rresp
+ s.r.bits.last := blackbox.io.s_axi_rlast
+ //s.r.bits.ruser := blackbox.io.s_axi_ruser
+ s.r.valid := blackbox.io.s_axi_rvalid
+ blackbox.io.s_axi_rready := s.r.ready
+
+ //ctl
+ //axi-lite slave interface write address
+ blackbox.io.s_axi_ctl_awaddr := c.aw.bits.addr
+ blackbox.io.s_axi_ctl_awvalid := c.aw.valid
+ c.aw.ready := blackbox.io.s_axi_ctl_awready
+ //axi-lite slave interface write data ports
+ blackbox.io.s_axi_ctl_wdata := c.w.bits.data
+ blackbox.io.s_axi_ctl_wstrb := c.w.bits.strb
+ blackbox.io.s_axi_ctl_wvalid := c.w.valid
+ c.w.ready := blackbox.io.s_axi_ctl_wready
+ //axi-lite slave interface write response
+ blackbox.io.s_axi_ctl_bready := c.b.ready
+ c.b.bits.id := UInt(0)
+ c.b.bits.resp := blackbox.io.s_axi_ctl_bresp
+ c.b.valid := blackbox.io.s_axi_ctl_bvalid
+ //axi-lite slave AXI interface read address ports
+ blackbox.io.s_axi_ctl_araddr := c.ar.bits.addr
+ blackbox.io.s_axi_ctl_arvalid := c.ar.valid
+ c.ar.ready := blackbox.io.s_axi_ctl_arready
+ //slave AXI interface read data ports
+ blackbox.io.s_axi_ctl_rready := c.r.ready
+ c.r.bits.id := UInt(0)
+ c.r.bits.data := blackbox.io.s_axi_ctl_rdata
+ c.r.bits.resp := blackbox.io.s_axi_ctl_rresp
+ c.r.bits.last := Bool(true)
+ c.r.valid := blackbox.io.s_axi_ctl_rvalid
+
+ //m
+ //AXI4 signals ordered per AXI4 Specification (Release D) Section A.2
+ //-{id,region,qos}
+ //-{aclk, aresetn, awuser, wid, wuser, buser, ruser}
+ //global signals
+ //aclk :=
+ //aresetn :=
+ //master interface write address
+ m.aw.bits.id := UInt(0)
+ m.aw.bits.addr := blackbox.io.m_axi_awaddr
+ m.aw.bits.len := blackbox.io.m_axi_awlen
+ m.aw.bits.size := blackbox.io.m_axi_awsize
+ m.aw.bits.burst := blackbox.io.m_axi_awburst
+ m.aw.bits.lock := blackbox.io.m_axi_awlock
+ m.aw.bits.cache := blackbox.io.m_axi_awcache
+ m.aw.bits.prot := blackbox.io.m_axi_awprot
+ m.aw.bits.qos := UInt(0)
+ //m.aw.bits.region := blackbox.io.m_axi_awregion
+ //m.aw.bits.user := blackbox.io.m_axi_awuser
+ m.aw.valid := blackbox.io.m_axi_awvalid
+ blackbox.io.m_axi_awready := m.aw.ready
+
+ //master interface write data ports
+ m.w.bits.data := blackbox.io.m_axi_wdata
+ m.w.bits.strb := blackbox.io.m_axi_wstrb
+ m.w.bits.last := blackbox.io.m_axi_wlast
+ //m.w.bits.user := blackbox.io.m_axi_wuser
+ m.w.valid := blackbox.io.m_axi_wvalid
+ blackbox.io.m_axi_wready := m.w.ready
+
+ //master interface write response
+ //blackbox.io.m_axi_bid := m.b.bits.id
+ blackbox.io.m_axi_bresp := m.b.bits.resp
+ //blackbox.io.m_axi_buser := m.b.bits.user
+ blackbox.io.m_axi_bvalid := m.b.valid
+ m.b.ready := blackbox.io.m_axi_bready
+
+ //master AXI interface read address ports
+ m.ar.bits.id := UInt(0)
+ m.ar.bits.addr := blackbox.io.m_axi_araddr
+ m.ar.bits.len := blackbox.io.m_axi_arlen
+ m.ar.bits.size := blackbox.io.m_axi_arsize
+ m.ar.bits.burst := blackbox.io.m_axi_arburst
+ m.ar.bits.lock := blackbox.io.m_axi_arlock
+ m.ar.bits.cache := blackbox.io.m_axi_arcache
+ m.ar.bits.prot := blackbox.io.m_axi_arprot
+ m.ar.bits.qos := UInt(0)
+ //m.ar.bits.region := blackbox.io.m_axi_arregion
+ //m.ar.bits.user := blackbox.io.s_axi_aruser
+ m.ar.valid := blackbox.io.m_axi_arvalid
+ blackbox.io.m_axi_arready := m.ar.ready
+
+ //master AXI interface read data ports
+ //blackbox.io.m_axi_rid := m.r.bits.id
+ blackbox.io.m_axi_rdata := m.r.bits.data
+ blackbox.io.m_axi_rresp := m.r.bits.resp
+ blackbox.io.m_axi_rlast := m.r.bits.last
+ //blackbox.io.s_axi_ruser := s.bits.ruser
+ blackbox.io.m_axi_rvalid := m.r.valid
+ m.r.ready := blackbox.io.m_axi_rready
+ }
+
+ ElaborationArtefacts.add(
+ "vc707axi_to_pcie_x1.vivado.tcl",
+ """
+ create_ip -vendor xilinx.com -library ip -version 2.8 -name axi_pcie -module_name vc707axi_to_pcie_x1 -dir $ipdir -force
+ set_property -dict [list \
+ CONFIG.AXIBAR2PCIEBAR_0 {0x40000000} \
+ CONFIG.AXIBAR2PCIEBAR_1 {0x00000000} \
+ CONFIG.AXIBAR2PCIEBAR_2 {0x00000000} \
+ CONFIG.AXIBAR2PCIEBAR_3 {0x00000000} \
+ CONFIG.AXIBAR2PCIEBAR_4 {0x00000000} \
+ CONFIG.AXIBAR2PCIEBAR_5 {0x00000000} \
+ CONFIG.AXIBAR_0 {0x40000000} \
+ CONFIG.AXIBAR_1 {0xFFFFFFFF} \
+ CONFIG.AXIBAR_2 {0xFFFFFFFF} \
+ CONFIG.AXIBAR_3 {0xFFFFFFFF} \
+ CONFIG.AXIBAR_4 {0xFFFFFFFF} \
+ CONFIG.AXIBAR_5 {0xFFFFFFFF} \
+ CONFIG.AXIBAR_AS_0 {true} \
+ CONFIG.AXIBAR_AS_1 {false} \
+ CONFIG.AXIBAR_AS_2 {false} \
+ CONFIG.AXIBAR_AS_3 {false} \
+ CONFIG.AXIBAR_AS_4 {false} \
+ CONFIG.AXIBAR_AS_5 {false} \
+ CONFIG.AXIBAR_HIGHADDR_0 {0x5FFFFFFF} \
+ CONFIG.AXIBAR_HIGHADDR_1 {0x00000000} \
+ CONFIG.AXIBAR_HIGHADDR_2 {0x00000000} \
+ CONFIG.AXIBAR_HIGHADDR_3 {0x00000000} \
+ CONFIG.AXIBAR_HIGHADDR_4 {0x00000000} \
+ CONFIG.AXIBAR_HIGHADDR_5 {0x00000000} \
+ CONFIG.AXIBAR_NUM {1} \
+ CONFIG.BAR0_ENABLED {true} \
+ CONFIG.BAR0_SCALE {Gigabytes} \
+ CONFIG.BAR0_SIZE {4} \
+ CONFIG.BAR0_TYPE {Memory} \
+ CONFIG.BAR1_ENABLED {false} \
+ CONFIG.BAR1_SCALE {N/A} \
+ CONFIG.BAR1_SIZE {8} \
+ CONFIG.BAR1_TYPE {N/A} \
+ CONFIG.BAR2_ENABLED {false} \
+ CONFIG.BAR2_SCALE {N/A} \
+ CONFIG.BAR2_SIZE {8} \
+ CONFIG.BAR2_TYPE {N/A} \
+ CONFIG.BAR_64BIT {true} \
+ CONFIG.BASEADDR {0x00000000} \
+ CONFIG.BASE_CLASS_MENU {Bridge_device} \
+ CONFIG.CLASS_CODE {0x060400} \
+ CONFIG.COMP_TIMEOUT {50ms} \
+ CONFIG.Component_Name {design_1_axi_pcie_1_0} \
+ CONFIG.DEVICE_ID {0x7111} \
+ CONFIG.ENABLE_CLASS_CODE {true} \
+ CONFIG.HIGHADDR {0x03FFFFFF} \
+ CONFIG.INCLUDE_BAROFFSET_REG {true} \
+ CONFIG.INCLUDE_RC {Root_Port_of_PCI_Express_Root_Complex} \
+ CONFIG.INTERRUPT_PIN {false} \
+ CONFIG.MAX_LINK_SPEED {2.5_GT/s} \
+ CONFIG.MSI_DECODE_ENABLED {true} \
+ CONFIG.M_AXI_ADDR_WIDTH {32} \
+ CONFIG.M_AXI_DATA_WIDTH {64} \
+ CONFIG.NO_OF_LANES {X1} \
+ CONFIG.NUM_MSI_REQ {0} \
+ CONFIG.PCIEBAR2AXIBAR_0_SEC {1} \
+ CONFIG.PCIEBAR2AXIBAR_0 {0x00000000} \
+ CONFIG.PCIEBAR2AXIBAR_1 {0xFFFFFFFF} \
+ CONFIG.PCIEBAR2AXIBAR_1_SEC {1} \
+ CONFIG.PCIEBAR2AXIBAR_2 {0xFFFFFFFF} \
+ CONFIG.PCIEBAR2AXIBAR_2_SEC {1} \
+ CONFIG.PCIE_BLK_LOCN {X1Y1} \
+ CONFIG.PCIE_USE_MODE {GES_and_Production} \
+ CONFIG.REF_CLK_FREQ {100_MHz} \
+ CONFIG.REV_ID {0x00} \
+ CONFIG.SLOT_CLOCK_CONFIG {true} \
+ CONFIG.SUBSYSTEM_ID {0x0007} \
+ CONFIG.SUBSYSTEM_VENDOR_ID {0x10EE} \
+ CONFIG.SUB_CLASS_INTERFACE_MENU {Host_bridge} \
+ CONFIG.S_AXI_ADDR_WIDTH {32} \
+ CONFIG.S_AXI_DATA_WIDTH {64} \
+ CONFIG.S_AXI_ID_WIDTH {4} \
+ CONFIG.S_AXI_SUPPORTS_NARROW_BURST {false} \
+ CONFIG.VENDOR_ID {0x10EE} \
+ CONFIG.XLNX_REF_BOARD {None} \
+ CONFIG.axi_aclk_loopback {false} \
+ CONFIG.en_ext_ch_gt_drp {false} \
+ CONFIG.en_ext_clk {false} \
+ CONFIG.en_ext_gt_common {false} \
+ CONFIG.en_ext_pipe_interface {false} \
+ CONFIG.en_transceiver_status_ports {false} \
+ CONFIG.no_slv_err {false} \
+ CONFIG.rp_bar_hide {true} \
+ CONFIG.shared_logic_in_core {false} ] [get_ips vc707axi_to_pcie_x1]"""
+ )
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/vc707mig/vc707mig.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/vc707mig/vc707mig.scala
new file mode 100644
index 0000000..d5d58ab
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/vc707mig/vc707mig.scala
@@ -0,0 +1,534 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.xilinx.vc707mig
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// IP VLNV: xilinx.com:customize_ip:vc707mig:1.0
+// Black Box
+
+class VC707MIGIODDR(depth : BigInt) extends GenericParameterizedBundle(depth) {
+ require((depth<=0x100000000L),"VC707MIGIODDR supports upto 4GB depth configuraton")
+ val ddr3_addr = Bits(OUTPUT,if(depth<=0x40000000L) 14 else 16)
+ val ddr3_ba = Bits(OUTPUT,3)
+ val ddr3_ras_n = Bool(OUTPUT)
+ val ddr3_cas_n = Bool(OUTPUT)
+ val ddr3_we_n = Bool(OUTPUT)
+ val ddr3_reset_n = Bool(OUTPUT)
+ val ddr3_ck_p = Bits(OUTPUT,1)
+ val ddr3_ck_n = Bits(OUTPUT,1)
+ val ddr3_cke = Bits(OUTPUT,1)
+ val ddr3_cs_n = Bits(OUTPUT,1)
+ val ddr3_dm = Bits(OUTPUT,8)
+ val ddr3_odt = Bits(OUTPUT,1)
+
+ val ddr3_dq = Analog(64.W)
+ val ddr3_dqs_n = Analog(8.W)
+ val ddr3_dqs_p = Analog(8.W)
+}
+
+//reused directly in io bundle for sifive.blocks.devices.xilinxvc707mig
+trait VC707MIGIOClocksReset extends Bundle {
+ //inputs
+ //"NO_BUFFER" clock source (must be connected to IBUF outside of IP)
+ val sys_clk_i = Bool(INPUT)
+ //user interface signals
+ val ui_clk = Clock(OUTPUT)
+ val ui_clk_sync_rst = Bool(OUTPUT)
+ val mmcm_locked = Bool(OUTPUT)
+ val aresetn = Bool(INPUT)
+ //misc
+ val init_calib_complete = Bool(OUTPUT)
+ val sys_rst = Bool(INPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class vc707mig(depth : BigInt)(implicit val p:Parameters) extends BlackBox
+{
+ require((depth<=0x100000000L),"vc707mig supports upto 4GB depth configuraton")
+ override def desiredName = if(depth<=0x40000000) "vc707mig1gb" else "vc707mig4gb"
+
+ val io = new VC707MIGIODDR(depth) with VC707MIGIOClocksReset {
+ // User interface signals
+ val app_sr_req = Bool(INPUT)
+ val app_ref_req = Bool(INPUT)
+ val app_zq_req = Bool(INPUT)
+ val app_sr_active = Bool(OUTPUT)
+ val app_ref_ack = Bool(OUTPUT)
+ val app_zq_ack = Bool(OUTPUT)
+ //axi_s
+ //slave interface write address ports
+ val s_axi_awid = Bits(INPUT,4)
+ val s_axi_awaddr = Bits(INPUT,if(depth<=0x40000000) 30 else 32)
+ val s_axi_awlen = Bits(INPUT,8)
+ val s_axi_awsize = Bits(INPUT,3)
+ val s_axi_awburst = Bits(INPUT,2)
+ val s_axi_awlock = Bits(INPUT,1)
+ val s_axi_awcache = Bits(INPUT,4)
+ val s_axi_awprot = Bits(INPUT,3)
+ val s_axi_awqos = Bits(INPUT,4)
+ val s_axi_awvalid = Bool(INPUT)
+ val s_axi_awready = Bool(OUTPUT)
+ //slave interface write data ports
+ val s_axi_wdata = Bits(INPUT,64)
+ val s_axi_wstrb = Bits(INPUT,8)
+ val s_axi_wlast = Bool(INPUT)
+ val s_axi_wvalid = Bool(INPUT)
+ val s_axi_wready = Bool(OUTPUT)
+ //slave interface write response ports
+ val s_axi_bready = Bool(INPUT)
+ val s_axi_bid = Bits(OUTPUT,4)
+ val s_axi_bresp = Bits(OUTPUT,2)
+ val s_axi_bvalid = Bool(OUTPUT)
+ //slave interface read address ports
+ val s_axi_arid = Bits(INPUT,4)
+ val s_axi_araddr = Bits(INPUT,if(depth<=0x40000000) 30 else 32)
+ val s_axi_arlen = Bits(INPUT,8)
+ val s_axi_arsize = Bits(INPUT,3)
+ val s_axi_arburst = Bits(INPUT,2)
+ val s_axi_arlock = Bits(INPUT,1)
+ val s_axi_arcache = Bits(INPUT,4)
+ val s_axi_arprot = Bits(INPUT,3)
+ val s_axi_arqos = Bits(INPUT,4)
+ val s_axi_arvalid = Bool(INPUT)
+ val s_axi_arready = Bool(OUTPUT)
+ //slave interface read data ports
+ val s_axi_rready = Bool(INPUT)
+ val s_axi_rid = Bits(OUTPUT,4)
+ val s_axi_rdata = Bits(OUTPUT,64)
+ val s_axi_rresp = Bits(OUTPUT,2)
+ val s_axi_rlast = Bool(OUTPUT)
+ val s_axi_rvalid = Bool(OUTPUT)
+ //misc
+ val device_temp = Bits(OUTPUT,12)
+ }
+
+ val vc707mig1gbprj = """ {
+
+
+ vc707mig1gp
+ 1
+ 1
+ OFF
+ 1024
+ ON
+ Enabled
+ xc7vx485t-ffg1761/-2
+ 3.0
+ No Buffer
+ Use System Clock
+ ACTIVE HIGH
+ FALSE
+ 0
+ 50 Ohms
+ 0
+
+ DDR3_SDRAM/SODIMMs/MT8JTF12864HZ-1G6
+ 1250
+ 2.0V
+ 4:1
+ 200
+ 0
+ 800
+ 1.000
+ 1
+ 1
+ 1
+ 1
+ 64
+ 1
+ 1
+ Disabled
+ Normal
+ FALSE
+
+ 14
+ 10
+ 3
+ 1.5V
+ BANK_ROW_COLUMN
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 8 - Fixed
+ Sequential
+ 11
+ Normal
+ No
+ Slow Exit
+ Enable
+ RZQ/7
+ Disable
+ Enable
+ RZQ/6
+ 0
+ Disabled
+ Enabled
+ Output Buffer Enabled
+ Full Array
+ 8
+ Enabled
+ Normal
+ Dynamic ODT off
+ AXI
+
+ RD_PRI_REG
+ 30
+ 64
+ 4
+ 0
+
+
+
+ } """
+
+ val vc707mig4gbprj = """ {
+
+
+ vc707mig4gb
+ 1
+ 1
+ OFF
+ 1024
+ ON
+ Enabled
+ xc7vx485t-ffg1761/-2
+ 3.0
+ No Buffer
+ Use System Clock
+ ACTIVE HIGH
+ FALSE
+ 0
+ 50 Ohms
+ 0
+
+ DDR3_SDRAM/SODIMMs/MT8KTF51264HZ-1G9
+ 1250
+ 2.0V
+ 4:1
+ 200
+ 0
+ 800
+ 1.000
+ 1
+ 1
+ 1
+ 1
+ 64
+ 1
+ 1
+ Disabled
+ Normal
+ FALSE
+
+ 16
+ 10
+ 3
+ 1.5V
+ BANK_ROW_COLUMN
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 8 - Fixed
+ Sequential
+ 11
+ Normal
+ No
+ Slow Exit
+ Enable
+ RZQ/7
+ Disable
+ Enable
+ RZQ/6
+ 0
+ Disabled
+ Enabled
+ Output Buffer Enabled
+ Full Array
+ 8
+ Enabled
+ Normal
+ Dynamic ODT off
+ AXI
+
+ RD_PRI_REG
+ 32
+ 64
+ 4
+ 0
+
+
+
+}"""
+
+ val migprj = if(depth<=0x40000000) vc707mig1gbprj else vc707mig4gbprj
+ val migprjname = if(depth<=0x40000000) """{/vc707mig1gb.prj}""" else """{/vc707mig4gb.prj}"""
+ val modulename = if(depth<=0x40000000) """vc707mig1gb""" else """vc707mig4gb"""
+
+
+ ElaborationArtefacts.add(
+ modulename++".vivado.tcl",
+ """set migprj """++migprj++"""
+ set migprjfile """++migprjname++"""
+ set migprjfilepath $ipdir$migprjfile
+ set fp [open $migprjfilepath w+]
+ puts $fp $migprj
+ close $fp
+ create_ip -vendor xilinx.com -library ip -name mig_7series -module_name """ ++ modulename ++ """ -dir $ipdir -force
+ set_property CONFIG.XML_INPUT_FILE $migprjfilepath [get_ips """ ++ modulename ++ """] """
+ )
+
+
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/vcu118mig/vcu118mig.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/vcu118mig/vcu118mig.scala
new file mode 100644
index 0000000..1c383fc
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/vcu118mig/vcu118mig.scala
@@ -0,0 +1,179 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.xilinx.vcu118mig
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// IP VLNV: xilinx.com:customize_ip:vcu118mig:1.0
+// Black Box
+
+class VCU118MIGIODDR(depth : BigInt) extends GenericParameterizedBundle(depth) {
+ require((depth<=0x80000000L),"VCU118MIGIODDR supports upto 2GB depth configuraton")
+ val c0_ddr4_adr = Bits(OUTPUT,17)
+ val c0_ddr4_bg = Bits(OUTPUT,1)
+ val c0_ddr4_ba = Bits(OUTPUT,2)
+ val c0_ddr4_reset_n = Bool(OUTPUT)
+ val c0_ddr4_act_n = Bool(OUTPUT)
+ val c0_ddr4_ck_c = Bits(OUTPUT,1)
+ val c0_ddr4_ck_t = Bits(OUTPUT,1)
+ val c0_ddr4_cke = Bits(OUTPUT,1)
+ val c0_ddr4_cs_n = Bits(OUTPUT,1)
+ val c0_ddr4_odt = Bits(OUTPUT,1)
+
+ val c0_ddr4_dq = Analog(64.W)
+ val c0_ddr4_dqs_c = Analog(8.W)
+ val c0_ddr4_dqs_t = Analog(8.W)
+ val c0_ddr4_dm_dbi_n = Analog(8.W)
+}
+
+//reused directly in io bundle for sifive.blocks.devices.xilinxvcu118mig
+trait VCU118MIGIOClocksReset extends Bundle {
+ //inputs
+ //"NO_BUFFER" clock source (must be connected to IBUF outside of IP)
+ val c0_sys_clk_i = Bool(INPUT)
+ //user interface signals
+ val c0_ddr4_ui_clk = Clock(OUTPUT)
+ val c0_ddr4_ui_clk_sync_rst = Bool(OUTPUT)
+ val c0_ddr4_aresetn = Bool(INPUT)
+ //misc
+ val c0_init_calib_complete = Bool(OUTPUT)
+ val sys_rst = Bool(INPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class vcu118mig(depth : BigInt)(implicit val p:Parameters) extends BlackBox
+{
+ require((depth<=0x80000000L),"vcu118mig supports upto 2GB depth configuraton")
+
+ val io = new VCU118MIGIODDR(depth) with VCU118MIGIOClocksReset {
+ //slave interface write address ports
+ val c0_ddr4_s_axi_awid = Bits(INPUT,4)
+ val c0_ddr4_s_axi_awaddr = Bits(INPUT,31)
+ val c0_ddr4_s_axi_awlen = Bits(INPUT,8)
+ val c0_ddr4_s_axi_awsize = Bits(INPUT,3)
+ val c0_ddr4_s_axi_awburst = Bits(INPUT,2)
+ val c0_ddr4_s_axi_awlock = Bits(INPUT,1)
+ val c0_ddr4_s_axi_awcache = Bits(INPUT,4)
+ val c0_ddr4_s_axi_awprot = Bits(INPUT,3)
+ val c0_ddr4_s_axi_awqos = Bits(INPUT,4)
+ val c0_ddr4_s_axi_awvalid = Bool(INPUT)
+ val c0_ddr4_s_axi_awready = Bool(OUTPUT)
+ //slave interface write data ports
+ val c0_ddr4_s_axi_wdata = Bits(INPUT,64)
+ val c0_ddr4_s_axi_wstrb = Bits(INPUT,8)
+ val c0_ddr4_s_axi_wlast = Bool(INPUT)
+ val c0_ddr4_s_axi_wvalid = Bool(INPUT)
+ val c0_ddr4_s_axi_wready = Bool(OUTPUT)
+ //slave interface write response ports
+ val c0_ddr4_s_axi_bready = Bool(INPUT)
+ val c0_ddr4_s_axi_bid = Bits(OUTPUT,4)
+ val c0_ddr4_s_axi_bresp = Bits(OUTPUT,2)
+ val c0_ddr4_s_axi_bvalid = Bool(OUTPUT)
+ //slave interface read address ports
+ val c0_ddr4_s_axi_arid = Bits(INPUT,4)
+ val c0_ddr4_s_axi_araddr = Bits(INPUT,31)
+ val c0_ddr4_s_axi_arlen = Bits(INPUT,8)
+ val c0_ddr4_s_axi_arsize = Bits(INPUT,3)
+ val c0_ddr4_s_axi_arburst = Bits(INPUT,2)
+ val c0_ddr4_s_axi_arlock = Bits(INPUT,1)
+ val c0_ddr4_s_axi_arcache = Bits(INPUT,4)
+ val c0_ddr4_s_axi_arprot = Bits(INPUT,3)
+ val c0_ddr4_s_axi_arqos = Bits(INPUT,4)
+ val c0_ddr4_s_axi_arvalid = Bool(INPUT)
+ val c0_ddr4_s_axi_arready = Bool(OUTPUT)
+ //slave interface read data ports
+ val c0_ddr4_s_axi_rready = Bool(INPUT)
+ val c0_ddr4_s_axi_rid = Bits(OUTPUT,4)
+ val c0_ddr4_s_axi_rdata = Bits(OUTPUT,64)
+ val c0_ddr4_s_axi_rresp = Bits(OUTPUT,2)
+ val c0_ddr4_s_axi_rlast = Bool(OUTPUT)
+ val c0_ddr4_s_axi_rvalid = Bool(OUTPUT)
+ }
+
+ ElaborationArtefacts.add(
+ "vcu118mig.vivado.tcl",
+ """
+ create_ip -vendor xilinx.com -library ip -version 2.2 -name ddr4 -module_name vcu118mig -dir $ipdir -force
+ set_property -dict [list \
+ CONFIG.AL_SEL {0} \
+ CONFIG.C0.ADDR_WIDTH {17} \
+ CONFIG.C0.BANK_GROUP_WIDTH {1} \
+ CONFIG.C0.CKE_WIDTH {1} \
+ CONFIG.C0.CK_WIDTH {1} \
+ CONFIG.C0.CS_WIDTH {1} \
+ CONFIG.C0.ControllerType {DDR4_SDRAM} \
+ CONFIG.C0.DDR4_AUTO_AP_COL_A3 {false} \
+ CONFIG.C0.DDR4_AutoPrecharge {false} \
+ CONFIG.C0.DDR4_AxiAddressWidth {31} \
+ CONFIG.C0.DDR4_AxiArbitrationScheme {RD_PRI_REG} \
+ CONFIG.C0.DDR4_AxiDataWidth {64} \
+ CONFIG.C0.DDR4_AxiIDWidth {4} \
+ CONFIG.C0.DDR4_AxiNarrowBurst {false} \
+ CONFIG.C0.DDR4_AxiSelection {true} \
+ CONFIG.C0.DDR4_BurstLength {8} \
+ CONFIG.C0.DDR4_BurstType {Sequential} \
+ CONFIG.C0.DDR4_CLKFBOUT_MULT {8} \
+ CONFIG.C0.DDR4_CLKOUT0_DIVIDE {5} \
+ CONFIG.C0.DDR4_Capacity {512} \
+ CONFIG.C0.DDR4_CasLatency {11} \
+ CONFIG.C0.DDR4_CasWriteLatency {9} \
+ CONFIG.C0.DDR4_ChipSelect {true} \
+ CONFIG.C0.DDR4_Clamshell {false} \
+ CONFIG.C0.DDR4_CustomParts {no_file_loaded} \
+ CONFIG.C0.DDR4_DIVCLK_DIVIDE {2} \
+ CONFIG.C0.DDR4_DataMask {DM_NO_DBI} \
+ CONFIG.C0.DDR4_DataWidth {64} \
+ CONFIG.C0.DDR4_Ecc {false} \
+ CONFIG.C0.DDR4_MCS_ECC {false} \
+ CONFIG.C0.DDR4_Mem_Add_Map {ROW_COLUMN_BANK} \
+ CONFIG.C0.DDR4_MemoryName {MainMemory} \
+ CONFIG.C0.DDR4_MemoryPart {MT40A256M16GE-083E} \
+ CONFIG.C0.DDR4_MemoryType {Components} \
+ CONFIG.C0.DDR4_MemoryVoltage {1.2V} \
+ CONFIG.C0.DDR4_OnDieTermination {RZQ/6} \
+ CONFIG.C0.DDR4_Ordering {Normal} \
+ CONFIG.C0.DDR4_OutputDriverImpedenceControl {RZQ/7} \
+ CONFIG.C0.DDR4_PhyClockRatio {4:1} \
+ CONFIG.C0.DDR4_SAVE_RESTORE {false} \
+ CONFIG.C0.DDR4_SELF_REFRESH {false} \
+ CONFIG.C0.DDR4_Slot {Single} \
+ CONFIG.C0.DDR4_Specify_MandD {true} \
+ CONFIG.C0.DDR4_TimePeriod {1250} \
+ CONFIG.C0.DDR4_UserRefresh_ZQCS {false} \
+ CONFIG.C0.DDR4_isCKEShared {false} \
+ CONFIG.C0.DDR4_isCustom {false} \
+ CONFIG.C0.LR_WIDTH {1} \
+ CONFIG.C0.ODT_WIDTH {1} \
+ CONFIG.C0.StackHeight {1} \
+ CONFIG.C0_CLOCK_BOARD_INTERFACE {Custom} \
+ CONFIG.C0_DDR4_BOARD_INTERFACE {Custom} \
+ CONFIG.DCI_Cascade {false} \
+ CONFIG.DIFF_TERM_SYSCLK {false} \
+ CONFIG.Debug_Signal {Disable} \
+ CONFIG.Default_Bank_Selections {false} \
+ CONFIG.Enable_SysPorts {true} \
+ CONFIG.IOPowerReduction {OFF} \
+ CONFIG.IO_Power_Reduction {false} \
+ CONFIG.IS_FROM_PHY {1} \
+ CONFIG.MCS_DBG_EN {false} \
+ CONFIG.No_Controller {1} \
+ CONFIG.PARTIAL_RECONFIG_FLOW_MIG {false} \
+ CONFIG.PING_PONG_PHY {1} \
+ CONFIG.Phy_Only {Complete_Memory_Controller} \
+ CONFIG.RECONFIG_XSDB_SAVE_RESTORE {false} \
+ CONFIG.RESET_BOARD_INTERFACE {Custom} \
+ CONFIG.Reference_Clock {Differential} \
+ CONFIG.SET_DW_TO_40 {false} \
+ CONFIG.System_Clock {No_Buffer} \
+ CONFIG.TIMING_3DS {false} \
+ CONFIG.TIMING_OP1 {false} \
+ CONFIG.TIMING_OP2 {false} \
+ ] [get_ips vcu118mig]"""
+ )
+
+}
+//scalastyle:on
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/xdma/xdma.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/xdma/xdma.scala
new file mode 100644
index 0000000..93e2677
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/xdma/xdma.scala
@@ -0,0 +1,469 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.xilinx.xdma
+
+import chisel3._
+import chisel3.util._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.interrupts._
+import freechips.rocketchip.util.{ElaborationArtefacts}
+
+trait HasXDMAPads {
+ def lanes: Int
+
+ val pci_exp_txp = Output(UInt(lanes.W))
+ val pci_exp_txn = Output(UInt(lanes.W))
+ val pci_exp_rxp = Input(UInt(lanes.W))
+ val pci_exp_rxn = Input(UInt(lanes.W))
+}
+
+trait HasXDMAClocks {
+ val sys_clk = Input(Clock()) //
+ val sys_clk_gt = Input(Clock()) // PCIe reference clock IBUFDS_GTE4.O
+ val sys_rst_n = Input(Bool())
+ val axi_aclk = Output(Clock())
+ val axi_aresetn = Output(Bool())
+}
+
+trait HasXDMAJunk {
+ val cfg_ltssm_state = Output(UInt(6.W))
+ val user_lnk_up = Output(Bool())
+ val axi_ctl_aresetn = Output(Bool()) // copy of axi_aresetn in RP mode
+}
+
+case class XDMABusParams(idBits: Int, addrBits: Int, dataBytes: Int)
+{
+ val dataBits = dataBytes*8
+}
+
+trait HasXDMABus {
+ def mbus: XDMABusParams
+ def sbus: XDMABusParams
+ def slbus: XDMABusParams
+
+ // I
+ val interrupt_out = Output(Bool())
+ val interrupt_out_msi_vec0to31 = Output(Bool())
+ val interrupt_out_msi_vec32to63 = Output(Bool())
+
+ // M.AW
+ val m_axib_awready = Input(Bool())
+ val m_axib_awvalid = Output(Bool())
+ val m_axib_awid = Output(UInt(mbus.idBits.W))
+ val m_axib_awaddr = Output(UInt(mbus.addrBits.W))
+ val m_axib_awlen = Output(UInt(8.W))
+ val m_axib_awsize = Output(UInt(3.W))
+ val m_axib_awburst = Output(UInt(2.W))
+ val m_axib_awprot = Output(UInt(3.W))
+ val m_axib_awcache = Output(UInt(4.W))
+ val m_axib_awlock = Output(Bool())
+
+ // M.AR
+ val m_axib_arready = Input(Bool())
+ val m_axib_arvalid = Output(Bool())
+ val m_axib_arid = Output(UInt(mbus.idBits.W))
+ val m_axib_araddr = Output(UInt(mbus.addrBits.W))
+ val m_axib_arlen = Output(UInt(8.W))
+ val m_axib_arsize = Output(UInt(3.W))
+ val m_axib_arburst = Output(UInt(2.W))
+ val m_axib_arprot = Output(UInt(3.W))
+ val m_axib_arcache = Output(UInt(4.W))
+ val m_axib_arlock = Output(Bool())
+
+ // M.W
+ val m_axib_wready = Input(Bool())
+ val m_axib_wvalid = Output(Bool())
+ val m_axib_wdata = Output(UInt(mbus.dataBits.W))
+ val m_axib_wstrb = Output(UInt(mbus.dataBytes.W))
+ val m_axib_wlast = Output(Bool())
+
+ // M.B
+ val m_axib_bready = Output(Bool())
+ val m_axib_bvalid = Input(Bool())
+ val m_axib_bid = Input(UInt(mbus.idBits.W))
+ val m_axib_bresp = Input(UInt(2.W))
+
+ // M.R
+ val m_axib_rready = Output(Bool())
+ val m_axib_rvalid = Input(Bool())
+ val m_axib_rid = Input(UInt(mbus.idBits.W))
+ val m_axib_rdata = Input(UInt(mbus.dataBits.W))
+ val m_axib_rresp = Input(UInt(2.W))
+ val m_axib_rlast = Input(Bool())
+
+ // S.AW
+ val s_axib_awready = Output(Bool())
+ val s_axib_awvalid = Input(Bool())
+ val s_axib_awid = Input(UInt(sbus.idBits.W))
+ val s_axib_awaddr = Input(UInt(sbus.addrBits.W))
+ val s_axib_awregion = Input(UInt(4.W))
+ val s_axib_awlen = Input(UInt(8.W))
+ val s_axib_awsize = Input(UInt(3.W))
+ val s_axib_awburst = Input(UInt(2.W))
+
+ // S.AR
+ val s_axib_arready = Output(Bool())
+ val s_axib_arvalid = Input(Bool())
+ val s_axib_arid = Input(UInt(sbus.idBits.W))
+ val s_axib_araddr = Input(UInt(sbus.addrBits.W))
+ val s_axib_arregion = Input(UInt(4.W))
+ val s_axib_arlen = Input(UInt(8.W))
+ val s_axib_arsize = Input(UInt(3.W))
+ val s_axib_arburst = Input(UInt(2.W))
+
+ // S.W
+ val s_axib_wready = Output(Bool())
+ val s_axib_wvalid = Input(Bool())
+ val s_axib_wdata = Input(UInt(sbus.dataBits.W))
+ val s_axib_wstrb = Input(UInt(sbus.dataBytes.W))
+ val s_axib_wlast = Input(Bool())
+
+ // S.B
+ val s_axib_bready = Input(Bool())
+ val s_axib_bvalid = Output(Bool())
+ val s_axib_bid = Output(UInt(sbus.idBits.W))
+ val s_axib_bresp = Output(UInt(2.W))
+
+ // S.R
+ val s_axib_rready = Input(Bool())
+ val s_axib_rvalid = Output(Bool())
+ val s_axib_rid = Output(UInt(sbus.idBits.W))
+ val s_axib_rdata = Output(UInt(sbus.dataBits.W))
+ val s_axib_rresp = Output(UInt(2.W))
+ val s_axib_rlast = Output(Bool())
+
+ // SL.AW
+ val s_axil_awready = Output(Bool())
+ val s_axil_awvalid = Input(Bool())
+ val s_axil_awaddr = Input(UInt(slbus.addrBits.W))
+ val s_axil_awprot = Input(UInt(3.W))
+
+ // SL.AR
+ val s_axil_arready = Output(Bool())
+ val s_axil_arvalid = Input(Bool())
+ val s_axil_araddr = Input(UInt(slbus.addrBits.W))
+ val s_axil_arprot = Input(UInt(3.W))
+
+ // SL.W
+ val s_axil_wready = Output(Bool())
+ val s_axil_wvalid = Input(Bool())
+ val s_axil_wdata = Input(UInt(slbus.dataBits.W))
+ val s_axil_wstrb = Input(UInt(slbus.dataBytes.W))
+
+ // SL.B
+ val s_axil_bready = Input(Bool())
+ val s_axil_bvalid = Output(Bool())
+ val s_axil_bresp = Output(UInt(2.W))
+
+ // SL.R
+ val s_axil_rready = Input(Bool())
+ val s_axil_rvalid = Output(Bool())
+ val s_axil_rdata = Output(UInt(slbus.dataBits.W))
+ val s_axil_rresp = Output(UInt(2.W))
+}
+
+class XDMABlackBoxIO(
+ val lanes: Int,
+ val mbus: XDMABusParams,
+ val sbus: XDMABusParams,
+ val slbus: XDMABusParams) extends Bundle
+ with HasXDMAPads
+ with HasXDMAClocks
+ with HasXDMAJunk
+ with HasXDMABus
+
+class XDMAPads(val lanes: Int) extends Bundle with HasXDMAPads
+class XDMAClocks() extends Bundle with HasXDMAClocks
+
+case class XDMAParams(
+ name: String,
+ location: String,
+ bars: Seq[AddressSet],
+ control: BigInt,
+ lanes: Int = 1,
+ gen: Int = 3,
+ addrBits: Int = 64,
+ mIDBits: Int = 4,
+ sIDBits: Int = 4)
+{
+ require (!bars.isEmpty)
+ require (lanes >= 1 && lanes <= 16 && isPow2(lanes))
+ require (gen >= 1 && gen <= 3)
+ require (addrBits == 32 || addrBits == 64)
+ require (mIDBits >= 1 && mIDBits <= 8)
+ require (sIDBits >= 1 && sIDBits <= 8)
+ bars.foreach { a => require (a.max >> addrBits == 0) }
+
+ private val bandwidth = lanes * 250 << (gen-1) // MB/s
+ private val busBytesAt250MHz = bandwidth / 250
+ val busBytes = busBytesAt250MHz max 8
+ private val minMHz = 250.0 * busBytesAt250MHz / busBytes
+ val axiMHz = minMHz max 62.5
+
+ val ecamSize = 0x4000000
+ val ecamMask = ecamSize - 1
+ require ((control & ecamMask) == 0)
+}
+
+class XDMABlackBox(c: XDMAParams) extends BlackBox
+{
+ override def desiredName = c.name
+
+ val mbus = XDMABusParams(c.mIDBits, c.addrBits, c.busBytes)
+ val sbus = XDMABusParams(c.sIDBits, c.addrBits, c.busBytes)
+ val slbus = XDMABusParams(0, 32, 4)
+
+ val io = IO(new XDMABlackBoxIO(c.lanes, mbus, sbus, slbus))
+ val pcieGTs = c.gen match {
+ case 1 => "2.5_GT/s"
+ case 2 => "5.0_GT/s"
+ case 3 => "8.0_GT/s"
+ case _ => "wrong"
+ }
+
+ // 62.5, 125, 250 (no trailing zeros)
+ val formatter = new java.text.DecimalFormat("0.###")
+ val axiMHzStr = formatter.format(c.axiMHz)
+
+ val bars = c.bars.zipWithIndex.map { case (a, i) =>
+ f""" CONFIG.axibar_${i} {0x${a.base}%X} \\
+ | CONFIG.axibar_highaddr_${i} {0x${a.max}%X} \\
+ | CONFIG.axibar2pciebar_${i} {0x${a.base}%X} \\
+ |""".stripMargin
+ }
+
+ ElaborationArtefacts.add(s"${desiredName}.vivado.tcl",
+ s"""create_ip -vendor xilinx.com -library ip -version 4.1 -name xdma -module_name ${desiredName} -dir $$ipdir -force
+ |set_property -dict [list \\
+ | CONFIG.functional_mode {AXI_Bridge} \\
+ | CONFIG.pcie_blk_locn {${c.location}} \\
+ | CONFIG.device_port_type {Root_Port_of_PCI_Express_Root_Complex} \\
+ | CONFIG.pf0_bar0_enabled {false} \\
+ | CONFIG.pf0_sub_class_interface_menu {PCI_to_PCI_bridge} \\
+ | CONFIG.ref_clk_freq {100_MHz} \\
+ | CONFIG.pl_link_cap_max_link_width {X${c.lanes}} \\
+ | CONFIG.pl_link_cap_max_link_speed {${pcieGTs}} \\
+ | CONFIG.msi_rx_pin_en {true} \\
+ | CONFIG.axisten_freq {${axiMHzStr}} \\
+ | CONFIG.axi_addr_width {${c.addrBits}} \\
+ | CONFIG.axi_data_width {${c.busBytes*8}_bit} \\
+ | CONFIG.axi_id_width {${c.mIDBits}} \\
+ | CONFIG.s_axi_id_width {${c.sIDBits}} \\
+ | CONFIG.axibar_num {${c.bars.size}} \\
+ |${bars.mkString}] [get_ips ${desiredName}]
+ |""".stripMargin)
+}
+
+class DiplomaticXDMA(c: XDMAParams)(implicit p:Parameters) extends LazyModule
+{
+ val device = new SimpleDevice("pci", Seq("xlnx,xdma-host-3.00")) {
+ override def describe(resources: ResourceBindings): Description = {
+ val Description(name, mapping) = super.describe(resources)
+ val intc = s"${c.name}_intc"
+ def ofInt(x: Int) = Seq(ResourceInt(BigInt(x)))
+ def ofMap(x: Int) = Seq(0, 0, 0, x).flatMap(ofInt) ++ Seq(ResourceReference(intc)) ++ ofInt(x)
+ val extra = Map(
+ "#address-cells" -> ofInt(3),
+ "#size-cells" -> ofInt(2),
+ "#interrupt-cells" -> ofInt(1),
+ "device_type" -> Seq(ResourceString("pci")),
+ "interrupt-names" -> Seq("misc", "msi0", "msi1").map(ResourceString.apply _),
+ "interrupt-map-mask" -> Seq(0, 0, 0, 7).flatMap(ofInt),
+ "interrupt-map" -> Seq(1, 2, 3, 4).flatMap(ofMap),
+ "ranges" -> resources("ranges").map(x =>
+ (x: @unchecked) match { case Binding(_, ResourceAddress(address, perms)) =>
+ ResourceMapping(address, BigInt(0x02000000) << 64, perms) }),
+ "interrupt-controller" -> Seq(ResourceMap(labels = Seq(intc), value = Map(
+ "interrupt-controller" -> Nil,
+ "#address-cells" -> ofInt(0),
+ "#interrupt-cells" -> ofInt(1)))))
+ Description(name, mapping ++ extra)
+ }
+ }
+
+ val slave = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = c.bars,
+ resources = Seq(Resource(device, "ranges")),
+ executable = true,
+ supportsWrite = TransferSizes(1, 128),
+ supportsRead = TransferSizes(1, 128))),
+ beatBytes = c.busBytes)))
+
+ val control = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = List(AddressSet(c.control, c.ecamMask)),
+ resources = device.reg("control"),
+ supportsWrite = TransferSizes(1, 4),
+ supportsRead = TransferSizes(1, 4),
+ interleavedId = Some(0))), // AXI4-Lite never interleaves responses
+ beatBytes = 4)))
+
+ val master = AXI4MasterNode(Seq(AXI4MasterPortParameters(
+ masters = Seq(AXI4MasterParameters(
+ name = c.name,
+ id = IdRange(0, 1 << c.mIDBits),
+ aligned = false)))))
+
+ val intnode = IntSourceNode(IntSourcePortSimple(num = 3, resources = device.int))
+
+ lazy val module = new LazyRawModuleImp(this) {
+ // The master on the control port must be AXI-lite
+ require (control.edges.in(0).master.endId == 1)
+ // Must have the right number of slave idBits
+ require (slave.edges.in(0).bundle.idBits <= c.sIDBits)
+ // Must have the right bus width
+ require (master.edges.out(0).slave.beatBytes == c.busBytes)
+
+ val io = IO(new Bundle {
+ val pads = new XDMAPads(c.lanes)
+ val clocks = new XDMAClocks
+ })
+
+ val blackbox = Module(new XDMABlackBox(c))
+
+ val (s, _) = slave.in(0)
+ val (t, _) = control.in(0)
+ val (m, _) = master.out(0)
+ val (i, _) = intnode.out(0)
+
+ // Pads
+ io.pads.pci_exp_txp := blackbox.io.pci_exp_txp
+ io.pads.pci_exp_txn := blackbox.io.pci_exp_txn
+ blackbox.io.pci_exp_rxp := io.pads.pci_exp_rxp
+ blackbox.io.pci_exp_rxn := io.pads.pci_exp_rxn
+
+ // Clocks
+ blackbox.io.sys_clk := io.clocks.sys_clk
+ blackbox.io.sys_clk_gt := io.clocks.sys_clk_gt
+ blackbox.io.sys_rst_n := io.clocks.sys_rst_n
+ io.clocks.axi_aclk := blackbox.io.axi_aclk
+ io.clocks.axi_aresetn := blackbox.io.axi_aresetn
+
+ // I
+ i(0) := blackbox.io.interrupt_out
+ i(1) := blackbox.io.interrupt_out_msi_vec0to31
+ i(2) := blackbox.io.interrupt_out_msi_vec32to63
+
+ // M.AW
+ blackbox.io.m_axib_awready := m.aw.ready
+ m.aw.valid := blackbox.io.m_axib_awvalid
+ m.aw.bits.id := blackbox.io.m_axib_awid
+ m.aw.bits.addr := blackbox.io.m_axib_awaddr
+ m.aw.bits.len := blackbox.io.m_axib_awlen
+ m.aw.bits.size := blackbox.io.m_axib_awsize
+ m.aw.bits.burst := blackbox.io.m_axib_awburst
+ m.aw.bits.prot := blackbox.io.m_axib_awprot
+ m.aw.bits.cache := blackbox.io.m_axib_awcache
+ m.aw.bits.lock := blackbox.io.m_axib_awlock
+ m.aw.bits.qos := 0.U
+
+ // M.AR
+ blackbox.io.m_axib_arready := m.ar.ready
+ m.ar.valid := blackbox.io.m_axib_arvalid
+ m.ar.bits.id := blackbox.io.m_axib_arid
+ m.ar.bits.addr := blackbox.io.m_axib_araddr
+ m.ar.bits.len := blackbox.io.m_axib_arlen
+ m.ar.bits.size := blackbox.io.m_axib_arsize
+ m.ar.bits.burst := blackbox.io.m_axib_arburst
+ m.ar.bits.prot := blackbox.io.m_axib_arprot
+ m.ar.bits.cache := blackbox.io.m_axib_arcache
+ m.ar.bits.lock := blackbox.io.m_axib_arlock
+ m.ar.bits.qos := 0.U
+
+ // M.W
+ blackbox.io.m_axib_wready := m.w.ready
+ m.w.valid := blackbox.io.m_axib_wvalid
+ m.w.bits.data := blackbox.io.m_axib_wdata
+ m.w.bits.strb := blackbox.io.m_axib_wstrb
+ m.w.bits.last := blackbox.io.m_axib_wlast
+
+ // M.B
+ m.b.ready := blackbox.io.m_axib_bready
+ blackbox.io.m_axib_bvalid := m.b.valid
+ blackbox.io.m_axib_bid := m.b.bits.id
+ blackbox.io.m_axib_bresp := m.b.bits.resp
+
+ // M.R
+ m.r.ready := blackbox.io.m_axib_rready
+ blackbox.io.m_axib_rvalid := m.r.valid
+ blackbox.io.m_axib_rid := m.r.bits.id
+ blackbox.io.m_axib_rdata := m.r.bits.data
+ blackbox.io.m_axib_rresp := m.r.bits.resp
+ blackbox.io.m_axib_rlast := m.r.bits.last
+
+ // S.AW
+ s.aw.ready := blackbox.io.s_axib_awready
+ blackbox.io.s_axib_awvalid := s.aw.valid
+ blackbox.io.s_axib_awid := s.aw.bits.id
+ blackbox.io.s_axib_awaddr := s.aw.bits.addr
+ blackbox.io.s_axib_awregion := 0.U
+ blackbox.io.s_axib_awlen := s.aw.bits.len
+ blackbox.io.s_axib_awsize := s.aw.bits.size
+ blackbox.io.s_axib_awburst := s.aw.bits.burst
+
+ // S.AR
+ s.ar.ready := blackbox.io.s_axib_arready
+ blackbox.io.s_axib_arvalid := s.ar.valid
+ blackbox.io.s_axib_arid := s.ar.bits.id
+ blackbox.io.s_axib_araddr := s.ar.bits.addr
+ blackbox.io.s_axib_arregion := 0.U
+ blackbox.io.s_axib_arlen := s.ar.bits.len
+ blackbox.io.s_axib_arsize := s.ar.bits.size
+ blackbox.io.s_axib_arburst := s.ar.bits.burst
+
+ // S.W
+ s.w.ready := blackbox.io.s_axib_wready
+ blackbox.io.s_axib_wvalid := s.w.valid
+ blackbox.io.s_axib_wdata := s.w.bits.data
+ blackbox.io.s_axib_wstrb := s.w.bits.strb
+ blackbox.io.s_axib_wlast := s.w.bits.last
+
+ // S.B
+ blackbox.io.s_axib_bready := s.b.ready
+ s.b.valid := blackbox.io.s_axib_bvalid
+ s.b.bits.id := blackbox.io.s_axib_bid
+ s.b.bits.resp := blackbox.io.s_axib_bresp
+
+ // S.R
+ blackbox.io.s_axib_rready := s.r.ready
+ s.r.valid := blackbox.io.s_axib_rvalid
+ s.r.bits.id := blackbox.io.s_axib_rid
+ s.r.bits.data := blackbox.io.s_axib_rdata
+ s.r.bits.resp := blackbox.io.s_axib_rresp
+ s.r.bits.last := blackbox.io.s_axib_rlast
+
+ // SL.AW
+ t.aw.ready := blackbox.io.s_axil_awready
+ blackbox.io.s_axil_awvalid := t.aw.valid
+ blackbox.io.s_axil_awaddr := t.aw.bits.addr & c.ecamMask.U
+ blackbox.io.s_axil_awprot := t.aw.bits.prot
+
+ // SL.AR
+ t.ar.ready := blackbox.io.s_axil_arready
+ blackbox.io.s_axil_arvalid := t.ar.valid
+ blackbox.io.s_axil_araddr := t.ar.bits.addr & c.ecamMask.U
+ blackbox.io.s_axil_arprot := t.ar.bits.prot
+
+ // SL.W
+ t.w.ready := blackbox.io.s_axil_wready
+ blackbox.io.s_axil_wvalid := t.w.valid
+ blackbox.io.s_axil_wdata := t.w.bits.data
+ blackbox.io.s_axil_wstrb := t.w.bits.strb
+
+ // SL.B
+ blackbox.io.s_axil_bready := t.b.ready
+ t.b.valid := blackbox.io.s_axil_bvalid
+ t.b.bits.id := 0.U
+ t.b.bits.resp := blackbox.io.s_axil_bresp
+
+ // SL.R
+ blackbox.io.s_axil_rready := t.r.ready
+ t.r.valid := blackbox.io.s_axil_rvalid
+ t.r.bits.id := 0.U
+ t.r.bits.data := blackbox.io.s_axil_rdata
+ t.r.bits.resp := blackbox.io.s_axil_rresp
+ t.r.bits.last := true.B
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/xxv_ethernet/nfmac10g.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/xxv_ethernet/nfmac10g.scala
new file mode 100644
index 0000000..2ddddcf
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/xxv_ethernet/nfmac10g.scala
@@ -0,0 +1,52 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.xilinx.xxv_ethernet
+
+import chisel3._
+import chisel3.util._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+
+class nfmac10g extends BlackBox {
+ val io = IO(new Bundle {
+ val tx_clk0 = Input(Clock())
+ val rx_clk0 = Input(Clock())
+ val reset = Input(Bool())
+ val tx_dcm_locked = Input(Bool())
+ val rx_dcm_locked = Input(Bool())
+
+ // XGMII
+ val xgmii_txd = Output(UInt(64.W))
+ val xgmii_txc = Output(UInt(8.W))
+ val xgmii_rxd = Input (UInt(64.W))
+ val xgmii_rxc = Input (UInt(8.W))
+
+ // Tx AXIS
+ val tx_axis_aresetn = Input (Bool())
+ val tx_axis_tready = Output(Bool())
+ val tx_axis_tvalid = Input (Bool())
+ val tx_axis_tlast = Input (Bool())
+ val tx_axis_tdata = Input (UInt(64.W))
+ val tx_axis_tkeep = Input (UInt(8.W))
+ val tx_axis_tuser = Input (UInt(1.W))
+
+ // Rx AXIS
+ val rx_axis_aresetn = Input (Bool())
+ val rx_axis_tvalid = Output(Bool())
+ val rx_axis_tlast = Output(Bool())
+ val rx_axis_tdata = Output(UInt(64.W))
+ val rx_axis_tkeep = Output(UInt(8.W))
+ val rx_axis_tuser = Output(UInt(1.W))
+
+ // Unused by nfmac10g
+ val tx_ifg_delay = Input(UInt(8.W))
+ val pause_val = Input(UInt(16.W))
+ val pause_req = Input(Bool())
+ val tx_configuration_vector = Input(UInt(80.W))
+ val rx_configuration_vector = Input(UInt(80.W))
+ val status_vector = Output(UInt(2.W))
+ val tx_statistics_vector = Output(UInt(26.W))
+ val tx_statistics_valid = Output(Bool())
+ val rx_statistics_vector = Output(UInt(30.W))
+ val rx_statistics_valid = Output(Bool())
+ })
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/xxv_ethernet/xxv_ethernet.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/xxv_ethernet/xxv_ethernet.scala
new file mode 100644
index 0000000..47d75e7
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/ip/xilinx/xxv_ethernet/xxv_ethernet.scala
@@ -0,0 +1,177 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.xilinx.xxv_ethernet
+
+import chisel3._
+import chisel3.util._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.util.{ElaborationArtefacts}
+
+trait HasXXVEthernetPads {
+ val gt_txp_out_0 = Output(Bool())
+ val gt_txn_out_0 = Output(Bool())
+ val gt_rxp_in_0 = Input(Bool())
+ val gt_rxn_in_0 = Input(Bool())
+ val gt_refclk_p = Input(Clock())
+ val gt_refclk_n = Input(Clock())
+}
+
+trait HasXXVEthernetClocks {
+ val rx_core_clk_0 = Input (Clock()) // >= 156.25MHz ... maybe core clock to avoid another crossing?
+ val tx_mii_clk_0 = Output(Clock()) // TX data path
+
+ val sys_reset = Input(Bool())
+ val dclk = Input(Clock()) // free-running fsm clock
+
+ val user_rx_reset_0 = Output(Bool())
+ val user_tx_reset_0 = Output(Bool())
+}
+
+trait HasXXVEthernetMAC {
+ val rx_mii_d_0 = Output(UInt(64.W))
+ val tx_mii_d_0 = Input (UInt(64.W))
+ val rx_mii_c_0 = Output(UInt(8.W))
+ val tx_mii_c_0 = Input (UInt(8.W))
+
+ val gt_loopback_in_0 = Input(UInt(3.W))
+ val stat_rx_block_lock_0 = Output(Bool())
+}
+
+trait HasXXVEthernetJunk {
+ // Unused loopback test stuff
+ val ctl_rx_test_pattern_0 = Input(Bool())
+ val ctl_rx_test_pattern_enable_0 = Input(Bool())
+ val ctl_rx_data_pattern_select_0 = Input(Bool())
+ val ctl_rx_prbs31_test_pattern_enable_0 = Input(Bool())
+
+ val ctl_tx_test_pattern_0 = Input(Bool())
+ val ctl_tx_test_pattern_enable_0 = Input(Bool())
+ val ctl_tx_test_pattern_select_0 = Input(Bool())
+ val ctl_tx_data_pattern_select_0 = Input(Bool())
+ val ctl_tx_test_pattern_seed_a_0 = Input(UInt(58.W))
+ val ctl_tx_test_pattern_seed_b_0 = Input(UInt(58.W))
+ val ctl_tx_prbs31_test_pattern_enable_0 = Input(Bool())
+
+ // Drive these always to 0
+ val rx_reset_0 = Input(Bool())
+ val tx_reset_0 = Input(Bool())
+ val gtwiz_reset_tx_datapath_0 = Input(Bool())
+ val gtwiz_reset_rx_datapath_0 = Input(Bool())
+
+ val gtpowergood_out_0 = Output(Bool())
+ val gt_refclk_out = Output(Clock()) // 156.25MHz from xcvr refclk pads
+ val rx_clk_out_0 = Output(Clock()) // RX control+status signals
+ val rxrecclkout_0 = Output(Clock())
+
+ // Drive these always to 3'b101 as per documentation
+ val txoutclksel_in_0 = Input(UInt(3.W))
+ val rxoutclksel_in_0 = Input(UInt(3.W))
+
+ val stat_rx_framing_err_valid_0 = Output(Bool())
+ val stat_rx_framing_err_0 = Output(Bool())
+ val stat_rx_hi_ber_0 = Output(Bool())
+ val stat_rx_valid_ctrl_code_0 = Output(Bool())
+ val stat_rx_bad_code_0 = Output(Bool())
+ val stat_rx_bad_code_valid_0 = Output(Bool())
+ val stat_rx_error_valid_0 = Output(Bool())
+ val stat_rx_error_0 = Output(UInt(8.W))
+ val stat_rx_fifo_error_0 = Output(Bool())
+ val stat_rx_local_fault_0 = Output(Bool())
+ val stat_rx_status_0 = Output(Bool())
+ val stat_tx_local_fault_0 = Output(Bool())
+}
+
+class XXVEthernetBlackBoxIO extends Bundle
+ with HasXXVEthernetPads
+ with HasXXVEthernetClocks
+ with HasXXVEthernetMAC
+ with HasXXVEthernetJunk
+
+class XXVEthernetPads() extends Bundle with HasXXVEthernetPads
+class XXVEthernetMAC() extends Bundle with HasXXVEthernetMAC
+class XXVEthernetClocks() extends Bundle with HasXXVEthernetClocks
+
+case class XXVEthernetParams(
+ name: String,
+ speed: Int,
+ dclkMHz: Double)
+{
+ require (speed == 10 || speed == 25)
+ val refMHz = if (speed == 10) 156.25 else 161.1328125
+}
+
+class XXVEthernetBlackBox(c: XXVEthernetParams) extends BlackBox
+{
+ override def desiredName = c.name
+
+ val io = IO(new XXVEthernetBlackBoxIO)
+
+ ElaborationArtefacts.add(s"${desiredName}.vivado.tcl",
+ s"""create_ip -vendor xilinx.com -library ip -version 2.4 -name xxv_ethernet -module_name ${desiredName} -dir $$ipdir -force
+ |set_property -dict [list \\
+ | CONFIG.NUM_OF_CORES {1} \\
+ | CONFIG.CORE {Ethernet PCS/PMA 64-bit} \\
+ | CONFIG.BASE_R_KR {BASE-R} \\
+ | CONFIG.LINE_RATE {${c.speed}} \\
+ | CONFIG.GT_REF_CLK_FREQ {${c.refMHz}} \\
+ | CONFIG.GT_DRP_CLK {${c.dclkMHz}} \\
+ |] [get_ips ${desiredName}]
+ |""".stripMargin)
+}
+
+class DiplomaticXXVEthernet(c: XXVEthernetParams)(implicit p:Parameters) extends LazyModule
+{
+ lazy val module = new LazyRawModuleImp(this) {
+ val io = IO(new Bundle {
+ val pads = new XXVEthernetPads
+ val mac = new XXVEthernetMAC
+ val clocks = new XXVEthernetClocks
+ })
+
+ val blackbox = Module(new XXVEthernetBlackBox(c))
+
+ // pads
+ io.pads.gt_txp_out_0 := blackbox.io.gt_txp_out_0
+ io.pads.gt_txn_out_0 := blackbox.io.gt_txn_out_0
+ blackbox.io.gt_rxp_in_0 := io.pads.gt_rxp_in_0
+ blackbox.io.gt_rxn_in_0 := io.pads.gt_rxn_in_0
+ blackbox.io.gt_refclk_p := io.pads.gt_refclk_p
+ blackbox.io.gt_refclk_n := io.pads.gt_refclk_n
+
+ // clocks
+ io.clocks.tx_mii_clk_0 := blackbox.io.tx_mii_clk_0
+ io.clocks.user_rx_reset_0 := blackbox.io.user_rx_reset_0
+ io.clocks.user_tx_reset_0 := blackbox.io.user_tx_reset_0
+ blackbox.io.rx_core_clk_0 := io.clocks.rx_core_clk_0
+ blackbox.io.sys_reset := io.clocks.sys_reset
+ blackbox.io.dclk := io.clocks.dclk
+
+ // MAC
+ blackbox.io.tx_mii_d_0 := io.mac.tx_mii_d_0
+ blackbox.io.tx_mii_c_0 := io.mac.tx_mii_c_0
+ io.mac.rx_mii_d_0 := blackbox.io.rx_mii_d_0
+ io.mac.rx_mii_c_0 := blackbox.io.rx_mii_c_0
+ blackbox.io.gt_loopback_in_0 := io.mac.gt_loopback_in_0
+ io.mac.stat_rx_block_lock_0 := blackbox.io.stat_rx_block_lock_0
+
+ // Junk
+ blackbox.io.txoutclksel_in_0 := 5.U
+ blackbox.io.rxoutclksel_in_0 := 5.U
+ blackbox.io.rx_reset_0 := io.clocks.sys_reset
+ blackbox.io.tx_reset_0 := io.clocks.sys_reset
+ blackbox.io.gtwiz_reset_tx_datapath_0 := io.clocks.sys_reset
+ blackbox.io.gtwiz_reset_rx_datapath_0 := io.clocks.sys_reset
+ blackbox.io.ctl_rx_test_pattern_0 := false.B
+ blackbox.io.ctl_rx_test_pattern_enable_0 := false.B
+ blackbox.io.ctl_rx_data_pattern_select_0 := false.B
+ blackbox.io.ctl_rx_prbs31_test_pattern_enable_0 := false.B
+ blackbox.io.ctl_tx_test_pattern_0 := false.B
+ blackbox.io.ctl_tx_test_pattern_enable_0 := false.B
+ blackbox.io.ctl_tx_test_pattern_select_0 := false.B
+ blackbox.io.ctl_tx_data_pattern_select_0 := false.B
+ blackbox.io.ctl_tx_test_pattern_seed_a_0 := 0.U
+ blackbox.io.ctl_tx_test_pattern_seed_b_0 := 0.U
+ blackbox.io.ctl_tx_prbs31_test_pattern_enable_0 := false.B
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/ButtonOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/ButtonOverlay.scala
new file mode 100644
index 0000000..df7021c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/ButtonOverlay.scala
@@ -0,0 +1,28 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+
+case class ButtonShellInput(
+ header: String = "",
+ number: Int = 0)
+
+case class ButtonDesignInput()(implicit val p: Parameters)
+case class ButtonOverlayOutput(but: ModuleValue[Bool])
+case object ButtonOverlayKey extends Field[Seq[DesignPlacer[ButtonDesignInput, ButtonShellInput, ButtonOverlayOutput]]](Nil)
+trait ButtonShellPlacer[Shell] extends ShellPlacer[ButtonDesignInput, ButtonShellInput, ButtonOverlayOutput]
+
+abstract class ButtonPlacedOverlay(
+ val name: String, val di: ButtonDesignInput, si:ButtonShellInput)
+ extends IOPlacedOverlay[Bool, ButtonDesignInput, ButtonShellInput, ButtonOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = Input(Bool())
+
+ val buttonSource = shell { BundleBridgeSource(() => Bool()) }
+ val buttonSink = buttonSource.makeSink()
+ def overlayOutput = ButtonOverlayOutput(but = InModuleBody { buttonSink.bundle })
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/CTSResetOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/CTSResetOverlay.scala
new file mode 100644
index 0000000..fa2762e
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/CTSResetOverlay.scala
@@ -0,0 +1,23 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+
+//Core-To-Shell Reset Overlay: No IOs, but passes a Bool into the shell to be orred into the pllReset, allowing core signals to reset the shell
+
+case class CTSResetShellInput()
+case class CTSResetDesignInput(rst: Bool)(implicit val p: Parameters)
+case class CTSResetOverlayOutput()
+case object CTSResetOverlayKey extends Field[Seq[DesignPlacer[CTSResetDesignInput, CTSResetShellInput, CTSResetOverlayOutput]]](Nil)
+trait CTSResetShellPlacer[Shell] extends ShellPlacer[CTSResetDesignInput, CTSResetShellInput, CTSResetOverlayOutput]
+
+abstract class CTSResetPlacedOverlay(
+ val name: String, val di: CTSResetDesignInput, si: CTSResetShellInput)
+ extends PlacedOverlay[CTSResetDesignInput, CTSResetShellInput, CTSResetOverlayOutput]
+{
+ implicit val p = di.p
+
+ def overlayOutput = CTSResetOverlayOutput()
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/ChipLinkOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/ChipLinkOverlay.scala
new file mode 100644
index 0000000..290f0d0
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/ChipLinkOverlay.scala
@@ -0,0 +1,58 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import sifive.blocks.devices.chiplink._
+import sifive.fpgashells.clocks._
+
+case class ChipLinkShellInput(
+ fmc: String = "")
+
+case class ChipLinkDesignInput(
+ di: ChipLinkParams,
+ txGroup: ClockGroupNode,
+ txData: ClockSinkNode,
+ wrangler: ClockAdapterNode)(
+ implicit val p: Parameters)
+
+case class ChipLinkOverlayOutput(node: TLNode)
+case object ChipLinkOverlayKey extends Field[Seq[DesignPlacer[ChipLinkDesignInput, ChipLinkShellInput, ChipLinkOverlayOutput]]](Nil)
+trait ChipLinkShellPlacer[Shell] extends ShellPlacer[ChipLinkDesignInput, ChipLinkShellInput, ChipLinkOverlayOutput]
+
+abstract class ChipLinkPlacedOverlay(
+ val name: String,
+ val di: ChipLinkDesignInput,
+ val si: ChipLinkShellInput,
+ val rxPhase: Double,
+ val txPhase: Double)
+ extends IOPlacedOverlay[WideDataLayerPort, ChipLinkDesignInput, ChipLinkShellInput, ChipLinkOverlayOutput]
+{
+ implicit val p = di.p
+ val freqMHz = di.txData.portParams.head.take.get.freqMHz
+ val phaseDeg = di.txData.portParams.head.phaseDeg
+
+ def fpgaReset = false
+ val link = LazyModule(new ChipLink(di.di.copy(fpgaReset = fpgaReset)))
+ val rxPLL = p(PLLFactoryKey)(feedback = true)
+ val ioSink = shell { link.ioNode.makeSink() }
+ val rxI = shell { ClockSourceNode(freqMHz = freqMHz, jitterPS = 100) }
+ val rxGroup = shell { ClockGroup() }
+ val rxO = shell { ClockSinkNode(freqMHz = freqMHz, phaseDeg = rxPhase) }
+ val txClock = shell { ClockSinkNode(freqMHz = freqMHz, phaseDeg = phaseDeg + txPhase) }
+
+ rxO := di.wrangler := rxGroup := rxPLL := rxI
+ txClock := di.wrangler := di.txGroup
+
+ def overlayOutput = ChipLinkOverlayOutput(node = link.node)
+ def ioFactory = new WideDataLayerPort(ChipLinkParams(Nil,Nil))
+
+ shell { InModuleBody {
+ val (rxOut, _) = rxO.in(0)
+ val port = ioSink.bundle
+ io <> port
+ port.b2c.clk := rxOut.clock
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/ClockOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/ClockOverlay.scala
new file mode 100644
index 0000000..b2fce1d
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/ClockOverlay.scala
@@ -0,0 +1,81 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.clocks._
+
+case class ClockInputShellInput()
+case class ClockOutputShellInput()
+case class ClockInputDesignInput()(implicit val p: Parameters)
+case class ClockOutputDesignInput()(implicit val p: Parameters)
+case class ClockInputOverlayOutput(node: ClockSourceNode)
+case class ClockOutputOverlayOutput(clock: ClockSinkNode)
+
+trait ClockInputShellPlacer[Shell] extends ShellPlacer[ClockInputDesignInput, ClockInputShellInput, ClockInputOverlayOutput]
+trait ClockOutputShellPlacer[Shell] extends ShellPlacer[ClockOutputDesignInput, ClockOutputShellInput, ClockOutputOverlayOutput]
+
+case object ClockInputOverlayKey extends Field[Seq[DesignPlacer[ClockInputDesignInput, ClockInputShellInput, ClockInputOverlayOutput]]](Nil)
+case object ClockOutputOverlayKey extends Field[Seq[DesignPlacer[ClockOutputDesignInput, ClockOutputShellInput, ClockOutputOverlayOutput]]](Nil)
+
+class LVDSClock extends Bundle
+{
+ val p = Clock()
+ val n = Clock()
+}
+
+abstract class LVDSClockInputPlacedOverlay(
+ val name: String, val di: ClockInputDesignInput, val si: ClockInputShellInput)
+ extends IOPlacedOverlay[LVDSClock, ClockInputDesignInput, ClockInputShellInput, ClockInputOverlayOutput]
+{
+ implicit val p = di.p
+ def node: ClockSourceNode
+
+ def ioFactory = Input(new LVDSClock)
+
+ val clock = shell { InModuleBody {
+ val (bundle, edge) = node.out.head
+ shell.sdc.addClock(name, io.p, edge.clock.freqMHz)
+ bundle.clock
+ } }
+ def overlayOutput = ClockInputOverlayOutput(node)
+}
+
+
+abstract class SingleEndedClockInputPlacedOverlay(
+ val name: String, val di: ClockInputDesignInput, val si: ClockInputShellInput)
+ extends IOPlacedOverlay[Clock, ClockInputDesignInput, ClockInputShellInput, ClockInputOverlayOutput]
+{
+ implicit val p = di.p
+ def node: ClockSourceNode
+
+ def ioFactory = Input(Clock())
+
+ val clock = shell { InModuleBody {
+ val (bundle, edge) = node.out.head
+ shell.sdc.addClock(name, io:Clock, edge.clock.freqMHz)
+ bundle.clock
+ } }
+ def overlayOutput = ClockInputOverlayOutput(node)
+}
+
+abstract class SingleEndedClockBundleInputPlacedOverlay(
+ val name: String, val di: ClockInputDesignInput, val si: ClockInputShellInput)
+ extends IOPlacedOverlay[ClockBundle, ClockInputDesignInput, ClockInputShellInput, ClockInputOverlayOutput]
+{
+ implicit val p = di.p
+ def node: ClockSourceNode
+
+ def ioFactory = Input(new ClockBundle(ClockBundleParameters()))
+
+ val clock = shell { InModuleBody {
+ val (bundle, edge) = node.out.head
+ bundle.clock
+ } }
+ val reset = shell { InModuleBody {
+ val (bundle, edge) = node.out.head
+ bundle.reset
+ } }
+ def overlayOutput = ClockInputOverlayOutput(node)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/DDROverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/DDROverlay.scala
new file mode 100644
index 0000000..be0ed9e
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/DDROverlay.scala
@@ -0,0 +1,27 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import sifive.fpgashells.clocks._
+
+
+case class DDRShellInput()
+case class DDRDesignInput(
+ baseAddress: BigInt,
+ wrangler: ClockAdapterNode,
+ corePLL: PLLNode,
+ vc7074gbdimm: Boolean = false)(
+ implicit val p: Parameters)
+case class DDROverlayOutput(ddr: TLInwardNode)
+trait DDRShellPlacer[Shell] extends ShellPlacer[DDRDesignInput, DDRShellInput, DDROverlayOutput]
+
+case object DDROverlayKey extends Field[Seq[DesignPlacer[DDRDesignInput, DDRShellInput, DDROverlayOutput]]](Nil)
+
+abstract class DDRPlacedOverlay[IO <: Data](val name: String, val di: DDRDesignInput, val si: DDRShellInput)
+ extends IOPlacedOverlay[IO, DDRDesignInput, DDRShellInput, DDROverlayOutput]
+{
+ implicit val p = di.p
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/Ethernet.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/Ethernet.scala
new file mode 100644
index 0000000..7ab9ff4
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/Ethernet.scala
@@ -0,0 +1,51 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.blocks.devices.uart._
+import freechips.rocketchip.subsystem.{BaseSubsystem, PeripheryBus, PeripheryBusKey}
+import freechips.rocketchip.tilelink.TLBusWrapper
+import freechips.rocketchip.interrupts.IntInwardNode
+
+case class EthernetShellInput()
+case class EthernetDesignInput()(implicit val p: Parameters)
+case class EthernetOverlayOutput(eth: ModuleValue[EthernetPCS])
+case object EthernetOverlayKey extends Field[Seq[DesignPlacer[EthernetDesignInput, EthernetShellInput, EthernetOverlayOutput]]](Nil)
+trait EthernetShellPlacer[Shell] extends ShellPlacer[EthernetDesignInput, EthernetShellInput, EthernetOverlayOutput]
+
+class EthernetPads extends Bundle {
+ val tx_p = Output(Bool())
+ val tx_n = Output(Bool())
+ val rx_p = Input(Bool())
+ val rx_n = Input(Bool())
+ val refclk_p = Input(Clock())
+ val refclk_n = Input(Clock())
+}
+
+class EthernetPCS extends Bundle {
+ val rx_clock = Output(Clock())
+ val rx_reset = Output(Bool())
+ val rx_d = Output(UInt(64.W))
+ val rx_c = Output(UInt(8.W))
+ val tx_clock = Output(Clock())
+ val tx_reset = Output(Bool())
+ val tx_d = Input(UInt(64.W))
+ val tx_c = Input(UInt(8.W))
+ val loopback = Input(UInt(3.W))
+ val rx_lock = Output(Bool())
+ val sfp_detect = Output(Bool())
+}
+
+abstract class EthernetPlacedOverlay(
+ val name: String, val di: EthernetDesignInput, val si: EthernetShellInput)
+ extends IOPlacedOverlay[EthernetPads, EthernetDesignInput, EthernetShellInput, EthernetOverlayOutput]
+{
+ implicit val p = di.p
+
+ val pcsPads = InModuleBody { Wire(new EthernetPCS) }
+
+ def ioFactory = new EthernetPads
+ def overlayOutput = EthernetOverlayOutput(eth = pcsPads)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/GPIOOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/GPIOOverlay.scala
new file mode 100644
index 0000000..d3d575b
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/GPIOOverlay.scala
@@ -0,0 +1,35 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.blocks.devices.gpio._
+import freechips.rocketchip.tilelink.TLBusWrapper
+import freechips.rocketchip.interrupts.IntInwardNode
+import chisel3.experimental.Analog
+
+//Might delete later...
+//Should GPIO be an overlay? Probably not, PinOverlay might take over this use case
+//Plus this should NOT place the controller
+case class GPIOShellInput()
+case class GPIODesignInput(gpioParam: GPIOParams, controlBus: TLBusWrapper, intNode: IntInwardNode)(implicit val p: Parameters)
+case class GPIOOverlayOutput(gpio: TLGPIO)
+case object GPIOOverlayKey extends Field[Seq[DesignPlacer[GPIODesignInput, GPIOShellInput, GPIOOverlayOutput]]](Nil)
+trait GPIOShellPlacer[Shell] extends ShellPlacer[GPIODesignInput, GPIOShellInput, GPIOOverlayOutput]
+
+class ShellGPIOPortIO(width: Int = 4) extends Bundle {
+ val gpio = Vec(width, Analog(1.W))
+}
+
+abstract class GPIOPlacedOverlay(
+ val name: String, val di: GPIODesignInput, si: GPIOShellInput)
+ extends IOPlacedOverlay[ShellGPIOPortIO, GPIODesignInput, GPIOShellInput, GPIOOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = new ShellGPIOPortIO(di.gpioParam.width)
+ val tlgpio = GPIO.attach(GPIOAttachParams(di.gpioParam, di.controlBus, di.intNode))
+ val tlgpioSink = shell { tlgpio.ioNode.makeSink }
+ def overlayOutput = GPIOOverlayOutput(gpio = tlgpio)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/GPIOPMODOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/GPIOPMODOverlay.scala
new file mode 100644
index 0000000..e43b8e3
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/GPIOPMODOverlay.scala
@@ -0,0 +1,45 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.blocks.devices.gpio._
+import freechips.rocketchip.tilelink.TLBusWrapper
+import freechips.rocketchip.interrupts.IntInwardNode
+import chisel3.experimental.Analog
+
+case class GPIOPMODShellInput()
+case class GPIOPMODDesignInput()(implicit val p: Parameters)
+case class GPIOPMODOverlayOutput(pmod: ModuleValue[GPIOPMODPortIO])
+case object GPIOPMODOverlayKey extends Field[Seq[DesignPlacer[GPIOPMODDesignInput, GPIOPMODShellInput, GPIOPMODOverlayOutput]]](Nil)
+trait GPIOPMODShellPlacer[Shell] extends ShellPlacer[GPIOPMODDesignInput, GPIOPMODShellInput, GPIOPMODOverlayOutput]
+
+class GPIOPMODPortIO extends Bundle {
+ val gpio_pmod_0 = Analog(1.W)
+ val gpio_pmod_1 = Analog(1.W)
+ val gpio_pmod_2 = Analog(1.W)
+ val gpio_pmod_3 = Analog(1.W)
+ val gpio_pmod_4 = Analog(1.W)
+ val gpio_pmod_5 = Analog(1.W)
+ val gpio_pmod_6 = Analog(1.W)
+ val gpio_pmod_7 = Analog(1.W)
+}
+
+abstract class GPIOPMODPlacedOverlay(
+ val name: String, val di: GPIOPMODDesignInput, val si: GPIOPMODShellInput)
+ extends IOPlacedOverlay[GPIOPMODPortIO, GPIOPMODDesignInput, GPIOPMODShellInput, GPIOPMODOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = new GPIOPMODPortIO
+
+ val pmodgpioSource = BundleBridgeSource(() => new GPIOPMODPortIO)
+ val pmodgpioSink = shell { pmodgpioSource.makeSink }
+
+ def overlayOutput = GPIOPMODOverlayOutput(pmod = InModuleBody { pmodgpioSource.bundle } )
+
+ shell { InModuleBody {
+ io <> pmodgpioSink.bundle
+ }}
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/I2COverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/I2COverlay.scala
new file mode 100644
index 0000000..0c40f59
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/I2COverlay.scala
@@ -0,0 +1,38 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import chisel3.experimental.Analog
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.blocks.devices.i2c._
+import freechips.rocketchip.subsystem.{BaseSubsystem, PeripheryBus, PeripheryBusKey}
+import freechips.rocketchip.tilelink.TLBusWrapper
+import freechips.rocketchip.interrupts.IntInwardNode
+
+//This should NOT do the device placement, just return the bundlebridge
+case class I2CShellInput(index: Int = 0)
+case class I2CDesignInput(i2cParams: I2CParams, controlBus: TLBusWrapper, intNode: IntInwardNode)(implicit val p: Parameters)
+case class I2COverlayOutput(i2c: TLI2C)
+trait I2CShellPlacer[Shell] extends ShellPlacer[I2CDesignInput, I2CShellInput, I2COverlayOutput]
+
+case object I2COverlayKey extends Field[Seq[DesignPlacer[I2CDesignInput, I2CShellInput, I2COverlayOutput]]](Nil)
+
+class ShellI2CPortIO extends Bundle {
+ val scl = Analog(1.W)
+ val sda = Analog(1.W)
+}
+
+abstract class I2CPlacedOverlay(
+ val name: String, val di: I2CDesignInput, val si: I2CShellInput)
+ extends IOPlacedOverlay[ShellI2CPortIO, I2CDesignInput, I2CShellInput, I2COverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = new ShellI2CPortIO
+
+ val tli2c = I2C.attach(I2CAttachParams(di.i2cParams, di.controlBus, di.intNode))
+ val tli2cSink = shell { tli2c.ioNode.makeSink }
+
+ def overlayOutput = I2COverlayOutput(i2c = tli2c)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/IOShell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/IOShell.scala
new file mode 100644
index 0000000..d40bf18
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/IOShell.scala
@@ -0,0 +1,159 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import chisel3.experimental.{DataMirror, IO}
+import freechips.rocketchip.config._
+import freechips.rocketchip.util._
+import freechips.rocketchip.diplomacy._
+
+case class IOPin(element: Element, index: Int = 0)
+{
+ private val width = DataMirror.widthOf(element)
+ require (width.known)
+ require (index >= 0 && index < width.get)
+
+ def name = {
+ //replace all [#]'s with _# in the pin base name, then append on the final [#] (pindex) if width > 1
+ val pin = element.instanceName.split("\\.").map(_.replaceAll("""\[(\d+)\]""", "_$1")).mkString("_")
+ val path = element.parentPathName.split("\\.")
+ val pindex = pin + (if (width.get > 1) s"[${index}]" else "")
+ (path.drop(1) :+ pindex).mkString("/")
+ }
+
+ def sdcPin = {
+ val path = name
+ if (path.contains("/")) s"[get_pins {${path}}]" else s"[get_ports {${path}}]"
+ }
+
+ def sdcClock = s"[get_clocks -of_objects ${sdcPin}]"
+
+ def isOutput = {
+ import chisel3.ActualDirection._
+ DataMirror.directionOf(element) match {
+ case Output => true
+ case Input => false
+ case Bidirectional(_) => true
+ case Unspecified => { require(false); false }
+ }
+ }
+
+ def isInput = {
+ import chisel3.ActualDirection._
+ DataMirror.directionOf(element) match {
+ case Output => false
+ case Input => true
+ case Bidirectional(_) => true
+ case Unspecified => { require(false); false }
+ }
+ }
+}
+
+object IOPin
+{
+ def of(x: Data): Seq[IOPin] = {
+ val elts = x match {
+ case a: Aggregate => getDataElements(a).reverse // because Chisel has it backwards
+ case e: Element => Seq(e)
+ }
+ elts.flatMap { elt =>
+ val width = DataMirror.widthOf(elt)
+ require (width.known)
+ Seq.tabulate(width.get) { i => IOPin(elt, i) }
+ }
+ }
+}
+
+case class IOTiming(
+ minInput: Double = 0,
+ maxInput: Double = 0,
+ minOutput: Double = 0,
+ maxOutput: Double = 0)
+
+class SDC(val name: String)
+{
+ private var clocks: Seq[() => String] = Nil
+ private var groups: Seq[() => String] = Nil
+ private var falses: Seq[() => String] = Nil
+ private var timings: Seq[() => String] = Nil
+
+ protected def addRawClock (command: => String) { clocks = (() => command) +: clocks }
+ protected def addRawGroup (command: => String) { groups = (() => command) +: groups }
+ protected def addRawFalse (command: => String) { falses = (() => command) +: falses }
+ protected def addRawTiming(command: => String) { timings = (() => command) +: timings }
+ addRawGroup("set_clock_groups -asynchronous")
+
+ private def flatten(x: Seq[() => String], sep: String = "\n") = x.map(_()).filter(_ != "").reverse.mkString(sep)
+ ElaborationArtefacts.add(name,
+ s"""# ------------------------- Base Clocks --------------------
+ |${flatten(clocks)}
+ |# ------------------------- Clock Groups -------------------
+ |${if (groups.size == 1) "" else flatten(groups, " \\\n")}
+ |# ------------------------- False Paths --------------------
+ |${flatten(falses)}
+ |# ------------------------- IO Timings ---------------------
+ |${flatten(timings)}
+ |""".stripMargin)
+
+ def addClock(name: => String, pin: => IOPin, freqMHz: => Double, jitterNs: => Double = 0.5) {
+ addRawClock(s"create_clock -name ${name} -period ${1000/freqMHz} ${pin.sdcPin}")
+ addRawClock(s"set_input_jitter ${name} ${jitterNs}")
+ }
+
+ def addDerivedClock(name: => String, source: => IOPin, sink: => IOPin) {
+ addRawClock(s"create_generated_clock -name ${name} -divide_by 1 -source ${source.sdcPin} ${sink.sdcPin}")
+ }
+
+ def addGroup(clocks: => Seq[String] = Nil, pins: => Seq[IOPin] = Nil) {
+ def thunk = {
+ val clocksList = clocks
+ val (pinsList, portsList) = pins.map(_.name).partition(_.contains("/"))
+ val sep = " \\\n "
+ val clocksStr = (" [get_clocks {" +: clocksList).mkString(sep) + " \\\n }]"
+ val pinsStr = (" [get_clocks -of_objects [get_pins {" +: pinsList ).mkString(sep) + " \\\n }]]"
+ val portsStr = (" [get_clocks -of_objects [get_ports {" +: portsList).mkString(sep) + " \\\n }]]"
+ val str = s" -group [list${if (clocksList.isEmpty) "" else clocksStr}${if (pinsList.isEmpty) "" else pinsStr}${if (portsList.isEmpty) "" else portsStr}]"
+ if (clocksList.isEmpty && pinsList.isEmpty && portsList.isEmpty) "" else str
+ }
+ addRawGroup(thunk)
+ }
+
+ def addAsyncPath(through: => Seq[IOPin]) {
+ addRawFalse("set_false_path" + through.map(x => s" -through ${x.sdcPin}").mkString)
+ }
+
+ def addInputDelay(port: => IOPin, clock: => String, min: => Double, max: => Double) {
+ addRawTiming(f"set_input_delay -min ${min}% -5.2f -clock ${clock} ${port.sdcPin}")
+ addRawTiming(f"set_input_delay -max ${max}% -5.2f -clock ${clock} ${port.sdcPin}")
+ }
+
+ def addOutputDelay(port: => IOPin, clock: => String, min: => Double, max: => Double) {
+ addRawTiming(f"set_output_delay -min ${min}% -5.2f -clock ${clock} ${port.sdcPin}")
+ addRawTiming(f"set_output_delay -max ${max}% -5.2f -clock ${clock} ${port.sdcPin}")
+ }
+
+ def addIOTiming(io: IOPin, clock: => String, timing: => IOTiming) {
+ if (io.isInput) { addInputDelay (io, clock, timing.minInput, timing.maxInput) }
+ if (io.isOutput) { addOutputDelay(io, clock, timing.minOutput, timing.maxOutput) }
+ }
+}
+
+// An IOOverlay is an Overlay with a public shell-level IO
+
+trait IOPlacedOverlay[IO <: Data, DesignInput, ShellInput, OverlayOutput] extends PlacedOverlay[DesignInput, ShellInput, OverlayOutput]
+{
+ def ioFactory: IO
+ def shell: IOShell
+
+ val io = shell { InModuleBody {
+ val port = IO(ioFactory)
+ port.suggestName(name)
+ port
+ } }
+}
+
+abstract class IOShell()(implicit p: Parameters) extends Shell
+{
+ // This can be overriden if a particular vendor needs customized SDC output
+ def sdc: SDC
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/JTAGDebugBScanOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/JTAGDebugBScanOverlay.scala
new file mode 100644
index 0000000..6d353a0
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/JTAGDebugBScanOverlay.scala
@@ -0,0 +1,31 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import chisel3.experimental._
+import freechips.rocketchip.config._
+import freechips.rocketchip.util._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.jtag._
+import freechips.rocketchip.devices.debug._
+import freechips.rocketchip.subsystem.{BaseSubsystem, PeripheryBus, PeripheryBusKey}
+import sifive.fpgashells.ip.xilinx._
+
+case class JTAGDebugBScanShellInput()
+case class JTAGDebugBScanDesignInput()(implicit val p: Parameters)
+case class JTAGDebugBScanOverlayOutput(jtag: ModuleValue[FlippedJTAGIO])
+case object JTAGDebugBScanOverlayKey extends Field[Seq[DesignPlacer[JTAGDebugBScanDesignInput, JTAGDebugBScanShellInput, JTAGDebugBScanOverlayOutput]]](Nil)
+trait JTAGDebugBScanShellPlacer[Shell] extends ShellPlacer[JTAGDebugBScanDesignInput, JTAGDebugBScanShellInput, JTAGDebugBScanOverlayOutput]
+
+abstract class JTAGDebugBScanPlacedOverlay(
+ val name: String, val di: JTAGDebugBScanDesignInput, val si: JTAGDebugBScanShellInput)
+ extends PlacedOverlay[JTAGDebugBScanDesignInput, JTAGDebugBScanShellInput, JTAGDebugBScanOverlayOutput]
+{
+ implicit val p = di.p
+ def shell: Shell
+
+ val jtagDebugSource = BundleBridgeSource(() => new FlippedJTAGIO())
+ val jtagDebugSink = shell { jtagDebugSource.makeSink }
+ val jtout = InModuleBody { jtagDebugSource.bundle}
+ def overlayOutput = JTAGDebugBScanOverlayOutput(jtag = jtout)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/JTAGDebugOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/JTAGDebugOverlay.scala
new file mode 100644
index 0000000..0e9373b
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/JTAGDebugOverlay.scala
@@ -0,0 +1,50 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import chisel3.experimental.Analog
+import freechips.rocketchip.config._
+import freechips.rocketchip.util._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.jtag._
+import freechips.rocketchip.devices.debug._
+import freechips.rocketchip.subsystem.{BaseSubsystem, PeripheryBus, PeripheryBusKey}
+import sifive.fpgashells.ip.xilinx._
+
+case class JTAGDebugShellInput()
+case class JTAGDebugDesignInput()(implicit val p: Parameters)
+case class JTAGDebugOverlayOutput(jtag: ModuleValue[FlippedJTAGIO])
+case object JTAGDebugOverlayKey extends Field[Seq[DesignPlacer[JTAGDebugDesignInput, JTAGDebugShellInput, JTAGDebugOverlayOutput]]](Nil)
+trait JTAGDebugShellPlacer[Shell] extends ShellPlacer[JTAGDebugDesignInput, JTAGDebugShellInput, JTAGDebugOverlayOutput]
+
+class ShellJTAGIO extends Bundle {
+ // JTAG
+ val jtag_TCK = Analog(1.W)
+ val jtag_TMS = Analog(1.W)
+ val jtag_TDI = Analog(1.W)
+ val jtag_TDO = Analog(1.W)
+ val srst_n = Analog(1.W)
+}
+
+// TODO: Fix interaction of BundleBridge/Flipped to get rid of this Bundle
+class FlippedJTAGIO extends Bundle {
+ val TCK = Input(Clock())
+ val TMS = Input(Bool())
+ val TDI = Input(Bool())
+ val TDO = Output(new Tristate())
+ val srst_n = Input(Bool())
+}
+
+abstract class JTAGDebugPlacedOverlay(
+ val name: String, val di: JTAGDebugDesignInput, val si: JTAGDebugShellInput)
+ extends IOPlacedOverlay[ShellJTAGIO, JTAGDebugDesignInput, JTAGDebugShellInput, JTAGDebugOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = new ShellJTAGIO
+
+ val jtagDebugSource = BundleBridgeSource(() => new FlippedJTAGIO())
+ val jtagDebugSink = shell { jtagDebugSource.makeSink }
+ val jtout = InModuleBody { jtagDebugSource.bundle}
+ def overlayOutput = JTAGDebugOverlayOutput(jtag = jtout)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/LEDOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/LEDOverlay.scala
new file mode 100644
index 0000000..fb0631a
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/LEDOverlay.scala
@@ -0,0 +1,30 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+
+case class LEDShellInput(
+ color: String = "",
+ header: String = "",
+ rgb: Boolean = false,
+ number: Int = 0)
+
+case class LEDDesignInput()(implicit val p: Parameters)
+case class LEDOverlayOutput(led: ModuleValue[Bool])
+case object LEDOverlayKey extends Field[Seq[DesignPlacer[LEDDesignInput, LEDShellInput, LEDOverlayOutput]]](Nil)
+trait LEDShellPlacer[Shell] extends ShellPlacer[LEDDesignInput, LEDShellInput, LEDOverlayOutput]
+
+abstract class LEDPlacedOverlay(
+ val name: String, val di: LEDDesignInput, si: LEDShellInput)
+ extends IOPlacedOverlay[Bool, LEDDesignInput, LEDShellInput, LEDOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = Output(Bool())
+
+ val ledSource = BundleBridgeSource(() => Bool())
+ val ledSink = shell { ledSource.makeSink() }
+ def overlayOutput = LEDOverlayOutput(InModuleBody { ledSource.out(0)._1 })
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/PCIeOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/PCIeOverlay.scala
new file mode 100644
index 0000000..4762eae
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/PCIeOverlay.scala
@@ -0,0 +1,31 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import sifive.fpgashells.clocks._
+
+case class PCIeShellInput()
+case class PCIeDesignInput(
+ wrangler: ClockAdapterNode,
+ bars: Seq[AddressSet] = Seq(AddressSet(0x40000000L, 0x1FFFFFFFL)),
+ ecam: BigInt = 0x2000000000L,
+ corePLL: PLLNode)(
+ implicit val p: Parameters)
+
+case class PCIeOverlayOutput(
+ pcieNode: TLNode,
+ intNode: IntOutwardNode)
+trait PCIeShellPlacer[Shell] extends ShellPlacer[PCIeDesignInput, PCIeShellInput, PCIeOverlayOutput]
+
+case object PCIeOverlayKey extends Field[Seq[DesignPlacer[PCIeDesignInput, PCIeShellInput, PCIeOverlayOutput]]](Nil)
+
+abstract class PCIePlacedOverlay[IO <: Data](
+ val name: String, val di: PCIeDesignInput, val si: PCIeShellInput)
+ extends IOPlacedOverlay[IO, PCIeDesignInput, PCIeShellInput, PCIeOverlayOutput]
+{
+ implicit val p = di.p
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/PWMOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/PWMOverlay.scala
new file mode 100644
index 0000000..97639f4
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/PWMOverlay.scala
@@ -0,0 +1,36 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import chisel3.experimental.Analog
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.blocks.devices.pwm._
+import freechips.rocketchip.subsystem.{BaseSubsystem, PeripheryBus, PeripheryBusKey}
+import freechips.rocketchip.tilelink.TLBusWrapper
+import freechips.rocketchip.interrupts.IntInwardNode
+
+//another one that makes the controller... remove this
+case class PWMShellInput(index: Int = 0)
+case class PWMDesignInput(pwmParams: PWMParams, controlBus: TLBusWrapper, intNode: IntInwardNode)(implicit val p: Parameters)
+case class PWMOverlayOutput(pwm: TLPWM)
+case object PWMOverlayKey extends Field[Seq[DesignPlacer[PWMDesignInput, PWMShellInput, PWMOverlayOutput]]](Nil)
+trait PWMShellPlacer[Shell] extends ShellPlacer[PWMDesignInput, PWMShellInput, PWMOverlayOutput]
+
+class ShellPWMPortIO extends Bundle {
+ val pwm_gpio = Vec(4, Analog(1.W))
+}
+
+abstract class PWMPlacedOverlay(
+ val name: String, val di: PWMDesignInput, val si: PWMShellInput)
+ extends IOPlacedOverlay[ShellPWMPortIO, PWMDesignInput, PWMShellInput, PWMOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = new ShellPWMPortIO
+
+ val tlpwm = PWM.attach(PWMAttachParams(di.pwmParams, di.controlBus, di.intNode))
+ val tlpwmSink = shell { tlpwm.ioNode.makeSink }
+
+ def overlayOutput = PWMOverlayOutput(pwm = tlpwm)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/PinOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/PinOverlay.scala
new file mode 100644
index 0000000..f617b59
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/PinOverlay.scala
@@ -0,0 +1,38 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.blocks.devices.gpio._
+import freechips.rocketchip.tilelink.TLBusWrapper
+import freechips.rocketchip.interrupts.IntInwardNode
+import chisel3.experimental.Analog
+
+case class PinShellInput()
+case class PinDesignInput()(implicit val p: Parameters)
+case class PinOverlayOutput(pin: ModuleValue[PinPortIO])
+case object PinOverlayKey extends Field[Seq[DesignPlacer[PinDesignInput, PinShellInput, PinOverlayOutput]]](Nil)
+trait PinShellPlacer[Shell] extends ShellPlacer[PinDesignInput, PinShellInput, PinOverlayOutput]
+
+class PinPortIO extends Bundle {
+ val pins = Vec(8, Analog(1.W))
+}
+
+abstract class PinPlacedOverlay(
+ val name: String, val di: PinDesignInput, val si: PinShellInput)
+ extends IOPlacedOverlay[PinPortIO, PinDesignInput, PinShellInput, PinOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = new PinPortIO
+
+ val pinSource = BundleBridgeSource(() => new PinPortIO)
+ val pinSink = shell { pinSource.makeSink }
+
+ def overlayOutput = PinOverlayOutput(pin = InModuleBody { pinSource.bundle } )
+
+ shell { InModuleBody {
+ io <> pinSink.bundle
+ }}
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/SDIOOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/SDIOOverlay.scala
new file mode 100644
index 0000000..8c57359
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/SDIOOverlay.scala
@@ -0,0 +1,70 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import chisel3.experimental.Analog
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.blocks.devices.spi._
+import freechips.rocketchip.tilelink.TLBusWrapper
+import freechips.rocketchip.interrupts.IntInwardNode
+
+//This should not do the controller placement either
+case class SDIOShellInput()
+case class SDIODesignInput(spiParam: SPIParams, controlBus: TLBusWrapper, intNode: IntInwardNode)(implicit val p: Parameters)
+case class SDIOOverlayOutput(spi: TLSPI)
+case object SDIOOverlayKey extends Field[Seq[DesignPlacer[SDIODesignInput, SDIOShellInput, SDIOOverlayOutput]]](Nil)
+trait SDIOShellPlacer[Shell] extends ShellPlacer[SDIODesignInput, SDIOShellInput, SDIOOverlayOutput]
+
+// SDIO Port. Not sure how generic this is, it might need to move.
+class FPGASDIOPortIO extends Bundle {
+ val sdio_clk = Output(Bool())
+ val sdio_cmd = Output(Bool())
+ val sdio_dat_0 = Input(Bool())
+ val sdio_dat_1 = Analog(1.W)
+ val sdio_dat_2 = Analog(1.W)
+ val sdio_dat_3 = Output(Bool())
+}
+
+abstract class SDIOPlacedOverlay(
+ val name: String, val di: SDIODesignInput, val si: SDIOShellInput)
+ extends IOPlacedOverlay[FPGASDIOPortIO, SDIODesignInput, SDIOShellInput, SDIOOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = new FPGASDIOPortIO
+ val tlspi = SPI.attach(SPIAttachParams(di.spiParam, di.controlBus, di.intNode))
+ val tlspiSink = tlspi.ioNode.makeSink
+
+ val spiSource = BundleBridgeSource(() => new SPIPortIO(di.spiParam))
+ val spiSink = shell { spiSource.makeSink }
+ def overlayOutput = SDIOOverlayOutput(spi = tlspi)
+
+ InModuleBody {
+ val (io, _) = spiSource.out(0)
+ val tlspiport = tlspiSink.bundle
+ io <> tlspiport
+ (0 to 3).foreach { case q =>
+ tlspiport.dq(q).i := RegNext(RegNext(io.dq(q).i))
+ }
+ }
+
+ shell { InModuleBody {
+ val sd_spi_sck = spiSink.bundle.sck
+ val sd_spi_cs = spiSink.bundle.cs(0)
+
+ val sd_spi_dq_i = Wire(Vec(4, Bool()))
+ val sd_spi_dq_o = Wire(Vec(4, Bool()))
+
+ spiSink.bundle.dq.zipWithIndex.foreach {
+ case(pin, idx) =>
+ sd_spi_dq_o(idx) := pin.o
+ pin.i := sd_spi_dq_i(idx)
+ }
+
+ io.sdio_clk := sd_spi_sck
+ io.sdio_dat_3 := sd_spi_cs
+ io.sdio_cmd := sd_spi_dq_o(0)
+ sd_spi_dq_i := Seq(false.B, io.sdio_dat_0, false.B, false.B)
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/SPIFlashOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/SPIFlashOverlay.scala
new file mode 100644
index 0000000..a542116
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/SPIFlashOverlay.scala
@@ -0,0 +1,37 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.blocks.devices.spi._
+import freechips.rocketchip.tilelink.TLBusWrapper
+import freechips.rocketchip.interrupts.IntInwardNode
+import chisel3.experimental.Analog
+
+//This one does controller also
+case class SPIFlashShellInput(index: Int = 0)
+case class SPIFlashDesignInput(spiFlashParam: SPIFlashParams, controlBus: TLBusWrapper, memBus: TLBusWrapper, intNode: IntInwardNode)(implicit val p: Parameters)
+case class SPIFlashOverlayOutput(spiflash: TLSPIFlash)
+case object SPIFlashOverlayKey extends Field[Seq[DesignPlacer[SPIFlashDesignInput, SPIFlashShellInput, SPIFlashOverlayOutput]]](Nil)
+trait SPIFlashShellPlacer[Shell] extends ShellPlacer[SPIFlashDesignInput, SPIFlashShellInput, SPIFlashOverlayOutput]
+
+
+class ShellSPIFlashPortIO extends Bundle {
+ val qspi_sck = Analog(1.W)
+ val qspi_cs = Analog(1.W)
+ val qspi_dq = Vec(4, Analog(1.W))
+}
+
+abstract class SPIFlashPlacedOverlay(
+ val name: String, val di: SPIFlashDesignInput, val si: SPIFlashShellInput)
+ extends IOPlacedOverlay[ShellSPIFlashPortIO, SPIFlashDesignInput, SPIFlashShellInput, SPIFlashOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = new ShellSPIFlashPortIO
+ val tlqspi = SPI.attachFlash(SPIFlashAttachParams(di.spiFlashParam, di.controlBus, di.memBus, di.intNode))
+
+ val tlqspiSink = shell { tlqspi.ioNode.makeSink }
+ def overlayOutput = SPIFlashOverlayOutput(spiflash = tlqspi)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/Shell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/Shell.scala
new file mode 100644
index 0000000..b570408
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/Shell.scala
@@ -0,0 +1,80 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+
+import chisel3.experimental.ChiselAnnotation
+import firrtl._
+import firrtl.analyses._
+import firrtl.annotations._
+//import firrtl.ir._
+import freechips.rocketchip.util.DontTouch
+
+case object DesignKey extends Field[Parameters => LazyModule]
+
+// Overlays are declared by the Shell and placed somewhere by the Design
+// ... they inject diplomatic code both where they were placed and in the shell
+// ... they are instantiated with DesignInput and return DesignOutput
+// placed overlay has been invoked by the design
+trait PlacedOverlay[DesignInput, ShellInput, OverlayOutput] {
+ def name: String
+ def designInput: DesignInput
+ def shellInput: ShellInput
+ def overlayOutput: OverlayOutput
+}
+
+trait ShellPlacer[DesignInput, ShellInput, OverlayOutput] {
+ def valName: ValName
+ def shellInput: ShellInput
+ def place(di: DesignInput): PlacedOverlay[DesignInput, ShellInput, OverlayOutput]
+}
+
+trait DesignPlacer[DesignInput, ShellInput, OverlayOutput] {
+ def isPlaced: Boolean
+ def name: String
+ def shellInput: ShellInput
+ def place(di: DesignInput): PlacedOverlay[DesignInput, ShellInput, OverlayOutput]
+}
+
+trait ShellOverlayAccessor[DesignInput, ShellInput, OverlayOutput] {
+ def get(): Option[PlacedOverlay[DesignInput, ShellInput, OverlayOutput]]
+}
+
+abstract class Shell()(implicit p: Parameters) extends LazyModule with LazyScope
+{
+ private var overlays = Parameters.empty
+ def designParameters: Parameters = overlays ++ p
+
+ def Overlay[DesignInput, ShellInput, OverlayOutput](
+ key: Field[Seq[DesignPlacer[DesignInput, ShellInput, OverlayOutput]]],
+ placer: ShellPlacer[DesignInput, ShellInput, OverlayOutput]):
+ ShellOverlayAccessor[DesignInput, ShellInput, OverlayOutput] = {
+ val thunk = new Object
+ with ShellOverlayAccessor[DesignInput, ShellInput, OverlayOutput]
+ with DesignPlacer[DesignInput, ShellInput, OverlayOutput] {
+ var placedOverlay: Option[PlacedOverlay[DesignInput, ShellInput, OverlayOutput]] = None
+ def get() = placedOverlay
+ def isPlaced = !placedOverlay.isEmpty
+ def name = placer.valName.name
+ def shellInput = placer.shellInput
+ def place(input: DesignInput): PlacedOverlay[DesignInput, ShellInput, OverlayOutput] = {
+ require (!isPlaced, s"Overlay ${name} has already been placed by the design; cannot place again")
+ val it = placer.place(input)
+ placedOverlay = Some(it)
+ it
+ }
+ }
+ overlays = overlays ++ Parameters((site, here, up) => {
+ case x: Field[_] if x eq key => {
+ val tail = up(key)
+ if (thunk.isPlaced) { tail } else { thunk +: tail }
+ }
+ })
+ thunk
+ }
+
+ // feel free to override this if necessary
+ lazy val module = new LazyRawModuleImp(this)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/SwitchOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/SwitchOverlay.scala
new file mode 100644
index 0000000..ba81d0c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/SwitchOverlay.scala
@@ -0,0 +1,25 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+
+case class SwitchShellInput(number: Int = 0)
+case class SwitchDesignInput()(implicit val p: Parameters)
+case class SwitchOverlayOutput(sw: ModuleValue[Bool])
+case object SwitchOverlayKey extends Field[Seq[DesignPlacer[SwitchDesignInput, SwitchShellInput, SwitchOverlayOutput]]](Nil)
+trait SwitchShellPlacer[Shell] extends ShellPlacer[SwitchDesignInput, SwitchShellInput, SwitchOverlayOutput]
+
+abstract class SwitchPlacedOverlay(
+ val name: String, val di: SwitchDesignInput, val si: SwitchShellInput)
+ extends IOPlacedOverlay[Bool, SwitchDesignInput, SwitchShellInput, SwitchOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = Input(Bool())
+
+ val switchSource = shell { BundleBridgeSource(() => Bool()) }
+ val switchSink = switchSource.makeSink()
+ def overlayOutput = SwitchOverlayOutput(sw = InModuleBody { switchSink.bundle } )
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/TracePMODOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/TracePMODOverlay.scala
new file mode 100644
index 0000000..6c1175c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/TracePMODOverlay.scala
@@ -0,0 +1,30 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.blocks.devices.gpio._
+import freechips.rocketchip.tilelink.TLBusWrapper
+import freechips.rocketchip.interrupts.IntInwardNode
+import chisel3.experimental.Analog
+
+case class TracePMODShellInput()
+case class TracePMODDesignInput()(implicit val p: Parameters)
+case class TracePMODOverlayOutput(trace: ModuleValue[UInt])
+case object TracePMODOverlayKey extends Field[Seq[DesignPlacer[TracePMODDesignInput, TracePMODShellInput, TracePMODOverlayOutput]]](Nil)
+trait TracePMODShellPlacer[Shell] extends ShellPlacer[TracePMODDesignInput, TracePMODShellInput, TracePMODOverlayOutput]
+
+abstract class TracePMODPlacedOverlay(
+ val name: String, val di: TracePMODDesignInput, val si: TracePMODShellInput)
+ extends IOPlacedOverlay[UInt, TracePMODDesignInput, TracePMODShellInput, TracePMODOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = Output(UInt(8.W))
+
+ val pmodTraceSource = BundleBridgeSource(() => UInt(8.W))
+ val pmodTraceSink = shell { pmodTraceSource.makeSink }
+ val traceout = InModuleBody { pmodTraceSource.out(0)._1 }
+ def overlayOutput = TracePMODOverlayOutput(trace = traceout )
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/UARTOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/UARTOverlay.scala
new file mode 100644
index 0000000..a2e6425
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/UARTOverlay.scala
@@ -0,0 +1,46 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import chisel3.experimental.Analog
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import sifive.blocks.devices.uart._
+import freechips.rocketchip.subsystem.{BaseSubsystem, PeripheryBus, PeripheryBusKey}
+import freechips.rocketchip.tilelink.TLBusWrapper
+import freechips.rocketchip.interrupts.IntInwardNode
+
+//dont make the controller here
+//move flowcontrol to shell input??
+case class UARTShellInput(index: Int = 0)
+case class UARTDesignInput(uartParams: UARTParams, divInit: Int, controlBus: TLBusWrapper, intNode: IntInwardNode)(implicit val p: Parameters)
+case class UARTOverlayOutput(uart: TLUART)
+case object UARTOverlayKey extends Field[Seq[DesignPlacer[UARTDesignInput, UARTShellInput, UARTOverlayOutput]]](Nil)
+trait UARTShellPlacer[Shell] extends ShellPlacer[UARTDesignInput, UARTShellInput, UARTOverlayOutput]
+
+// Tack on cts, rts signals available on some FPGAs. They are currently unused
+// by our designs.
+class ShellUARTPortIO(val flowControl: Boolean) extends Bundle {
+ val txd = Analog(1.W)
+ val rxd = Analog(1.W)
+ val rtsn = if (flowControl) Some(Analog(1.W)) else None
+ val ctsn = if (flowControl) Some(Analog(1.W)) else None
+}
+
+//class UARTReplacementBundle extends Bundle with HasUARTTopBundleContents
+
+abstract class UARTPlacedOverlay(
+ val name: String, val di: UARTDesignInput, val si: UARTShellInput, val flowControl: Boolean)
+ extends IOPlacedOverlay[ShellUARTPortIO, UARTDesignInput, UARTShellInput, UARTOverlayOutput]
+{
+ implicit val p = di.p
+
+ def ioFactory = new ShellUARTPortIO(flowControl)
+
+ val tluart = UART.attach(UARTAttachParams(di.uartParams, di.divInit, di.controlBus, di.intNode))
+ val tluartSink = tluart.ioNode.makeSink
+ val uartSource = BundleBridgeSource(() => new UARTPortIO())
+ val uartSink = shell { uartSource.makeSink }
+
+ def overlayOutput = UARTOverlayOutput(uart = tluart)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/Util.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/Util.scala
new file mode 100644
index 0000000..4a713ed
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/Util.scala
@@ -0,0 +1,53 @@
+package sifive.fpgashells.shell
+
+import chisel3._
+import chisel3.experimental.{Analog, attach}
+import chisel3.util.HasBlackBoxInline
+
+class AnalogToUInt(w: Int = 1) extends BlackBox with HasBlackBoxInline {
+ val io = IO(new Bundle {
+ val a = Analog(w.W)
+ val b = Output(UInt(w.W))
+ })
+ setInline(s"AnalogToUInt_${w.toString}.v",
+ s"""module AnalogToUInt (a, b);
+ | inout [${w - 1}:0] a;
+ | output [${w - 1}:0] b;
+ | assign b = a;
+ |endmodule
+ |""".stripMargin)
+}
+
+object AnalogToUInt {
+ def apply(a: Analog): UInt = {
+ val a2b = Module(new AnalogToUInt(w = a.getWidth))
+ attach(a, a2b.io.a)
+ a2b.io.b
+ }
+}
+
+class UIntToAnalog(w: Int = 1) extends BlackBox with HasBlackBoxInline {
+ val io = IO(new Bundle {
+ val a = Analog(w.W)
+ val b = Input(UInt(w.W))
+ val b_en = Input(Bool())
+ })
+ require(w >= 1)
+ setInline(s"UIntToAnalog_${w.toString}.v",
+ s"""module UIntToAnalog_${w.toString} (a, b, b_en);
+ | inout [${w - 1}:0] a;
+ | input [${w - 1}:0] b;
+ | input b_en;
+ | assign a = b_en ? b : $w'b${"z"*w};
+ |endmodule
+ |""".stripMargin)
+}
+
+object UIntToAnalog {
+ def apply(b: UInt, a: Analog, b_en: Bool): Unit = {
+ val a2b = Module(new UIntToAnalog(w = a.getWidth))
+ attach(a, a2b.io.a)
+ a2b.io.b := b
+ a2b.io.b_en := b_en
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/cJTAGDebugOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/cJTAGDebugOverlay.scala
new file mode 100644
index 0000000..a14c61c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/cJTAGDebugOverlay.scala
@@ -0,0 +1,57 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell
+
+import chisel3._
+import chisel3.experimental.Analog
+import freechips.rocketchip.config._
+import freechips.rocketchip.util._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.devices.debug._
+import freechips.rocketchip.subsystem.{BaseSubsystem, PeripheryBus, PeripheryBusKey}
+import sifive.fpgashells.ip.xilinx._
+import sifive.blocks.devices.pinctrl._
+
+case class cJTAGDebugShellInput(
+ color: String = "",
+ header: String = "",
+ rgb: Bool = false.B,
+ number: Int = 0)
+
+case class cJTAGDebugDesignInput()(implicit val p: Parameters)
+case class cJTAGDebugOverlayOutput(cjtag: ModuleValue[FPGAcJTAGSignals])
+trait cJTAGDebugShellPlacer[Shell] extends ShellPlacer[cJTAGDebugDesignInput, cJTAGDebugShellInput, cJTAGDebugOverlayOutput]
+
+case object cJTAGDebugOverlayKey extends Field[Seq[DesignPlacer[cJTAGDebugDesignInput, cJTAGDebugShellInput, cJTAGDebugOverlayOutput]]](Nil)
+
+class FPGAcJTAGIO extends Bundle {
+ // cJTAG
+ val cjtag_TCKC = Analog(1.W)
+ val cjtag_TMSC = Analog(1.W)
+ val srst_n = Analog(1.W)
+}
+
+class FPGAcJTAGSignals extends Bundle {
+ val tckc_pin = Input(Clock())
+ val tmsc_pin = new BasePin()
+ val srst_n = Input(Bool())
+}
+
+abstract class cJTAGDebugPlacedOverlay(
+ val name: String, val di: cJTAGDebugDesignInput, val si: cJTAGDebugShellInput)
+ extends IOPlacedOverlay[FPGAcJTAGIO, cJTAGDebugDesignInput, cJTAGDebugShellInput, cJTAGDebugOverlayOutput]
+{
+ implicit val p = di.p
+ def ioFactory = new FPGAcJTAGIO
+
+ val cjtagDebugSource = BundleBridgeSource(() => new FPGAcJTAGSignals)
+ val cjtagDebugSink = shell { cjtagDebugSource.makeSink }
+
+ def overlayOutput = cJTAGDebugOverlayOutput(cjtag = InModuleBody { cjtagDebugSource.bundle} )
+
+ shell { InModuleBody {
+ cjtagDebugSink.bundle.tckc_pin := IOBUF(io.cjtag_TCKC).asClock
+ IOBUF(io.cjtag_TMSC, cjtagDebugSink.bundle.tmsc_pin)
+ KEEPER(io.cjtag_TMSC)
+ cjtagDebugSink.bundle.srst_n := IOBUF(io.srst_n)
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/ChipLinkOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/ChipLinkOverlay.scala
new file mode 100644
index 0000000..de3e1c7
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/ChipLinkOverlay.scala
@@ -0,0 +1,84 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.microsemi
+
+ import chisel3._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.util._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.microsemi._
+
+ abstract class ChipLinkPolarFirePlacedOverlay(name: String, di: ChipLinkDesignInput, si: ChipLinkShellInput)
+ extends ChipLinkPlacedOverlay(name, di, si, rxPhase=180, txPhase=270)
+{
+ def shell: VeraShell
+
+ override def fpgaReset = true
+ val resetBBSource = shell { BundleBridgeSource(() => Bool()) }
+ val resetBBSink = resetBBSource.makeSink
+
+ shell { InModuleBody {
+ val bb = resetBBSource.bundle
+ bb := shell.initMonitor.io.DEVICE_INIT_DONE
+ } }
+
+ InModuleBody {
+ val bb = resetBBSink.bundle
+ // Provide reset pulse to initialize b2c_reset (before RX PLL locks)
+ link.module.io.fpga_reset.foreach { _ := !bb }
+ }
+
+ shell { InModuleBody {
+ val (tx, _) = txClock.in(0)
+ val (rx, _) = rxI.out(0)
+ val rxEdge = rxI.edges.out(0)
+
+ // !!! add a DDR pad
+ io.c2b.clk := tx.clock
+
+ val clkint = Module(new CLKINT)
+ clkint.suggestName(s"${name}_rx_clkint")
+ clkint.io.A := io.b2c.clk
+ rx.clock := clkint.io.Y
+
+ // Consume as much slack for safey for trace jitter+skew on both sides as possible
+ val txMargin = 0.3 //was 1.5, 0.0
+ val rxMargin = 0.3 // <- we badly need a PLL with external feedback!
+
+ // At 125MHz, 6 corner analysis yields these worst min/max corners:
+ // RX min_slow_lv_lt: 0.038ns slack + 0!!! margin
+ // max_fast_hv_lt: 0.089ns slack + 0!!! margin
+ // TX min_fast_hv_lt: 0.086ns slack + 1.5 margin
+ // max_slow_lv_lt: 0.024ns slack + 1.5 margin
+
+ // We have to add a these constants to work around some Libero timing analysis bug
+ val periodNs = 1000.0 / rxEdge.clock.freqMHz
+
+ val timing = IOTiming(
+ /* The data signals coming from Aloe have: clock - 1.2 <= transition <= clock + 0.8
+ * min = hold = - 1.2
+ * max = period - setup = 0.8
+ */
+ minInput = -2.2 - rxMargin + periodNs*2,
+ maxInput = -0.2 + rxMargin + periodNs*2,
+ /* The data signals going to Aloe must have: clock - 1.85 <= NO transition <= clock + 0.65
+ * min = -hold = -0.65
+ * max = setup = 1.85
+ */
+ minOutput = -0.65 - txMargin + periodNs,
+ maxOutput = 1.85 + txMargin + periodNs)
+
+ val sysclk: Clock = shell.sys_clock.get() match {
+ case Some(x: SysClockVeraPlacedOverlay) => x.clock
+ }
+
+ shell.sdc.addClock(s"${name}_b2c_clock", io.b2c.clk, rxEdge.clock.freqMHz)
+ //shell.sdc.addDerivedClock(sdcTxClockName, "{corePLL/corePLL_0/pll_inst_0/OUT1}", io.c2b.clk)
+ shell.sdc.addDerivedClock(s"${name}_c2b_clock", IOPin(sysclk), io.c2b.clk)
+ IOPin.of(io).filter(p => p.isInput && !(p.element eq io.b2c.clk)).foreach { e =>
+ shell.sdc.addIOTiming(e, s"${name}_b2c_clock", timing)
+ }
+ IOPin.of(io).filter(p => p.isOutput && !(p.element eq io.c2b.clk)).foreach { e =>
+ shell.sdc.addIOTiming(e, s"${name}_c2b_clock", timing)
+ }
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/ClockOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/ClockOverlay.scala
new file mode 100644
index 0000000..23210d8
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/ClockOverlay.scala
@@ -0,0 +1,23 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.microsemi
+
+ import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.microsemi._
+
+ abstract class ClockInputMicrosemiPlacedOverlay(name: String, di: ClockInputDesignInput, si: ClockInputShellInput)
+ extends SingleEndedClockInputPlacedOverlay(name, di, si)
+{
+ def shell: MicrosemiShell
+
+ shell { InModuleBody {
+ val (c, _) = node.out(0)
+ val clkint = Module(new CLKINT)
+ clkint.suggestName(s"${name}_clkint")
+
+ clkint.io.A := io
+ c.clock := clkint.io.Y
+ c.reset := false.B
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/LEDOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/LEDOverlay.scala
new file mode 100644
index 0000000..aa81c0c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/LEDOverlay.scala
@@ -0,0 +1,19 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.microsemi
+
+ import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.microsemi._
+
+ abstract class LEDMicrosemiPlacedOverlay(name: String, di: LEDDesignInput, si: LEDShellInput, pins: Seq[String] = Nil)
+ extends LEDPlacedOverlay(name, di, si)
+{
+ def shell: MicrosemiShell
+ val width = pins.size
+
+ shell { InModuleBody {
+ io := ledSink.bundle // could/should put OBUFs here?
+ (pins zip IOPin.of(io)) foreach { case (pin, io) => shell.io_pdc.addPin(io, pin) }
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/PolarFireEvalKitShell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/PolarFireEvalKitShell.scala
new file mode 100644
index 0000000..fc79189
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/PolarFireEvalKitShell.scala
@@ -0,0 +1,661 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.microsemi.polarfireevalkitshell
+
+import Chisel._
+import chisel3.{Input, Output, RawModule, withClockAndReset}
+import chisel3.experimental.{Analog, attach}
+
+import freechips.rocketchip.config._
+import freechips.rocketchip.devices.debug._
+import freechips.rocketchip.util.{SyncResetSynchronizerShiftReg, ResetCatchAndSync, ElaborationArtefacts, HeterogeneousBag}
+
+import sifive.blocks.devices.gpio._
+import sifive.blocks.devices.spi._
+import sifive.blocks.devices.uart._
+
+import sifive.fpgashells.ip.microsemi.{CLKINT}
+
+import sifive.fpgashells.devices.microsemi.polarfireddr3._
+import sifive.fpgashells.devices.microsemi.polarfireddr4._
+
+import sifive.fpgashells.ip.microsemi.corejtagdebug._
+import sifive.fpgashells.ip.microsemi.polarfireccc._
+import sifive.fpgashells.ip.microsemi.polarfireinitmonitor._
+import sifive.fpgashells.ip.microsemi.polarfirereset._
+
+import sifive.fpgashells.devices.microsemi.polarfireevalkitpciex4._
+import sifive.fpgashells.ip.microsemi.polarfirexcvrrefclk._
+import sifive.fpgashells.ip.microsemi.polarfiretxpll._
+
+import sifive.fpgashells.ip.microsemi.polarfire_oscillator._
+import sifive.fpgashells.ip.microsemi.polarfireclockdivider._
+import sifive.fpgashells.ip.microsemi.polarfireglitchlessmux._
+import sifive.blocks.devices.chiplink._
+import sifive.fpgashells.clocks._
+
+
+//-------------------------------------------------------------------------
+// PolarFire Evaluation Kit Shell
+//-------------------------------------------------------------------------
+
+trait HasDDR3 { this: PolarFireEvalKitShell =>
+
+ require(!p.lift(MemoryMicrosemiDDR3Key).isEmpty)
+ val ddr = IO(new PolarFireEvalKitDDR3Pads(p(MemoryMicrosemiDDR3Key)))
+
+ def connectMIG(dut: HasMemoryPolarFireEvalKitDDR3ModuleImp): Unit = {
+ // Clock & Reset
+ dut.polarfireddrsubsys.PLL_REF_CLK := mig_clock_in
+ dut.polarfireddrsubsys.SYS_RESET_N := sys_reset_n
+
+ mig_clock_out := dut.polarfireddrsubsys.SYS_CLK
+ mig_plllock_out := dut.polarfireddrsubsys.PLL_LOCK
+ ddr_ctrlr_ready := dut.polarfireddrsubsys.CTRLR_READY
+
+ ddr <> dut.polarfireddrsubsys
+ }
+}
+
+trait HasDDR4 { this: PolarFireEvalKitShell =>
+
+ require(!p.lift(MemoryMicrosemiDDR4Key).isEmpty)
+ val ddr = IO(new PolarFireEvalKitDDR4Pads(p(MemoryMicrosemiDDR4Key)))
+
+ def connectMIG(dut: HasMemoryPolarFireEvalKitDDR4ModuleImp): Unit = {
+ // Clock & Reset
+ dut.polarfireddrsubsys.PLL_REF_CLK := mig_clock_in
+ dut.polarfireddrsubsys.SYS_RESET_N := sys_reset_n
+
+ mig_clock_out := dut.polarfireddrsubsys.SYS_CLK
+ mig_plllock_out := dut.polarfireddrsubsys.PLL_LOCK
+ ddr_ctrlr_ready := dut.polarfireddrsubsys.CTRLR_READY
+
+ ddr <> dut.polarfireddrsubsys
+ }
+}
+
+trait HasPCIe { this: PolarFireEvalKitShell =>
+ val pcie = IO(new PolarFireEvalKitPCIeX4Pads)
+
+ def connectPCIe(dut: HasSystemPolarFireEvalKitPCIeX4ModuleImp): Unit = {
+ // Clock & Reset
+// dut.pf_eval_kit_pcie.APB_S_PCLK := hart_clk
+ dut.pf_eval_kit_pcie.APB_S_PCLK := dut_clock
+ dut.pf_eval_kit_pcie.APB_S_PRESET_N := UInt("b1")
+
+// dut.pf_eval_kit_pcie.AXI_CLK := hart_clk_150
+ dut.pf_eval_kit_pcie.AXI_CLK := dut_clock
+ dut.pf_eval_kit_pcie.AXI_CLK_STABLE := hart_clk_lock
+
+ dut.pf_eval_kit_pcie.PCIE_1_TL_CLK_125MHz := pcie_tl_clk
+
+ dut.pf_eval_kit_pcie.PCIE_1_TX_PLL_REF_CLK := pf_tx_pll_refclk_to_lane
+
+ dut.pf_eval_kit_pcie.PCIE_1_TX_BIT_CLK := pf_tx_pll_bitclk
+
+ dut.pf_eval_kit_pcie.PCIESS_LANE0_CDR_REF_CLK_0 := pcie_refclk
+ dut.pf_eval_kit_pcie.PCIESS_LANE1_CDR_REF_CLK_0 := pcie_refclk
+ dut.pf_eval_kit_pcie.PCIESS_LANE2_CDR_REF_CLK_0 := pcie_refclk
+ dut.pf_eval_kit_pcie.PCIESS_LANE3_CDR_REF_CLK_0 := pcie_refclk
+
+ dut.pf_eval_kit_pcie.PCIE_1_TX_PLL_LOCK := pf_tx_pll_lock
+
+ pcie <> dut.pf_eval_kit_pcie
+ }
+}
+/*
+trait HasCoreJTAGDebug { this: PolarFireEvalKitShell =>
+ // JTAG inside the FPGA fabric through user JTAG FPGA macro (UJTAG)
+ val fpga_jtag = Module(new CoreJtagDebugBlock)
+
+ fpga_jtag.io.UTDO_IN_0 := UInt("b0")
+ fpga_jtag.io.UTDO_IN_1 := UInt("b0")
+ fpga_jtag.io.UTDO_IN_2 := UInt("b0")
+ fpga_jtag.io.UTDO_IN_3 := UInt("b0")
+ fpga_jtag.io.UTDODRV_0 := UInt("b0")
+ fpga_jtag.io.UTDODRV_1 := UInt("b0")
+ fpga_jtag.io.UTDODRV_2 := UInt("b0")
+ fpga_jtag.io.UTDODRV_3 := UInt("b0")
+
+}
+*/
+
+
+trait HasPFEvalKitChipLink { this: PolarFireEvalKitShell =>
+
+ val chiplink = IO(new WideDataLayerPort(ChipLinkParams(Nil,Nil)))
+ val ereset_n = IO(Bool(INPUT))
+
+ def constrainChipLink(iofpga: Boolean = false): Unit = {
+ val direction0Pins = if(iofpga) "chiplink_b2c" else "chiplink_c2b"
+ val direction1Pins = if(iofpga) "chiplink_c2b" else "chiplink_b2c"
+/*
+ ElaborationArtefacts.add(
+ """vc707chiplink.vivado.tcl""",
+ """set vc707chiplink_vivado_tcl_dir [file dirname [file normalize [info script]]]
+ add_files -fileset [current_fileset -constrset] [glob -directory $vc707chiplink_vivado_tcl_dir {*.vc707chiplink.xdc}]"""
+ )
+*/
+
+/*
+ ElaborationArtefacts.add(
+ """vc707chiplink.xdc""", s"""
+ set_property PACKAGE_PIN AF39 [get_ports ${direction0Pins}_clk]
+ set_property PACKAGE_PIN AD40 [get_ports {${direction0Pins}_data[0]}]
+ set_property PACKAGE_PIN AD41 [get_ports {${direction0Pins}_data[1]}]
+ set_property PACKAGE_PIN AF41 [get_ports {${direction0Pins}_data[2]}]
+ set_property PACKAGE_PIN AG41 [get_ports {${direction0Pins}_data[3]}]
+ set_property PACKAGE_PIN AK39 [get_ports {${direction0Pins}_data[4]}]
+ set_property PACKAGE_PIN AL39 [get_ports {${direction0Pins}_data[5]}]
+ set_property PACKAGE_PIN AJ42 [get_ports {${direction0Pins}_data[6]}]
+ set_property PACKAGE_PIN AK42 [get_ports {${direction0Pins}_data[7]}]
+ set_property PACKAGE_PIN AL41 [get_ports {${direction0Pins}_data[8]}]
+ set_property PACKAGE_PIN AL42 [get_ports {${direction0Pins}_data[9]}]
+ set_property PACKAGE_PIN AF42 [get_ports {${direction0Pins}_data[10]}]
+ set_property PACKAGE_PIN AG42 [get_ports {${direction0Pins}_data[11]}]
+ set_property PACKAGE_PIN AD38 [get_ports {${direction0Pins}_data[12]}]
+ set_property PACKAGE_PIN AE38 [get_ports {${direction0Pins}_data[13]}]
+ set_property PACKAGE_PIN AC40 [get_ports {${direction0Pins}_data[14]}]
+ set_property PACKAGE_PIN AC41 [get_ports {${direction0Pins}_data[15]}]
+ set_property PACKAGE_PIN AD42 [get_ports {${direction0Pins}_data[16]}]
+ set_property PACKAGE_PIN AE42 [get_ports {${direction0Pins}_data[17]}]
+ set_property PACKAGE_PIN AJ38 [get_ports {${direction0Pins}_data[18]}]
+ set_property PACKAGE_PIN AK38 [get_ports {${direction0Pins}_data[19]}]
+ set_property PACKAGE_PIN AB41 [get_ports {${direction0Pins}_data[20]}]
+ set_property PACKAGE_PIN AB42 [get_ports {${direction0Pins}_data[21]}]
+ set_property PACKAGE_PIN Y42 [get_ports {${direction0Pins}_data[22]}]
+ set_property PACKAGE_PIN AA42 [get_ports {${direction0Pins}_data[23]}]
+ set_property PACKAGE_PIN Y39 [get_ports {${direction0Pins}_data[24]}]
+ set_property PACKAGE_PIN AA39 [get_ports {${direction0Pins}_data[25]}]
+ set_property PACKAGE_PIN W40 [get_ports {${direction0Pins}_data[26]}]
+ set_property PACKAGE_PIN Y40 [get_ports {${direction0Pins}_data[27]}]
+ set_property PACKAGE_PIN AB38 [get_ports {${direction0Pins}_data[28]}]
+ set_property PACKAGE_PIN AB39 [get_ports {${direction0Pins}_data[29]}]
+ set_property PACKAGE_PIN AC38 [get_ports {${direction0Pins}_data[30]}]
+ set_property PACKAGE_PIN AC39 [get_ports {${direction0Pins}_data[31]}]
+ set_property PACKAGE_PIN AJ40 [get_ports ${direction0Pins}_send]
+ set_property PACKAGE_PIN AJ41 [get_ports ${direction0Pins}_rst]
+
+ set_property PACKAGE_PIN U39 [get_ports ${direction1Pins}_clk]
+ set_property PACKAGE_PIN U37 [get_ports {${direction1Pins}_data[0]}]
+ set_property PACKAGE_PIN U38 [get_ports {${direction1Pins}_data[1]}]
+ set_property PACKAGE_PIN U36 [get_ports {${direction1Pins}_data[2]}]
+ set_property PACKAGE_PIN T37 [get_ports {${direction1Pins}_data[3]}]
+ set_property PACKAGE_PIN U32 [get_ports {${direction1Pins}_data[4]}]
+ set_property PACKAGE_PIN U33 [get_ports {${direction1Pins}_data[5]}]
+ set_property PACKAGE_PIN V33 [get_ports {${direction1Pins}_data[6]}]
+ set_property PACKAGE_PIN V34 [get_ports {${direction1Pins}_data[7]}]
+ set_property PACKAGE_PIN P35 [get_ports {${direction1Pins}_data[8]}]
+ set_property PACKAGE_PIN P36 [get_ports {${direction1Pins}_data[9]}]
+ set_property PACKAGE_PIN W32 [get_ports {${direction1Pins}_data[10]}]
+ set_property PACKAGE_PIN W33 [get_ports {${direction1Pins}_data[11]}]
+ set_property PACKAGE_PIN R38 [get_ports {${direction1Pins}_data[12]}]
+ set_property PACKAGE_PIN R39 [get_ports {${direction1Pins}_data[13]}]
+ set_property PACKAGE_PIN U34 [get_ports {${direction1Pins}_data[14]}]
+ set_property PACKAGE_PIN T35 [get_ports {${direction1Pins}_data[15]}]
+ set_property PACKAGE_PIN R33 [get_ports {${direction1Pins}_data[16]}]
+ set_property PACKAGE_PIN R34 [get_ports {${direction1Pins}_data[17]}]
+ set_property PACKAGE_PIN N33 [get_ports {${direction1Pins}_data[18]}]
+ set_property PACKAGE_PIN N34 [get_ports {${direction1Pins}_data[19]}]
+ set_property PACKAGE_PIN P32 [get_ports {${direction1Pins}_data[20]}]
+ set_property PACKAGE_PIN P33 [get_ports {${direction1Pins}_data[21]}]
+ set_property PACKAGE_PIN V35 [get_ports {${direction1Pins}_data[22]}]
+ set_property PACKAGE_PIN V36 [get_ports {${direction1Pins}_data[23]}]
+ set_property PACKAGE_PIN W36 [get_ports {${direction1Pins}_data[24]}]
+ set_property PACKAGE_PIN W37 [get_ports {${direction1Pins}_data[25]}]
+ set_property PACKAGE_PIN T32 [get_ports {${direction1Pins}_data[26]}]
+ set_property PACKAGE_PIN R32 [get_ports {${direction1Pins}_data[27]}]
+ set_property PACKAGE_PIN V39 [get_ports {${direction1Pins}_data[28]}]
+ set_property PACKAGE_PIN V40 [get_ports {${direction1Pins}_data[29]}]
+ set_property PACKAGE_PIN P37 [get_ports {${direction1Pins}_data[30]}]
+ set_property PACKAGE_PIN P38 [get_ports {${direction1Pins}_data[31]}]
+
+ set_property PACKAGE_PIN T36 [get_ports ${direction1Pins}_send]
+ set_property PACKAGE_PIN R37 [get_ports ${direction1Pins}_rst]
+
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[31]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[30]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[29]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[28]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[27]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[26]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[25]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[24]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[23]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[22]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[21]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[20]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[19]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[18]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[17]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[16]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[15]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[14]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[13]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[12]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[11]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[10]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[9]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[8]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[7]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[6]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[5]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[4]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[3]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[2]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[1]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[0]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[31]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[30]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[29]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[28]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[27]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[26]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[25]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[24]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[23]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[22]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[21]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[20]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[19]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[18]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[17]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[16]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[15]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[14]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[13]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[12]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[11]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[10]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[9]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[8]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[7]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[6]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[5]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[4]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[3]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[2]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[1]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[0]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[31]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[30]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[29]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[28]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[27]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[26]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[25]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[24]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[23]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[22]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[21]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[20]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[19]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[18]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[17]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[16]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[15]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[14]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[13]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[12]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[11]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[10]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[9]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[8]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[7]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[6]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[5]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[4]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[3]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[2]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[1]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[0]}]
+
+
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction0Pins}_clk]
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction0Pins}_rst]
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction0Pins}_send]
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction1Pins}_clk]
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction1Pins}_rst]
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction1Pins}_send]
+ set_property SLEW FAST [get_ports ${direction1Pins}_clk]
+ set_property SLEW FAST [get_ports ${direction1Pins}_rst]
+ set_property SLEW FAST [get_ports ${direction1Pins}_send]
+
+
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[31]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[30]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[29]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[28]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[27]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[26]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[25]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[24]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[23]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[22]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[21]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[20]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[19]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[18]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[17]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[16]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[15]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[14]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[13]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[12]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[11]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[10]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[9]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[8]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[7]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[6]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[5]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[4]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[3]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[2]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[1]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[0]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_send]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_clk]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_rst]
+
+ # Aloe reset sent to FPGA
+ set_property IOSTANDARD LVCMOS18 [get_ports ereset_n]
+ set_property PACKAGE_PIN AF40 [get_ports ereset_n]
+
+ #Put first level RX/TX flops in IOB
+ set_property IOB TRUE [get_cells -of_objects [all_fanout -flat -endpoints_only [get_ports "chiplink_b2c_data*"]]]
+ set_property IOB TRUE [get_cells -of_objects [all_fanout -flat -endpoints_only [get_ports "chiplink_b2c_send"]]]
+ set_property IOB TRUE [get_cells -of_objects [all_fanin -flat -startpoints_only [get_ports "chiplink_c2b_data*"]]]
+ set_property IOB TRUE [get_cells -of_objects [all_fanin -flat -startpoints_only [get_ports "chiplink_c2b_send"]]]
+"""
+ )
+*/
+ }
+
+ def connectChipLink(dut: { val chiplink: Seq[WideDataLayerPort] } , iofpga: Boolean = false): Unit = {
+ constrainChipLink(iofpga)
+
+ chiplink <> dut.chiplink(0)
+ //dut.chiplink_xilinx_7series_phy.get.idelayctrl_refclk := sys_clock
+ }
+}
+
+abstract class PolarFireEvalKitShell(implicit val p: Parameters) extends RawModule {
+
+ //-----------------------------------------------------------------------
+ // Interface
+ //-----------------------------------------------------------------------
+
+ // 50MHz crystal oscillator
+ val ref_clk0 = IO(Input(Clock()))
+
+ //
+ val ref_clk_pad_p = IO(Input(Bool()))
+ val ref_clk_pad_n = IO(Input(Bool()))
+
+ // Reset push-button - active low
+ val pf_user_reset_n = IO(Input(Bool()))
+
+ // LED
+ val led = IO(Vec(8, Output(Bool())))
+
+ // UART
+ val uart_tx = IO(Output(Bool()))
+ val uart_rx = IO(Input(Bool()))
+
+ // SPI Flash
+ val spi_flash_reset = IO(Output(Bool()))
+ val spi_flash_sdo = IO(Output(Bool()))
+ val spi_flash_sdi = IO(Input(Bool()))
+ val spi_flash_sck = IO(Output(Bool()))
+ val spi_flash_ss = IO(Output(Bool()))
+ val spi_flash_wp = IO(Output(Bool()))
+ val spi_flash_hold = IO(Output(Bool()))
+
+ // JTAG
+ val jtag_TRSTB = IO(Input(Bool()))
+ val jtag_TCK = IO(Input(Clock()))
+ val jtag_TMS = IO(Input(Bool()))
+ val jtag_TDI = IO(Input(Bool()))
+ val jtag_TDO = IO(Output(Bool()))
+
+ //Buttons
+ val btn_0 = IO(Analog(1.W))
+ val btn_1 = IO(Analog(1.W))
+ val btn_2 = IO(Analog(1.W))
+ val btn_3 = IO(Analog(1.W))
+
+ //Sliding switches
+ val sw_0 = IO(Analog(1.W))
+ val sw_1 = IO(Analog(1.W))
+ val sw_2 = IO(Analog(1.W))
+ val sw_3 = IO(Analog(1.W))
+ val sw_4 = IO(Analog(1.W))
+ val sw_5 = IO(Analog(1.W))
+ val sw_6 = IO(Analog(1.W))
+ val sw_7 = IO(Analog(1.W))
+
+ // debug
+ val debug_io0 = IO(Output(Bool()))
+ val debug_io1 = IO(Output(Clock()))
+ val debug_io2 = IO(Output(Bool()))
+ val debug_io3 = IO(Output(Bool()))
+ val debug_io4 = IO(Output(Clock()))
+ val debug_io5 = IO(Output(Bool()))
+
+ //-----------------------------------------------------------------------
+ // Wire declarations
+ //-----------------------------------------------------------------------
+
+ val sys_clock = Wire(Clock())
+ val sys_reset_n = Wire(Bool())
+
+ val dut_clock = Wire(Clock())
+ val dut_reset = Wire(Bool())
+ val dut_reset_i = Wire(Bool())
+ val dut_reset_sync = Wire(Bool())
+
+ val dut_ndreset = Wire(Bool())
+
+ val mig_mmcm_locked = Wire(Bool())
+ val mig_sys_reset = Wire(Bool())
+
+ val mig_clock = Wire(Clock())
+ val mig_reset = Wire(Bool())
+ val mig_resetn = Wire(Bool())
+
+ val mig_clock_in = Wire(Clock())
+ val mig_clock_out = Wire(Clock())
+ val mig_plllock_out = Wire(Bool())
+
+ val pcie_dat_reset = Wire(Bool())
+ val pcie_dat_resetn = Wire(Bool())
+ val pcie_cfg_reset = Wire(Bool())
+ val pcie_cfg_resetn = Wire(Bool())
+ val pcie_dat_clock = Wire(Clock())
+ val pcie_cfg_clock = Wire(Clock())
+ val mmcm_lock_pcie = Wire(Bool())
+
+ val fpga_reset = Wire(Bool())
+ val ddr_ctrlr_ready = Wire(Bool())
+
+ //-----------------------------------------------------------------------
+ // Differential clock
+ //-----------------------------------------------------------------------
+ val pf_xcvr_ref_clk = Module(new PolarFireTransceiverRefClk)
+ pf_xcvr_ref_clk.io.REF_CLK_PAD_P := ref_clk_pad_p
+ pf_xcvr_ref_clk.io.REF_CLK_PAD_N := ref_clk_pad_n
+ val pcie_refclk = pf_xcvr_ref_clk.io.REF_CLK
+
+ val pf_tx_pll = Module(new PolarFireTxPLL)
+ pf_tx_pll.io.REF_CLK := pcie_refclk
+ val pf_tx_pll_bitclk = pf_tx_pll.io.BIT_CLK
+ val pf_tx_pll_refclk_to_lane = pf_tx_pll.io.REF_CLK_TO_LANE
+ val pf_tx_pll_lock = pf_tx_pll.io.LOCK
+
+ //-----------------------------------------------------------------------
+ // DDR3 Subsystem Clocks
+ //-----------------------------------------------------------------------
+ val ddr3_clk_ccc = Module(new PolarFireCCC(
+ PLLParameters(
+ name = "ddr3_clk_ccc",
+ PLLInClockParameters(50),
+ Seq(PLLOutClockParameters(111.111)))))
+
+ ddr3_clk_ccc.io.REF_CLK_0 := ref_clk0
+ val ddr3_clk_in = ddr3_clk_ccc.io.OUT0_FABCLK_0.get
+ val ddr3_clk_in_lock = ddr3_clk_ccc.io.PLL_LOCK_0
+ mig_clock_in := ddr3_clk_in
+
+ //-----------------------------------------------------------------------
+ // Coreplex Clock Generator
+ //-----------------------------------------------------------------------
+ val hart_clk_ccc = Module(new PolarFireCCC(
+ PLLParameters(
+ name = "hart_clk_ccc",
+ PLLInClockParameters(166.666),
+ Seq(
+ PLLOutClockParameters(25),
+ PLLOutClockParameters(125),
+ PLLOutClockParameters(150)
+ )
+ )
+ ))
+
+ val hart_clk_25 = hart_clk_ccc.io.OUT0_FABCLK_0.get
+ val hart_clk_125 = hart_clk_ccc.io.OUT1_FABCLK_0.get
+ val hart_clk_150 = hart_clk_ccc.io.OUT2_FABCLK_0.get
+ val hart_clk_lock = hart_clk_ccc.io.PLL_LOCK_0
+
+ // DUT clock
+ hart_clk_ccc.io.REF_CLK_0 := mig_clock_out
+ dut_clock := hart_clk_25
+
+// debug_io1 := dut_clock
+// debug_io2 := hart_clk_lock
+// debug_io3 := ddr3_clk_in
+
+ //-----------------------------------------------------------------------
+ // System reset
+ //-----------------------------------------------------------------------
+ val pf_init_monitor = Module(new PolarFireInitMonitor)
+
+ val pf_reset = Module(new PolarFireReset)
+
+ pf_reset.io.CLK := ddr3_clk_in
+ pf_reset.io.PLL_LOCK := ddr3_clk_in_lock
+ pf_reset.io.INIT_DONE := pf_init_monitor.io.DEVICE_INIT_DONE
+ pf_reset.io.EXT_RST_N := pf_user_reset_n
+
+ pf_reset.io.SS_BUSY := UInt("b0")
+ pf_reset.io.FF_US_RESTORE := UInt("b0")
+
+ fpga_reset := !pf_reset.io.FABRIC_RESET_N
+
+ sys_reset_n := pf_reset.io.FABRIC_RESET_N
+
+// debug_io4 := sys_reset_n
+
+ mig_resetn := !mig_reset
+ pcie_dat_resetn := !pcie_dat_reset
+ pcie_cfg_resetn := !pcie_cfg_reset
+
+ dut_reset_i := !pf_reset.io.FABRIC_RESET_N | !hart_clk_lock | !ddr_ctrlr_ready
+
+// withClockAndReset(hart_clk, fpga_reset) {
+// dut_reset := ResetCatchAndSync(hart_clk, dut_reset_i, 10)
+// }
+ withClockAndReset(dut_clock, fpga_reset) {
+ dut_reset := ResetCatchAndSync(dut_clock, dut_reset_i, 10)
+ }
+
+ //overrided in connectMIG and connect PCIe
+ //provide defaults to allow above reset sequencing logic to work without both
+ mig_clock := dut_clock
+ pcie_dat_clock := dut_clock
+ pcie_cfg_clock := dut_clock
+ mig_mmcm_locked := UInt("b1")
+ mmcm_lock_pcie := UInt("b1")
+
+ led(4) := dut_ndreset
+ led(5) := !pf_user_reset_n
+ led(6) := fpga_reset
+ led(7) := dut_reset
+
+ //-----------------------------------------------------------------------
+ // PCIe Subsystem TL Clock
+ //-----------------------------------------------------------------------
+ val pf_oscillator = Module(new PolarFireOscillator)
+ val pf_clk_divider = Module(new PolarFireClockDivider)
+ val pf_glitchless_mux = Module(new PolarFireGlitchlessMux)
+ pf_clk_divider.io.CLK_IN := pf_oscillator.io.RCOSC_160MHZ_GL
+ pf_glitchless_mux.io.CLK0 := pf_clk_divider.io.CLK_OUT
+ pf_glitchless_mux.io.CLK1 := hart_clk_125
+ pf_glitchless_mux.io.SEL := pf_init_monitor.io.PCIE_INIT_DONE
+ val pcie_tl_clk = pf_glitchless_mux.io.CLK_OUT
+
+ //---------------------------------------------------------------------
+ // Debug JTAG
+ //---------------------------------------------------------------------
+
+ // JTAG inside the FPGA fabric through user JTAG FPGA macro (UJTAG)
+/*
+ val fpga_jtag = Module(new CoreJtagDebugBlock)
+
+ fpga_jtag.io.UTDO_IN_0 := UInt("b0")
+ fpga_jtag.io.UTDO_IN_1 := UInt("b0")
+ fpga_jtag.io.UTDO_IN_2 := UInt("b0")
+ fpga_jtag.io.UTDO_IN_3 := UInt("b0")
+ fpga_jtag.io.UTDODRV_0 := UInt("b0")
+ fpga_jtag.io.UTDODRV_1 := UInt("b0")
+ fpga_jtag.io.UTDODRV_2 := UInt("b0")
+ fpga_jtag.io.UTDODRV_3 := UInt("b0")
+
+ def connectDebugJTAG(dut: HasPeripheryDebugModuleImp): SystemJTAGIO = {
+ val djtag = dut.debug.systemjtag.get
+
+ djtag.jtag.TCK := fpga_jtag.io.TGT_TCK
+ djtag.jtag.TMS := fpga_jtag.io.TGT_TMS
+ djtag.jtag.TDI := fpga_jtag.io.TGT_TDI
+ fpga_jtag.io.TGT_TDO := djtag.jtag.TDO.data
+
+ fpga_jtag.io.TRSTB := jtag_TRSTB
+ fpga_jtag.io.TCK := jtag_TCK
+ fpga_jtag.io.TMS := jtag_TMS
+ fpga_jtag.io.TDI := jtag_TDI
+ jtag_TDO := fpga_jtag.io.TDO
+
+ djtag.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W)
+
+ djtag.reset := fpga_reset
+ dut_ndreset := dut.debug.ndreset
+ djtag
+ }
+*/
+ //-----------------------------------------------------------------------
+ // UART
+ //-----------------------------------------------------------------------
+
+ def connectUART(dut: HasPeripheryUARTModuleImp): Unit = dut.uart.headOption.foreach(connectUART)
+
+ def connectUART(uart: UARTPortIO): Unit = {
+ uart.rxd := SyncResetSynchronizerShiftReg(uart_rx, 2, init = Bool(true), name=Some("uart_rxd_sync"))
+ uart_tx := uart.txd
+ }
+
+ //-----------------------------------------------------------------------
+ // SPI
+ //-----------------------------------------------------------------------
+
+ def connectSPI(dut: HasPeripherySPIModuleImp): Unit = dut.spi.headOption.foreach(connectSPI)
+
+ def connectSPI(spi: SPIPortIO): Unit = {
+ spi_flash_reset := fpga_reset
+ spi_flash_wp := UInt("b0")
+ spi_flash_hold := UInt("b0")
+ spi_flash_sck := spi.sck
+ spi_flash_ss := spi.cs(0)
+ spi_flash_sdo := spi.dq(0).o
+ spi.dq(0).i := spi_flash_sdi
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/PolarFireShell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/PolarFireShell.scala
new file mode 100644
index 0000000..c6e0d69
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/PolarFireShell.scala
@@ -0,0 +1,42 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.microsemi
+
+ import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.util._
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.ip.microsemi.polarfireccc._
+import sifive.fpgashells.ip.microsemi.polarfireinitmonitor._
+import sifive.fpgashells.shell._
+
+ class IO_PDC(val name: String)
+{
+ private var constraints: Seq[() => String] = Nil
+ protected def addConstraint(command: => String) { constraints = (() => command) +: constraints }
+ ElaborationArtefacts.add(name, constraints.map(_()).reverse.mkString("\n") + "\n")
+
+ def addPin(io: IOPin, pin: String, ioStandard: String = "") {
+ def dir = if (io.isInput) { if (io.isOutput) "INOUT" else "INPUT" } else { "OUTPUT" }
+ def ioSt = if (!ioStandard.isEmpty) {
+ require(ioStandard == "LVCMOS33")
+ "-io_std LVCMOS33"
+ } else {""}
+ addConstraint(s"set_io -port_name {${io.name}} -pin_name ${pin} -fixed true -DIRECTION ${dir} ${ioSt} ")
+ }
+}
+
+ abstract class MicrosemiShell()(implicit p: Parameters) extends IOShell
+{
+ val sdc = new SDC("shell.sdc")
+ val io_pdc = new IO_PDC("shell.io.pdc")
+}
+
+ abstract class PolarFireShell()(implicit p: Parameters) extends MicrosemiShell
+{
+ val initMonitor = InModuleBody { Module(new PolarFireInitMonitor) }
+ val pllFactory = new PLLFactory(this, 7, p => Module(new PolarFireCCC(p)))
+ override def designParameters = super.designParameters.alterPartial {
+ case PLLFactoryKey => pllFactory
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/VeraShell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/VeraShell.scala
new file mode 100644
index 0000000..8a21424
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/microsemi/VeraShell.scala
@@ -0,0 +1,251 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.microsemi
+
+import chisel3._
+import chisel3.experimental.IO
+import freechips.rocketchip.config._
+import freechips.rocketchip.util._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.microsemi._
+import sifive.blocks.devices.chiplink._
+
+import sifive.fpgashells.devices.microsemi.polarfireevalkitpciex4._
+import sifive.fpgashells.devices.microsemi.polarfireddr4._
+
+import sifive.fpgashells.ip.microsemi._
+import sifive.fpgashells.ip.microsemi.polarfirexcvrrefclk._
+import sifive.fpgashells.ip.microsemi.polarfiretxpll._
+import sifive.fpgashells.ip.microsemi.polarfire_oscillator._
+import sifive.fpgashells.ip.microsemi.polarfireclockdivider._
+import sifive.fpgashells.ip.microsemi.polarfireglitchlessmux._
+import sifive.fpgashells.ip.microsemi.polarfirereset._
+
+class SysClockVeraPlacedOverlay(val shell: VeraShell, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput)
+ extends ClockInputMicrosemiPlacedOverlay(name, designInput, shellInput)
+{
+ val node = shell { ClockSourceNode(freqMHz = 50, jitterPS = 50)(ValName(name)) }
+
+ shell { InModuleBody {
+ val (c, _) = node.out(0)
+ c.reset := shell.pllReset
+ shell.io_pdc.addPin(io:Clock, "AG4")
+ } }
+}
+class SysClockVeraShellPlacer(val shell: VeraShell, val shellInput: ClockInputShellInput)(implicit val valName: ValName)
+ extends ClockInputShellPlacer[VeraShell] {
+ def place(designInput: ClockInputDesignInput) = new SysClockVeraPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class LEDVeraPlacedOverlay(val shell: VeraShell, name: String, val designInput: LEDDesignInput, val shellInput: LEDShellInput)
+ extends LEDMicrosemiPlacedOverlay(name, designInput, shellInput, Seq("AK17", "AN17", "AM17", "AL18"))
+class LEDVeraShellPlacer(val shell: VeraShell, val shellInput: LEDShellInput)(implicit val valName: ValName)
+ extends LEDShellPlacer[VeraShell] {
+ def place(designInput: LEDDesignInput) = new LEDVeraPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class ChipLinkVeraPlacedOverlay(val shell: VeraShell, name: String, val designInput: ChipLinkDesignInput, val shellInput: ChipLinkShellInput)
+ extends ChipLinkPolarFirePlacedOverlay(name, designInput, shellInput)
+{
+ val ereset_n = shell { InModuleBody {
+ val ereset_n = IO(Input(Bool()))
+ ereset_n.suggestName("ereset_n")
+ shell.io_pdc.addPin(ereset_n, "U5")
+ ereset_n
+ } }
+
+ shell { InModuleBody {
+ val dir1 = Seq("U10", "AC8", "U9", /* clk, rst, send */
+ "V13", "W13", "T5", "T4", "V14", "W14", "R3", "R2",
+ "W6", "Y6", "U2", "U1", "T3", "T2", "W1", "Y1",
+ "V3", "V4", "AA4", "AA5", "V1", "V2", "Y3", "Y2",
+ "W4", "W3", "AA3", "AA2", "Y7", "AA7", "AB2", "AB1")
+ val dir2 = Seq("T9", "AD5", "AD3", /* clk, rst, send */
+ "AB9", "AA8", "AB5", "AC4", "AC1", "AD1", "AB4", "AC3",
+ "W10", "Y10", "AB7", "AB6", "W8", "Y8", "Y12", "Y13",
+ "AA10","AA9", "W11", "Y11", "AC7", "AC6", "AA14","AA13",
+ "AB11","AB10","AB14","AC13","AC11","AC12","AB12","AA12")
+ val dirB2C = Seq(IOPin(io.b2c.clk), IOPin(io.b2c.rst), IOPin(io.b2c.send)) ++
+ IOPin.of(io.b2c.data)
+ val dirC2B = Seq(IOPin(io.c2b.clk), IOPin(io.c2b.rst), IOPin(io.c2b.send)) ++
+ IOPin.of(io.c2b.data)
+ (dirB2C zip dir1) foreach { case (io, pin) => shell.io_pdc.addPin(io, pin) }
+ (dirC2B zip dir2) foreach { case (io, pin) => shell.io_pdc.addPin(io, pin) }
+
+ val (rx, _) = rxI.out(0)
+ rx.reset := shell.pllReset
+ } }
+}
+class ChipLinkVeraShellPlacer(val shell: VeraShell, val shellInput: ChipLinkShellInput)(implicit val valName: ValName)
+ extends ChipLinkShellPlacer[VeraShell] {
+ def place(designInput: ChipLinkDesignInput) = new ChipLinkVeraPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class PCIeVeraPlacedOverlay(val shell: VeraShell, name: String, val designInput: PCIeDesignInput, val shellInput: PCIeShellInput)
+ extends PCIePlacedOverlay[PolarFireEvalKitPCIeX4Pads](name, designInput, shellInput)
+{
+ val sdcClockName = "axiClock"
+ val pcie = LazyModule(new PolarFireEvalKitPCIeX4)
+ val ioNode = BundleBridgeSource(() => pcie.module.io.cloneType)
+ val topIONode = shell { ioNode.makeSink() }
+ val pcieClk_125 = shell { ClockSinkNode(freqMHz = 125)}
+ val pcieGroup = shell { ClockGroup()}
+ pcieClk_125 := designInput.wrangler := pcieGroup := designInput.corePLL
+
+ val slaveSide = TLIdentityNode()
+ pcie.crossTLIn(pcie.slave) := slaveSide
+ pcie.crossTLIn(pcie.control) := slaveSide
+ val node = NodeHandle(slaveSide, pcie.crossTLOut(pcie.master))
+ val intnode = pcie.crossIntOut(pcie.intnode)
+
+ def overlayOutput = PCIeOverlayOutput(node, intnode)
+ def ioFactory = new PolarFireEvalKitPCIeX4Pads
+
+ InModuleBody { ioNode.bundle <> pcie.module.io }
+
+ shell { InModuleBody {
+ val (sys, _) = shell.sys_clock.get.get.overlayOutput.node.out(0)
+ val (pcieClk, _) = pcieClk_125.in(0)
+ val port = topIONode.bundle.port
+ val coreClock = shell.pllFactory.plls.getWrappedValue(1)._1.getClocks(0)
+ io <> port
+
+
+ val refClk = Module(new PolarFireTransceiverRefClk)
+ val pcie_tx_pll = Module(new PolarFireTxPLL)
+ val pf_osc = Module(new PolarFireOscillator)
+ val pf_clk_div = Module(new PolarFireClockDivider)
+ val pf_gless_mux = Module(new PolarFireGlitchlessMux)
+
+ val pf_reset = Module(new PolarFireReset)
+ pf_reset.io.CLK := coreClock
+ pf_reset.io.PLL_LOCK := shell.pllFactory.plls.getWrappedValue(1)._1.getLocked
+ pf_reset.io.INIT_DONE := shell.initMonitor.io.DEVICE_INIT_DONE
+ pf_reset.io.EXT_RST_N := !shell.pllReset
+ //pf_reset.io.EXT_RST_N := true.B
+ pf_reset.io.SS_BUSY := false.B
+ pf_reset.io.FF_US_RESTORE := false.B
+ val sys_reset_n = pf_reset.io.FABRIC_RESET_N
+
+ val osc_rc160mhz = pf_osc.io.RCOSC_160MHZ_GL
+
+ pf_clk_div.io.CLK_IN := osc_rc160mhz
+ pf_gless_mux.io.CLK0 := pf_clk_div.io.CLK_OUT
+ pf_gless_mux.io.CLK1 := pcieClk.clock
+ pf_gless_mux.io.SEL := shell.initMonitor.io.PCIE_INIT_DONE
+
+ refClk.io.REF_CLK_PAD_P := io.REFCLK_rxp
+ refClk.io.REF_CLK_PAD_N := io.REFCLK_rxn
+ val pcie_fab_ref_clk = refClk.io.FAB_REF_CLK
+ pcie_tx_pll.io.REF_CLK := refClk.io.REF_CLK
+
+ val pf_rstb = IO(Output(Bool()))
+ pf_rstb.suggestName("pf_rstb")
+ val perst_x1_slot = IO(Output(Bool()))
+ perst_x1_slot.suggestName("perst_x1_slot")
+ val perst_x16_slot = IO(Output(Bool()))
+ perst_x16_slot.suggestName("perst_x16_slot")
+ val perst_m2_slot = IO(Output(Bool()))
+ perst_m2_slot.suggestName("perst_m2_slot")
+ val perst_sata_slot = IO(Output(Bool()))
+ perst_sata_slot.suggestName("perst_sata_slot")
+
+ val led_test = IO(Output(Bool()))
+ led_test.suggestName("led_test")
+ val led_test1 = IO(Output(Bool()))
+ led_test1.suggestName("led_test1")
+ val led_test2 = IO(Output(Bool()))
+ led_test2.suggestName("led_test2")
+
+ withClockAndReset(coreClock, !sys_reset_n) {
+ val timer = RegInit(268435456.U(29.W))
+ timer := timer - timer.orR
+ val pf_rstb_i= !(!pf_reset.io.FABRIC_RESET_N || timer.orR)
+
+ pf_rstb := pf_rstb_i
+ perst_x1_slot := pf_rstb_i
+ perst_x16_slot := pf_rstb_i
+ perst_m2_slot := pf_rstb_i
+ perst_sata_slot := pf_rstb_i
+
+ led_test := pf_rstb_i
+ }
+ led_test1 := shell.initMonitor.io.PCIE_INIT_DONE
+ led_test2 := shell.pllFactory.plls.getWrappedValue(1)._1.getLocked
+
+ port.APB_S_PCLK := coreClock
+ port.APB_S_PRESET_N := true.B
+ port.AXI_CLK := coreClock
+ port.AXI_CLK_STABLE := shell.pllFactory.plls.getWrappedValue(1)._1.getLocked //TODO: how to get correct number?
+ port.PCIE_1_TL_CLK_125MHz := pf_gless_mux.io.CLK_OUT
+ port.PCIE_1_TX_PLL_REF_CLK := pcie_tx_pll.io.REF_CLK_TO_LANE
+ port.PCIE_1_TX_BIT_CLK := pcie_tx_pll.io.BIT_CLK
+ port.PCIESS_LANE0_CDR_REF_CLK_0 := refClk.io.REF_CLK
+ port.PCIESS_LANE1_CDR_REF_CLK_0 := refClk.io.REF_CLK
+ port.PCIESS_LANE2_CDR_REF_CLK_0 := refClk.io.REF_CLK
+ port.PCIESS_LANE3_CDR_REF_CLK_0 := refClk.io.REF_CLK
+ port.PCIE_1_TX_PLL_LOCK := pcie_tx_pll.io.LOCK
+
+ shell.io_pdc.addPin(led_test, "AK17")
+ shell.io_pdc.addPin(led_test1, "AN17")
+ shell.io_pdc.addPin(led_test2, "AM17")
+ shell.io_pdc.addPin(pf_rstb, "AG15")
+ shell.io_pdc.addPin(perst_x1_slot, "B4", ioStandard = "LVCMOS33")
+ shell.io_pdc.addPin(perst_x16_slot, "A4", ioStandard = "LVCMOS33")
+ shell.io_pdc.addPin(perst_m2_slot, "B5", ioStandard = "LVCMOS33")
+ shell.io_pdc.addPin(perst_sata_slot, "A5", ioStandard = "LVCMOS33")
+ shell.io_pdc.addPin(io.REFCLK_rxp, "W27")
+ shell.io_pdc.addPin(io.REFCLK_rxn, "W28")
+ shell.io_pdc.addPin(io.PCIESS_LANE_TXD0_N, "V34")
+ shell.io_pdc.addPin(io.PCIESS_LANE_TXD0_P, "V33")
+ shell.io_pdc.addPin(io.PCIESS_LANE_TXD1_N, "Y34")
+ shell.io_pdc.addPin(io.PCIESS_LANE_TXD1_P, "Y33")
+ shell.io_pdc.addPin(io.PCIESS_LANE_TXD2_N, "AA32")
+ shell.io_pdc.addPin(io.PCIESS_LANE_TXD2_P, "AA31")
+ shell.io_pdc.addPin(io.PCIESS_LANE_TXD3_N, "AB34")
+ shell.io_pdc.addPin(io.PCIESS_LANE_TXD3_P, "AB33")
+ shell.io_pdc.addPin(io.PCIESS_LANE_RXD0_N, "V30")
+ shell.io_pdc.addPin(io.PCIESS_LANE_RXD0_P, "V29")
+ shell.io_pdc.addPin(io.PCIESS_LANE_RXD1_N, "W32")
+ shell.io_pdc.addPin(io.PCIESS_LANE_RXD1_P, "W31")
+ shell.io_pdc.addPin(io.PCIESS_LANE_RXD2_N, "Y30")
+ shell.io_pdc.addPin(io.PCIESS_LANE_RXD2_P, "Y29")
+ shell.io_pdc.addPin(io.PCIESS_LANE_RXD3_N, "AB30")
+ shell.io_pdc.addPin(io.PCIESS_LANE_RXD3_P, "AB29")
+
+ shell.sdc.addClock(s"${name}_ref_clk", io.REFCLK_rxp, 100)
+ } }
+
+ shell.sdc.addGroup(clocks = Seq("osc_rc160mhz"))
+}
+class PCIeVeraShellPlacer(val shell: VeraShell, val shellInput: PCIeShellInput)(implicit val valName: ValName)
+ extends PCIeShellPlacer[VeraShell] {
+ def place(designInput: PCIeDesignInput) = new PCIeVeraPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class VeraShell()(implicit p: Parameters) extends PolarFireShell
+{
+ // PLL reset causes
+ val pllReset = InModuleBody { Wire(Bool()) }
+
+ val sys_clock = Overlay(ClockInputOverlayKey, new SysClockVeraShellPlacer(this, ClockInputShellInput()))
+ val led = Overlay(LEDOverlayKey, new LEDVeraShellPlacer(this, LEDShellInput()))
+ val chiplink = Overlay(ChipLinkOverlayKey, new ChipLinkVeraShellPlacer(this, ChipLinkShellInput()))
+ val pcie = Overlay(PCIeOverlayKey, new PCIeVeraShellPlacer(this, PCIeShellInput()))
+
+ val topDesign = LazyModule(p(DesignKey)(designParameters))
+
+ override lazy val module = new LazyRawModuleImp(this) {
+ val pf_user_reset_n = IO(Input(Bool()))
+ io_pdc.addPin(pf_user_reset_n, "AK18")
+ val ereset: Bool = chiplink.get() match {
+ case Some(x: ChipLinkVeraPlacedOverlay) => !x.ereset_n
+ case _ => false.B
+ }
+ pllReset :=
+ !pf_user_reset_n ||
+ !initMonitor.io.DEVICE_INIT_DONE || ereset
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/package.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/package.scala
new file mode 100644
index 0000000..0669f14
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/package.scala
@@ -0,0 +1,10 @@
+// See LICENSE for license details.
+package sifive.fpgashells
+
+import chisel3._
+import scala.language.implicitConversions
+
+package object shell {
+ implicit def boolToIOPin(x: Bool): IOPin = IOPin(x, 0)
+ implicit def clockToIOPin(x: Clock): IOPin = IOPin(x, 0)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/Arty100TShell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/Arty100TShell.scala
new file mode 100644
index 0000000..a03a5bd
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/Arty100TShell.scala
@@ -0,0 +1,369 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.util.SyncResetSynchronizerShiftReg
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+import sifive.fpgashells.devices.xilinx.xilinxarty100tmig._
+
+class SysClockArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput)
+ extends SingleEndedClockInputXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ val node = shell { ClockSourceNode(freqMHz = 100, jitterPS = 50) }
+
+ shell { InModuleBody {
+ val clk: Clock = io
+ shell.xdc.addPackagePin(clk, "E3")
+ shell.xdc.addIOStandard(clk, "LVCMOS33")
+ } }
+}
+class SysClockArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: ClockInputShellInput)(implicit val valName: ValName)
+ extends ClockInputShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: ClockInputDesignInput) = new SysClockArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+//PMOD JA used for SDIO
+class SDIOArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: SDIODesignInput, val shellInput: SDIOShellInput)
+ extends SDIOXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("D12", IOPin(io.sdio_clk)),
+ ("B11", IOPin(io.sdio_cmd)),
+ ("A11", IOPin(io.sdio_dat_0)),
+ ("D13", IOPin(io.sdio_dat_1)),
+ ("B18", IOPin(io.sdio_dat_2)),
+ ("G13", IOPin(io.sdio_dat_3)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS33")
+ shell.xdc.addIOB(io)
+ } }
+ packagePinsWithPackageIOs drop 1 foreach { case (pin, io) => {
+ shell.xdc.addPullup(io)
+ } }
+ } }
+}
+class SDIOArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: SDIOShellInput)(implicit val valName: ValName)
+ extends SDIOShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: SDIODesignInput) = new SDIOArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class SPIFlashArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: SPIFlashDesignInput, val shellInput: SPIFlashShellInput)
+ extends SPIFlashXilinxPlacedOverlay(name, designInput, shellInput)
+{
+
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("L16", IOPin(io.qspi_sck)),
+ ("L13", IOPin(io.qspi_cs)),
+ ("K17", IOPin(io.qspi_dq(0))),
+ ("K18", IOPin(io.qspi_dq(1))),
+ ("L14", IOPin(io.qspi_dq(2))),
+ ("M14", IOPin(io.qspi_dq(3))))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS33")
+ } }
+ packagePinsWithPackageIOs drop 1 foreach { case (pin, io) => {
+ shell.xdc.addPullup(io)
+ } }
+ } }
+}
+class SPIFlashArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: SPIFlashShellInput)(implicit val valName: ValName)
+ extends SPIFlashShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: SPIFlashDesignInput) = new SPIFlashArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class TracePMODArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: TracePMODDesignInput, val shellInput: TracePMODShellInput)
+ extends TracePMODXilinxPlacedOverlay(name, designInput, shellInput, packagePins = Seq("U12", "V12", "V10", "V11", "U14", "V14", "T13", "U13"))
+class TracePMODArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: TracePMODShellInput)(implicit val valName: ValName)
+ extends TracePMODShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: TracePMODDesignInput) = new TracePMODArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class GPIOPMODArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: GPIOPMODDesignInput, val shellInput: GPIOPMODShellInput)
+ extends GPIOPMODXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("E15", IOPin(io.gpio_pmod_0)), //These are PMOD B
+ ("E16", IOPin(io.gpio_pmod_1)),
+ ("D15", IOPin(io.gpio_pmod_2)),
+ ("C15", IOPin(io.gpio_pmod_3)),
+ ("J17", IOPin(io.gpio_pmod_4)),
+ ("J18", IOPin(io.gpio_pmod_5)),
+ ("K15", IOPin(io.gpio_pmod_6)),
+ ("J15", IOPin(io.gpio_pmod_7)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS33")
+ } }
+ packagePinsWithPackageIOs drop 7 foreach { case (pin, io) => {
+ shell.xdc.addPullup(io)
+ } }
+ } }
+}
+class GPIOPMODArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: GPIOPMODShellInput)(implicit val valName: ValName)
+ extends GPIOPMODShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: GPIOPMODDesignInput) = new GPIOPMODArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class UARTArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: UARTDesignInput, val shellInput: UARTShellInput)
+ extends UARTXilinxPlacedOverlay(name, designInput, shellInput, false)
+{
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("A9", IOPin(io.rxd)),
+ ("D10", IOPin(io.txd)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS33")
+ shell.xdc.addIOB(io)
+ } }
+ } }
+}
+class UARTArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: UARTShellInput)(implicit val valName: ValName)
+ extends UARTShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: UARTDesignInput) = new UARTArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+//LEDS - 4 normal leds, r0, g0, b0, r1, g1, b1 ...
+object LEDArtyPinConstraints{
+ val pins = Seq("H5", "J5", "T9", "T10", "G6", "F6", "E1", "G3", "J4", "G4", "J3", "J2", "H4", "K1", "H6", "K2")
+}
+class LEDArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: LEDDesignInput, val shellInput: LEDShellInput)
+ extends LEDXilinxPlacedOverlay(name, designInput, shellInput, packagePin = Some(LEDArtyPinConstraints.pins(shellInput.number)))
+class LEDArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: LEDShellInput)(implicit val valName: ValName)
+ extends LEDShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: LEDDesignInput) = new LEDArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+//SWs
+object SwitchArtyPinConstraints{
+ val pins = Seq("A8", "C11", "C10", "A10")
+}
+class SwitchArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: SwitchDesignInput, val shellInput: SwitchShellInput)
+ extends SwitchXilinxPlacedOverlay(name, designInput, shellInput, packagePin = Some(SwitchArtyPinConstraints.pins(shellInput.number)))
+class SwitchArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: SwitchShellInput)(implicit val valName: ValName)
+ extends SwitchShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: SwitchDesignInput) = new SwitchArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+//Buttons
+object ButtonArtyPinConstraints {
+ val pins = Seq("D9", "C9", "B9", "B8")
+}
+class ButtonArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: ButtonDesignInput, val shellInput: ButtonShellInput)
+ extends ButtonXilinxPlacedOverlay(name, designInput, shellInput, packagePin = Some(ButtonArtyPinConstraints.pins(shellInput.number)))
+class ButtonArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: ButtonShellInput)(implicit val valName: ValName)
+ extends ButtonShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: ButtonDesignInput) = new ButtonArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class JTAGDebugBScanArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: JTAGDebugBScanDesignInput, val shellInput: JTAGDebugBScanShellInput)
+ extends JTAGDebugBScanXilinxPlacedOverlay(name, designInput, shellInput)
+class JTAGDebugBScanArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: JTAGDebugBScanShellInput)(implicit val valName: ValName)
+ extends JTAGDebugBScanShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: JTAGDebugBScanDesignInput) = new JTAGDebugBScanArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+// PMOD JD used for JTAG
+class JTAGDebugArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: JTAGDebugDesignInput, val shellInput: JTAGDebugShellInput)
+ extends JTAGDebugXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ shell.sdc.addClock("JTCK", IOPin(io.jtag_TCK), 10)
+ shell.sdc.addGroup(clocks = Seq("JTCK"))
+ shell.xdc.clockDedicatedRouteFalse(IOPin(io.jtag_TCK))
+ val packagePinsWithPackageIOs = Seq(("F4", IOPin(io.jtag_TCK)), //pin JD-3
+ ("D2", IOPin(io.jtag_TMS)), //pin JD-8
+ ("E2", IOPin(io.jtag_TDI)), //pin JD-7
+ ("D4", IOPin(io.jtag_TDO)), //pin JD-1
+ ("H2", IOPin(io.srst_n)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS33")
+ shell.xdc.addPullup(io)
+ } }
+ } }
+}
+class JTAGDebugArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: JTAGDebugShellInput)(implicit val valName: ValName)
+ extends JTAGDebugShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: JTAGDebugDesignInput) = new JTAGDebugArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+//cjtag
+class cJTAGDebugArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: cJTAGDebugDesignInput, val shellInput: cJTAGDebugShellInput)
+ extends cJTAGDebugXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ shell.sdc.addClock("JTCKC", IOPin(io.cjtag_TCKC), 10)
+ shell.sdc.addGroup(clocks = Seq("JTCKC"))
+ shell.xdc.clockDedicatedRouteFalse(IOPin(io.cjtag_TCKC))
+ val packagePinsWithPackageIOs = Seq(("F4", IOPin(io.cjtag_TCKC)), //pin JD-3
+ ("D2", IOPin(io.cjtag_TMSC)), //pin JD-8
+ ("H2", IOPin(io.srst_n)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS33")
+ } }
+ shell.xdc.addPullup(IOPin(io.cjtag_TCKC))
+ shell.xdc.addPullup(IOPin(io.srst_n))
+ } }
+}
+class cJTAGDebugArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: cJTAGDebugShellInput)(implicit val valName: ValName)
+ extends cJTAGDebugShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: cJTAGDebugDesignInput) = new cJTAGDebugArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+case object ArtyDDRSize extends Field[BigInt](0x10000000L * 1) // 256 MB
+class DDRArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: DDRDesignInput, val shellInput: DDRShellInput)
+ extends DDRPlacedOverlay[XilinxArty100TMIGPads](name, designInput, shellInput)
+{
+ val size = p(ArtyDDRSize)
+
+ val ddrClk1 = shell { ClockSinkNode(freqMHz = 166.666)}
+ val ddrClk2 = shell { ClockSinkNode(freqMHz = 200)}
+ val ddrGroup = shell { ClockGroup() }
+ ddrClk1 := di.wrangler := ddrGroup := di.corePLL
+ ddrClk2 := di.wrangler := ddrGroup
+
+ val migParams = XilinxArty100TMIGParams(address = AddressSet.misaligned(di.baseAddress, size))
+ val mig = LazyModule(new XilinxArty100TMIG(migParams))
+ val ioNode = BundleBridgeSource(() => mig.module.io.cloneType)
+ val topIONode = shell { ioNode.makeSink() }
+ val ddrUI = shell { ClockSourceNode(freqMHz = 100) }
+ val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) }
+ areset := di.wrangler := ddrUI
+
+ def overlayOutput = DDROverlayOutput(ddr = mig.node)
+ def ioFactory = new XilinxArty100TMIGPads(size)
+
+ InModuleBody { ioNode.bundle <> mig.module.io }
+
+ shell { InModuleBody {
+ require (shell.sys_clock.get.isDefined, "Use of DDRArtyPlacedOverlay depends on SysClockArtyPlacedOverlay")
+ val (sys, _) = shell.sys_clock.get.get.overlayOutput.node.out(0)
+ val (ui, _) = ddrUI.out(0)
+ val (dclk1, _) = ddrClk1.in(0)
+ val (dclk2, _) = ddrClk2.in(0)
+ val (ar, _) = areset.in(0)
+ val port = topIONode.bundle.port
+
+ io <> port
+ ui.clock := port.ui_clk
+ ui.reset := !port.mmcm_locked || port.ui_clk_sync_rst
+ port.sys_clk_i := dclk1.clock.asUInt
+ port.clk_ref_i := dclk2.clock.asUInt
+ port.sys_rst := shell.pllReset
+ port.aresetn := !ar.reset
+ } }
+
+ shell.sdc.addGroup(clocks = Seq("clk_pll_i"), pins = Seq(mig.island.module.blackbox.io.ui_clk))
+}
+class DDRArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: DDRShellInput)(implicit val valName: ValName)
+ extends DDRShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: DDRDesignInput) = new DDRArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+//Core to shell external resets
+class CTSResetArtyPlacedOverlay(val shell: Arty100TShellBasicOverlays, name: String, val designInput: CTSResetDesignInput, val shellInput: CTSResetShellInput)
+ extends CTSResetPlacedOverlay(name, designInput, shellInput)
+class CTSResetArtyShellPlacer(val shell: Arty100TShellBasicOverlays, val shellInput: CTSResetShellInput)(implicit val valName: ValName)
+ extends CTSResetShellPlacer[Arty100TShellBasicOverlays] {
+ def place(designInput: CTSResetDesignInput) = new CTSResetArtyPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+
+abstract class Arty100TShellBasicOverlays()(implicit p: Parameters) extends Series7Shell {
+ // Order matters; ddr depends on sys_clock
+ val sys_clock = Overlay(ClockInputOverlayKey, new SysClockArtyShellPlacer(this, ClockInputShellInput()))
+ val led = Seq.tabulate(16)(i => Overlay(LEDOverlayKey, new LEDArtyShellPlacer(this, LEDMetas(i))(valName = ValName(s"led_$i"))))
+ val switch = Seq.tabulate(4)(i => Overlay(SwitchOverlayKey, new SwitchArtyShellPlacer(this, SwitchShellInput(number = i))(valName = ValName(s"switch_$i"))))
+ val button = Seq.tabulate(4)(i => Overlay(ButtonOverlayKey, new ButtonArtyShellPlacer(this, ButtonShellInput(number = i))(valName = ValName(s"button_$i"))))
+ val ddr = Overlay(DDROverlayKey, new DDRArtyShellPlacer(this, DDRShellInput()))
+ val uart = Overlay(UARTOverlayKey, new UARTArtyShellPlacer(this, UARTShellInput()))
+ val sdio = Overlay(SDIOOverlayKey, new SDIOArtyShellPlacer(this, SDIOShellInput()))
+ val jtag = Overlay(JTAGDebugOverlayKey, new JTAGDebugArtyShellPlacer(this, JTAGDebugShellInput()))
+ val cjtag = Overlay(cJTAGDebugOverlayKey, new cJTAGDebugArtyShellPlacer(this, cJTAGDebugShellInput()))
+ val spi_flash = Overlay(SPIFlashOverlayKey, new SPIFlashArtyShellPlacer(this, SPIFlashShellInput()))
+ val cts_reset = Overlay(CTSResetOverlayKey, new CTSResetArtyShellPlacer(this, CTSResetShellInput()))
+ val jtagBScan = Overlay(JTAGDebugBScanOverlayKey, new JTAGDebugBScanArtyShellPlacer(this, JTAGDebugBScanShellInput()))
+
+ def LEDMetas(i: Int): LEDShellInput =
+ LEDShellInput(
+ color = if((i < 12) && (i % 3 == 1)) "green" else if((i < 12) && (i % 3 == 2)) "blue" else "red",
+ rgb = (i < 12),
+ number = i)
+}
+
+class Arty100TShell()(implicit p: Parameters) extends Arty100TShellBasicOverlays
+{
+ // PLL reset causes
+ val pllReset = InModuleBody { Wire(Bool()) }
+
+ val topDesign = LazyModule(p(DesignKey)(designParameters))
+
+ // Place the sys_clock at the Shell if the user didn't ask for it
+ p(ClockInputOverlayKey).foreach(_.place(ClockInputDesignInput()))
+
+ override lazy val module = new LazyRawModuleImp(this) {
+ val reset = IO(Input(Bool()))
+ xdc.addBoardPin(reset, "reset")
+
+ val reset_ibuf = Module(new IBUF)
+ reset_ibuf.io.I := reset
+ val sysclk: Clock = sys_clock.get() match {
+ case Some(x: SysClockArtyPlacedOverlay) => x.clock
+ }
+ val powerOnReset = PowerOnResetFPGAOnly(sysclk)
+ sdc.addAsyncPath(Seq(powerOnReset))
+
+ pllReset :=
+ (!reset_ibuf.io.O) || powerOnReset //Arty100T is active low reset
+ }
+}
+
+class Arty100TShellGPIOPMOD()(implicit p: Parameters) extends Arty100TShellBasicOverlays
+//This is the Shell used for coreip arty builds, with GPIOS and trace signals on the pmods
+{
+ // PLL reset causes
+ val pllReset = InModuleBody { Wire(Bool()) }
+
+ val gpio_pmod = Overlay(GPIOPMODOverlayKey, new GPIOPMODArtyShellPlacer(this, GPIOPMODShellInput()))
+ val trace_pmod = Overlay(TracePMODOverlayKey, new TracePMODArtyShellPlacer(this, TracePMODShellInput()))
+
+ val topDesign = LazyModule(p(DesignKey)(designParameters))
+
+ // Place the sys_clock at the Shell if the user didn't ask for it
+ p(ClockInputOverlayKey).foreach(_.place(ClockInputDesignInput()))
+
+ override lazy val module = new LazyRawModuleImp(this) {
+ val reset = IO(Input(Bool()))
+ xdc.addBoardPin(reset, "reset")
+
+ val reset_ibuf = Module(new IBUF)
+ reset_ibuf.io.I := reset
+
+ val sysclk: Clock = sys_clock.get() match {
+ case Some(x: SysClockArtyPlacedOverlay) => x.clock
+ }
+ val powerOnReset = PowerOnResetFPGAOnly(sysclk)
+ sdc.addAsyncPath(Seq(powerOnReset))
+ val ctsReset: Bool = cts_reset.get() match {
+ case Some(x: CTSResetArtyPlacedOverlay) => x.designInput.rst
+ case None => false.B
+ }
+
+ pllReset :=
+ (!reset_ibuf.io.O) || powerOnReset || ctsReset //Arty100T is active low reset
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ArtyShell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ArtyShell.scala
new file mode 100644
index 0000000..a1e964c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ArtyShell.scala
@@ -0,0 +1,245 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx.artyshell
+
+import Chisel._
+import chisel3.{Input, Output, RawModule, withClockAndReset}
+import chisel3.experimental.{attach, Analog}
+
+import freechips.rocketchip.config._
+import freechips.rocketchip.devices.debug._
+
+import sifive.blocks.devices.gpio._
+import sifive.blocks.devices.pwm._
+import sifive.blocks.devices.spi._
+import sifive.blocks.devices.uart._
+import sifive.blocks.devices.pinctrl.{BasePin}
+
+import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, mmcm, reset_sys, PowerOnResetFPGAOnly}
+
+//-------------------------------------------------------------------------
+// ArtyShell
+//-------------------------------------------------------------------------
+
+abstract class ArtyShell(implicit val p: Parameters) extends RawModule {
+
+ //-----------------------------------------------------------------------
+ // Interface
+ //-----------------------------------------------------------------------
+
+ // Clock & Reset
+ val CLK100MHZ = IO(Input(Clock()))
+ val ck_rst = IO(Input(Bool()))
+
+ // Green LEDs
+ val led_0 = IO(Analog(1.W))
+ val led_1 = IO(Analog(1.W))
+ val led_2 = IO(Analog(1.W))
+ val led_3 = IO(Analog(1.W))
+
+ // RGB LEDs, 3 pins each
+ val led0_r = IO(Analog(1.W))
+ val led0_g = IO(Analog(1.W))
+ val led0_b = IO(Analog(1.W))
+
+ val led1_r = IO(Analog(1.W))
+ val led1_g = IO(Analog(1.W))
+ val led1_b = IO(Analog(1.W))
+
+ val led2_r = IO(Analog(1.W))
+ val led2_g = IO(Analog(1.W))
+ val led2_b = IO(Analog(1.W))
+
+ // Sliding switches
+ val sw_0 = IO(Analog(1.W))
+ val sw_1 = IO(Analog(1.W))
+ val sw_2 = IO(Analog(1.W))
+ val sw_3 = IO(Analog(1.W))
+
+ // Buttons. First 3 used as GPIO, the last is used as wakeup
+ val btn_0 = IO(Analog(1.W))
+ val btn_1 = IO(Analog(1.W))
+ val btn_2 = IO(Analog(1.W))
+ val btn_3 = IO(Analog(1.W))
+
+ // Dedicated QSPI interface
+ val qspi_cs = IO(Analog(1.W))
+ val qspi_sck = IO(Analog(1.W))
+ val qspi_dq = IO(Vec(4, Analog(1.W)))
+
+ // UART0
+ val uart_rxd_out = IO(Analog(1.W))
+ val uart_txd_in = IO(Analog(1.W))
+
+ // JA (Used for more generic GPIOs)
+ val ja_0 = IO(Analog(1.W))
+ val ja_1 = IO(Analog(1.W))
+ val ja_2 = IO(Analog(1.W))
+ val ja_3 = IO(Analog(1.W))
+ val ja_4 = IO(Analog(1.W))
+ val ja_5 = IO(Analog(1.W))
+ val ja_6 = IO(Analog(1.W))
+ val ja_7 = IO(Analog(1.W))
+
+ // JC (used for additional debug/trace connection)
+ val jc = IO(Vec(8, Analog(1.W)))
+
+ // JD (used for JTAG connection)
+ val jd_0 = IO(Analog(1.W)) // TDO
+ val jd_1 = IO(Analog(1.W)) // TRST_n
+ val jd_2 = IO(Analog(1.W)) // TCK
+ val jd_4 = IO(Analog(1.W)) // TDI
+ val jd_5 = IO(Analog(1.W)) // TMS
+ val jd_6 = IO(Analog(1.W)) // SRST_n
+
+ // ChipKit Digital I/O Pins
+ val ck_io = IO(Vec(20, Analog(1.W)))
+
+ // ChipKit SPI
+ val ck_miso = IO(Analog(1.W))
+ val ck_mosi = IO(Analog(1.W))
+ val ck_ss = IO(Analog(1.W))
+ val ck_sck = IO(Analog(1.W))
+
+ //-----------------------------------------------------------------------
+ // Wire declrations
+ //-----------------------------------------------------------------------
+
+ // Note: these frequencies are approximate.
+ val clock_8MHz = Wire(Clock())
+ val clock_32MHz = Wire(Clock())
+ val clock_65MHz = Wire(Clock())
+
+ val mmcm_locked = Wire(Bool())
+
+ val reset_core = Wire(Bool())
+ val reset_bus = Wire(Bool())
+ val reset_periph = Wire(Bool())
+ val reset_intcon_n = Wire(Bool())
+ val reset_periph_n = Wire(Bool())
+
+ val SRST_n = Wire(Bool())
+
+ val dut_jtag_TCK = Wire(Clock())
+ val dut_jtag_TMS = Wire(Bool())
+ val dut_jtag_TDI = Wire(Bool())
+ val dut_jtag_TDO = Wire(Bool())
+ val dut_jtag_reset = Wire(Bool())
+ val dut_ndreset = Wire(Bool())
+
+ //-----------------------------------------------------------------------
+ // Clock Generator
+ //-----------------------------------------------------------------------
+ // Mixed-mode clock generator
+
+ val ip_mmcm = Module(new mmcm())
+
+ ip_mmcm.io.clk_in1 := CLK100MHZ
+ clock_8MHz := ip_mmcm.io.clk_out1 // 8.388 MHz = 32.768 kHz * 256
+ clock_65MHz := ip_mmcm.io.clk_out2 // 65 Mhz
+ clock_32MHz := ip_mmcm.io.clk_out3 // 65/2 Mhz
+ ip_mmcm.io.resetn := ck_rst
+ mmcm_locked := ip_mmcm.io.locked
+
+ //-----------------------------------------------------------------------
+ // System Reset
+ //-----------------------------------------------------------------------
+ // processor system reset module
+
+ val ip_reset_sys = Module(new reset_sys())
+
+ ip_reset_sys.io.slowest_sync_clk := clock_8MHz
+ ip_reset_sys.io.ext_reset_in := ck_rst & SRST_n
+ ip_reset_sys.io.aux_reset_in := true.B
+ ip_reset_sys.io.mb_debug_sys_rst := dut_ndreset
+ ip_reset_sys.io.dcm_locked := mmcm_locked
+
+ reset_core := ip_reset_sys.io.mb_reset
+ reset_bus := ip_reset_sys.io.bus_struct_reset
+ reset_periph := ip_reset_sys.io.peripheral_reset
+ reset_intcon_n := ip_reset_sys.io.interconnect_aresetn
+ reset_periph_n := ip_reset_sys.io.peripheral_aresetn
+
+ //-----------------------------------------------------------------------
+ // SPI Flash
+ //-----------------------------------------------------------------------
+
+ def connectSPIFlash(dut: HasPeripherySPIFlashModuleImp): Unit = dut.qspi.headOption.foreach {
+ connectSPIFlash(_, dut.clock, dut.reset)
+ }
+
+ def connectSPIFlash(qspi: SPIPortIO, clock: Clock, reset: Bool): Unit = {
+ val qspi_pins = Wire(new SPIPins(() => {new BasePin()}, qspi.c))
+
+ SPIPinsFromPort(qspi_pins, qspi, clock, reset, syncStages = qspi.c.defaultSampleDel)
+
+ IOBUF(qspi_sck, qspi.sck)
+ IOBUF(qspi_cs, qspi.cs(0))
+
+ (qspi_dq zip qspi_pins.dq).foreach { case(a, b) => IOBUF(a, b) }
+ }
+
+ //---------------------------------------------------------------------
+ // Debug JTAG
+ //---------------------------------------------------------------------
+
+ def connectDebugJTAG(dut: HasPeripheryDebugModuleImp): SystemJTAGIO = {
+
+ require(dut.debug.isDefined, "Connecting JTAG requires that debug module exists")
+ //-------------------------------------------------------------------
+ // JTAG Reset
+ //-------------------------------------------------------------------
+
+ val jtag_power_on_reset = PowerOnResetFPGAOnly(clock_32MHz)
+
+ dut_jtag_reset := jtag_power_on_reset
+
+ //-------------------------------------------------------------------
+ // JTAG IOBUFs
+ //-------------------------------------------------------------------
+
+ dut_jtag_TCK := IBUFG(IOBUF(jd_2).asClock)
+
+ dut_jtag_TMS := IOBUF(jd_5)
+ PULLUP(jd_5)
+
+ dut_jtag_TDI := IOBUF(jd_4)
+ PULLUP(jd_4)
+
+ IOBUF(jd_0, dut_jtag_TDO)
+
+ SRST_n := IOBUF(jd_6)
+ PULLUP(jd_6)
+
+ //-------------------------------------------------------------------
+ // JTAG PINS
+ //-------------------------------------------------------------------
+
+ val djtag = dut.debug.get.systemjtag.get
+
+ djtag.jtag.TCK := dut_jtag_TCK
+ djtag.jtag.TMS := dut_jtag_TMS
+ djtag.jtag.TDI := dut_jtag_TDI
+ dut_jtag_TDO := djtag.jtag.TDO.data
+
+ djtag.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W)
+ djtag.part_number := p(JtagDTMKey).idcodePartNum.U(16.W)
+ djtag.version := p(JtagDTMKey).idcodeVersion.U(4.W)
+
+ djtag.reset := dut_jtag_reset
+ dut_ndreset := dut.debug.get.ndreset
+
+ djtag
+ }
+
+ //---------------------------------------------------------------------
+ // UART
+ //---------------------------------------------------------------------
+
+ def connectUART(dut: HasPeripheryUARTModuleImp): Unit = dut.uart.headOption.foreach(connectUART)
+
+ def connectUART(uart: UARTPortIO): Unit = {
+ IOBUF(uart_rxd_out, uart.txd)
+ uart.rxd := IOBUF(uart_txd_in)
+ }
+
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ButtonOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ButtonOverlay.scala
new file mode 100644
index 0000000..a197597
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ButtonOverlay.scala
@@ -0,0 +1,34 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class ButtonXilinxPlacedOverlay(name: String, di: ButtonDesignInput, si: ButtonShellInput, boardPin: Option[String] = None, packagePin: Option[String] = None, ioStandard: String = "LVCMOS33")
+ extends ButtonPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ val but = Wire(Bool())
+ buttonSource.out(0)._1 := but
+ val ibuf = Module(new IBUF)
+ ibuf.suggestName(s"button_ibuf_${si.number}")
+ ibuf.io.I := io
+ but := ibuf.io.O
+
+ require((boardPin.isEmpty || packagePin.isEmpty), "can't provide both boardpin and packagepin, this is ambiguous")
+ val cutAt = if(boardPin.isDefined) 1 else 0
+ val ios = IOPin.of(io)
+ val boardIO = ios.take(cutAt)
+ val packageIO = ios.drop(cutAt)
+
+ (boardPin zip boardIO) foreach { case (pin, io) => shell.xdc.addBoardPin (io, pin) }
+ (packagePin zip packageIO) foreach { case (pin, io) =>
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, ioStandard)
+ }
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ChipLinkOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ChipLinkOverlay.scala
new file mode 100644
index 0000000..aac3f33
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ChipLinkOverlay.scala
@@ -0,0 +1,73 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.util._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class ChipLinkXilinxPlacedOverlay(name: String, di: ChipLinkDesignInput, si: ChipLinkShellInput, rxPhase: Double, txPhase: Double, rxMargin: Double, txMargin: Double)
+ extends ChipLinkPlacedOverlay(name, di.copy(di = di.di.copy(fpgaReset = true))(di.p), si, rxPhase, txPhase)
+{
+ def shell: XilinxShell
+
+ override def fpgaReset = true
+
+ InModuleBody {
+ // Provide reset pulse to initialize b2c_reset (before RX PLL locks)
+ link.module.io.fpga_reset.foreach { _ := PowerOnResetFPGAOnly(Module.clock) }
+ }
+
+ shell { InModuleBody {
+ val (tx, _) = txClock.in(0)
+ val (rx, _) = rxI.out(0)
+ val rxEdge = rxI.edges.out(0)
+
+ val oddr = Module(new ODDR(DDR_CLK_EDGE = "SAME_EDGE", SRTYPE = "ASYNC"))
+ oddr.suggestName(s"${name}_tx_oddr")
+ io.c2b.clk := oddr.io.Q.asClock
+ oddr.io.C := tx.clock
+ oddr.io.CE := true.B
+ oddr.io.D1 := true.B
+ oddr.io.D2 := false.B
+ oddr.io.S := false.B
+ // We can't use tx.reset here as it waits for all PLLs to lock,
+ // including RX, which depends on this clock being driven.
+ // tap.reset only waits for the TX PLL to lock.
+ oddr.io.R := ResetCatchAndSync(tx.clock, PowerOnResetFPGAOnly(tx.clock))
+
+ val ibufg = Module(new IBUFG)
+ ibufg.suggestName(s"${name}_rx_ibufg")
+ ibufg.io.I := io.b2c.clk
+ rx.clock := ibufg.io.O
+ rx.reset := shell.pllReset
+
+ IOPin.of(io).foreach { shell.xdc.addIOStandard(_, "LVCMOS18") }
+ IOPin.of(io).filterNot(_.element eq io.b2c.clk).foreach { shell.xdc.addIOB(_) }
+ IOPin.of(io).filter(_.isOutput).foreach { shell.xdc.addSlew(_, "FAST") }
+
+ val timing = IOTiming(
+ /* The data signals coming from Aloe have: clock - 1.2 <= transition <= clock + 0.8
+ * min = hold = - 1.2
+ * max = period - setup = 0.8
+ */
+ minInput = -1.2 - rxMargin,
+ maxInput = 0.8 + rxMargin,
+ /* The data signals going to Aloe must have: clock - 1.85 <= NO transition <= clock + 0.65
+ * min = -hold = -0.65
+ * max = setup = 1.85
+ */
+ minOutput = -0.65 - txMargin,
+ maxOutput = 1.85 + txMargin)
+
+ shell.sdc.addClock(s"${name}_b2c_clock", io.b2c.clk, rxEdge.clock.freqMHz, 0.3)
+ shell.sdc.addDerivedClock(s"${name}_c2b_clock", oddr.io.C, io.c2b.clk)
+ IOPin.of(io).filter(p => p.isInput && !(p.element eq io.b2c.clk)).foreach { e =>
+ shell.sdc.addIOTiming(e, s"${name}_b2c_clock", timing)
+ }
+ IOPin.of(io).filter(p => p.isOutput && !(p.element eq io.c2b.clk)).foreach { e =>
+ shell.sdc.addIOTiming(e, s"${name}_c2b_clock", timing)
+ }
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ClockOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ClockOverlay.scala
new file mode 100644
index 0000000..839a589
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/ClockOverlay.scala
@@ -0,0 +1,41 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class LVDSClockInputXilinxPlacedOverlay(name: String, di: ClockInputDesignInput, si: ClockInputShellInput)
+ extends LVDSClockInputPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ val ibufds = Module(new IBUFDS)
+ ibufds.suggestName(s"${name}_ibufds")
+
+ val (c, _) = node.out(0)
+ ibufds.io.I := io.p
+ ibufds.io.IB := io.n
+ c.clock := ibufds.io.O
+ c.reset := shell.pllReset
+ } }
+}
+
+
+abstract class SingleEndedClockInputXilinxPlacedOverlay(name: String, di: ClockInputDesignInput, si: ClockInputShellInput)
+ extends SingleEndedClockInputPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ val ibuf = Module(new IBUFG)
+ ibuf.suggestName(s"${name}_ibufg")
+
+ val (c, _) = node.out(0)
+ ibuf.io.I := io
+ c.clock := ibuf.io.O
+ c.reset := shell.pllReset
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/GPIOPMODXilinxOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/GPIOPMODXilinxOverlay.scala
new file mode 100644
index 0000000..d77f69c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/GPIOPMODXilinxOverlay.scala
@@ -0,0 +1,13 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class GPIOPMODXilinxPlacedOverlay(name: String, di: GPIOPMODDesignInput, si: GPIOPMODShellInput)
+ extends GPIOPMODPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/GPIOXilinxOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/GPIOXilinxOverlay.scala
new file mode 100644
index 0000000..d578ac6
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/GPIOXilinxOverlay.scala
@@ -0,0 +1,20 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class GPIOXilinxPlacedOverlay(name: String, di: GPIODesignInput, si: GPIOShellInput)
+ extends GPIOPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ tlgpioSink.bundle.pins.zipWithIndex.foreach{ case (tlpin, idx) => {
+ UIntToAnalog(tlpin.o.oval, io.gpio(idx), tlpin.o.oe)
+ tlpin.i.ival := AnalogToUInt(io.gpio(idx))
+ } }
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/I2COverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/I2COverlay.scala
new file mode 100644
index 0000000..07fca0d
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/I2COverlay.scala
@@ -0,0 +1,21 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+ import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+ abstract class I2CXilinxPlacedOverlay(name: String, di: I2CDesignInput, si: I2CShellInput)
+ extends I2CPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ UIntToAnalog(tli2cSink.bundle.scl.out, io.scl, tli2cSink.bundle.scl.oe)
+ UIntToAnalog(tli2cSink.bundle.sda.out, io.sda, tli2cSink.bundle.sda.oe)
+
+ tli2cSink.bundle.scl.in := AnalogToUInt(io.scl)
+ tli2cSink.bundle.sda.in := AnalogToUInt(io.sda)
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/JTAGDebugBScanOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/JTAGDebugBScanOverlay.scala
new file mode 100644
index 0000000..cd43e10
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/JTAGDebugBScanOverlay.scala
@@ -0,0 +1,29 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class JTAGDebugBScanXilinxPlacedOverlay(name: String, di: JTAGDebugBScanDesignInput, si: JTAGDebugBScanShellInput)
+ extends JTAGDebugBScanPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ val tmp_tck = Wire(Bool())
+ val tmp_tms = Wire(Bool())
+ val tmp_tdi = Wire(Bool())
+ val tmp_tdo = Wire(Bool())
+ val tmp_tdo_en = Wire(Bool())
+
+ JTAGTUNNEL(tmp_tck, tmp_tms, tmp_tdi, tmp_tdo, tmp_tdo_en)
+
+ jtagDebugSink.bundle.TCK := tmp_tck.asClock()
+ jtagDebugSink.bundle.TMS := tmp_tms
+ jtagDebugSink.bundle.TDI := tmp_tdi
+ tmp_tdo := jtagDebugSink.bundle.TDO.data
+ tmp_tdo_en := jtagDebugSink.bundle.TDO.driven
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/JTAGDebugOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/JTAGDebugOverlay.scala
new file mode 100644
index 0000000..e91bb94
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/JTAGDebugOverlay.scala
@@ -0,0 +1,21 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class JTAGDebugXilinxPlacedOverlay(name: String, di: JTAGDebugDesignInput, si: JTAGDebugShellInput)
+ extends JTAGDebugPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ jtagDebugSink.bundle.TCK := AnalogToUInt(io.jtag_TCK).asBool.asClock
+ jtagDebugSink.bundle.TMS := AnalogToUInt(io.jtag_TMS)
+ jtagDebugSink.bundle.TDI := AnalogToUInt(io.jtag_TDI)
+ UIntToAnalog(jtagDebugSink.bundle.TDO.data,io.jtag_TDO,jtagDebugSink.bundle.TDO.driven)
+ jtagDebugSink.bundle.srst_n := AnalogToUInt(io.srst_n)
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/LEDOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/LEDOverlay.scala
new file mode 100644
index 0000000..1725ffe
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/LEDOverlay.scala
@@ -0,0 +1,29 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class LEDXilinxPlacedOverlay(name: String, di: LEDDesignInput, si: LEDShellInput, boardPin: Option[String] = None, packagePin: Option[String] = None, ioStandard: String = "LVCMOS33")
+ extends LEDPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ io := ledSink.bundle // could/should put OBUFs here?
+
+ require((boardPin.isEmpty || packagePin.isEmpty), "can't provide both boardpin and packagepin, this is ambiguous")
+ val cutAt = if(boardPin.isDefined) 1 else 0
+ val ios = IOPin.of(io)
+ val boardIO = ios.take(cutAt)
+ val packageIO = ios.drop(cutAt)
+
+ (boardPin zip boardIO) foreach { case (pin, io) => shell.xdc.addBoardPin (io, pin) }
+ (packagePin zip packageIO) foreach { case (pin, io) =>
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, ioStandard)
+ }
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/PWMOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/PWMOverlay.scala
new file mode 100644
index 0000000..c182e59
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/PWMOverlay.scala
@@ -0,0 +1,19 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+ import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class PWMXilinxPlacedOverlay(name: String, di: PWMDesignInput, si: PWMShellInput)
+ extends PWMPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ tlpwmSink.bundle.gpio.zip(io.pwm_gpio).foreach { case(design_pwm, io_pwm) =>
+ UIntToAnalog(design_pwm, io_pwm, true.B)
+ }
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/PeripheralsVC707Shell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/PeripheralsVC707Shell.scala
new file mode 100644
index 0000000..c9f2d31
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/PeripheralsVC707Shell.scala
@@ -0,0 +1,163 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import chisel3.experimental._
+
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.util._
+
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+import sifive.blocks.devices.gpio._
+import sifive.blocks.devices.pinctrl._
+
+class UARTPeripheralVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: UARTDesignInput, val shellInput: UARTShellInput)
+ extends UARTXilinxPlacedOverlay(name, designInput, shellInput, true)
+{
+ shell { InModuleBody {
+ val uartLocations = List(List("AT32", "AR34", "AU33", "AU36"), List("V34", "T35", "V33", "U34")) //uart0 - USB, uart1 - FMC 105 debug card J20 p1-rx p2-tx p3-ctsn p4-rtsn
+ val packagePinsWithPackageIOs = Seq((uartLocations(shellInput.index)(0), IOPin(io.ctsn.get)),
+ (uartLocations(shellInput.index)(1), IOPin(io.rtsn.get)),
+ (uartLocations(shellInput.index)(2), IOPin(io.rxd)),
+ (uartLocations(shellInput.index)(3), IOPin(io.txd)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addIOB(io)
+ } }
+ } }
+}
+
+class UARTPeripheralVC707ShellPlacer(val shell: VC707Shell, val shellInput: UARTShellInput)(implicit val valName: ValName)
+ extends UARTShellPlacer[VC707Shell]
+{
+ def place(designInput: UARTDesignInput) = new UARTPeripheralVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class I2CPeripheralVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: I2CDesignInput, val shellInput: I2CShellInput)
+ extends I2CXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ val i2cLocations = List(List("AJ38", "U32"), List("AK38", "U33")) //i2c0: J1 p37-scl p38-sda i2c1: J2 p39-scl p40-sda
+ val packagePinsWithPackageIOs = Seq((i2cLocations(shellInput.index)(0), IOPin(io.scl)),
+ (i2cLocations(shellInput.index)(1), IOPin(io.sda)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addIOB(io)
+ } }
+ } }
+}
+
+class I2CPeripheralVC707ShellPlacer(val shell: VC707Shell, val shellInput: I2CShellInput)(implicit val valName: ValName)
+ extends I2CShellPlacer[VC707Shell]
+{
+ def place(designInput: I2CDesignInput) = new I2CPeripheralVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class QSPIPeripheralVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: SPIFlashDesignInput, val shellInput: SPIFlashShellInput)
+ extends SPIFlashXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ val qspiLocations = List(List("AD40", "AB41", "AD41", "AB42", "AF41", "Y42"), List("AG41", "AA42", "AK39", "Y39", "AL39", "AA39")) //J1 pins 1-6 and 7-12 (sck, cs, dq0-3)
+ val packagePinsWithPackageIOs = Seq((qspiLocations(shellInput.index)(0), IOPin(io.qspi_sck)),
+ (qspiLocations(shellInput.index)(1), IOPin(io.qspi_cs)),
+ (qspiLocations(shellInput.index)(2), IOPin(io.qspi_dq(0))),
+ (qspiLocations(shellInput.index)(3), IOPin(io.qspi_dq(1))),
+ (qspiLocations(shellInput.index)(4), IOPin(io.qspi_dq(2))),
+ (qspiLocations(shellInput.index)(5), IOPin(io.qspi_dq(3))))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addIOB(io)
+ } }
+ packagePinsWithPackageIOs drop 1 foreach { case (pin, io) => {
+ shell.xdc.addPullup(io)
+ } }
+ } }
+}
+
+class QSPIPeripheralVC707ShellPlacer(val shell: VC707Shell, val shellInput: SPIFlashShellInput)(implicit val valName: ValName)
+ extends SPIFlashShellPlacer[VC707Shell]
+{
+ def place(designInput: SPIFlashDesignInput) = new QSPIPeripheralVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class PWMPeripheralVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: PWMDesignInput, val shellInput: PWMShellInput)
+ extends PWMXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("AD36", IOPin(io.pwm_gpio(0))), //J23 pins 5-8
+ ("Y35", IOPin(io.pwm_gpio(1))),
+ ("AD37", IOPin(io.pwm_gpio(2))),
+ ("AA36", IOPin(io.pwm_gpio(3))))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addIOB(io)
+ } }
+ } }
+}
+
+class PWMPeripheralVC707ShellPlacer(val shell: VC707Shell, val shellInput: PWMShellInput)(implicit val valName: ValName)
+ extends PWMShellPlacer[VC707Shell] {
+ def place(designInput: PWMDesignInput) = new PWMPeripheralVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class GPIOPeripheralVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: GPIODesignInput, val shellInput: GPIOShellInput)
+ extends GPIOXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ val gpioLocations = List("AB33", "AF31", "AC33", "AF32", "AD32", "AE34", "AD33", "AE35", "AC30", "AF34", "AD30", "AG34", "AA29", "AE32", "AA30", "AE33") //J3 pins 1-16
+ val iosWithLocs = io.gpio.zip(gpioLocations)
+ val packagePinsWithPackageIOs = iosWithLocs.map { case (io, pin) => (pin, IOPin(io)) }
+ println(packagePinsWithPackageIOs)
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addIOB(io)
+ } }
+ } }
+}
+
+class GPIOPeripheralVC707ShellPlacer(val shell: VC707Shell, val shellInput: GPIOShellInput)(implicit val valName: ValName)
+ extends GPIOShellPlacer[VC707Shell] {
+
+ def place(designInput: GPIODesignInput) = new GPIOPeripheralVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class PeripheralVC707Shell(implicit p: Parameters) extends VC707Shell {
+
+ val gpio = Overlay(GPIOOverlayKey, new GPIOPeripheralVC707ShellPlacer(this, GPIOShellInput()))
+ val uart = Seq.tabulate(2) { i => Overlay(UARTOverlayKey, new UARTPeripheralVC707ShellPlacer(this, UARTShellInput(index = i))(valName = ValName(s"uart$i"))) }
+ val qspi = Seq.tabulate(2) { i => Overlay(SPIFlashOverlayKey, new QSPIPeripheralVC707ShellPlacer(this, SPIFlashShellInput(index = i))(valName = ValName(s"qspi$i"))) }
+ val pwm = Seq.tabulate(1) { i => Overlay(PWMOverlayKey, new PWMPeripheralVC707ShellPlacer(this, PWMShellInput(index = i))(valName = ValName(s"pwm$i"))) }
+ val i2c = Seq.tabulate(2) { i => Overlay(I2COverlayKey, new I2CPeripheralVC707ShellPlacer(this, I2CShellInput(index = i))(valName = ValName(s"i2c$i"))) }
+
+ val topDesign = LazyModule(p(DesignKey)(designParameters))
+
+ p(ClockInputOverlayKey).foreach(_.place(ClockInputDesignInput()))
+
+ override lazy val module = new LazyRawModuleImp(this) {
+
+ val reset = IO(Input(Bool()))
+ val clock = IO(Input(Clock()))
+ xdc.addBoardPin(reset, "reset")
+ val por_clock = sys_clock.get.get.asInstanceOf[SysClockVC707PlacedOverlay].clock
+ val powerOnReset = PowerOnResetFPGAOnly(por_clock)
+
+ pllReset :=
+ reset || powerOnReset
+
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/PinXilinxOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/PinXilinxOverlay.scala
new file mode 100644
index 0000000..5794487
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/PinXilinxOverlay.scala
@@ -0,0 +1,13 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class PinXilinxPlacedOverlay(name: String, di: PinDesignInput, si: PinShellInput)
+ extends PinPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/SDIOOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/SDIOOverlay.scala
new file mode 100644
index 0000000..a73b109
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/SDIOOverlay.scala
@@ -0,0 +1,13 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class SDIOXilinxPlacedOverlay(name: String, di: SDIODesignInput, si: SDIOShellInput)
+ extends SDIOPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/SPIFlashXilinxOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/SPIFlashXilinxOverlay.scala
new file mode 100644
index 0000000..97b4673
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/SPIFlashXilinxOverlay.scala
@@ -0,0 +1,23 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class SPIFlashXilinxPlacedOverlay(name: String, di: SPIFlashDesignInput, si: SPIFlashShellInput)
+ extends SPIFlashPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ UIntToAnalog(tlqspiSink.bundle.sck , io.qspi_sck, true.B)
+ UIntToAnalog(tlqspiSink.bundle.cs(0), io.qspi_cs , true.B)
+
+ tlqspiSink.bundle.dq.zip(io.qspi_dq).foreach { case(design_dq, io_dq) =>
+ UIntToAnalog(design_dq.o, io_dq, design_dq.oe)
+ design_dq.i := AnalogToUInt(io_dq)
+ }
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/SwitchOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/SwitchOverlay.scala
new file mode 100644
index 0000000..0955139
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/SwitchOverlay.scala
@@ -0,0 +1,34 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class SwitchXilinxPlacedOverlay(name: String, di: SwitchDesignInput, si: SwitchShellInput, boardPin: Option[String] = None, packagePin: Option[String] = None, ioStandard: String = "LVCMOS33")
+ extends SwitchPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+
+ shell { InModuleBody {
+ val bwire = Wire(Bool())
+ switchSource.out(0)._1 := bwire.asUInt
+ val ibuf = Module(new IBUF)
+ ibuf.suggestName(s"switch_ibuf_${si.number}")
+ ibuf.io.I := io
+ bwire := ibuf.io.O
+
+ require((boardPin.isEmpty || packagePin.isEmpty), "can't provide both boardpin and packagepin, this is ambiguous")
+ val cutAt = if(boardPin.isDefined) 1 else 0
+ val ios = IOPin.of(io)
+ val boardIO = ios.take(cutAt)
+ val packageIO = ios.drop(cutAt)
+
+ (boardPin zip boardIO) foreach { case (pin, io) => shell.xdc.addBoardPin (io, pin) }
+ (packagePin zip packageIO) foreach { case (pin, io) =>
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, ioStandard)
+ }
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/TracePMODOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/TracePMODOverlay.scala
new file mode 100644
index 0000000..7a408c9
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/TracePMODOverlay.scala
@@ -0,0 +1,29 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class TracePMODXilinxPlacedOverlay(name: String, di: TracePMODDesignInput, si: TracePMODShellInput, boardPins: Seq[String] = Nil, packagePins: Seq[String] = Nil, ioStandard: String = "LVCMOS33")
+ extends TracePMODPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+ val width = boardPins.size + packagePins.size
+
+ shell { InModuleBody {
+ io := pmodTraceSink.bundle
+
+ val cutAt = boardPins.size
+ val ios = IOPin.of(io)
+ val boardIOs = ios.take(cutAt)
+ val packageIOs = ios.drop(cutAt)
+
+ (boardPins zip boardIOs) foreach { case (pin, io) => shell.xdc.addBoardPin (io, pin) }
+ (packagePins zip packageIOs) foreach { case (pin, io) =>
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, ioStandard)
+ }
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/UARTOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/UARTOverlay.scala
new file mode 100644
index 0000000..d6a50e0
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/UARTOverlay.scala
@@ -0,0 +1,25 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class UARTXilinxPlacedOverlay(name: String, di: UARTDesignInput, si: UARTShellInput, flowControl: Boolean)
+ extends UARTPlacedOverlay(name, di, si, flowControl)
+{
+ def shell: XilinxShell
+
+ InModuleBody {
+ val (io, _) = uartSource.out(0)
+ val tluartport = tluartSink.bundle
+ io <> tluartport
+ tluartport.rxd := RegNext(RegNext(io.rxd))
+ }
+
+ shell { InModuleBody {
+ UIntToAnalog(uartSink.bundle.txd, io.txd, true.B)
+ uartSink.bundle.rxd := AnalogToUInt(io.rxd)
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/UltraScaleShell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/UltraScaleShell.scala
new file mode 100644
index 0000000..49b5f57
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/UltraScaleShell.scala
@@ -0,0 +1,135 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+import sifive.fpgashells.devices.xilinx.xdma._
+import sifive.fpgashells.devices.xilinx.ethernet._
+import sifive.fpgashells.ip.xilinx.xxv_ethernet._
+
+class XDMATopPads(val numLanes: Int) extends Bundle {
+ val refclk = Input(new LVDSClock)
+ val lanes = new XDMAPads(numLanes)
+}
+
+class XDMABridge(val numLanes: Int) extends Bundle {
+ val lanes = new XDMAPads(numLanes)
+ val srstn = Input(Bool())
+ val O = Input(Clock())
+ val ODIV2 = Input(Clock())
+}
+
+abstract class EthernetUltraScalePlacedOverlay(name: String, di: EthernetDesignInput, si: EthernetShellInput, config: XXVEthernetParams)
+ extends EthernetPlacedOverlay(name, di, si)
+{
+ def shell: UltraScaleShell
+
+ val pcs = LazyModule(new DiplomaticXXVEthernet(config))
+ pcs.suggestName(name + "_pcs")
+
+ val padSource = BundleBridgeSource(() => new XXVEthernetPads)
+ val padSink = shell { padSource.makeSink() }
+ val dclk = InModuleBody { Wire(Clock()) }
+
+ InModuleBody {
+ padSource.bundle <> pcs.module.io.pads
+
+ val clocks = pcs.module.io.clocks
+ clocks.rx_core_clk_0 := clocks.tx_mii_clk_0
+ clocks.dclk := dclk
+ clocks.sys_reset := Module.reset
+
+ val macIO = pcs.module.io.mac
+ val pcsIO = overlayOutput.eth
+ macIO.tx_mii_d_0 := pcsIO.tx_d
+ macIO.tx_mii_c_0 := pcsIO.tx_c
+ pcsIO.rx_d := macIO.rx_mii_d_0
+ pcsIO.rx_c := macIO.rx_mii_c_0
+
+ macIO.gt_loopback_in_0 := pcsIO.loopback
+ pcsIO.rx_lock := macIO.stat_rx_block_lock_0
+ pcsIO.sfp_detect := true.B
+
+ pcsIO.rx_clock := clocks.tx_mii_clk_0
+ pcsIO.rx_reset := clocks.user_rx_reset_0
+ pcsIO.tx_clock := clocks.tx_mii_clk_0
+ pcsIO.tx_reset := clocks.user_tx_reset_0
+
+ // refclk_p is added by the IP xdc's anonymous create_clock [get_pins name_refclk_p]
+ shell.sdc.addGroup(clocks = Seq(s"${name}_refclk_p"), pins = Seq(pcs.module.blackbox.io.tx_mii_clk_0))
+ }
+
+ shell { InModuleBody {
+ val pcsIO = padSink.bundle
+ io.tx_p := pcsIO.gt_txp_out_0
+ io.tx_n := pcsIO.gt_txn_out_0
+ pcsIO.gt_rxp_in_0 := io.rx_p
+ pcsIO.gt_rxn_in_0 := io.rx_n
+ pcsIO.gt_refclk_p := io.refclk_p
+ pcsIO.gt_refclk_n := io.refclk_n
+ } }
+}
+
+abstract class PCIeUltraScalePlacedOverlay(name: String, di: PCIeDesignInput, si: PCIeShellInput, config: XDMAParams)
+ extends PCIePlacedOverlay[XDMATopPads](name, di, si)
+{
+ def shell: UltraScaleShell
+
+ val pcie = LazyModule(new XDMA(config))
+ val bridge = BundleBridgeSource(() => new XDMABridge(config.lanes))
+ val topBridge = shell { bridge.makeSink() }
+ val axiClk = ClockSourceNode(freqMHz = config.axiMHz)
+ val areset = ClockSinkNode(Seq(ClockSinkParameters()))
+ areset := di.wrangler := axiClk
+
+ val slaveSide = TLIdentityNode()
+ pcie.crossTLIn(pcie.slave) := slaveSide
+ pcie.crossTLIn(pcie.control) := slaveSide
+ val node = NodeHandle(slaveSide, pcie.crossTLOut(pcie.master))
+ val intnode = pcie.crossIntOut(pcie.intnode)
+
+ def overlayOutput = PCIeOverlayOutput(node, intnode)
+ def ioFactory = new XDMATopPads(config.lanes)
+
+ InModuleBody {
+ val (axi, _) = axiClk.out(0)
+ val (ar, _) = areset.in(0)
+ val b = bridge.out(0)._1
+
+ pcie.module.clock := ar.clock
+ pcie.module.reset := ar.reset
+
+ b.lanes <> pcie.module.io.pads
+
+ axi.clock := pcie.module.io.clocks.axi_aclk
+ axi.reset := !pcie.module.io.clocks.axi_aresetn
+ pcie.module.io.clocks.sys_rst_n := b.srstn
+ pcie.module.io.clocks.sys_clk := b.ODIV2
+ pcie.module.io.clocks.sys_clk_gt := b.O
+
+ shell.sdc.addGroup(clocks = Seq(s"${name}_ref_clk"), pins = Seq(pcie.imp.module.blackbox.io.axi_aclk))
+// shell.sdc.addGroup(pins = Seq(pcie.imp.module.blackbox.io.sys_clk_gt))
+ shell.sdc.addAsyncPath(Seq(pcie.imp.module.blackbox.io.axi_aresetn))
+ }
+
+ shell { InModuleBody {
+ val b = topBridge.in(0)._1
+
+ val ibufds = Module(new IBUFDS_GTE4)
+ ibufds.suggestName(s"${name}_refclk_ibufds")
+ ibufds.io.CEB := false.B
+ ibufds.io.I := io.refclk.p
+ ibufds.io.IB := io.refclk.n
+ b.O := ibufds.io.O
+ b.ODIV2 := ibufds.io.ODIV2
+ b.srstn := !shell.pllReset
+ io.lanes <> b.lanes
+
+ shell.sdc.addClock(s"${name}_ref_clk", io.refclk.p, 100)
+ } }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VC707NewShell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VC707NewShell.scala
new file mode 100644
index 0000000..ddbd8ed
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VC707NewShell.scala
@@ -0,0 +1,337 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import chisel3.experimental.IO
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.util.SyncResetSynchronizerShiftReg
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+import sifive.blocks.devices.chiplink._
+import sifive.fpgashells.devices.xilinx.xilinxvc707mig._
+import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1._
+
+class SysClockVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput)
+ extends LVDSClockInputXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ val node = shell { ClockSourceNode(freqMHz = 200, jitterPS = 50)(ValName(name)) }
+
+ shell { InModuleBody {
+ shell.xdc.addBoardPin(io.p, "clk_p")
+ shell.xdc.addBoardPin(io.n, "clk_n")
+ } }
+}
+class SysClockVC707ShellPlacer(val shell: VC707Shell, val shellInput: ClockInputShellInput)(implicit val valName: ValName)
+ extends ClockInputShellPlacer[VC707Shell] {
+ def place(designInput: ClockInputDesignInput) = new SysClockVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class SDIOVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: SDIODesignInput, val shellInput: SDIOShellInput)
+ extends SDIOXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("AN30", IOPin(io.sdio_clk)),
+ ("AP30", IOPin(io.sdio_cmd)),
+ ("AR30", IOPin(io.sdio_dat_0)),
+ ("AU31", IOPin(io.sdio_dat_1)),
+ ("AV31", IOPin(io.sdio_dat_2)),
+ ("AT30", IOPin(io.sdio_dat_3)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addIOB(io)
+ } }
+ packagePinsWithPackageIOs drop 1 foreach { case (pin, io) => {
+ shell.xdc.addPullup(io)
+ } }
+ } }
+}
+class SDIOVC707ShellPlacer(val shell: VC707Shell, val shellInput: SDIOShellInput)(implicit val valName: ValName)
+ extends SDIOShellPlacer[VC707Shell] {
+ def place(designInput: SDIODesignInput) = new SDIOVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class UARTVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: UARTDesignInput, val shellInput: UARTShellInput)
+ extends UARTXilinxPlacedOverlay(name, designInput, shellInput, true)
+{
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("AT32", IOPin(io.ctsn.get)),
+ ("AR34", IOPin(io.rtsn.get)),
+ ("AU33", IOPin(io.rxd)),
+ ("AU36", IOPin(io.txd)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addIOB(io)
+ } }
+ } }
+}
+class UARTVC707ShellPlacer(val shell: VC707Shell, val shellInput: UARTShellInput)(implicit val valName: ValName)
+ extends UARTShellPlacer[VC707Shell] {
+ def place(designInput: UARTDesignInput) = new UARTVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class LEDVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: LEDDesignInput, val shellInput: LEDShellInput)
+ extends LEDXilinxPlacedOverlay(name, designInput, shellInput, boardPin = Some(s"leds_8bits_tri_o_${shellInput.number}"))
+class LEDVC707ShellPlacer(val shell: VC707Shell, val shellInput: LEDShellInput)(implicit val valName: ValName)
+ extends LEDShellPlacer[VC707Shell] {
+ def place(designInput: LEDDesignInput) = new LEDVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class SwitchVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: SwitchDesignInput, val shellInput: SwitchShellInput)
+ extends SwitchXilinxPlacedOverlay(name, designInput, shellInput, boardPin = Some(s"dip_switches_tri_i_${shellInput.number}"))
+class SwitchVC707ShellPlacer(val shell: VC707Shell, val shellInput: SwitchShellInput)(implicit val valName: ValName)
+ extends SwitchShellPlacer[VC707Shell] {
+ def place(designInput: SwitchDesignInput) = new SwitchVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class ButtonVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: ButtonDesignInput, val shellInput: ButtonShellInput)
+ extends ButtonXilinxPlacedOverlay(name, designInput, shellInput, boardPin = Some(s"push_buttons_5bits_tri_i_${shellInput.number}"))
+class ButtonVC707ShellPlacer(val shell: VC707Shell, val shellInput: ButtonShellInput)(implicit val valName: ValName)
+ extends ButtonShellPlacer[VC707Shell] {
+ def place(designInput: ButtonDesignInput) = new ButtonVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class ChipLinkVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: ChipLinkDesignInput, val shellInput: ChipLinkShellInput)
+ extends ChipLinkXilinxPlacedOverlay(name, designInput, shellInput, rxPhase=280, txPhase=220, rxMargin=0.3, txMargin=0.3)
+{
+ val ereset_n = shell { InModuleBody {
+ val ereset_n = IO(Input(Bool()))
+ ereset_n.suggestName("ereset_n")
+ shell.xdc.addPackagePin(ereset_n, "AF40")
+ shell.xdc.addIOStandard(ereset_n, "LVCMOS18")
+ shell.xdc.addTermination(ereset_n, "NONE")
+ ereset_n
+ } }
+
+ shell { InModuleBody {
+ val dir1 = Seq("AF39", "AJ41", "AJ40", /* clk, rst, send */
+ "AD40", "AD41", "AF41", "AG41", "AK39", "AL39", "AJ42", "AK42",
+ "AL41", "AL42", "AF42", "AG42", "AD38", "AE38", "AC40", "AC41",
+ "AD42", "AE42", "AJ38", "AK38", "AB41", "AB42", "Y42", "AA42",
+ "Y39", "AA39", "W40", "Y40", "AB38", "AB39", "AC38", "AC39")
+ val dir2 = Seq("U39", "R37", "T36", /* clk, rst, send */
+ "U37", "U38", "U36", "T37", "U32", "U33", "V33", "V34",
+ "P35", "P36", "W32", "W33", "R38", "R39", "U34", "T35",
+ "R33", "R34", "N33", "N34", "P32", "P33", "V35", "V36",
+ "W36", "W37", "T32", "R32", "V39", "V40", "P37", "P38")
+ (IOPin.of(io.b2c) zip dir1) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) }
+ (IOPin.of(io.c2b) zip dir2) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) }
+ } }
+}
+class ChipLinkVC707ShellPlacer(val shell: VC707Shell, val shellInput: ChipLinkShellInput)(implicit val valName: ValName)
+ extends ChipLinkShellPlacer[VC707Shell] {
+ def place(designInput: ChipLinkDesignInput) = new ChipLinkVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+// TODO: JTAG is untested
+class JTAGDebugVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: JTAGDebugDesignInput, val shellInput: JTAGDebugShellInput)
+ extends JTAGDebugXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ shell.sdc.addClock("JTCK", IOPin(io.jtag_TCK), 10)
+ shell.sdc.addGroup(clocks = Seq("JTCK"))
+ shell.xdc.clockDedicatedRouteFalse(IOPin(io.jtag_TCK))
+/* if old method
+ val packagePinsWithPackageIOs = Seq(("R32", IOPin(io.jtag_TCK)),
+ ("W36", IOPin(io.jtag_TMS)),
+ ("W37", IOPin(io.jtag_TDI)),
+ ("V40", IOPin(io.jtag_TDO)))
+*/
+ /*
+ #Olimex Pin Olimex Function LCD Pin LCD Function FPGA Pin
+ #1 VREF 14 5V
+ #3 TTRST_N 1 LCD_DB7 AN40
+ #5 TTDI 2 LCD_DB6 AR39
+ #7 TTMS 3 LCD_DB5 AR38
+ #9 TTCK 4 LCD_DB4 AT42
+ #11 TRTCK NC NC NC
+ #13 TTDO 9 LCD_E AT40
+ #15 TSRST_N 10 LCD_RW AR42
+ #2 VREF 14 5V
+ #18 GND 13 GND
+ */
+ val packagePinsWithPackageIOs = Seq(("AT42", IOPin(io.jtag_TCK)),
+ ("AR38", IOPin(io.jtag_TMS)),
+ ("AR39", IOPin(io.jtag_TDI)),
+ ("AT40", IOPin(io.jtag_TDO)))
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addPullup(io)
+ } }
+ } }
+}
+class JTAGDebugVC707ShellPlacer(val shell: VC707Shell, val shellInput: JTAGDebugShellInput)(implicit val valName: ValName)
+ extends JTAGDebugShellPlacer[VC707Shell] {
+ def place(designInput: JTAGDebugDesignInput) = new JTAGDebugVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+case object VC7071GDDRSize extends Field[BigInt](0x40000000L * 1) // 1GB
+case object VC7074GDDRSize extends Field[BigInt](0x40000000L * 4) // 4GB
+class DDRVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: DDRDesignInput, val shellInput: DDRShellInput)
+ extends DDRPlacedOverlay[XilinxVC707MIGPads](name, designInput, shellInput)
+{
+ val size = if (designInput.vc7074gbdimm) p(VC7074GDDRSize) else p(VC7071GDDRSize)
+
+ val migParams = XilinxVC707MIGParams(address = AddressSet.misaligned(di.baseAddress, size))
+ val mig = LazyModule(new XilinxVC707MIG(migParams))
+ val ioNode = BundleBridgeSource(() => mig.module.io.cloneType)
+ val topIONode = shell { ioNode.makeSink() }
+ val ddrUI = shell { ClockSourceNode(freqMHz = 200) }
+ val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) }
+ areset := designInput.wrangler := ddrUI
+
+ def overlayOutput = DDROverlayOutput(ddr = mig.node)
+ def ioFactory = new XilinxVC707MIGPads(size)
+
+ InModuleBody { ioNode.bundle <> mig.module.io }
+
+ shell { InModuleBody {
+ require (shell.sys_clock.get.isDefined, "Use of DDRVC707PlacedOverlay depends on SysClockVC707PlacedOverlay")
+ val (sys, _) = shell.sys_clock.get.get.overlayOutput.node.out(0)
+ val (ui, _) = ddrUI.out(0)
+ val (ar, _) = areset.in(0)
+ val port = topIONode.bundle.port
+ io <> port
+ ui.clock := port.ui_clk
+ ui.reset := !port.mmcm_locked || port.ui_clk_sync_rst
+ port.sys_clk_i := sys.clock.asUInt
+ port.sys_rst := sys.reset // pllReset
+ port.aresetn := !ar.reset
+ } }
+
+ shell.sdc.addGroup(clocks = Seq("clk_pll_i"))
+}
+class DDRVC707ShellPlacer(val shell: VC707Shell, val shellInput: DDRShellInput)(implicit val valName: ValName)
+ extends DDRShellPlacer[VC707Shell] {
+ def place(designInput: DDRDesignInput) = new DDRVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class PCIeVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: PCIeDesignInput, val shellInput: PCIeShellInput)
+ extends PCIePlacedOverlay[XilinxVC707PCIeX1Pads](name, designInput, shellInput)
+{
+ val pcie = LazyModule(new XilinxVC707PCIeX1)
+ val ioNode = BundleBridgeSource(() => pcie.module.io.cloneType)
+ val topIONode = shell { ioNode.makeSink() }
+ val axiClk = shell { ClockSourceNode(freqMHz = 125) }
+ val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) }
+ areset := designInput.wrangler := axiClk
+
+ val slaveSide = TLIdentityNode()
+ pcie.crossTLIn(pcie.slave) := slaveSide
+ pcie.crossTLIn(pcie.control) := slaveSide
+ val node = NodeHandle(slaveSide, pcie.crossTLOut(pcie.master))
+ val intnode = pcie.crossIntOut(pcie.intnode)
+
+ def overlayOutput = PCIeOverlayOutput(node, intnode)
+ def ioFactory = new XilinxVC707PCIeX1Pads
+
+ InModuleBody { ioNode.bundle <> pcie.module.io }
+
+ shell { InModuleBody {
+ val (axi, _) = axiClk.out(0)
+ val (ar, _) = areset.in(0)
+ val port = topIONode.bundle.port
+ io <> port
+ axi.clock := port.axi_aclk_out
+ axi.reset := !port.mmcm_lock
+ port.axi_aresetn := !ar.reset
+ port.axi_ctl_aresetn := !ar.reset
+
+ shell.xdc.addPackagePin(io.REFCLK_rxp, "A10")
+ shell.xdc.addPackagePin(io.REFCLK_rxn, "A9")
+ shell.xdc.addPackagePin(io.pci_exp_txp, "H4")
+ shell.xdc.addPackagePin(io.pci_exp_txn, "H3")
+ shell.xdc.addPackagePin(io.pci_exp_rxp, "G6")
+ shell.xdc.addPackagePin(io.pci_exp_rxn, "G5")
+
+ shell.sdc.addClock(s"${name}_ref_clk", io.REFCLK_rxp, 100)
+ } }
+
+ shell.sdc.addGroup(clocks = Seq("txoutclk", "userclk1"))
+}
+class PCIeVC707ShellPlacer(val shell: VC707Shell, val shellInput: PCIeShellInput)(implicit val valName: ValName)
+ extends PCIeShellPlacer[VC707Shell] {
+ def place(designInput: PCIeDesignInput) = new PCIeVC707PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+abstract class VC707Shell()(implicit p: Parameters) extends Series7Shell
+{
+ // PLL reset causes
+ val pllReset = InModuleBody { Wire(Bool()) }
+
+ // Order matters; ddr depends on sys_clock
+ val sys_clock = Overlay(ClockInputOverlayKey, new SysClockVC707ShellPlacer(this, ClockInputShellInput()))
+ val led = Seq.tabulate(8)(i => Overlay(LEDOverlayKey, new LEDVC707ShellPlacer(this, LEDShellInput(color = "red", number = i))(valName = ValName(s"led_$i"))))
+ val switch = Seq.tabulate(8)(i => Overlay(SwitchOverlayKey, new SwitchVC707ShellPlacer(this, SwitchShellInput(number = i))(valName = ValName(s"switch_$i"))))
+ val button = Seq.tabulate(5)(i => Overlay(ButtonOverlayKey, new ButtonVC707ShellPlacer(this, ButtonShellInput(number = i))(valName = ValName(s"button_$i"))))
+ val chiplink = Overlay(ChipLinkOverlayKey, new ChipLinkVC707ShellPlacer(this, ChipLinkShellInput()))
+ val ddr = Overlay(DDROverlayKey, new DDRVC707ShellPlacer(this, DDRShellInput()))
+ val sdio = Overlay(SDIOOverlayKey, new SDIOVC707ShellPlacer(this, SDIOShellInput()))
+ val jtag = Overlay(JTAGDebugOverlayKey, new JTAGDebugVC707ShellPlacer(this, JTAGDebugShellInput()))
+}
+
+class VC707BaseShell()(implicit p: Parameters) extends VC707Shell
+{
+ val uart = Seq.tabulate(1)(i => Overlay(UARTOverlayKey, new UARTVC707ShellPlacer(this, UARTShellInput(index = 0))))
+ val topDesign = LazyModule(p(DesignKey)(designParameters))
+
+ // Place the sys_clock at the Shell if the user didn't ask for it
+ p(ClockInputOverlayKey).foreach(_.place(ClockInputDesignInput()))
+
+ override lazy val module = new LazyRawModuleImp(this) {
+ val reset = IO(Input(Bool()))
+ xdc.addBoardPin(reset, "reset")
+
+ val reset_ibuf = Module(new IBUF)
+ reset_ibuf.io.I := reset
+
+ val sysclk: Clock = sys_clock.get() match {
+ case Some(x: SysClockVC707PlacedOverlay) => x.clock
+ }
+ val powerOnReset = PowerOnResetFPGAOnly(sysclk)
+ sdc.addAsyncPath(Seq(powerOnReset))
+
+ val ereset: Bool = chiplink.get() match {
+ case Some(x: ChipLinkVCU118PlacedOverlay) => !x.ereset_n
+ case _ => false.B
+ }
+ pllReset :=
+ reset_ibuf.io.O || powerOnReset || ereset
+ }
+}
+
+class VC707PCIeShell()(implicit p: Parameters) extends VC707Shell
+{
+ val uart = Seq.tabulate(1)(i => Overlay(UARTOverlayKey, new UARTVC707ShellPlacer(this, UARTShellInput(index = 0))))
+ val pcie = Overlay(PCIeOverlayKey, new PCIeVC707ShellPlacer(this, PCIeShellInput()))
+ val topDesign = LazyModule(p(DesignKey)(designParameters))
+
+ // Place the sys_clock at the Shell if the user didn't ask for it
+ p(ClockInputOverlayKey).foreach(_.place(ClockInputDesignInput()))
+
+ override lazy val module = new LazyRawModuleImp(this) {
+ val reset = IO(Input(Bool()))
+ xdc.addBoardPin(reset, "reset")
+
+ val reset_ibuf = Module(new IBUF)
+ reset_ibuf.io.I := reset
+ val sysclk: Clock = sys_clock.get() match {
+ case Some(x: SysClockVC707PlacedOverlay) => x.clock
+ }
+ val powerOnReset = PowerOnResetFPGAOnly(sysclk)
+ sdc.addAsyncPath(Seq(powerOnReset))
+ val ereset: Bool = chiplink.get() match {
+ case Some(x: ChipLinkVCU118PlacedOverlay) => !x.ereset_n
+ case _ => false.B
+ }
+ pllReset :=
+ reset_ibuf.io.O || powerOnReset || ereset
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VC707Shell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VC707Shell.scala
new file mode 100644
index 0000000..a0ed4c2
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VC707Shell.scala
@@ -0,0 +1,613 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx.vc707shell
+
+import Chisel._
+import chisel3.{Input, Output, RawModule, withClockAndReset}
+import chisel3.experimental.{attach, Analog}
+
+import freechips.rocketchip.config._
+import freechips.rocketchip.devices.debug._
+import freechips.rocketchip.util.{SyncResetSynchronizerShiftReg, ElaborationArtefacts, HeterogeneousBag}
+
+import sifive.blocks.devices.gpio._
+import sifive.blocks.devices.spi._
+import sifive.blocks.devices.uart._
+import sifive.blocks.devices.chiplink._
+
+import sifive.fpgashells.devices.xilinx.xilinxvc707mig._
+import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1._
+import sifive.fpgashells.ip.xilinx.{IBUFDS, PowerOnResetFPGAOnly, sdio_spi_bridge, Series7MMCM, vc707reset}
+
+//vc707_sys_clock_mmcm0, vc707_sys_clock_, vc707_sys_clock_mmcm2 , vc707reset}
+import sifive.fpgashells.clocks._
+//-------------------------------------------------------------------------
+// VC707Shell
+//-------------------------------------------------------------------------
+
+trait HasDDR3 { this: VC707Shell =>
+
+ require(!p.lift(MemoryXilinxDDRKey).isEmpty)
+ val ddr = IO(new XilinxVC707MIGPads(p(MemoryXilinxDDRKey)))
+
+ def connectMIG(dut: HasMemoryXilinxVC707MIGModuleImp): Unit = {
+ // Clock & Reset
+ dut.xilinxvc707mig.sys_clk_i := sys_clock.asUInt
+ mig_clock := dut.xilinxvc707mig.ui_clk
+ mig_sys_reset := dut.xilinxvc707mig.ui_clk_sync_rst
+ mig_mmcm_locked := dut.xilinxvc707mig.mmcm_locked
+ dut.xilinxvc707mig.aresetn := mig_resetn
+ dut.xilinxvc707mig.sys_rst := sys_reset
+
+ ddr <> dut.xilinxvc707mig
+ }
+}
+
+trait HasPCIe { this: VC707Shell =>
+ val pcie = IO(new XilinxVC707PCIeX1Pads)
+
+ def connectPCIe(dut: HasSystemXilinxVC707PCIeX1ModuleImp): Unit = {
+ // Clock & Reset
+ dut.xilinxvc707pcie.axi_aresetn := pcie_dat_resetn
+ pcie_dat_clock := dut.xilinxvc707pcie.axi_aclk_out
+ pcie_cfg_clock := dut.xilinxvc707pcie.axi_ctl_aclk_out
+ mmcm_lock_pcie := dut.xilinxvc707pcie.mmcm_lock
+ dut.xilinxvc707pcie.axi_ctl_aresetn := pcie_dat_resetn
+
+ pcie <> dut.xilinxvc707pcie
+ }
+}
+
+trait HasDebugJTAG { this: VC707Shell =>
+ // JTAG
+ val jtag_TCK = IO(Input(Clock()))
+ val jtag_TMS = IO(Input(Bool()))
+ val jtag_TDI = IO(Input(Bool()))
+ val jtag_TDO = IO(Output(Bool()))
+
+ def connectDebugJTAG(dut: HasPeripheryDebugModuleImp, fmcxm105: Boolean = true): SystemJTAGIO = {
+
+ require(dut.debug.isDefined, "Connecting JTAG requires that debug module exists")
+ ElaborationArtefacts.add(
+ """debugjtag.vivado.tcl""",
+ """set vc707debugjtag_vivado_tcl_dir [file dirname [file normalize [info script]]]
+ add_files -fileset [current_fileset -constrset] [glob -directory $vc707debugjtag_vivado_tcl_dir {*.vc707debugjtag.xdc}]"""
+ )
+
+ if(fmcxm105) {
+ //VC707 constraints for Xilinx FMC XM105 Debug Card
+ ElaborationArtefacts.add(
+ """vc707debugjtag.xdc""",
+ """set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jtag_TCK]
+ set_property -dict { PACKAGE_PIN R32 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TCK}]
+ set_property -dict { PACKAGE_PIN W36 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TMS}]
+ set_property -dict { PACKAGE_PIN W37 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TDI}]
+ set_property -dict { PACKAGE_PIN V40 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TDO}]
+ create_clock -add -name JTCK -period 100 -waveform {0 50} [get_ports {jtag_TCK}];"""
+ )
+ } else {
+ //VC707 constraints for Olimex connect to LCD panel header
+ ElaborationArtefacts.add(
+ """vc707debugjtag.xdc""",
+ """
+ #Olimex Pin Olimex Function LCD Pin LCD Function FPGA Pin
+ #1 VREF 14 5V
+ #3 TTRST_N 1 LCD_DB7 AN40
+ #5 TTDI 2 LCD_DB6 AR39
+ #7 TTMS 3 LCD_DB5 AR38
+ #9 TTCK 4 LCD_DB4 AT42
+ #11 TRTCK NC NC NC
+ #13 TTDO 9 LCD_E AT40
+ #15 TSRST_N 10 LCD_RW AR42
+ #2 VREF 14 5V
+ #18 GND 13 GND
+ set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jtag_TCK]
+ set_property -dict { PACKAGE_PIN AT42 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TCK}]
+ set_property -dict { PACKAGE_PIN AR38 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TMS}]
+ set_property -dict { PACKAGE_PIN AR39 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TDI}]
+ set_property -dict { PACKAGE_PIN AT40 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TDO}]
+ create_clock -add -name JTCK -period 100 -waveform {0 50} [get_ports {jtag_TCK}];"""
+ )
+ }
+
+ val djtag = dut.debug.get.systemjtag.get
+
+ djtag.jtag.TCK := jtag_TCK
+ djtag.jtag.TMS := jtag_TMS
+ djtag.jtag.TDI := jtag_TDI
+ jtag_TDO := djtag.jtag.TDO.data
+
+ djtag.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W)
+ djtag.part_number := p(JtagDTMKey).idcodePartNum.U(16.W)
+ djtag.version := p(JtagDTMKey).idcodeVersion.U(4.W)
+
+ djtag.reset := PowerOnResetFPGAOnly(dut_clock)
+ dut_ndreset := dut.debug.get.ndreset
+ djtag
+ }
+}
+
+trait HasVC707ChipLink { this: VC707Shell =>
+
+ val chiplink = IO(new WideDataLayerPort(ChipLinkParams(Nil,Nil)))
+ val ereset_n = IO(Bool(INPUT))
+
+ def constrainChipLink(iofpga: Boolean = false): Unit = {
+ val direction0Pins = if(iofpga) "chiplink_b2c" else "chiplink_c2b"
+ val direction1Pins = if(iofpga) "chiplink_c2b" else "chiplink_b2c"
+
+ ElaborationArtefacts.add(
+ """vc707chiplink.vivado.tcl""",
+ """set vc707chiplink_vivado_tcl_dir [file dirname [file normalize [info script]]]
+ add_files -fileset [current_fileset -constrset] [glob -directory $vc707chiplink_vivado_tcl_dir {*.vc707chiplink.xdc}]"""
+ )
+
+ ElaborationArtefacts.add(
+ """vc707chiplink.xdc""", s"""
+ set_property PACKAGE_PIN AF39 [get_ports ${direction0Pins}_clk]
+ set_property PACKAGE_PIN AD40 [get_ports {${direction0Pins}_data[0]}]
+ set_property PACKAGE_PIN AD41 [get_ports {${direction0Pins}_data[1]}]
+ set_property PACKAGE_PIN AF41 [get_ports {${direction0Pins}_data[2]}]
+ set_property PACKAGE_PIN AG41 [get_ports {${direction0Pins}_data[3]}]
+ set_property PACKAGE_PIN AK39 [get_ports {${direction0Pins}_data[4]}]
+ set_property PACKAGE_PIN AL39 [get_ports {${direction0Pins}_data[5]}]
+ set_property PACKAGE_PIN AJ42 [get_ports {${direction0Pins}_data[6]}]
+ set_property PACKAGE_PIN AK42 [get_ports {${direction0Pins}_data[7]}]
+ set_property PACKAGE_PIN AL41 [get_ports {${direction0Pins}_data[8]}]
+ set_property PACKAGE_PIN AL42 [get_ports {${direction0Pins}_data[9]}]
+ set_property PACKAGE_PIN AF42 [get_ports {${direction0Pins}_data[10]}]
+ set_property PACKAGE_PIN AG42 [get_ports {${direction0Pins}_data[11]}]
+ set_property PACKAGE_PIN AD38 [get_ports {${direction0Pins}_data[12]}]
+ set_property PACKAGE_PIN AE38 [get_ports {${direction0Pins}_data[13]}]
+ set_property PACKAGE_PIN AC40 [get_ports {${direction0Pins}_data[14]}]
+ set_property PACKAGE_PIN AC41 [get_ports {${direction0Pins}_data[15]}]
+ set_property PACKAGE_PIN AD42 [get_ports {${direction0Pins}_data[16]}]
+ set_property PACKAGE_PIN AE42 [get_ports {${direction0Pins}_data[17]}]
+ set_property PACKAGE_PIN AJ38 [get_ports {${direction0Pins}_data[18]}]
+ set_property PACKAGE_PIN AK38 [get_ports {${direction0Pins}_data[19]}]
+ set_property PACKAGE_PIN AB41 [get_ports {${direction0Pins}_data[20]}]
+ set_property PACKAGE_PIN AB42 [get_ports {${direction0Pins}_data[21]}]
+ set_property PACKAGE_PIN Y42 [get_ports {${direction0Pins}_data[22]}]
+ set_property PACKAGE_PIN AA42 [get_ports {${direction0Pins}_data[23]}]
+ set_property PACKAGE_PIN Y39 [get_ports {${direction0Pins}_data[24]}]
+ set_property PACKAGE_PIN AA39 [get_ports {${direction0Pins}_data[25]}]
+ set_property PACKAGE_PIN W40 [get_ports {${direction0Pins}_data[26]}]
+ set_property PACKAGE_PIN Y40 [get_ports {${direction0Pins}_data[27]}]
+ set_property PACKAGE_PIN AB38 [get_ports {${direction0Pins}_data[28]}]
+ set_property PACKAGE_PIN AB39 [get_ports {${direction0Pins}_data[29]}]
+ set_property PACKAGE_PIN AC38 [get_ports {${direction0Pins}_data[30]}]
+ set_property PACKAGE_PIN AC39 [get_ports {${direction0Pins}_data[31]}]
+ set_property PACKAGE_PIN AJ40 [get_ports ${direction0Pins}_send]
+ set_property PACKAGE_PIN AJ41 [get_ports ${direction0Pins}_rst]
+
+ set_property PACKAGE_PIN U39 [get_ports ${direction1Pins}_clk]
+ set_property PACKAGE_PIN U37 [get_ports {${direction1Pins}_data[0]}]
+ set_property PACKAGE_PIN U38 [get_ports {${direction1Pins}_data[1]}]
+ set_property PACKAGE_PIN U36 [get_ports {${direction1Pins}_data[2]}]
+ set_property PACKAGE_PIN T37 [get_ports {${direction1Pins}_data[3]}]
+ set_property PACKAGE_PIN U32 [get_ports {${direction1Pins}_data[4]}]
+ set_property PACKAGE_PIN U33 [get_ports {${direction1Pins}_data[5]}]
+ set_property PACKAGE_PIN V33 [get_ports {${direction1Pins}_data[6]}]
+ set_property PACKAGE_PIN V34 [get_ports {${direction1Pins}_data[7]}]
+ set_property PACKAGE_PIN P35 [get_ports {${direction1Pins}_data[8]}]
+ set_property PACKAGE_PIN P36 [get_ports {${direction1Pins}_data[9]}]
+ set_property PACKAGE_PIN W32 [get_ports {${direction1Pins}_data[10]}]
+ set_property PACKAGE_PIN W33 [get_ports {${direction1Pins}_data[11]}]
+ set_property PACKAGE_PIN R38 [get_ports {${direction1Pins}_data[12]}]
+ set_property PACKAGE_PIN R39 [get_ports {${direction1Pins}_data[13]}]
+ set_property PACKAGE_PIN U34 [get_ports {${direction1Pins}_data[14]}]
+ set_property PACKAGE_PIN T35 [get_ports {${direction1Pins}_data[15]}]
+ set_property PACKAGE_PIN R33 [get_ports {${direction1Pins}_data[16]}]
+ set_property PACKAGE_PIN R34 [get_ports {${direction1Pins}_data[17]}]
+ set_property PACKAGE_PIN N33 [get_ports {${direction1Pins}_data[18]}]
+ set_property PACKAGE_PIN N34 [get_ports {${direction1Pins}_data[19]}]
+ set_property PACKAGE_PIN P32 [get_ports {${direction1Pins}_data[20]}]
+ set_property PACKAGE_PIN P33 [get_ports {${direction1Pins}_data[21]}]
+ set_property PACKAGE_PIN V35 [get_ports {${direction1Pins}_data[22]}]
+ set_property PACKAGE_PIN V36 [get_ports {${direction1Pins}_data[23]}]
+ set_property PACKAGE_PIN W36 [get_ports {${direction1Pins}_data[24]}]
+ set_property PACKAGE_PIN W37 [get_ports {${direction1Pins}_data[25]}]
+ set_property PACKAGE_PIN T32 [get_ports {${direction1Pins}_data[26]}]
+ set_property PACKAGE_PIN R32 [get_ports {${direction1Pins}_data[27]}]
+ set_property PACKAGE_PIN V39 [get_ports {${direction1Pins}_data[28]}]
+ set_property PACKAGE_PIN V40 [get_ports {${direction1Pins}_data[29]}]
+ set_property PACKAGE_PIN P37 [get_ports {${direction1Pins}_data[30]}]
+ set_property PACKAGE_PIN P38 [get_ports {${direction1Pins}_data[31]}]""" + s"""
+
+ set_property PACKAGE_PIN T36 [get_ports ${direction1Pins}_send]
+ set_property PACKAGE_PIN R37 [get_ports ${direction1Pins}_rst]
+
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[31]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[30]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[29]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[28]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[27]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[26]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[25]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[24]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[23]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[22]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[21]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[20]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[19]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[18]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[17]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[16]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[15]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[14]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[13]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[12]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[11]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[10]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[9]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[8]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[7]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[6]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[5]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[4]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[3]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[2]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[1]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[0]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[31]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[30]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[29]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[28]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[27]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[26]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[25]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[24]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[23]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[22]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[21]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[20]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[19]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[18]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[17]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[16]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[15]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[14]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[13]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[12]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[11]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[10]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[9]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[8]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[7]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[6]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[5]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[4]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[3]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[2]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[1]}]
+ set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[0]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[31]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[30]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[29]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[28]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[27]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[26]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[25]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[24]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[23]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[22]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[21]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[20]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[19]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[18]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[17]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[16]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[15]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[14]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[13]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[12]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[11]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[10]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[9]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[8]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[7]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[6]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[5]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[4]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[3]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[2]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[1]}]
+ set_property SLEW FAST [get_ports {${direction1Pins}_data[0]}]""" + s"""
+
+
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction0Pins}_clk]
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction0Pins}_rst]
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction0Pins}_send]
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction1Pins}_clk]
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction1Pins}_rst]
+ set_property IOSTANDARD LVCMOS18 [get_ports ${direction1Pins}_send]
+ set_property SLEW FAST [get_ports ${direction1Pins}_clk]
+ set_property SLEW FAST [get_ports ${direction1Pins}_rst]
+ set_property SLEW FAST [get_ports ${direction1Pins}_send]
+
+
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[31]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[30]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[29]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[28]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[27]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[26]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[25]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[24]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[23]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[22]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[21]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[20]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[19]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[18]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[17]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[16]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[15]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[14]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[13]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[12]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[11]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[10]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[9]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[8]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[7]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[6]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[5]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[4]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[3]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[2]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[1]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[0]]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_send]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_clk]
+ set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_rst]
+
+ # Aloe reset sent to FPGA
+ set_property IOSTANDARD LVCMOS18 [get_ports ereset_n]
+ set_property PACKAGE_PIN AF40 [get_ports ereset_n]
+
+ #Put first level RX/TX flops in IOB
+ set_property IOB TRUE [get_cells -of_objects [all_fanout -flat -endpoints_only [get_ports "chiplink_b2c_data*"]]]
+ set_property IOB TRUE [get_cells -of_objects [all_fanout -flat -endpoints_only [get_ports "chiplink_b2c_send"]]]
+ set_property IOB TRUE [get_cells -of_objects [all_fanin -flat -startpoints_only [get_ports "chiplink_c2b_data*"]]]
+ set_property IOB TRUE [get_cells -of_objects [all_fanin -flat -startpoints_only [get_ports "chiplink_c2b_send"]]]
+"""
+ )
+ }
+
+ def connectChipLink(dut: { val chiplink: Seq[WideDataLayerPort] } , iofpga: Boolean = false): Unit = {
+ constrainChipLink(iofpga)
+
+ chiplink <> dut.chiplink(0)
+ //dut.chiplink_xilinx_7series_phy.get.idelayctrl_refclk := sys_clock
+ }
+}
+
+
+abstract class VC707Shell(implicit val p: Parameters) extends RawModule {
+
+ //-----------------------------------------------------------------------
+ // Interface
+ //-----------------------------------------------------------------------
+
+ // 200Mhz differential sysclk
+ val sys_diff_clock_clk_n = IO(Input(Clock()))
+ val sys_diff_clock_clk_p = IO(Input(Clock()))
+
+ // active high reset
+ val reset = IO(Input(Bool()))
+
+ // LED
+ val led = IO(Vec(8, Output(Bool())))
+
+ // UART
+ val uart_tx = IO(Output(Bool()))
+ val uart_rx = IO(Input(Bool()))
+ val uart_rtsn = IO(Output(Bool()))
+ val uart_ctsn = IO(Input(Bool()))
+
+ // SDIO
+ val sdio_clk = IO(Output(Bool()))
+ val sdio_cmd = IO(Analog(1.W))
+ val sdio_dat = IO(Analog(4.W))
+
+ //Buttons
+ val btn_0 = IO(Analog(1.W))
+ val btn_1 = IO(Analog(1.W))
+ val btn_2 = IO(Analog(1.W))
+ val btn_3 = IO(Analog(1.W))
+
+ //Sliding switches
+ val sw_0 = IO(Analog(1.W))
+ val sw_1 = IO(Analog(1.W))
+ val sw_2 = IO(Analog(1.W))
+ val sw_3 = IO(Analog(1.W))
+ val sw_4 = IO(Analog(1.W))
+ val sw_5 = IO(Analog(1.W))
+ val sw_6 = IO(Analog(1.W))
+ val sw_7 = IO(Analog(1.W))
+
+
+ //-----------------------------------------------------------------------
+ // Wire declrations
+ //-----------------------------------------------------------------------
+
+ val sys_clock = Wire(Clock())
+ val sys_reset = Wire(Bool())
+
+ val dut_clock = Wire(Clock())
+ val dut_reset = Wire(Bool())
+ val dut_resetn = Wire(Bool())
+
+ val dut_ndreset = Wire(Bool())
+
+ val sd_spi_sck = Wire(Bool())
+ val sd_spi_cs = Wire(Bool())
+ val sd_spi_dq_i = Wire(Vec(4, Bool()))
+ val sd_spi_dq_o = Wire(Vec(4, Bool()))
+
+ val do_reset = Wire(Bool())
+
+ val mig_mmcm_locked = Wire(Bool())
+ val mig_sys_reset = Wire(Bool())
+
+ val mig_clock = Wire(Clock())
+ val mig_reset = Wire(Bool())
+ val mig_resetn = Wire(Bool())
+
+ val pcie_dat_reset = Wire(Bool())
+ val pcie_dat_resetn = Wire(Bool())
+ val pcie_cfg_reset = Wire(Bool())
+ val pcie_cfg_resetn = Wire(Bool())
+ val pcie_dat_clock = Wire(Clock())
+ val pcie_cfg_clock = Wire(Clock())
+ val mmcm_lock_pcie = Wire(Bool())
+
+ //-----------------------------------------------------------------------
+ // Differential clock
+ //-----------------------------------------------------------------------
+
+ val sys_clk_ibufds = Module(new IBUFDS)
+ sys_clk_ibufds.io.I := sys_diff_clock_clk_p
+ sys_clk_ibufds.io.IB := sys_diff_clock_clk_n
+
+ //-----------------------------------------------------------------------
+ // System clock and reset
+ //-----------------------------------------------------------------------
+
+ // Clock that drives the clock generator and the MIG
+ sys_clock := sys_clk_ibufds.io.O
+
+ // Allow the debug module to reset everything. Resets the MIG
+ sys_reset := reset | dut_ndreset
+
+ //-----------------------------------------------------------------------
+ // Clock Generator
+ //-----------------------------------------------------------------------
+
+ //25MHz and multiples
+ val vc707_sys_clock_mmcm0 = Module(new Series7MMCM(PLLParameters(
+ "vc707_sys_clock_mmcm2",
+ PLLInClockParameters(200, 50),
+ Seq(
+ PLLOutClockParameters(12.5),
+ PLLOutClockParameters(25),
+ PLLOutClockParameters(37.5),
+ PLLOutClockParameters(50),
+ PLLOutClockParameters(100),
+ PLLOutClockParameters(150.00),
+ PLLOutClockParameters(100, 180)))))
+
+ vc707_sys_clock_mmcm0.io.clk_in1 := sys_clock
+ vc707_sys_clock_mmcm0.io.reset := reset
+ val vc707_sys_clock_mmcm0_locked = vc707_sys_clock_mmcm0.io.locked
+ val Seq(clk12_5, clk25, clk37_5, clk50, clk100, clk150, clk100_180) = vc707_sys_clock_mmcm0.getClocks
+
+ //65MHz and multiples
+ //val vc707_sys_clock_mmcm1 = Module(new vc707_sys_clock_mmcm1)
+ val vc707_sys_clock_mmcm1 = Module(new Series7MMCM(PLLParameters(
+ "vc707_sys_clock_mmcm1",
+ PLLInClockParameters(200, 50),
+ Seq(
+ PLLOutClockParameters(32.5),
+ PLLOutClockParameters(65, 180)))))
+
+ vc707_sys_clock_mmcm1.io.clk_in1 := sys_clock
+ vc707_sys_clock_mmcm1.io.reset := reset
+ val clk32_5 = vc707_sys_clock_mmcm1.io.clk_out1
+ val clk65 = vc707_sys_clock_mmcm1.io.clk_out2
+ val vc707_sys_clock_mmcm1_locked = vc707_sys_clock_mmcm1.io.locked
+
+ // DUT clock
+ dut_clock := clk37_5
+
+ //-----------------------------------------------------------------------
+ // System reset
+ //-----------------------------------------------------------------------
+
+ do_reset := !mig_mmcm_locked || !mmcm_lock_pcie || mig_sys_reset || !vc707_sys_clock_mmcm0_locked ||
+ !vc707_sys_clock_mmcm1_locked
+ mig_resetn := !mig_reset
+ dut_resetn := !dut_reset
+ pcie_dat_resetn := !pcie_dat_reset
+ pcie_cfg_resetn := !pcie_cfg_reset
+
+
+ val safe_reset = Module(new vc707reset)
+
+ safe_reset.io.areset := do_reset
+ safe_reset.io.clock1 := mig_clock
+ mig_reset := safe_reset.io.reset1
+ safe_reset.io.clock2 := pcie_dat_clock
+ pcie_dat_reset := safe_reset.io.reset2
+ safe_reset.io.clock3 := pcie_cfg_clock
+ pcie_cfg_reset := safe_reset.io.reset3
+ safe_reset.io.clock4 := dut_clock
+ dut_reset := safe_reset.io.reset4
+
+ //overrided in connectMIG and connect PCIe
+ //provide defaults to allow above reset sequencing logic to work without both
+ mig_clock := dut_clock
+ pcie_dat_clock := dut_clock
+ pcie_cfg_clock := dut_clock
+ mig_mmcm_locked := UInt("b1")
+ mmcm_lock_pcie := UInt("b1")
+
+
+
+ //-----------------------------------------------------------------------
+ // UART
+ //-----------------------------------------------------------------------
+
+ uart_rtsn := false.B
+
+ def connectUART(dut: HasPeripheryUARTModuleImp): Unit = dut.uart.headOption.foreach(connectUART)
+
+ def connectUART(uart: UARTPortIO): Unit = {
+ uart.rxd := SyncResetSynchronizerShiftReg(uart_rx, 2, init = Bool(true), name=Some("uart_rxd_sync"))
+ uart_tx := uart.txd
+ }
+
+ //-----------------------------------------------------------------------
+ // SPI
+ //-----------------------------------------------------------------------
+
+ def connectSPI(dut: HasPeripherySPIModuleImp): Unit = dut.spi.headOption.foreach(connectSPI)
+
+ def connectSPI(spi: SPIPortIO): Unit = {
+ // SPI
+ sd_spi_sck := spi.sck
+ sd_spi_cs := spi.cs(0)
+
+ spi.dq.zipWithIndex.foreach {
+ case(pin, idx) =>
+ sd_spi_dq_o(idx) := pin.o
+ pin.i := sd_spi_dq_i(idx)
+ }
+
+ //-------------------------------------------------------------------
+ // SDIO <> SPI Bridge
+ //-------------------------------------------------------------------
+
+ val ip_sdio_spi = Module(new sdio_spi_bridge())
+
+ ip_sdio_spi.io.clk := dut_clock
+ ip_sdio_spi.io.reset := dut_reset
+
+ // SDIO
+ attach(sdio_dat, ip_sdio_spi.io.sd_dat)
+ attach(sdio_cmd, ip_sdio_spi.io.sd_cmd)
+ sdio_clk := ip_sdio_spi.io.spi_sck
+
+ // SPI
+ ip_sdio_spi.io.spi_sck := sd_spi_sck
+ ip_sdio_spi.io.spi_cs := sd_spi_cs
+ sd_spi_dq_i := ip_sdio_spi.io.spi_dq_i.asBools
+ ip_sdio_spi.io.spi_dq_o := sd_spi_dq_o.asUInt
+ }
+
+ ElaborationArtefacts.add("old-shell.vivado.tcl",
+ """set obj [current_fileset -constrset]
+ |add_files -quiet -norecurse -fileset $obj [file join $boarddir tcl ios.tcl]
+ |add_files -quiet -norecurse -fileset $obj [file join $boarddir tcl clocks.tcl]
+ |""".stripMargin)
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VCU118NewShell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VCU118NewShell.scala
new file mode 100644
index 0000000..525760e
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VCU118NewShell.scala
@@ -0,0 +1,452 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import chisel3.experimental.{attach, Analog, IO}
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.util.SyncResetSynchronizerShiftReg
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+import sifive.blocks.devices.chiplink._
+import sifive.fpgashells.devices.xilinx.xilinxvcu118mig._
+import sifive.fpgashells.devices.xilinx.xdma._
+import sifive.fpgashells.ip.xilinx.xxv_ethernet._
+
+class SysClockVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput)
+ extends LVDSClockInputXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ val node = shell { ClockSourceNode(freqMHz = 250, jitterPS = 50)(ValName(name)) }
+
+ shell { InModuleBody {
+ shell.xdc.addPackagePin(io.p, "E12")
+ shell.xdc.addPackagePin(io.n, "D12")
+ shell.xdc.addIOStandard(io.p, "DIFF_SSTL12")
+ shell.xdc.addIOStandard(io.n, "DIFF_SSTL12")
+ } }
+}
+class SysClockVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: ClockInputShellInput)(implicit val valName: ValName)
+ extends ClockInputShellPlacer[VCU118ShellBasicOverlays]
+{
+ def place(designInput: ClockInputDesignInput) = new SysClockVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class RefClockVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput)
+ extends LVDSClockInputXilinxPlacedOverlay(name, designInput, shellInput) {
+ val node = shell { ClockSourceNode(freqMHz = 125, jitterPS = 50)(ValName(name)) }
+
+ shell { InModuleBody {
+ shell.xdc.addPackagePin(io.p, "AY24")
+ shell.xdc.addPackagePin(io.n, "AY23")
+ shell.xdc.addIOStandard(io.p, "LVDS")
+ shell.xdc.addIOStandard(io.n, "LVDS")
+ } }
+}
+class RefClockVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: ClockInputShellInput)(implicit val valName: ValName)
+ extends ClockInputShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: ClockInputDesignInput) = new RefClockVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class SDIOVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: SDIODesignInput, val shellInput: SDIOShellInput)
+ extends SDIOXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("AV15", IOPin(io.sdio_clk)),
+ ("AY15", IOPin(io.sdio_cmd)),
+ ("AW15", IOPin(io.sdio_dat_0)),
+ ("AV16", IOPin(io.sdio_dat_1)),
+ ("AU16", IOPin(io.sdio_dat_2)),
+ ("AY14", IOPin(io.sdio_dat_3)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ } }
+ packagePinsWithPackageIOs drop 1 foreach { case (pin, io) => {
+ shell.xdc.addPullup(io)
+ shell.xdc.addIOB(io)
+ } }
+ } }
+}
+class SDIOVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: SDIOShellInput)(implicit val valName: ValName)
+ extends SDIOShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: SDIODesignInput) = new SDIOVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class SPIFlashVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: SPIFlashDesignInput, val shellInput: SPIFlashShellInput)
+ extends SPIFlashXilinxPlacedOverlay(name, designInput, shellInput)
+{
+
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("AF13", IOPin(io.qspi_sck)),
+ ("AJ11", IOPin(io.qspi_cs)),
+ ("AP11", IOPin(io.qspi_dq(0))),
+ ("AN11", IOPin(io.qspi_dq(1))),
+ ("AM11", IOPin(io.qspi_dq(2))),
+ ("AL11", IOPin(io.qspi_dq(3))))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ // shell.xdc.addIOStandard(io, "LVCMOS18")
+ } }
+ //packagePinsWithPackageIOs drop 1 foreach { case (pin, io) => {
+ // shell.xdc.addPullup(io)
+ //} }
+ } }
+}
+class SPIFlashVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: SPIFlashShellInput)(implicit val valName: ValName)
+ extends SPIFlashShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: SPIFlashDesignInput) = new SPIFlashVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class UARTVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: UARTDesignInput, val shellInput: UARTShellInput)
+ extends UARTXilinxPlacedOverlay(name, designInput, shellInput, true)
+{
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("AY25", IOPin(io.ctsn.get)),
+ ("BB22", IOPin(io.rtsn.get)),
+ ("AW25", IOPin(io.rxd)),
+ ("BB21", IOPin(io.txd)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addIOB(io)
+ } }
+ } }
+}
+class UARTVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: UARTShellInput)(implicit val valName: ValName)
+ extends UARTShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: UARTDesignInput) = new UARTVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class QSFP1VCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: EthernetDesignInput, val shellInput: EthernetShellInput)
+ extends EthernetUltraScalePlacedOverlay(name, designInput, shellInput, XXVEthernetParams(name = name, speed = 10, dclkMHz = 125))
+{
+ val dclkSource = shell { BundleBridgeSource(() => Clock()) }
+ val dclkSink = dclkSource.makeSink()
+ InModuleBody {
+ dclk := dclkSink.bundle
+ }
+ shell { InModuleBody {
+ dclkSource.bundle := shell.ref_clock.get.get.overlayOutput.node.out(0)._1.clock
+ shell.xdc.addPackagePin(io.tx_p, "V7")
+ shell.xdc.addPackagePin(io.tx_n, "V6")
+ shell.xdc.addPackagePin(io.rx_p, "Y2")
+ shell.xdc.addPackagePin(io.rx_n, "Y1")
+ shell.xdc.addPackagePin(io.refclk_p, "W9")
+ shell.xdc.addPackagePin(io.refclk_n, "W8")
+ } }
+}
+class QSFP1VCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: EthernetShellInput)(implicit val valName: ValName)
+ extends EthernetShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: EthernetDesignInput) = new QSFP1VCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class QSFP2VCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: EthernetDesignInput, val shellInput: EthernetShellInput)
+ extends EthernetUltraScalePlacedOverlay(name, designInput, shellInput, XXVEthernetParams(name = name, speed = 10, dclkMHz = 125))
+{
+ val dclkSource = shell { BundleBridgeSource(() => Clock()) }
+ val dclkSink = dclkSource.makeSink()
+ InModuleBody {
+ dclk := dclkSink.bundle
+ }
+ shell { InModuleBody {
+ dclkSource.bundle := shell.ref_clock.get.get.overlayOutput.node.out(0)._1.clock
+ shell.xdc.addPackagePin(io.tx_p, "L5")
+ shell.xdc.addPackagePin(io.tx_n, "L4")
+ shell.xdc.addPackagePin(io.rx_p, "T2")
+ shell.xdc.addPackagePin(io.rx_n, "T1")
+ shell.xdc.addPackagePin(io.refclk_p, "R9")
+ shell.xdc.addPackagePin(io.refclk_n, "R8")
+ } }
+}
+class QSFP2VCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: EthernetShellInput)(implicit val valName: ValName)
+ extends EthernetShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: EthernetDesignInput) = new QSFP2VCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+object LEDVCU118PinConstraints {
+ val pins = Seq("AT32", "AV34", "AY30", "BB32", "BF32", "AU37", "AV36", "BA37")
+}
+class LEDVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: LEDDesignInput, val shellInput: LEDShellInput)
+ extends LEDXilinxPlacedOverlay(name, designInput, shellInput, packagePin = Some(LEDVCU118PinConstraints.pins(shellInput.number)), ioStandard = "LVCMOS12")
+class LEDVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: LEDShellInput)(implicit val valName: ValName)
+ extends LEDShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: LEDDesignInput) = new LEDVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+object SwitchVCU118PinConstraints {
+ val pins = Seq("B17", "G16", "J16", "D21")
+}
+class SwitchVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: SwitchDesignInput, val shellInput: SwitchShellInput)
+ extends SwitchXilinxPlacedOverlay(name, designInput, shellInput, packagePin = Some(SwitchVCU118PinConstraints.pins(shellInput.number)), ioStandard = "LVCMOS12")
+class SwitchVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: SwitchShellInput)(implicit val valName: ValName)
+ extends SwitchShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: SwitchDesignInput) = new SwitchVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class ChipLinkVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: ChipLinkDesignInput, val shellInput: ChipLinkShellInput)
+ extends ChipLinkXilinxPlacedOverlay(name, designInput, shellInput, rxPhase= -120, txPhase= -90, rxMargin=0.6, txMargin=0.5)
+{
+ val ereset_n = shell { InModuleBody {
+ val ereset_n = IO(Analog(1.W))
+ ereset_n.suggestName("ereset_n")
+ val pin = IOPin(ereset_n, 0)
+ shell.xdc.addPackagePin(pin, "BC8")
+ shell.xdc.addIOStandard(pin, "LVCMOS18")
+ shell.xdc.addTermination(pin, "NONE")
+ shell.xdc.addPullup(pin)
+
+ val iobuf = Module(new IOBUF)
+ iobuf.suggestName("chiplink_ereset_iobuf")
+ attach(ereset_n, iobuf.io.IO)
+ iobuf.io.T := true.B // !oe
+ iobuf.io.I := false.B
+
+ iobuf.io.O
+ } }
+
+ shell { InModuleBody {
+ val dir1 = Seq("BC9", "AV8", "AV9", /* clk, rst, send */
+ "AY9", "BA9", "BF10", "BF9", "BC11", "BD11", "BD12", "BE12",
+ "BF12", "BF11", "BE14", "BF14", "BD13", "BE13", "BC15", "BD15",
+ "BE15", "BF15", "BA14", "BB14", "BB13", "BB12", "BA16", "BA15",
+ "BC14", "BC13", "AY8", "AY7", "AW8", "AW7", "BB16", "BC16")
+ val dir2 = Seq("AV14", "AK13", "AK14", /* clk, rst, send */
+ "AR14", "AT14", "AP12", "AR12", "AW12", "AY12", "AW11", "AY10",
+ "AU11", "AV11", "AW13", "AY13", "AN16", "AP16", "AP13", "AR13",
+ "AT12", "AU12", "AK15", "AL15", "AL14", "AM14", "AV10", "AW10",
+ "AN15", "AP15", "AK12", "AL12", "AM13", "AM12", "AJ13", "AJ12")
+ (IOPin.of(io.b2c) zip dir1) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) }
+ (IOPin.of(io.c2b) zip dir2) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) }
+ } }
+}
+class ChipLinkVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: ChipLinkShellInput)(implicit val valName: ValName)
+ extends ChipLinkShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: ChipLinkDesignInput) = new ChipLinkVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+// TODO: JTAG is untested
+class JTAGDebugVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: JTAGDebugDesignInput, val shellInput: JTAGDebugShellInput)
+ extends JTAGDebugXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ shell.sdc.addClock("JTCK", IOPin(io.jtag_TCK), 10)
+ shell.sdc.addGroup(clocks = Seq("JTCK"))
+ shell.xdc.clockDedicatedRouteFalse(IOPin(io.jtag_TCK))
+ val packagePinsWithPackageIOs = Seq(("P29", IOPin(io.jtag_TCK)),
+ ("L31", IOPin(io.jtag_TMS)),
+ ("M31", IOPin(io.jtag_TDI)),
+ ("R29", IOPin(io.jtag_TDO)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addPullup(io)
+ } }
+ } }
+}
+class JTAGDebugVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: JTAGDebugShellInput)(implicit val valName: ValName)
+ extends JTAGDebugShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: JTAGDebugDesignInput) = new JTAGDebugVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+case object VCU118DDRSize extends Field[BigInt](0x40000000L * 2) // 2GB
+class DDRVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: DDRDesignInput, val shellInput: DDRShellInput)
+ extends DDRPlacedOverlay[XilinxVCU118MIGPads](name, designInput, shellInput)
+{
+ val size = p(VCU118DDRSize)
+
+ val migParams = XilinxVCU118MIGParams(address = AddressSet.misaligned(di.baseAddress, size))
+ val mig = LazyModule(new XilinxVCU118MIG(migParams))
+ val ioNode = BundleBridgeSource(() => mig.module.io.cloneType)
+ val topIONode = shell { ioNode.makeSink() }
+ val ddrUI = shell { ClockSourceNode(freqMHz = 200) }
+ val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) }
+ areset := designInput.wrangler := ddrUI
+
+ def overlayOutput = DDROverlayOutput(ddr = mig.node)
+ def ioFactory = new XilinxVCU118MIGPads(size)
+
+ InModuleBody { ioNode.bundle <> mig.module.io }
+
+ shell { InModuleBody {
+ require (shell.sys_clock.get.isDefined, "Use of DDRVCU118Overlay depends on SysClockVCU118Overlay")
+ val (sys, _) = shell.sys_clock.get.get.overlayOutput.node.out(0)
+ val (ui, _) = ddrUI.out(0)
+ val (ar, _) = areset.in(0)
+ val port = topIONode.bundle.port
+ io <> port
+ ui.clock := port.c0_ddr4_ui_clk
+ ui.reset := /*!port.mmcm_locked ||*/ port.c0_ddr4_ui_clk_sync_rst
+ port.c0_sys_clk_i := sys.clock.asUInt
+ port.sys_rst := sys.reset // pllReset
+ port.c0_ddr4_aresetn := !ar.reset
+
+ val allddrpins = Seq( "D14", "B15", "B16", "C14", "C15", "A13", "A14",
+ "A15", "A16", "B12", "C12", "B13", "C13", "D15", "H14", "H15", "F15",
+ "H13", "G15", "G13", "N20", "E13", "E14", "F14", "A10", "F13", "C8",
+ "F11", "E11", "F10", "F9", "H12", "G12", "E9", "D9", "R19", "P19",
+ "M18", "M17", "N19", "N18", "N17", "M16", "L16", "K16", "L18", "K18",
+ "J17", "H17", "H19", "H18", "F19", "F18", "E19", "E18", "G20", "F20",
+ "E17", "D16", "D17", "C17", "C19", "C18", "D20", "D19", "C20", "B20",
+ "N23", "M23", "R21", "P21", "R22", "P22", "T23", "R23", "K24", "J24",
+ "M21", "L21", "K21", "J21", "K22", "J22", "H23", "H22", "E23", "E22",
+ "F21", "E21", "F24", "F23", "D10", "P16", "J19", "E16", "A18", "M22",
+ "L20", "G23", "D11", "P17", "K19", "F16", "A19", "N22", "M20", "H24",
+ "G11", "R18", "K17", "G18", "B18", "P20", "L23", "G22")
+
+ (IOPin.of(io) zip allddrpins) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) }
+ } }
+
+ shell.sdc.addGroup(pins = Seq(mig.island.module.blackbox.io.c0_ddr4_ui_clk))
+}
+class DDRVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: DDRShellInput)(implicit val valName: ValName)
+ extends DDRShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: DDRDesignInput) = new DDRVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class PCIeVCU118FMCPlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: PCIeDesignInput, val shellInput: PCIeShellInput)
+ extends PCIeUltraScalePlacedOverlay(name, designInput, shellInput, XDMAParams(
+ name = "fmc_xdma",
+ location = "X0Y3",
+ bars = designInput.bars,
+ control = designInput.ecam,
+ lanes = 4))
+{
+ shell { InModuleBody {
+ // Work-around incorrectly pre-assigned pins
+ IOPin.of(io).foreach { shell.xdc.addPackagePin(_, "") }
+
+ // We need some way to connect both of these to reach x8
+ val ref126 = Seq("V38", "V39") /* [pn] GBT0 Bank 126 */
+ val ref121 = Seq("AK38", "AK39") /* [pn] GBT0 Bank 121 */
+ val ref = ref126
+
+ // Bank 126 (DP5, DP6, DP4, DP7), Bank 121 (DP3, DP2, DP1, DP0)
+ val rxp = Seq("U45", "R45", "W45", "N45", "AJ45", "AL45", "AN45", "AR45") /* [0-7] */
+ val rxn = Seq("U46", "R46", "W46", "N46", "AJ46", "AL46", "AN46", "AR46") /* [0-7] */
+ val txp = Seq("P42", "M42", "T42", "K42", "AL40", "AM42", "AP42", "AT42") /* [0-7] */
+ val txn = Seq("P43", "M43", "T43", "K43", "AL41", "AM43", "AP43", "AT43") /* [0-7] */
+
+ def bind(io: Seq[IOPin], pad: Seq[String]) {
+ (io zip pad) foreach { case (io, pad) => shell.xdc.addPackagePin(io, pad) }
+ }
+
+ bind(IOPin.of(io.refclk), ref)
+ // We do these individually so that zip falls off the end of the lanes:
+ bind(IOPin.of(io.lanes.pci_exp_txp), txp)
+ bind(IOPin.of(io.lanes.pci_exp_txn), txn)
+ bind(IOPin.of(io.lanes.pci_exp_rxp), rxp)
+ bind(IOPin.of(io.lanes.pci_exp_rxn), rxn)
+ } }
+}
+class PCIeVCU118FMCShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: PCIeShellInput)(implicit val valName: ValName)
+ extends PCIeShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: PCIeDesignInput) = new PCIeVCU118FMCPlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class PCIeVCU118EdgePlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: PCIeDesignInput, val shellInput: PCIeShellInput)
+ extends PCIeUltraScalePlacedOverlay(name, designInput, shellInput, XDMAParams(
+ name = "edge_xdma",
+ location = "X1Y2",
+ bars = designInput.bars,
+ control = designInput.ecam,
+ lanes = 8))
+{
+ shell { InModuleBody {
+ // Work-around incorrectly pre-assigned pins
+ IOPin.of(io).foreach { shell.xdc.addPackagePin(_, "") }
+
+ // PCIe Edge connector U2
+ // Lanes 00-03 Bank 227
+ // Lanes 04-07 Bank 226
+ // Lanes 08-11 Bank 225
+ // Lanes 12-15 Bank 224
+
+ // FMC+ J22
+ val ref227 = Seq("AC9", "AC8") /* [pn] Bank 227 PCIE_CLK2_*/
+ val ref = ref227
+
+ // PCIe Edge connector U2 : Bank 227, 226
+ val rxp = Seq("AA4", "AB2", "AC4", "AD2", "AE4", "AF2", "AG4", "AH2") // [0-7]
+ val rxn = Seq("AA3", "AB1", "AC3", "AD1", "AE3", "AF1", "AG3", "AH1") // [0-7]
+ val txp = Seq("Y7", "AB7", "AD7", "AF7", "AH7", "AK7", "AM7", "AN5") // [0-7]
+ val txn = Seq("Y6", "AB6", "AD6", "AF6", "AH6", "AK6", "AM6", "AN4") // [0-7]
+
+ def bind(io: Seq[IOPin], pad: Seq[String]) {
+ (io zip pad) foreach { case (io, pad) => shell.xdc.addPackagePin(io, pad) }
+ }
+
+ bind(IOPin.of(io.refclk), ref)
+ // We do these individually so that zip falls off the end of the lanes:
+ bind(IOPin.of(io.lanes.pci_exp_txp), txp)
+ bind(IOPin.of(io.lanes.pci_exp_txn), txn)
+ bind(IOPin.of(io.lanes.pci_exp_rxp), rxp)
+ bind(IOPin.of(io.lanes.pci_exp_rxn), rxn)
+ } }
+}
+class PCIeVCU118EdgeShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: PCIeShellInput)(implicit val valName: ValName)
+ extends PCIeShellPlacer[VCU118ShellBasicOverlays] {
+ def place(designInput: PCIeDesignInput) = new PCIeVCU118EdgePlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+abstract class VCU118ShellBasicOverlays()(implicit p: Parameters) extends UltraScaleShell{
+ val sys_clock = Overlay(ClockInputOverlayKey, new SysClockVCU118ShellPlacer(this, ClockInputShellInput()))
+ val ref_clock = Overlay(ClockInputOverlayKey, new RefClockVCU118ShellPlacer(this, ClockInputShellInput()))
+ val led = Seq.tabulate(8)(i => Overlay(LEDOverlayKey, new LEDVCU118ShellPlacer(this, LEDShellInput(color = "red", number = i))(valName = ValName(s"led_$i"))))
+ val switch = Seq.tabulate(4)(i => Overlay(SwitchOverlayKey, new SwitchVCU118ShellPlacer(this, SwitchShellInput(number = i))(valName = ValName(s"switch_$i"))))
+ val ddr = Overlay(DDROverlayKey, new DDRVCU118ShellPlacer(this, DDRShellInput()))
+ val uart = Overlay(UARTOverlayKey, new UARTVCU118ShellPlacer(this, UARTShellInput()))
+ val sdio = Overlay(SDIOOverlayKey, new SDIOVCU118ShellPlacer(this, SDIOShellInput()))
+ val jtag = Overlay(JTAGDebugOverlayKey, new JTAGDebugVCU118ShellPlacer(this, JTAGDebugShellInput()))
+ val qsfp1 = Overlay(EthernetOverlayKey, new QSFP1VCU118ShellPlacer(this, EthernetShellInput()))
+ val qsfp2 = Overlay(EthernetOverlayKey, new QSFP2VCU118ShellPlacer(this, EthernetShellInput()))
+ val chiplink = Overlay(ChipLinkOverlayKey, new ChipLinkVCU118ShellPlacer(this, ChipLinkShellInput()))
+ val spi_flash = Overlay(SPIFlashOverlayKey, new SPIFlashVCU118ShellPlacer(this, SPIFlashShellInput()))
+}
+
+class VCU118Shell()(implicit p: Parameters) extends VCU118ShellBasicOverlays
+{
+ // PLL reset causes
+ val pllReset = InModuleBody { Wire(Bool()) }
+
+ // Order matters; ddr depends on sys_clock
+ val fmc = Overlay(PCIeOverlayKey, new PCIeVCU118FMCShellPlacer(this, PCIeShellInput()))
+ val edge = Overlay(PCIeOverlayKey, new PCIeVCU118EdgeShellPlacer(this, PCIeShellInput()))
+
+ val topDesign = LazyModule(p(DesignKey)(designParameters))
+
+ // Place the sys_clock at the Shell if the user didn't ask for it
+ designParameters(ClockInputOverlayKey).foreach { unused =>
+ val source = unused.place(ClockInputDesignInput()).overlayOutput.node
+ val sink = ClockSinkNode(Seq(ClockSinkParameters()))
+ sink := source
+ }
+
+ override lazy val module = new LazyRawModuleImp(this) {
+ val reset = IO(Input(Bool()))
+ xdc.addPackagePin(reset, "L19")
+ xdc.addIOStandard(reset, "LVCMOS12")
+
+ val reset_ibuf = Module(new IBUF)
+ reset_ibuf.io.I := reset
+
+ val sysclk: Clock = sys_clock.get() match {
+ case Some(x: SysClockVCU118PlacedOverlay) => x.clock
+ }
+
+ val powerOnReset: Bool = PowerOnResetFPGAOnly(sysclk)
+ sdc.addAsyncPath(Seq(powerOnReset))
+
+ val ereset: Bool = chiplink.get() match {
+ case Some(x: ChipLinkVCU118PlacedOverlay) => !x.ereset_n
+ case _ => false.B
+ }
+
+ pllReset := (reset_ibuf.io.O || powerOnReset || ereset)
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VCU118Shell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VCU118Shell.scala
new file mode 100644
index 0000000..c18e95b
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/VCU118Shell.scala
@@ -0,0 +1,276 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx.vcu118shell
+
+import Chisel._
+import chisel3.{Input, Output, RawModule, withClockAndReset}
+import chisel3.experimental.{Analog, attach}
+
+import freechips.rocketchip.config._
+import freechips.rocketchip.devices.debug._
+import freechips.rocketchip.util.{SyncResetSynchronizerShiftReg}
+
+import sifive.blocks.devices.gpio._
+import sifive.blocks.devices.spi._
+import sifive.blocks.devices.uart._
+
+import sifive.fpgashells.devices.xilinx.xilinxvcu118mig._
+import sifive.fpgashells.ip.xilinx.{IBUFDS, PowerOnResetFPGAOnly, sdio_spi_bridge, vcu118_sys_clock_mmcm0,
+ vcu118_sys_clock_mmcm1, vcu118reset}
+
+//-------------------------------------------------------------------------
+// VCU118Shell
+//-------------------------------------------------------------------------
+
+trait HasDDR3 { this: VCU118Shell =>
+
+ require(!p.lift(MemoryXilinxDDRKey).isEmpty)
+ val ddr = IO(new XilinxVCU118MIGPads(p(MemoryXilinxDDRKey)))
+
+ def connectMIG(dut: HasMemoryXilinxVCU118MIGModuleImp): Unit = {
+ // Clock & Reset
+ dut.xilinxvcu118mig.c0_sys_clk_i := sys_clock.asUInt
+ mig_clock := dut.xilinxvcu118mig.c0_ddr4_ui_clk
+ mig_sys_reset := dut.xilinxvcu118mig.c0_ddr4_ui_clk_sync_rst
+ dut.xilinxvcu118mig.c0_ddr4_aresetn := mig_resetn
+ dut.xilinxvcu118mig.sys_rst := sys_reset
+
+ ddr <> dut.xilinxvcu118mig
+ }
+}
+
+abstract class VCU118Shell(implicit val p: Parameters) extends RawModule {
+
+ //-----------------------------------------------------------------------
+ // Interface
+ //-----------------------------------------------------------------------
+
+ // 250Mhz differential sysclk
+ val sys_diff_clock_clk_n = IO(Input(Clock()))
+ val sys_diff_clock_clk_p = IO(Input(Clock()))
+
+ // active high reset
+ val reset = IO(Input(Bool()))
+
+ // LED
+ //val led = IO(Vec(8, Output(Bool())))
+
+ // UART
+ val uart_tx = IO(Output(Bool()))
+ val uart_rx = IO(Input(Bool()))
+ val uart_rtsn = IO(Output(Bool()))
+ val uart_ctsn = IO(Input(Bool()))
+
+ // SDIO
+ val sdio_clk = IO(Output(Bool()))
+ val sdio_cmd = IO(Analog(1.W))
+ val sdio_dat = IO(Analog(4.W))
+
+ // JTAG
+ val jtag_TCK = IO(Input(Clock()))
+ val jtag_TMS = IO(Input(Bool()))
+ val jtag_TDI = IO(Input(Bool()))
+ val jtag_TDO = IO(Output(Bool()))
+
+ //Buttons
+ //val btn_0 = IO(Analog(1.W))
+ //val btn_1 = IO(Analog(1.W))
+ //val btn_2 = IO(Analog(1.W))
+ //val btn_3 = IO(Analog(1.W))
+
+ //Sliding switches
+ //val sw_0 = IO(Analog(1.W))
+ //val sw_1 = IO(Analog(1.W))
+ //val sw_2 = IO(Analog(1.W))
+ //val sw_3 = IO(Analog(1.W))
+ //val sw_4 = IO(Analog(1.W))
+ //val sw_5 = IO(Analog(1.W))
+ //val sw_6 = IO(Analog(1.W))
+ //val sw_7 = IO(Analog(1.W))
+
+
+ //-----------------------------------------------------------------------
+ // Wire declrations
+ //-----------------------------------------------------------------------
+
+ val sys_clock = Wire(Clock())
+ val sys_reset = Wire(Bool())
+
+ val dut_clock = Wire(Clock())
+ val dut_reset = Wire(Bool())
+ val dut_resetn = Wire(Bool())
+
+ val dut_ndreset = Wire(Bool())
+
+ val sd_spi_sck = Wire(Bool())
+ val sd_spi_cs = Wire(Bool())
+ val sd_spi_dq_i = Wire(Vec(4, Bool()))
+ val sd_spi_dq_o = Wire(Vec(4, Bool()))
+
+ val do_reset = Wire(Bool())
+
+ val mig_mmcm_locked = Wire(Bool())
+ val mig_sys_reset = Wire(Bool())
+
+ val mig_clock = Wire(Clock())
+ val mig_reset = Wire(Bool())
+ val mig_resetn = Wire(Bool())
+
+ val pcie_dat_reset = Wire(Bool())
+ val pcie_dat_resetn = Wire(Bool())
+ val pcie_cfg_reset = Wire(Bool())
+ val pcie_cfg_resetn = Wire(Bool())
+ val pcie_dat_clock = Wire(Clock())
+ val pcie_cfg_clock = Wire(Clock())
+ val mmcm_lock_pcie = Wire(Bool())
+
+ //-----------------------------------------------------------------------
+ // Differential clock
+ //-----------------------------------------------------------------------
+
+ val sys_clk_ibufds = Module(new IBUFDS)
+ sys_clk_ibufds.io.I := sys_diff_clock_clk_p
+ sys_clk_ibufds.io.IB := sys_diff_clock_clk_n
+
+ //-----------------------------------------------------------------------
+ // System clock and reset
+ //-----------------------------------------------------------------------
+
+ // Clock that drives the clock generator and the MIG
+ sys_clock := sys_clk_ibufds.io.O
+
+ // Allow the debug module to reset everything. Resets the MIG
+ sys_reset := reset | dut_ndreset
+
+ //-----------------------------------------------------------------------
+ // Clock Generator
+ //-----------------------------------------------------------------------
+
+ //25MHz and multiples
+ val vcu118_sys_clock_mmcm0 = Module(new vcu118_sys_clock_mmcm0)
+ vcu118_sys_clock_mmcm0.io.clk_in1 := sys_clock.asUInt
+ vcu118_sys_clock_mmcm0.io.reset := reset
+ val clk12_5 = vcu118_sys_clock_mmcm0.io.clk_out1
+ val clk25 = vcu118_sys_clock_mmcm0.io.clk_out2
+ val clk37_5 = vcu118_sys_clock_mmcm0.io.clk_out3
+ val clk50 = vcu118_sys_clock_mmcm0.io.clk_out4
+ val clk100 = vcu118_sys_clock_mmcm0.io.clk_out5
+ val clk150 = vcu118_sys_clock_mmcm0.io.clk_out6
+ val clk75 = vcu118_sys_clock_mmcm0.io.clk_out7
+ val vcu118_sys_clock_mmcm0_locked = vcu118_sys_clock_mmcm0.io.locked
+
+ //65MHz and multiples
+ val vcu118_sys_clock_mmcm1 = Module(new vcu118_sys_clock_mmcm1)
+ vcu118_sys_clock_mmcm1.io.clk_in1 := sys_clock.asUInt
+ vcu118_sys_clock_mmcm1.io.reset := reset
+ val clk32_5 = vcu118_sys_clock_mmcm1.io.clk_out1
+ val clk65 = vcu118_sys_clock_mmcm1.io.clk_out2
+ val vcu118_sys_clock_mmcm1_locked = vcu118_sys_clock_mmcm1.io.locked
+
+ // DUT clock
+ dut_clock := clk37_5
+
+ //-----------------------------------------------------------------------
+ // System reset
+ //-----------------------------------------------------------------------
+
+ do_reset := !mig_mmcm_locked || !mmcm_lock_pcie || mig_sys_reset || !vcu118_sys_clock_mmcm0_locked ||
+ !vcu118_sys_clock_mmcm1_locked
+ mig_resetn := !mig_reset
+ dut_resetn := !dut_reset
+ pcie_dat_resetn := !pcie_dat_reset
+ pcie_cfg_resetn := !pcie_cfg_reset
+
+
+ val safe_reset = Module(new vcu118reset)
+
+ safe_reset.io.areset := do_reset
+ safe_reset.io.clock1 := mig_clock
+ mig_reset := safe_reset.io.reset1
+ safe_reset.io.clock2 := pcie_dat_clock
+ pcie_dat_reset := safe_reset.io.reset2
+ safe_reset.io.clock3 := pcie_cfg_clock
+ pcie_cfg_reset := safe_reset.io.reset3
+ safe_reset.io.clock4 := dut_clock
+ dut_reset := safe_reset.io.reset4
+
+ //overrided in connectMIG and connect PCIe
+ //provide defaults to allow above reset sequencing logic to work without both
+ mig_clock := dut_clock
+ pcie_dat_clock := dut_clock
+ pcie_cfg_clock := dut_clock
+ mig_mmcm_locked := UInt("b1")
+ mmcm_lock_pcie := UInt("b1")
+
+ //---------------------------------------------------------------------
+ // Debug JTAG
+ //---------------------------------------------------------------------
+
+ def connectDebugJTAG(dut: HasPeripheryDebugModuleImp): SystemJTAGIO = {
+ require(dut.debug.isDefined, "Connecting JTAG requires that debug module exists")
+ val djtag = dut.debug.get.systemjtag.get
+ djtag.jtag.TCK := jtag_TCK
+ djtag.jtag.TMS := jtag_TMS
+ djtag.jtag.TDI := jtag_TDI
+ jtag_TDO := djtag.jtag.TDO.data
+
+ djtag.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W)
+ djtag.part_number := p(JtagDTMKey).idcodePartNum.U(16.W)
+ djtag.version := p(JtagDTMKey).idcodeVersion.U(4.W)
+
+ djtag.reset := PowerOnResetFPGAOnly(dut_clock)
+ dut_ndreset := dut.debug.get.ndreset
+ djtag
+ }
+
+ //-----------------------------------------------------------------------
+ // UART
+ //-----------------------------------------------------------------------
+
+ uart_rtsn := false.B
+
+ def connectUART(dut: HasPeripheryUARTModuleImp): Unit = dut.uart.headOption.foreach(connectUART)
+
+ def connectUART(uart: UARTPortIO): Unit = {
+ uart.rxd := SyncResetSynchronizerShiftReg(uart_rx, 2, init = Bool(true), name=Some("uart_rxd_sync"))
+ uart_tx := uart.txd
+ }
+
+ //-----------------------------------------------------------------------
+ // SPI
+ //-----------------------------------------------------------------------
+
+ def connectSPI(dut: HasPeripherySPIModuleImp): Unit = dut.spi.headOption.foreach(connectSPI)
+
+ def connectSPI(spi: SPIPortIO): Unit = {
+ // SPI
+ sd_spi_sck := spi.sck
+ sd_spi_cs := spi.cs(0)
+
+ spi.dq.zipWithIndex.foreach {
+ case(pin, idx) =>
+ sd_spi_dq_o(idx) := pin.o
+ pin.i := sd_spi_dq_i(idx)
+ }
+
+ //-------------------------------------------------------------------
+ // SDIO <> SPI Bridge
+ //-------------------------------------------------------------------
+
+ val ip_sdio_spi = Module(new sdio_spi_bridge())
+
+ ip_sdio_spi.io.clk := dut_clock
+ ip_sdio_spi.io.reset := dut_reset
+
+ // SDIO
+ attach(sdio_dat, ip_sdio_spi.io.sd_dat)
+ attach(sdio_cmd, ip_sdio_spi.io.sd_cmd)
+ sdio_clk := ip_sdio_spi.io.spi_sck
+
+ // SPI
+ ip_sdio_spi.io.spi_sck := sd_spi_sck
+ ip_sdio_spi.io.spi_cs := sd_spi_cs
+ sd_spi_dq_i := ip_sdio_spi.io.spi_dq_i.asBools
+ ip_sdio_spi.io.spi_dq_o := sd_spi_dq_o.asUInt
+ }
+
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/XilinxShell.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/XilinxShell.scala
new file mode 100644
index 0000000..4ee22b8
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/XilinxShell.scala
@@ -0,0 +1,83 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.util._
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.ip.xilinx._
+import sifive.fpgashells.shell._
+
+class XDC(val name: String)
+{
+ private var constraints: Seq[() => String] = Nil
+ protected def addConstraint(command: => String) { constraints = (() => command) +: constraints }
+ ElaborationArtefacts.add(name, constraints.map(_()).reverse.mkString("\n") + "\n")
+
+ def addBoardPin(io: IOPin, pin: String) {
+ addConstraint(s"set_property BOARD_PIN {${pin}} ${io.sdcPin}")
+ }
+ def addPackagePin(io: IOPin, pin: String) {
+ addConstraint(s"set_property PACKAGE_PIN {${pin}} ${io.sdcPin}")
+ }
+ def addIOStandard(io: IOPin, standard: String) {
+ addConstraint(s"set_property IOSTANDARD {${standard}} ${io.sdcPin}")
+ }
+ def addPullup(io: IOPin) {
+ addConstraint(s"set_property PULLUP {TRUE} ${io.sdcPin}")
+ }
+ def addIOB(io: IOPin) {
+ if (io.isOutput) {
+ addConstraint(s"set_property IOB {TRUE} [ get_cells -of_objects [ all_fanin -flat -startpoints_only ${io.sdcPin}]]")
+ } else {
+ addConstraint(s"set_property IOB {TRUE} [ get_cells -of_objects [ all_fanout -flat -endpoints_only ${io.sdcPin}]]")
+ }
+ }
+ def addSlew(io: IOPin, speed: String) {
+ addConstraint(s"set_property SLEW {${speed}} ${io.sdcPin}")
+ }
+ def addTermination(io: IOPin, kind: String) {
+ addConstraint(s"set_property OFFCHIP_TERM {${kind}} ${io.sdcPin}")
+ }
+ def clockDedicatedRouteFalse(io: IOPin) {
+ addConstraint(s"set_property CLOCK_DEDICATED_ROUTE {FALSE} [get_nets ${io.sdcPin}]")
+ }
+}
+
+abstract class XilinxShell()(implicit p: Parameters) extends IOShell
+{
+ val sdc = new SDC("shell.sdc")
+ val xdc = new XDC("shell.xdc")
+ def pllReset: ModuleValue[Bool]
+
+ ElaborationArtefacts.add("shell.vivado.tcl",
+ """set shell_vivado_tcl [file normalize [info script]]
+ |set shell_vivado_idx [string last ".shell.vivado.tcl" $shell_vivado_tcl]
+ |add_files -fileset [current_fileset -constrset] [string replace $shell_vivado_tcl $shell_vivado_idx 999 ".shell.sdc"]
+ |add_files -fileset [current_fileset -constrset] [string replace $shell_vivado_tcl $shell_vivado_idx 999 ".shell.xdc"]
+ |set extra_constr [string replace $shell_vivado_tcl $shell_vivado_idx 999 ".extra.shell.xdc"]
+ |if [file exist $extra_constr] {
+ | add_files -fileset [current_fileset -constrset] [string replace $shell_vivado_tcl $shell_vivado_idx 999 ".extra.shell.xdc"]
+ |}
+ |""".stripMargin)
+
+ //Including the extra .xdc file in this way is a bit of a hack since ElaborationArtefacts can't append, and this tcl will only read specific
+ // files. The long term solution is to make an overlay that does nothing but include .xdc constraints
+}
+
+abstract class Series7Shell()(implicit p: Parameters) extends XilinxShell
+{
+ val pllFactory = new PLLFactory(this, 7, p => Module(new Series7MMCM(p)))
+ override def designParameters = super.designParameters.alterPartial {
+ case PLLFactoryKey => pllFactory
+ }
+}
+
+abstract class UltraScaleShell()(implicit p: Parameters) extends XilinxShell
+{
+ val pllFactory = new PLLFactory(this, 7, p => Module(new Series7MMCM(p)))
+ override def designParameters = super.designParameters.alterPartial {
+ case PLLFactoryKey => pllFactory
+ }
+}
diff --git a/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/cJTAGDebugOverlay.scala b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/cJTAGDebugOverlay.scala
new file mode 100644
index 0000000..e611240
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/src/main/scala/shell/xilinx/cJTAGDebugOverlay.scala
@@ -0,0 +1,13 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import freechips.rocketchip.diplomacy._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+
+abstract class cJTAGDebugXilinxPlacedOverlay(name: String, di: cJTAGDebugDesignInput, si: cJTAGDebugShellInput)
+ extends cJTAGDebugPlacedOverlay(name, di, si)
+{
+ def shell: XilinxShell
+}
diff --git a/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/axis2xgmii.v b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/axis2xgmii.v
new file mode 100644
index 0000000..ba9612e
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/axis2xgmii.v
@@ -0,0 +1,499 @@
+//
+// Copyright (c) 2016 University of Cambridge All rights reserved.
+//
+// Author: Marco Forconesi
+//
+// This software was developed with the support of
+// Prof. Gustavo Sutter and Prof. Sergio Lopez-Buedo and
+// University of Cambridge Computer Laboratory NetFPGA team.
+//
+// @NETFPGA_LICENSE_HEADER_START@
+//
+// Licensed to NetFPGA C.I.C. (NetFPGA) under one or more
+// contributor license agreements. See the NOTICE file distributed with this
+// work for additional information regarding copyright ownership. NetFPGA
+// licenses this file to you under the NetFPGA Hardware-Software License,
+// Version 1.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at:
+//
+// http://www.netfpga-cic.org
+//
+// Unless required by applicable law or agreed to in writing, Work distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+// @NETFPGA_LICENSE_HEADER_END@
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1ns / 1ps
+//`default_nettype none
+
+module axis2xgmii (
+
+ // Clks and resets
+ input clk,
+ input rst,
+
+ // Stats
+ output reg [31:0] good_frames,
+ output reg [31:0] bad_frames,
+
+ // Conf vectors
+ input [79:0] configuration_vector,
+
+ // internal
+ output reg lane4_start,
+ output [1:0] dic_o,
+
+ // XGMII
+ output [63:0] xgmii_d,
+ output [7:0] xgmii_c,
+
+ // AXIS
+ input [63:0] tdata,
+ input [7:0] tkeep,
+ input tvalid,
+ output reg tready,
+ input tlast,
+ input [0:0] tuser
+ );
+
+ `include "xgmii_includes.vh"
+ // localparam
+ localparam SRES = 24'b000000000000000000000001;
+ localparam IDLE_L0 = 24'b000000000000000000000010;
+ localparam ST_LANE0 = 24'b000000000000000000000100;
+ localparam QW_IDLE = 24'b000000000000000000001000;
+ localparam L0_FIN_8B = 24'b000000000000000000100000;
+ localparam T_LANE4 = 24'b000000000000000001000000;
+ localparam L0_FIN_7B_6B_5B = 24'b000000000000000010000000;
+ localparam T_LANE3 = 24'b000000000000000100000000;
+ localparam DW_IDLE = 24'b000000000000001000000000;
+ localparam T_LANE2 = 24'b000000000000010000000000;
+ localparam T_LANE1 = 24'b000000000000100000000000;
+ localparam L0_FIN_4B = 24'b000000000001000000000000;
+ localparam T_LANE0 = 24'b000000000010000000000000;
+ localparam L0_FIN_3B_2B_1B = 24'b000000000100000000000000;
+ localparam T_LANE7 = 24'b000000001000000000000000;
+ localparam T_LANE6 = 24'b000000010000000000000000;
+ localparam T_LANE5 = 24'b000000100000000000000000;
+ localparam ST_LANE4 = 24'b000001000000000000000000;
+ localparam ST_LANE4_D = 24'b000010000000000000000000;
+ localparam L4_FIN_8B = 24'b000100000000000000000000;
+ localparam L4_FIN_7B_6B_5B = 24'b001000000000000000000000;
+ localparam L4_FIN_4B = 24'b010000000000000000000000;
+ localparam L4_FIN_3B_2B_1B = 24'b100000000000000000000000;
+
+ //-------------------------------------------------------
+ // Local adapter
+ //-------------------------------------------------------
+ reg [23:0] fsm = 'b1;
+ reg [63:0] tdata_i;
+ reg [7:0] tkeep_i;
+ reg [63:0] d;
+ reg [7:0] c;
+ reg [31:0] aux_dw;
+ reg [1:0] dic;
+
+ //-------------------------------------------------------
+ // Local CRC32
+ //-------------------------------------------------------
+ reg [31:0] crc_32;
+ reg [31:0] crc_32_7B;
+ reg [31:0] crc_32_6B;
+ reg [31:0] crc_32_5B;
+ reg [31:0] crc_32_4B;
+ reg [31:0] crc_32_3B;
+ reg [31:0] crc_32_2B;
+ reg [31:0] crc_32_1B;
+ reg [31:0] aux_var_crc;
+ reg [31:0] calcted_crc4B;
+ reg [31:0] crc_reg;
+
+ //-------------------------------------------------------
+ // assigns
+ //-------------------------------------------------------
+ assign xgmii_d = d;
+ assign xgmii_c = c;
+ assign dic_o = dic;
+
+ ////////////////////////////////////////////////
+ // adapter
+ ////////////////////////////////////////////////
+ always @(posedge clk) begin
+
+ if (rst) begin // rst
+ d <= QW_IDLE_D;
+ c <= QW_IDLE_C;
+ tready <= 1'b0;
+ fsm <= SRES;
+ end
+
+ else begin // not rst
+
+ case (fsm)
+
+ SRES : begin
+ dic <= 'b0;
+ tready <= 1'b1;
+ fsm <= IDLE_L0;
+ end
+
+ IDLE_L0 : begin
+ d <= QW_IDLE_D;
+ c <= QW_IDLE_C;
+ tdata_i <= tdata;
+ tkeep_i <= tkeep;
+ lane4_start <= 1'b0;
+ if (tvalid) begin
+ crc_32 <= crc8B(CRC802_3_PRESET,tdata);
+ d <= PREAMBLE_LANE0_D;
+ c <= PREAMBLE_LANE0_C;
+ fsm <= ST_LANE0;
+ end
+ else begin
+ if (dic) begin
+ dic <= dic - 1;
+ end
+ end
+ end
+
+ ST_LANE0 : begin
+ tready <= 1'b0;
+ tdata_i <= tdata;
+ tkeep_i <= tkeep;
+ d <= tdata_i;
+ c <= 8'b0;
+ crc_32 <= crc8B(crc_32,tdata);
+ crc_32_7B <= crc7B(crc_32,tdata[55:0]);
+ crc_32_6B <= crc6B(crc_32,tdata[47:0]);
+ crc_32_5B <= crc5B(crc_32,tdata[39:0]);
+ crc_32_4B <= crc4B(crc_32,tdata[31:0]);
+ crc_32_3B <= crc3B(crc_32,tdata[23:0]);
+ crc_32_2B <= crc2B(crc_32,tdata[15:0]);
+ crc_32_1B <= crc1B(crc_32,tdata[7:0]);
+
+ casex ({tuser[0], tlast, tkeep[7:3]})
+ {2'b1x, 5'hxx} : begin
+ d[7:0] <= XGMII_ERROR_L0_D;
+ d[63:56] <= T;
+ c <= XGMII_ERROR_L0_C;
+ c[7] <= 1'b1;
+ fsm <= QW_IDLE;
+ end
+ {2'b00, 5'hxx} : begin
+ tready <= 1'b1;
+ end
+ {2'b01, 5'b1xxxx} : begin
+ fsm <= L0_FIN_8B;
+ end
+ {2'b01, 5'b0xx1x} : begin
+ fsm <= L0_FIN_7B_6B_5B;
+ end
+ {2'b01, 5'bxxx01} : begin
+ fsm <= L0_FIN_4B;
+ end
+ {2'b01, 5'bxxxx0} : begin
+ fsm <= L0_FIN_3B_2B_1B;
+ end
+ endcase
+ end
+
+ QW_IDLE : begin
+ d <= QW_IDLE_D;
+ c <= QW_IDLE_C;
+ tready <= 1'b1;
+ fsm <= IDLE_L0;
+ end
+
+ L0_FIN_8B : begin
+ d <= tdata_i;
+ c <= 8'h00;
+ calcted_crc4B <= ~crc_rev(crc_32);
+ fsm <= T_LANE4;
+ end
+
+ T_LANE4 : begin
+ d <= {{3{I}}, T, calcted_crc4B};
+ c <= 8'hF0;
+ fsm <= QW_IDLE;
+ end
+
+ L0_FIN_7B_6B_5B : begin
+ casex (tkeep_i[6:4])
+ 3'b1xx : begin
+ aux_var_crc = ~crc_rev(crc_32_7B);
+ d <= {aux_var_crc[7:0], tdata_i[55:0]};
+ fsm <= T_LANE3;
+ end
+ 3'b01x : begin
+ aux_var_crc = ~crc_rev(crc_32_6B);
+ d <= {aux_var_crc[15:0], tdata_i[47:0]};
+ fsm <= T_LANE2;
+ end
+ 3'b001 : begin
+ aux_var_crc = ~crc_rev(crc_32_5B);
+ d <= {aux_var_crc[23:0], tdata_i[39:0]};
+ fsm <= T_LANE1;
+ end
+ endcase
+ c <= 8'b0;
+ crc_reg <= aux_var_crc;
+ end
+
+ T_LANE3 : begin
+ d <= {{4{I}}, T, crc_reg[31:8]};
+ c <= 8'hF8;
+ if (!dic) begin
+ dic <= 'h3;
+ tready <= 1'b1;
+ fsm <= DW_IDLE;
+ end
+ else begin
+ dic <= dic - 1;
+ fsm <= QW_IDLE;
+ end
+ end
+
+ DW_IDLE : begin
+ d <= QW_IDLE_D;
+ c <= QW_IDLE_C;
+ tdata_i <= tdata;
+ tkeep_i <= tkeep;
+ if (tvalid) begin
+ crc_32 <= crc8B(CRC802_3_PRESET,tdata);
+ d <= PREAMBLE_LANE4_D;
+ c <= PREAMBLE_LANE4_C;
+ fsm <= ST_LANE4;
+ end
+ else begin
+ fsm <= IDLE_L0;
+ end
+ end
+
+ T_LANE2 : begin
+ d <= {{5{I}}, T, crc_reg[31:16]};
+ c <= 8'hFC;
+ if (dic < 2) begin
+ dic <= dic + 2;
+ tready <= 1'b1;
+ fsm <= DW_IDLE;
+ end
+ else begin
+ dic <= dic - 2;
+ fsm <= QW_IDLE;
+ end
+ end
+
+ T_LANE1 : begin
+ d <= {{6{I}}, T, crc_reg[31:24]};
+ c <= 8'hFE;
+ if (dic < 3) begin
+ dic <= dic + 1;
+ tready <= 1'b1;
+ fsm <= DW_IDLE;
+ end
+ else begin
+ dic <= 'b0;
+ fsm <= QW_IDLE;
+ end
+ end
+
+ L0_FIN_4B : begin
+ d <= {~crc_rev(crc_32_4B), tdata_i[31:0]};
+ c <= 8'b0;
+ fsm <= T_LANE0;
+ end
+
+ T_LANE0 : begin
+ d <= {{7{I}}, T};
+ c <= 8'hFF;
+ tready <= 1'b1;
+ fsm <= DW_IDLE;
+ end
+
+ L0_FIN_3B_2B_1B : begin
+ casex (tkeep_i[2:0])
+ 3'b1xx : begin
+ d <= {T, ~crc_rev(crc_32_3B), tdata_i[23:0]};
+ c <= 8'h80;
+ fsm <= T_LANE7;
+ end
+ 3'b01x : begin
+ d <= {I, T, ~crc_rev(crc_32_2B), tdata_i[15:0]};
+ c <= 8'hC0;
+ fsm <= T_LANE6;
+ end
+ 3'b001 : begin
+ d <= {{2{I}}, T, ~crc_rev(crc_32_1B), tdata_i[7:0]};
+ c <= 8'hE0;
+ fsm <= T_LANE5;
+ end
+ endcase
+ end
+
+ T_LANE7 : begin
+ d <= QW_IDLE_D;
+ c <= QW_IDLE_C;
+ tready <= 1'b1;
+ if (!dic) begin
+ dic <= 'h3;
+ fsm <= IDLE_L0;
+ end
+ else begin
+ dic <= dic - 1;
+ fsm <= DW_IDLE;
+ end
+ end
+
+ T_LANE6 : begin
+ d <= QW_IDLE_D;
+ c <= QW_IDLE_C;
+ tready <= 1'b1;
+ if (dic < 2) begin
+ dic <= dic + 2;
+ fsm <= IDLE_L0;
+ end
+ else begin
+ dic <= dic - 2;
+ fsm <= DW_IDLE;
+ end
+ end
+
+ T_LANE5 : begin
+ d <= QW_IDLE_D;
+ c <= QW_IDLE_C;
+ tready <= 1'b1;
+ if (dic < 3) begin
+ dic <= dic + 1;
+ fsm <= IDLE_L0;
+ end
+ else begin
+ dic <= 'b0;
+ fsm <= DW_IDLE;
+ end
+ end
+
+ ST_LANE4 : begin
+ tdata_i <= tdata;
+ tkeep_i <= tkeep;
+ aux_dw <= tdata_i[63:32];
+ d <= {tdata_i[31:0], PREAMBLE_LANE4_END_D};
+ c <= PREAMBLE_LANE4_END_C;
+ crc_32 <= crc8B(crc_32,tdata);
+ lane4_start <= 1'b1;
+ if (tuser[0]) begin
+ d[7:0] <= XGMII_ERROR_L0_D;
+ d[63:56] <= T;
+ c <= XGMII_ERROR_L0_C;
+ c[7] <= 1'b1;
+ tready <= 1'b0;
+ fsm <= QW_IDLE;
+ end
+ else begin
+ fsm <= ST_LANE4_D;
+ end
+ end
+
+ ST_LANE4_D : begin
+ tready <= 1'b0;
+ tdata_i <= tdata;
+ tkeep_i <= tkeep;
+ aux_dw <= tdata_i[63:32];
+ d <= {tdata_i[31:0], aux_dw};
+ c <= 8'b0;
+ crc_32 <= crc8B(crc_32,tdata);
+ crc_32_7B <= crc7B(crc_32,tdata[55:0]);
+ crc_32_6B <= crc6B(crc_32,tdata[47:0]);
+ crc_32_5B <= crc5B(crc_32,tdata[39:0]);
+ crc_32_4B <= crc4B(crc_32,tdata[31:0]);
+ crc_32_3B <= crc3B(crc_32,tdata[23:0]);
+ crc_32_2B <= crc2B(crc_32,tdata[15:0]);
+ crc_32_1B <= crc1B(crc_32,tdata[7:0]);
+
+ casex ({tuser[0], tlast, tkeep[7:3]})
+ {2'b1x, 5'hxx} : begin
+ d[39:32] <= XGMII_ERROR_L4_D;
+ c <= XGMII_ERROR_L4_C;
+ fsm <= QW_IDLE;
+ end
+ {2'b00, 5'hxx} : begin
+ tready <= 1'b1;
+ end
+ {2'b01, 5'b1xxxx} : begin
+ fsm <= L4_FIN_8B;
+ end
+ {2'b01, 5'b0xx1x} : begin
+ fsm <= L4_FIN_7B_6B_5B;
+ end
+ {2'b01, 5'bxxx01} : begin
+ fsm <= L4_FIN_4B;
+ end
+ {2'b01, 5'bxxxx0} : begin
+ fsm <= L4_FIN_3B_2B_1B;
+ end
+ endcase
+ end
+
+ L4_FIN_8B : begin
+ d <= {tdata_i[31:0], aux_dw};
+ c <= 8'b0;
+ tdata_i[31:0] <= tdata_i[63:32];
+ crc_32_4B <= crc_32;
+ fsm <= L0_FIN_4B;
+ end
+
+ L4_FIN_7B_6B_5B : begin
+ c <= 8'b0;
+ crc_32_1B <= crc_32_5B;
+ crc_32_2B <= crc_32_6B;
+ crc_32_3B <= crc_32_7B;
+ tdata_i[31:0] <= tdata_i[63:32];
+ tkeep_i[2:0] <= tkeep_i[6:4];
+ d <= {tdata_i[31:0], aux_dw};
+ fsm <= L0_FIN_3B_2B_1B;
+ end
+
+ L4_FIN_4B : begin
+ d <= {tdata_i[31:0], aux_dw};
+ c <= 8'b0;
+ calcted_crc4B <= ~crc_rev(crc_32_4B);
+ fsm <= T_LANE4;
+ end
+
+ L4_FIN_3B_2B_1B : begin
+ casex (tkeep_i[2:0])
+ 3'b1xx : begin
+ aux_var_crc = ~crc_rev(crc_32_3B);
+ d <= {aux_var_crc[7:0], tdata_i[23:0], aux_dw};
+ fsm <= T_LANE3;
+ end
+ 3'b01x : begin
+ aux_var_crc = ~crc_rev(crc_32_2B);
+ d <= {aux_var_crc[15:0], tdata_i[15:0], aux_dw};
+ fsm <= T_LANE2;
+ end
+ 3'b001 : begin
+ aux_var_crc = ~crc_rev(crc_32_1B);
+ d <= {aux_var_crc[23:0], tdata_i[7:0], aux_dw};
+ fsm <= T_LANE1;
+ end
+ endcase
+ c <= 8'b0;
+ crc_reg <= aux_var_crc;
+ end
+
+ default : begin
+ fsm <= SRES;
+ end
+
+ endcase
+ end // not rst
+ end //always
+
+endmodule // axis2xgmii
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/nfmac10g.v b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/nfmac10g.v
new file mode 100644
index 0000000..d5dec34
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/nfmac10g.v
@@ -0,0 +1,195 @@
+//
+// Copyright (c) 2016 University of Cambridge All rights reserved.
+//
+// Author: Marco Forconesi
+//
+// This software was developed with the support of
+// Prof. Gustavo Sutter and Prof. Sergio Lopez-Buedo and
+// University of Cambridge Computer Laboratory NetFPGA team.
+//
+// @NETFPGA_LICENSE_HEADER_START@
+//
+// Licensed to NetFPGA C.I.C. (NetFPGA) under one or more
+// contributor license agreements. See the NOTICE file distributed with this
+// work for additional information regarding copyright ownership. NetFPGA
+// licenses this file to you under the NetFPGA Hardware-Software License,
+// Version 1.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at:
+//
+// http://www.netfpga-cic.org
+//
+// Unless required by applicable law or agreed to in writing, Work distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+// @NETFPGA_LICENSE_HEADER_END@
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1ns / 1ps
+//`default_nettype none
+
+module nfmac10g # (
+ parameter C_TX_SUBSYS_EN = 1,
+ parameter C_RX_SUBSYS_EN = 1
+ ) (
+
+ // Clks and resets
+ input tx_clk0,
+ input rx_clk0,
+ input reset,
+ input tx_dcm_locked,
+ input rx_dcm_locked,
+
+ // Flow control
+ input [7:0] tx_ifg_delay,
+ input [15:0] pause_val,
+ input pause_req,
+
+ // Conf and status vectors
+ input [79:0] tx_configuration_vector,
+ input [79:0] rx_configuration_vector,
+ output [1:0] status_vector,
+
+ // Statistic Vector Signals
+ output [25:0] tx_statistics_vector,
+ output tx_statistics_valid,
+ output [29:0] rx_statistics_vector,
+ output rx_statistics_valid,
+
+ // XGMII
+ output [63:0] xgmii_txd,
+ output [7:0] xgmii_txc,
+ input [63:0] xgmii_rxd,
+ input [7:0] xgmii_rxc,
+
+ // Tx AXIS
+ input tx_axis_aresetn,
+ input [63:0] tx_axis_tdata,
+ input [7:0] tx_axis_tkeep,
+ input tx_axis_tvalid,
+ output tx_axis_tready,
+ input tx_axis_tlast,
+ input [0:0] tx_axis_tuser,
+
+ // Rx AXIS
+ input rx_axis_aresetn,
+ output [63:0] rx_axis_tdata,
+ output [7:0] rx_axis_tkeep,
+ output rx_axis_tvalid,
+ output rx_axis_tlast,
+ output [0:0] rx_axis_tuser
+ );
+
+ //-------------------------------------------------------
+ // Local clk
+ //-------------------------------------------------------
+ wire tx_clk;
+ wire rx_clk;
+ wire tx_rst;
+ wire rx_rst;
+
+ //-------------------------------------------------------
+ // Local Rx
+ //-------------------------------------------------------
+ wire [31:0] rx_good_frames;
+ wire [31:0] rx_bad_frames;
+
+ //-------------------------------------------------------
+ // tx_rst_mod
+ //-------------------------------------------------------
+ rst_mod tx_rst_mod (
+ .clk(tx_clk), // I
+ .reset(reset), // I
+ .dcm_locked(tx_dcm_locked), // I
+ .rst(tx_rst) // O
+ );
+
+ //-------------------------------------------------------
+ // rx_rst_mod
+ //-------------------------------------------------------
+ rst_mod rx_rst_mod (
+ .clk(rx_clk), // I
+ .reset(reset), // I
+ .dcm_locked(rx_dcm_locked), // I
+ .rst(rx_rst) // O
+ );
+
+ //-------------------------------------------------------
+ // assigns
+ //-------------------------------------------------------
+ assign tx_clk = tx_clk0;
+ assign rx_clk = rx_clk0;
+ assign status_vector = 'b0;
+ assign tx_statistics_vector = 'b0;
+ assign tx_statistics_valid = 'b0;
+ assign rx_statistics_vector = 'b0;
+ assign rx_statistics_valid = 'b0;
+
+ //-------------------------------------------------------
+ // Tx
+ //-------------------------------------------------------
+ generate if (C_TX_SUBSYS_EN == 1) begin
+ tx tx_mod (
+ .clk(tx_clk), // I
+ .rst(tx_rst), // I
+ // Conf vectors
+ .configuration_vector(tx_configuration_vector), // I [79:0]
+ // XGMII
+ .xgmii_txd(xgmii_txd), // I [63:0]
+ .xgmii_txc(xgmii_txc), // I [7:0]
+ // AXIS
+ .axis_aresetn(tx_axis_aresetn), // I
+ .axis_tdata(tx_axis_tdata), // I [63:0]
+ .axis_tkeep(tx_axis_tkeep), // I [7:0]
+ .axis_tvalid(tx_axis_tvalid), // I
+ .axis_tready(tx_axis_tready), // O
+ .axis_tlast(tx_axis_tlast), // I
+ .axis_tuser(tx_axis_tuser) // I [0:0]
+ );
+ end
+ else begin // C_TX_SUBSYS_EN
+ assign xgmii_txd = 64'h0707070707070707;
+ assign xgmii_txc = 8'hFF;
+ assign tx_axis_tready = 1'b0;
+ end endgenerate
+
+ //-------------------------------------------------------
+ // Rx
+ //-------------------------------------------------------
+ generate if (C_RX_SUBSYS_EN == 1) begin
+ rx rx_mod (
+ .clk(rx_clk), // I
+ .rst(rx_rst), // I
+ // Stats
+ .good_frames(rx_good_frames), // O [31:0]
+ .bad_frames(rx_bad_frames), // O [31:0]
+ // Conf vectors
+ .configuration_vector(rx_configuration_vector), // I [79:0]
+ // XGMII
+ .xgmii_rxd(xgmii_rxd), // I [63:0]
+ .xgmii_rxc(xgmii_rxc), // I [7:0]
+ // AXIS
+ .axis_aresetn(rx_axis_aresetn), // I
+ .axis_tdata(rx_axis_tdata), // O [63:0]
+ .axis_tkeep(rx_axis_tkeep), // O [7:0]
+ .axis_tvalid(rx_axis_tvalid), // O
+ .axis_tlast(rx_axis_tlast), // O
+ .axis_tuser(rx_axis_tuser) // O [0:0]
+ );
+ end
+ else begin // C_RX_SUBSYS_EN
+ assign rx_good_frames = 'b0;
+ assign rx_bad_frames = 'b0;
+ assign rx_axis_tdata = 'b0;
+ assign rx_axis_tkeep = 'b0;
+ assign rx_axis_tvalid = 1'b0;
+ assign rx_axis_tlast = 1'b0;
+ assign rx_axis_tuser = 'b0;
+ end endgenerate
+
+endmodule // nfmac10g
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/padding_ctrl.v b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/padding_ctrl.v
new file mode 100644
index 0000000..789e470
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/padding_ctrl.v
@@ -0,0 +1,288 @@
+//
+// Copyright (c) 2016 University of Cambridge All rights reserved.
+//
+// Author: Marco Forconesi
+//
+// This software was developed with the support of
+// Prof. Gustavo Sutter and Prof. Sergio Lopez-Buedo and
+// University of Cambridge Computer Laboratory NetFPGA team.
+//
+// @NETFPGA_LICENSE_HEADER_START@
+//
+// Licensed to NetFPGA C.I.C. (NetFPGA) under one or more
+// contributor license agreements. See the NOTICE file distributed with this
+// work for additional information regarding copyright ownership. NetFPGA
+// licenses this file to you under the NetFPGA Hardware-Software License,
+// Version 1.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at:
+//
+// http://www.netfpga-cic.org
+//
+// Unless required by applicable law or agreed to in writing, Work distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+// @NETFPGA_LICENSE_HEADER_END@
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1ns / 1ps
+//`default_nettype none
+
+module padding_ctrl (
+
+ // Clks and resets
+ input clk,
+ input rst,
+
+ // AXIS In
+ input aresetn,
+ input [63:0] s_axis_tdata,
+ input [7:0] s_axis_tkeep,
+ input s_axis_tvalid,
+ output reg s_axis_tready,
+ input s_axis_tlast,
+ input [0:0] s_axis_tuser,
+
+ // AXIS Out
+ output reg [63:0] m_axis_tdata,
+ output reg [7:0] m_axis_tkeep,
+ output reg m_axis_tvalid,
+ input m_axis_tready,
+ output reg m_axis_tlast,
+ output reg [0:0] m_axis_tuser,
+
+ // internal
+ input lane4_start,
+ input [1:0] dic
+ );
+
+ `include "xgmii_includes.vh"
+ // localparam
+ localparam SRES = 8'b00000001;
+ localparam IDLE = 8'b00000010;
+ localparam ST = 8'b00000100;
+ localparam PAD_CHK = 8'b00001000;
+ localparam W3 = 8'b00010000;
+ localparam W2 = 8'b00100000;
+ localparam ERR_W_LAST = 8'b01000000;
+ localparam s7 = 8'b10000000;
+
+ //-------------------------------------------------------
+ // Local
+ //-------------------------------------------------------
+ wire inv_aresetn;
+
+ //-------------------------------------------------------
+ // Local adapter
+ //-------------------------------------------------------
+ reg [7:0] fsm = 'b1;
+ reg [4:0] trn;
+ reg [63:0] m_axis_tdata_d0;
+ reg m_axis_tvalid_d0;
+ reg [7:0] last_tkeep;
+
+ //-------------------------------------------------------
+ // assigns
+ //-------------------------------------------------------
+ assign inv_aresetn = ~aresetn;
+
+ ////////////////////////////////////////////////
+ // adapter
+ ////////////////////////////////////////////////
+ always @(posedge clk) begin
+
+ if (inv_aresetn) begin // rst
+ s_axis_tready <= 1'b0;
+ m_axis_tvalid <= 1'b0;
+ fsm <= SRES;
+ end
+
+ else begin // not rst
+
+ m_axis_tdata <= m_axis_tdata_d0;
+ m_axis_tvalid <= m_axis_tvalid_d0;
+ m_axis_tlast <= 1'b0;
+ m_axis_tuser[0] <= 1'b0;
+
+ case (fsm)
+
+ SRES : begin
+ m_axis_tuser <= 'b0;
+ if (m_axis_tready) begin
+ s_axis_tready <= 1'b1;
+ fsm <= IDLE;
+ end
+ end
+
+ IDLE : begin
+ m_axis_tdata_d0 <= s_axis_tdata;
+ m_axis_tkeep <= 8'hFF;
+ trn <= 1;
+ if (s_axis_tvalid) begin
+ m_axis_tvalid_d0 <= 1'b1;
+ fsm <= ST;
+ end
+ end
+
+ ST : begin
+ m_axis_tdata_d0 <= s_axis_tdata;
+ s_axis_tready <= 1'b0;
+ if (!trn[4]) begin
+ trn[3:0] <= trn[3:0] + 1;
+ end
+ if (trn[3]) begin
+ trn[4] <= 1'b1;
+ end
+ fsm <= PAD_CHK;
+
+ casex ({s_axis_tvalid, s_axis_tlast, s_axis_tuser[0], s_axis_tkeep})
+ {3'b0xx, 8'hxx} : begin
+ m_axis_tuser[0] <= 1'b1;
+ m_axis_tvalid_d0 <= 1'b0;
+ fsm <= W2;
+ end
+ {3'b101, 8'hxx} : begin
+ m_axis_tuser[0] <= 1'b1;
+ m_axis_tvalid_d0 <= 1'b0;
+ s_axis_tready <= 1'b1;
+ fsm <= ERR_W_LAST;
+ end
+ {3'b111, 8'hxx} : begin
+ m_axis_tuser[0] <= 1'b1;
+ m_axis_tvalid_d0 <= 1'b0;
+ fsm <= W2;
+ end
+ {3'b100, 8'bxxxxxxxx} : begin
+ s_axis_tready <= 1'b1;
+ fsm <= ST;
+ end
+ {3'b110, 8'b1xxxxxxx} : begin
+ last_tkeep <= 8'hFF;
+ end
+ {3'b110, 8'b01xxxxxx} : begin
+ m_axis_tdata_d0 <= {8'b0, s_axis_tdata[55:0]};
+ last_tkeep <= 8'h7F;
+ end
+ {3'b110, 8'bx01xxxxx} : begin
+ m_axis_tdata_d0 <= {16'b0, s_axis_tdata[47:0]};
+ last_tkeep <= 8'h3F;
+ end
+ {3'b110, 8'bxx01xxxx} : begin
+ m_axis_tdata_d0 <= {24'b0, s_axis_tdata[39:0]};
+ last_tkeep <= 8'h1F;
+ end
+ {3'b110, 8'bxxx01xxx} : begin
+ m_axis_tdata_d0 <= {32'b0, s_axis_tdata[31:0]};
+ last_tkeep <= 8'h0F;
+ end
+ {3'b110, 8'bxxxx01xx} : begin
+ m_axis_tdata_d0 <= {40'b0, s_axis_tdata[23:0]};
+ last_tkeep <= 8'h07;
+ end
+ {3'b110, 8'bxxxxx01x} : begin
+ m_axis_tdata_d0 <= {48'b0, s_axis_tdata[15:0]};
+ last_tkeep <= 8'h03;
+ end
+ {3'b110, 8'bxxxxxx01} : begin
+ m_axis_tdata_d0 <= {56'b0, s_axis_tdata[7:0]};
+ last_tkeep <= 8'h01;
+ end
+ endcase
+ end
+
+ PAD_CHK : begin
+ m_axis_tdata_d0 <= 'b0;
+ last_tkeep <= 8'h0F;
+ trn <= trn + 1;
+ if (trn >= 8) begin
+ m_axis_tvalid_d0 <= 1'b0;
+ m_axis_tlast <= 1'b1;
+ m_axis_tkeep <= last_tkeep;
+ casex ({lane4_start, dic, last_tkeep, trn[4]})
+ // L0
+ {1'b0, 2'b00, 8'b01xxxxxx, 1'bx} : begin // 7f
+ fsm <= W2;
+ end
+ {1'b0, 2'b00, 8'bx01xxxxx, 1'bx} : begin // 3f
+ fsm <= W2;
+ end
+ {1'b0, 2'b01, 8'bx01xxxxx, 1'bx} : begin // 3f
+ fsm <= W2;
+ end
+ {1'b0, 2'b00, 8'bxx01xxxx, 1'bx} : begin // 1f
+ fsm <= W2;
+ end
+ {1'b0, 2'b01, 8'bxx01xxxx, 1'bx} : begin // 1f
+ fsm <= W2;
+ end
+ {1'b0, 2'b10, 8'bxx01xxxx, 1'bx} : begin // 1f
+ fsm <= W2;
+ end
+ {1'b0, 2'bxx, 8'bxxx0xxxx, 1'b1} : begin // 0f, 07, 03, 01
+ fsm <= W2;
+ end
+
+ // L4
+ {1'b1, 2'b00, 8'bxxxx01xx, 1'b1} : begin // 07
+ fsm <= W2;
+ end
+ {1'b1, 2'b00, 8'bxxxxx01x, 1'b1} : begin // 03
+ fsm <= W2;
+ end
+ {1'b1, 2'b01, 8'bxxxxx01x, 1'b1} : begin // 03
+ fsm <= W2;
+ end
+ {1'b1, 2'b00, 8'bxxxxxx01, 1'b1} : begin // 01
+ fsm <= W2;
+ end
+ {1'b1, 2'b01, 8'bxxxxxx01, 1'b1} : begin // 01
+ fsm <= W2;
+ end
+ {1'b1, 2'b10, 8'bxxxxxx01, 1'b1} : begin // 01
+ fsm <= W2;
+ end
+
+ // 8-trn
+ {1'b0, 2'bxx, 8'bxxx0xxxx, 1'b0} : begin // 0f, 07, 03, 01
+ m_axis_tkeep <= 8'h0F;
+ fsm <= W2;
+ end
+ {1'bx, 2'bxx, 8'bxxxx0xxx, 1'b0} : begin // 07, 03, 01
+ m_axis_tkeep <= 8'h0F;
+ fsm <= W3;
+ end
+ default : begin
+ fsm <= W3;
+ end
+ endcase
+ end
+ end
+
+ W3 : fsm <= W2;
+
+ W2 : begin
+ s_axis_tready <= 1'b1;
+ fsm <= IDLE;
+ end
+
+ ERR_W_LAST : begin
+ if (!s_axis_tvalid || s_axis_tlast) begin
+ s_axis_tready <= 1'b0;
+ fsm <= W2;
+ end
+ end
+
+ default : begin
+ fsm <= SRES;
+ end
+
+ endcase
+ end // not rst
+ end //always
+
+endmodule // padding_ctrl
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/rst_mod.v b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/rst_mod.v
new file mode 100644
index 0000000..59b4637
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/rst_mod.v
@@ -0,0 +1,103 @@
+//
+// Copyright (c) 2016 University of Cambridge All rights reserved.
+//
+// Author: Marco Forconesi
+//
+// This software was developed with the support of
+// Prof. Gustavo Sutter and Prof. Sergio Lopez-Buedo and
+// University of Cambridge Computer Laboratory NetFPGA team.
+//
+// @NETFPGA_LICENSE_HEADER_START@
+//
+// Licensed to NetFPGA C.I.C. (NetFPGA) under one or more
+// contributor license agreements. See the NOTICE file distributed with this
+// work for additional information regarding copyright ownership. NetFPGA
+// licenses this file to you under the NetFPGA Hardware-Software License,
+// Version 1.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at:
+//
+// http://www.netfpga-cic.org
+//
+// Unless required by applicable law or agreed to in writing, Work distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+// @NETFPGA_LICENSE_HEADER_END@
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1ns / 1ps
+//`default_nettype none
+
+module rst_mod (
+
+ // Clks and resets
+ input clk,
+ input reset,
+ input dcm_locked,
+
+ // Output
+ output reg rst
+ );
+
+ // localparam
+ localparam s0 = 8'b00000001;
+ localparam s1 = 8'b00000010;
+ localparam s2 = 8'b00000100;
+ localparam s3 = 8'b00001000;
+ localparam s4 = 8'b00010000;
+ localparam s5 = 8'b00100000;
+ localparam s6 = 8'b01000000;
+ localparam s7 = 8'b10000000;
+
+ //-------------------------------------------------------
+ // Local gen_rst
+ //-------------------------------------------------------
+ reg [7:0] fsm = 'b1;
+
+ ////////////////////////////////////////////////
+ // gen_rst
+ ////////////////////////////////////////////////
+ always @(posedge clk or posedge reset) begin
+
+ if (reset) begin // reset
+ rst <= 1'b1;
+ fsm <= s0;
+ end
+
+ else begin // not reset
+
+ case (fsm)
+
+ s0 : begin
+ rst <= 1'b1;
+ fsm <= s1;
+ end
+
+ s1 : fsm <= s2;
+ s2 : fsm <= s3;
+ s3 : fsm <= s4;
+
+ s4 : begin
+ if (dcm_locked) begin
+ fsm <= s5;
+ end
+ end
+
+ s5 : begin
+ rst <= 1'b0;
+ end
+
+ default : begin
+ fsm <= s0;
+ end
+
+ endcase
+ end // not reset
+ end //always
+
+endmodule // rst_mod
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/rx.v b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/rx.v
new file mode 100644
index 0000000..a493378
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/rx.v
@@ -0,0 +1,99 @@
+//
+// Copyright (c) 2016 University of Cambridge All rights reserved.
+//
+// Author: Marco Forconesi
+//
+// This software was developed with the support of
+// Prof. Gustavo Sutter and Prof. Sergio Lopez-Buedo and
+// University of Cambridge Computer Laboratory NetFPGA team.
+//
+// @NETFPGA_LICENSE_HEADER_START@
+//
+// Licensed to NetFPGA C.I.C. (NetFPGA) under one or more
+// contributor license agreements. See the NOTICE file distributed with this
+// work for additional information regarding copyright ownership. NetFPGA
+// licenses this file to you under the NetFPGA Hardware-Software License,
+// Version 1.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at:
+//
+// http://www.netfpga-cic.org
+//
+// Unless required by applicable law or agreed to in writing, Work distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+// @NETFPGA_LICENSE_HEADER_END@
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1ns / 1ps
+//`default_nettype none
+
+module rx (
+
+ // Clks and resets
+ input clk,
+ input rst,
+
+ // Stats
+ output [31:0] good_frames,
+ output [31:0] bad_frames,
+
+ // Conf vectors
+ input [79:0] configuration_vector,
+
+ // XGMII
+ input [63:0] xgmii_rxd,
+ input [7:0] xgmii_rxc,
+
+ // AXIS
+ input axis_aresetn,
+ output [63:0] axis_tdata,
+ output [7:0] axis_tkeep,
+ output axis_tvalid,
+ output axis_tlast,
+ output [0:0] axis_tuser
+ );
+
+ //-------------------------------------------------------
+ // Local xgmii2axis
+ //-------------------------------------------------------
+ //wire ??;
+
+ //-------------------------------------------------------
+ // Local
+ //-------------------------------------------------------
+ //wire [31:0] ??;
+
+ //-------------------------------------------------------
+ // assigns
+ //-------------------------------------------------------
+
+ //-------------------------------------------------------
+ // xgmii2axis
+ //-------------------------------------------------------
+ xgmii2axis xgmii2axis_mod (
+ .clk(clk), // I
+ .rst(rst), // I
+ // Stats
+ .good_frames(good_frames), // O [31:0]
+ .bad_frames(bad_frames), // O [31:0]
+ // Conf vectors
+ .configuration_vector(configuration_vector), // I [79:0]
+ // XGMII
+ .xgmii_d(xgmii_rxd), // I [63:0]
+ .xgmii_c(xgmii_rxc), // I [7:0]
+ // AXIS
+ .aresetn(axis_aresetn), // I
+ .tdata(axis_tdata), // O [63:0]
+ .tkeep(axis_tkeep), // O [7:0]
+ .tvalid(axis_tvalid), // O
+ .tlast(axis_tlast), // O
+ .tuser(axis_tuser) // O [0:0]
+ );
+
+endmodule // rx
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/tx.v b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/tx.v
new file mode 100644
index 0000000..dcf59bc
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/tx.v
@@ -0,0 +1,139 @@
+//
+// Copyright (c) 2016 University of Cambridge All rights reserved.
+//
+// Author: Marco Forconesi
+//
+// This software was developed with the support of
+// Prof. Gustavo Sutter and Prof. Sergio Lopez-Buedo and
+// University of Cambridge Computer Laboratory NetFPGA team.
+//
+// @NETFPGA_LICENSE_HEADER_START@
+//
+// Licensed to NetFPGA C.I.C. (NetFPGA) under one or more
+// contributor license agreements. See the NOTICE file distributed with this
+// work for additional information regarding copyright ownership. NetFPGA
+// licenses this file to you under the NetFPGA Hardware-Software License,
+// Version 1.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at:
+//
+// http://www.netfpga-cic.org
+//
+// Unless required by applicable law or agreed to in writing, Work distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+// @NETFPGA_LICENSE_HEADER_END@
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1ns / 1ps
+//`default_nettype none
+
+module tx (
+
+ // Clks and resets
+ input clk,
+ input rst,
+
+ // Conf vectors
+ input [79:0] configuration_vector,
+
+ // XGMII
+ output [63:0] xgmii_txd,
+ output [7:0] xgmii_txc,
+
+ // AXIS
+ input axis_aresetn,
+ input [63:0] axis_tdata,
+ input [7:0] axis_tkeep,
+ input axis_tvalid,
+ output axis_tready,
+ input axis_tlast,
+ input [0:0] axis_tuser
+ );
+
+ //-------------------------------------------------------
+ // Local padding_ctrl
+ //-------------------------------------------------------
+ // S
+ wire [63:0] s_axis_tdata;
+ wire [7:0] s_axis_tkeep;
+ wire s_axis_tvalid;
+ wire s_axis_tready;
+ wire s_axis_tlast;
+ wire [0:0] s_axis_tuser;
+ // M
+ wire [63:0] m_axis_tdata;
+ wire [7:0] m_axis_tkeep;
+ wire m_axis_tvalid;
+ wire m_axis_tready;
+ wire m_axis_tlast;
+ wire [0:0] m_axis_tuser;
+ // internal
+ wire lane4_start;
+ wire [1:0] dic;
+
+ //-------------------------------------------------------
+ // assigns
+ //-------------------------------------------------------
+ assign s_axis_tdata = axis_tdata;
+ assign s_axis_tkeep = axis_tkeep;
+ assign s_axis_tvalid = axis_tvalid;
+ assign axis_tready = s_axis_tready;
+ assign s_axis_tlast = axis_tlast;
+ assign s_axis_tuser = axis_tuser;
+
+ //-------------------------------------------------------
+ // padding_ctrl
+ //-------------------------------------------------------
+ padding_ctrl padding_ctrl_mod (
+ .clk(clk), // I
+ .rst(rst), // I
+ // AXIS In
+ .aresetn(axis_aresetn), // I
+ .s_axis_tdata(s_axis_tdata), // I [63:0]
+ .s_axis_tkeep(s_axis_tkeep), // I [7:0]
+ .s_axis_tvalid(s_axis_tvalid), // I
+ .s_axis_tready(s_axis_tready), // O
+ .s_axis_tlast(s_axis_tlast), // I
+ .s_axis_tuser(s_axis_tuser), // I [0:0]
+ // AXIS Out
+ .m_axis_tdata(m_axis_tdata), // O [63:0]
+ .m_axis_tkeep(m_axis_tkeep), // O [7:0]
+ .m_axis_tvalid(m_axis_tvalid), // O
+ .m_axis_tready(m_axis_tready), // I
+ .m_axis_tlast(m_axis_tlast), // O
+ .m_axis_tuser(m_axis_tuser), // O [0:0]
+ // internal
+ .lane4_start(lane4_start), // I
+ .dic(dic) // I [1:0]
+ );
+
+ //-------------------------------------------------------
+ // axis2xgmii
+ //-------------------------------------------------------
+ axis2xgmii axis2xgmii_mod (
+ .clk(clk), // I
+ .rst(rst), // I
+ // Conf vectors
+ .configuration_vector(configuration_vector), // I [79:0]
+ // internal
+ .lane4_start(lane4_start), // O
+ .dic_o(dic), // O [1:0]
+ // XGMII
+ .xgmii_d(xgmii_txd), // O [63:0]
+ .xgmii_c(xgmii_txc), // O [7:0]
+ // AXIS
+ .tdata(m_axis_tdata), // I [63:0]
+ .tkeep(m_axis_tkeep), // I [7:0]
+ .tvalid(m_axis_tvalid), // I
+ .tready(m_axis_tready), // O
+ .tlast(m_axis_tlast), // I
+ .tuser(m_axis_tuser) // I [0:0]
+ );
+
+endmodule // tx
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/xgmii2axis.v b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/xgmii2axis.v
new file mode 100644
index 0000000..04c4f3d
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/xgmii2axis.v
@@ -0,0 +1,448 @@
+//
+// Copyright (c) 2016 University of Cambridge All rights reserved.
+//
+// Author: Marco Forconesi
+//
+// This software was developed with the support of
+// Prof. Gustavo Sutter and Prof. Sergio Lopez-Buedo and
+// University of Cambridge Computer Laboratory NetFPGA team.
+//
+// @NETFPGA_LICENSE_HEADER_START@
+//
+// Licensed to NetFPGA C.I.C. (NetFPGA) under one or more
+// contributor license agreements. See the NOTICE file distributed with this
+// work for additional information regarding copyright ownership. NetFPGA
+// licenses this file to you under the NetFPGA Hardware-Software License,
+// Version 1.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at:
+//
+// http://www.netfpga-cic.org
+//
+// Unless required by applicable law or agreed to in writing, Work distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+// @NETFPGA_LICENSE_HEADER_END@
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1ns / 1ps
+//`default_nettype none
+
+module xgmii2axis (
+
+ // Clks and resets
+ input clk,
+ input rst,
+
+ // Stats
+ output reg [31:0] good_frames,
+ output reg [31:0] bad_frames,
+
+ // Conf vectors
+ input [79:0] configuration_vector,
+
+ // XGMII
+ input [63:0] xgmii_d,
+ input [7:0] xgmii_c,
+
+ // AXIS
+ input aresetn,
+ output reg [63:0] tdata,
+ output reg [7:0] tkeep,
+ output reg tvalid,
+ output reg tlast,
+ output reg [0:0] tuser
+ );
+
+ `include "xgmii_includes.vh"
+ // localparam
+ localparam SRES = 8'b00000001;
+ localparam IDLE = 8'b00000010;
+ localparam ST_LANE0 = 8'b00000100;
+ localparam ST_LANE4 = 8'b00001000;
+ localparam FIN = 8'b00010000;
+ localparam D_LANE4 = 8'b00100000;
+ localparam FINL4 = 8'b01000000;
+ localparam s7 = 8'b10000000;
+
+ //-------------------------------------------------------
+ // Local output
+ //-------------------------------------------------------
+ reg synch;
+ wire inv_aresetn;
+
+ //-------------------------------------------------------
+ // Local adapter
+ //-------------------------------------------------------
+ reg [7:0] fsm = 'b1;
+ reg [63:0] tdata_i;
+ reg [7:0] tkeep_i;
+ reg [7:0] last_tkeep_i;
+ reg tvalid_i;
+ reg tlast_i;
+ reg [0:0] tuser_i;
+ reg [63:0] tdata_d0;
+ reg tvalid_d0;
+ wire [63:0] d;
+ wire [7:0] c;
+ reg [63:0] d_reg;
+ reg [7:0] c_reg;
+ reg inbound_frame;
+ reg [15:0] len;
+ reg [31:0] aux_dw;
+ reg chk_tchar;
+
+ //-------------------------------------------------------
+ // Local CRC32
+ //-------------------------------------------------------
+ reg [31:0] crc_32;
+ reg [31:0] crc_32_7B;
+ reg [31:0] crc_32_6B;
+ reg [31:0] crc_32_5B;
+ reg [31:0] crc_32_4B;
+ reg [31:0] crc_32_3B;
+ reg [31:0] crc_32_2B;
+ reg [31:0] crc_32_1B;
+ reg [31:0] rcved_crc;
+ reg [31:0] calcted_crc;
+
+ //-------------------------------------------------------
+ // assigns
+ //-------------------------------------------------------
+ assign d = xgmii_d;
+ assign c = xgmii_c;
+ assign inv_aresetn = ~aresetn;
+
+ ////////////////////////////////////////////////
+ // output
+ ////////////////////////////////////////////////
+ always @(posedge clk) begin
+
+ if (inv_aresetn) begin // aresetn
+ tvalid <= 1'b0;
+ synch <= 1'b0;
+ end
+
+ else begin // not aresetn
+
+ if (!inbound_frame || synch) begin
+ synch <= 1'b1;
+ tdata <= tdata_i;
+ tkeep <= tkeep_i;
+ tvalid <= tvalid_i;
+ tlast <= tlast_i;
+ tuser <= tuser_i;
+ end
+ else begin
+ tvalid <= 1'b0;
+ end
+
+ end // not aresetn
+ end //always
+
+ ////////////////////////////////////////////////
+ // adapter
+ ////////////////////////////////////////////////
+ always @(posedge clk) begin
+
+ if (rst) begin // rst
+ tvalid_i <= 1'b0;
+ tvalid_d0 <= 1'b0;
+ fsm <= SRES;
+ end
+
+ else begin // not rst
+
+ if (tvalid && tlast && tuser[0]) begin
+ good_frames <= good_frames + 1;
+ end
+
+ if (tvalid && tlast && ~tuser[0]) begin
+ bad_frames <= bad_frames + 1;
+ end
+
+ tdata_i <= tdata_d0;
+ tvalid_i <= tvalid_d0;
+
+ case (fsm)
+
+ SRES : begin
+ good_frames <= 'b0;
+ bad_frames <= 'b0;
+ fsm <= IDLE;
+ end
+
+ IDLE : begin
+ tvalid_d0 <= 1'b0;
+ tlast_i <= 1'b0;
+ tuser_i <= 'b0;
+ crc_32 <= CRC802_3_PRESET;
+ inbound_frame <= 1'b0;
+ d_reg <= d;
+ c_reg <= c;
+ len <= 0;
+ if (sof_lane0(d,c)) begin
+ inbound_frame <= 1'b1;
+ fsm <= ST_LANE0;
+ end
+ else if (sof_lane4(d,c)) begin
+ inbound_frame <= 1'b1;
+ fsm <= ST_LANE4;
+ end
+ end
+
+ ST_LANE0 : begin
+ tdata_d0 <= d;
+ tvalid_d0 <= 1'b1;
+ tkeep_i <= 8'hFF;
+ tlast_i <= 1'b0;
+ tuser_i <= 'b0;
+ d_reg <= d;
+ c_reg <= c;
+ crc_32 <= crc8B(crc_32,d);
+ crc_32_7B <= crc7B(crc_32,d[55:0]);
+ crc_32_6B <= crc6B(crc_32,d[47:0]);
+ crc_32_5B <= crc5B(crc_32,d[39:0]);
+ crc_32_4B <= crc4B(crc_32,d[31:0]);
+
+ case (c)
+ 8'h0 : begin
+ len <= len + 8;
+ end
+ 8'hFF : begin
+ len <= len;
+ tkeep_i <= 8'h0F;
+ tvalid_d0 <= 1'b0;
+ tlast_i <= 1'b1;
+ if ((~crc_rev(crc_32_4B) == d_reg[63:32]) && is_tchar(d[7:0])) begin
+ tuser_i[0] <= 1'b1;
+ end
+ fsm <= IDLE;
+ end
+ 8'hFE : begin
+ len <= len + 1;
+ tkeep_i <= 8'h1F;
+ tvalid_d0 <= 1'b0;
+ tlast_i <= 1'b1;
+ if ((~crc_rev(crc_32_5B) == {d[7:0], d_reg[63:40]}) && is_tchar(d[15:8])) begin
+ tuser_i[0] <= 1'b1;
+ end
+ fsm <= IDLE;
+ end
+ 8'hFC : begin
+ len <= len + 2;
+ tkeep_i <= 8'h3F;
+ tvalid_d0 <= 1'b0;
+ tlast_i <= 1'b1;
+ if ((~crc_rev(crc_32_6B) == {d[15:0], d_reg[63:48]}) && is_tchar(d[23:16])) begin
+ tuser_i[0] <= 1'b1;
+ end
+ fsm <= IDLE;
+ end
+ 8'hF8 : begin
+ len <= len + 3;
+ tkeep_i <= 8'h7F;
+ tvalid_d0 <= 1'b0;
+ tlast_i <= 1'b1;
+ if ((~crc_rev(crc_32_7B) == {d[23:0], d_reg[63:56]}) && is_tchar(d[31:24])) begin
+ tuser_i[0] <= 1'b1;
+ end
+ fsm <= IDLE;
+ end
+ 8'hF0 : begin
+ len <= len + 4;
+ tvalid_d0 <= 1'b0;
+ tlast_i <= 1'b1;
+ if ((~crc_rev(crc_32) == d[31:0]) && is_tchar(d[39:32])) begin
+ tuser_i[0] <= 1'b1;
+ end
+ fsm <= IDLE;
+ end
+ 8'hE0 : begin
+ len <= len + 5;
+ last_tkeep_i <= 8'h01;
+ rcved_crc <= d[39:8];
+ calcted_crc <= crc1B(crc_32,d[7:0]);
+ chk_tchar <= is_tchar(d[47:40]);
+ fsm <= FIN;
+ end
+ 8'hC0 : begin
+ len <= len + 6;
+ last_tkeep_i <= 8'h03;
+ rcved_crc <= d[47:16];
+ calcted_crc <= crc2B(crc_32,d[15:0]);
+ chk_tchar <= is_tchar(d[55:48]);
+ fsm <= FIN;
+ end
+ 8'h80 : begin
+ len <= len + 7;
+ last_tkeep_i <= 8'h07;
+ rcved_crc <= d[55:24];
+ calcted_crc <= crc3B(crc_32,d[23:0]);
+ chk_tchar <= is_tchar(d[63:56]);
+ fsm <= FIN;
+ end
+ default : begin
+ tlast_i <= 1'b1;
+ tvalid_d0 <= 1'b0;
+ tvalid_i <= 1'b1;
+ fsm <= IDLE;
+ end
+ endcase
+ end
+
+ FIN : begin
+ tkeep_i <= last_tkeep_i;
+ tlast_i <= 1'b1;
+ tvalid_d0 <= 1'b0;
+ crc_32 <= CRC802_3_PRESET;
+ if ((~crc_rev(calcted_crc) == rcved_crc) && chk_tchar) begin
+ tuser_i[0] <= 1'b1;
+ end
+ if (sof_lane4(d,c)) begin
+ fsm <= ST_LANE4;
+ end
+ else begin
+ fsm <= IDLE;
+ end
+ end
+
+ ST_LANE4 : begin
+ len <= 4;
+ tlast_i <= 1'b0;
+ tuser_i <= 'b0;
+ crc_32 <= crc4B(crc_32,d[63:32]);
+ aux_dw <= d[63:32];
+ if (!c) begin
+ fsm <= D_LANE4;
+ end
+ else begin
+ fsm <= IDLE;
+ end
+ end
+
+ D_LANE4 : begin
+ tdata_d0 <= {d[31:0], aux_dw};
+ tvalid_d0 <= 1'b1;
+ tkeep_i <= 8'hFF;
+ aux_dw <= d[63:32];
+ d_reg <= d;
+ c_reg <= c;
+ crc_32 <= crc8B(crc_32,d);
+ crc_32_4B <= crc4B(crc_32,d[31:0]);
+ crc_32_5B <= crc5B(crc_32,d[39:0]);
+ crc_32_6B <= crc6B(crc_32,d[47:0]);
+ crc_32_7B <= crc7B(crc_32,d[55:0]);
+
+ case (c)
+ 8'h0 : begin
+ len <= len + 8;
+ end
+ 8'hFF : begin
+ len <= len;
+ tvalid_d0 <= 1'b0;
+ tlast_i <= 1'b1;
+ if ((~crc_rev(crc_32_4B) == d_reg[63:32]) && is_tchar(d[7:0])) begin
+ tuser_i[0] <= 1'b1;
+ end
+ fsm <= IDLE;
+ end
+ 8'hFE : begin
+ len <= len + 1;
+ last_tkeep_i <= 8'h01;
+ rcved_crc <= {d[7:0], aux_dw[31:8]};
+ calcted_crc <= crc_32_5B;
+ chk_tchar <= is_tchar(d[15:8]);
+ fsm <= FINL4;
+ end
+ 8'hFC : begin
+ len <= len + 2;
+ last_tkeep_i <= 8'h03;
+ rcved_crc <= {d[15:0], aux_dw[31:16]};
+ calcted_crc <= crc_32_6B;
+ chk_tchar <= is_tchar(d[23:16]);
+ fsm <= FINL4;
+ end
+ 8'hF8 : begin
+ len <= len + 3;
+ last_tkeep_i <= 8'h07;
+ rcved_crc <= {d[23:0], aux_dw[31:24]};
+ calcted_crc <= crc_32_7B;
+ chk_tchar <= is_tchar(d[31:24]);
+ fsm <= FINL4;
+ end
+ 8'hF0 : begin
+ len <= len + 4;
+ last_tkeep_i <= 8'h0F;
+ rcved_crc <= d[31:0];
+ calcted_crc <= crc_32;
+ chk_tchar <= is_tchar(d[39:32]);
+ fsm <= FIN;
+ end
+ 8'hE0 : begin
+ len <= len + 5;
+ last_tkeep_i <= 8'h1F;
+ rcved_crc <= d[39:8];
+ calcted_crc <= crc1B(crc_32,d[7:0]);
+ chk_tchar <= is_tchar(d[47:40]);
+ fsm <= FIN;
+ end
+ 8'hC0 : begin
+ len <= len + 6;
+ last_tkeep_i <= 8'h3F;
+ rcved_crc <= d[47:16];
+ calcted_crc <= crc2B(crc_32,d[15:0]);
+ chk_tchar <= is_tchar(d[55:48]);
+ fsm <= FIN;
+ end
+ 8'h80 : begin
+ len <= len + 7;
+ last_tkeep_i <= 8'h7F;
+ rcved_crc <= d[55:24];
+ calcted_crc <= crc3B(crc_32,d[23:0]);
+ chk_tchar <= is_tchar(d[63:56]);
+ fsm <= FIN;
+ end
+ default : begin
+ tlast_i <= 1'b1;
+ tvalid_d0 <= 1'b0;
+ tvalid_i <= 1'b1;
+ fsm <= IDLE;
+ end
+ endcase
+ end
+
+ FINL4 : begin
+ len <= 0;
+ tkeep_i <= last_tkeep_i;
+ tlast_i <= 1'b1;
+ tvalid_d0 <= 1'b0;
+ crc_32 <= CRC802_3_PRESET;
+ if ((~crc_rev(calcted_crc) == rcved_crc) && chk_tchar) begin
+ tuser_i[0] <= 1'b1;
+ end
+ if (sof_lane0(d,c)) begin
+ fsm <= ST_LANE0;
+ end
+ else if (sof_lane4(d,c)) begin
+ fsm <= ST_LANE4;
+ end
+ else begin
+ fsm <= IDLE;
+ end
+ end
+
+ default : begin
+ fsm <= IDLE;
+ end
+
+ endcase
+ end // not rst
+ end //always
+
+endmodule // xgmii2axis
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/xgmii_includes.vh b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/xgmii_includes.vh
new file mode 100644
index 0000000..50c4a81
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/vsrc/nfmac10g/xgmii_includes.vh
@@ -0,0 +1,494 @@
+//
+// Copyright (c) 2016 University of Cambridge All rights reserved.
+//
+// Author: Marco Forconesi
+//
+// This software was developed with the support of
+// Prof. Gustavo Sutter and Prof. Sergio Lopez-Buedo and
+// University of Cambridge Computer Laboratory NetFPGA team.
+//
+// @NETFPGA_LICENSE_HEADER_START@
+//
+// Licensed to NetFPGA C.I.C. (NetFPGA) under one or more
+// contributor license agreements. See the NOTICE file distributed with this
+// work for additional information regarding copyright ownership. NetFPGA
+// licenses this file to you under the NetFPGA Hardware-Software License,
+// Version 1.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at:
+//
+// http://www.netfpga-cic.org
+//
+// Unless required by applicable law or agreed to in writing, Work distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+// @NETFPGA_LICENSE_HEADER_END@
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+ // XGMII characters
+ localparam S = 8'hFB;
+ localparam T = 8'hFD;
+ localparam E = 8'hFE;
+ localparam I = 8'h07;
+
+ localparam PREAMBLE_LANE0_D = {56'hD5555555555555, S};
+ localparam PREAMBLE_LANE0_C = 8'h01;
+
+ localparam PREAMBLE_LANE4_D = {24'h555555, S, {4{I}}};
+ localparam PREAMBLE_LANE4_C = 8'h1F;
+
+ localparam PREAMBLE_LANE4_END_D = 32'hD5555555;
+ localparam PREAMBLE_LANE4_END_C = 8'b0;
+
+ localparam QW_IDLE_D = {8{I}};
+ localparam QW_IDLE_C = 8'hFF;
+
+ localparam XGMII_ERROR_L0_D = E;
+ localparam XGMII_ERROR_L0_C = 8'h01;
+
+ localparam XGMII_ERROR_L4_D = E;
+ localparam XGMII_ERROR_L4_C = 8'h10;
+
+ localparam CRC802_3_PRESET = 32'hFFFFFFFF;
+
+ ////////////////////////////////////////////////
+ // sof_lane0
+ ////////////////////////////////////////////////
+ function sof_lane0 (
+ input [63:0] xgmii_d,
+ input [7:0] xgmii_c
+ );
+ begin
+ if ((xgmii_d[7:0] == S) && xgmii_c[0])
+ sof_lane0 = 1'b1;
+ else
+ sof_lane0 = 1'b0;
+ end
+ endfunction // sof_lane0
+
+ ////////////////////////////////////////////////
+ // sof_lane4
+ ////////////////////////////////////////////////
+ function sof_lane4 (
+ input [63:0] xgmii_d,
+ input [7:0] xgmii_c
+ );
+ begin
+ if ((xgmii_d[39:32] == S) && xgmii_c[4])
+ sof_lane4 = 1'b1;
+ else
+ sof_lane4 = 1'b0;
+ end
+ endfunction // sof_lane4
+
+ ////////////////////////////////////////////////
+ // crc_rev
+ ////////////////////////////////////////////////
+ function [31:0] crc_rev (
+ input [31:0] crc
+ );
+ integer i;
+ reg [31:0] o;
+ begin
+ for (i = 0; i < 32; i = i + 1) begin
+ o[i] = crc[31-i];
+ end
+ crc_rev = o;
+ end
+ endfunction // crc_rev
+
+ ////////////////////////////////////////////////
+ // byte_rev
+ ////////////////////////////////////////////////
+ function [7:0] byte_rev (
+ input [7:0] b
+ );
+ integer i;
+ reg [7:0] o;
+ begin
+ for (i = 0; i < 8; i = i + 1) begin
+ o[i] = b[7-i];
+ end
+ byte_rev = o;
+ end
+ endfunction // byte_rev
+
+ ////////////////////////////////////////////////
+ // is_tchar
+ ////////////////////////////////////////////////
+ function is_tchar (
+ input [7:0] bytez
+ );
+ begin
+ if (bytez == T)
+ is_tchar = 1'b1;
+ else
+ is_tchar = 1'b0;
+ end
+ endfunction // is_tchar
+
+ ////////////////////////////////////////////////
+ // crc8B
+ ////////////////////////////////////////////////
+ function [31:0] crc8B (
+ input [31:0] c,
+ input [63:0] d
+ );
+ reg [31:0] o;
+ begin
+o[0] = d[15] ^ c[12] ^ d[63] ^ d[47] ^ d[39] ^ d[5] ^ d[32] ^ c[28] ^ d[16] ^ c[21] ^ c[13] ^ c[0] ^ d[33] ^ c[29] ^ c[22] ^ d[10] ^ d[57] ^ d[34] ^ d[0] ^ d[26] ^ c[31] ^ d[18] ^ c[23] ^ c[15] ^ d[51] ^ c[2] ^ d[8] ^ d[35] ^ d[19] ^ c[16] ^ d[9] ^ d[2] ^ d[13] ^ d[53] ^ d[37] ^ d[3] ^ d[29] ^ c[26] ^ c[18] ^ d[54] ^ c[5] ^ d[38] ^ d[31] ;
+o[1] = c[27] ^ c[19] ^ c[12] ^ d[63] ^ c[6] ^ d[47] ^ d[39] ^ d[5] ^ c[28] ^ d[16] ^ c[21] ^ d[56] ^ d[25] ^ c[30] ^ d[17] ^ d[10] ^ c[14] ^ d[57] ^ d[50] ^ c[1] ^ d[7] ^ d[0] ^ d[26] ^ c[31] ^ c[15] ^ d[51] ^ c[2] ^ d[35] ^ d[1] ^ d[19] ^ d[12] ^ c[24] ^ d[52] ^ c[3] ^ d[36] ^ d[28] ^ d[13] ^ c[17] ^ d[3] ^ d[30] ^ d[29] ^ c[26] ^ d[14] ^ c[18] ^ d[62] ^ d[54] ^ c[5] ^ d[46] ^ d[4] ;
+o[2] = c[27] ^ c[19] ^ c[20] ^ c[12] ^ d[63] ^ d[55] ^ c[6] ^ d[47] ^ d[39] ^ d[5] ^ d[32] ^ d[24] ^ c[21] ^ d[56] ^ c[7] ^ c[0] ^ d[33] ^ d[6] ^ d[25] ^ d[10] ^ d[57] ^ d[50] ^ d[49] ^ d[26] ^ d[11] ^ c[23] ^ d[8] ^ d[27] ^ d[19] ^ d[12] ^ c[3] ^ d[28] ^ c[25] ^ d[61] ^ d[45] ^ c[4] ^ d[37] ^ c[26] ^ d[62] ^ d[54] ^ c[5] ^ d[46] ^ d[4] ^ d[31] ;
+o[3] = d[23] ^ c[27] ^ c[20] ^ d[55] ^ c[6] ^ d[32] ^ d[5] ^ d[24] ^ c[28] ^ c[21] ^ c[13] ^ d[56] ^ c[7] ^ d[48] ^ c[0] ^ d[25] ^ d[10] ^ c[22] ^ c[8] ^ d[49] ^ c[1] ^ d[7] ^ d[26] ^ d[18] ^ d[11] ^ d[27] ^ c[24] ^ d[60] ^ d[44] ^ d[9] ^ d[36] ^ d[61] ^ d[53] ^ c[4] ^ d[45] ^ d[3] ^ d[30] ^ c[26] ^ d[62] ^ d[54] ^ c[5] ^ d[46] ^ d[38] ^ d[4] ^ d[31] ;
+o[4] = d[23] ^ d[15] ^ c[27] ^ c[12] ^ d[63] ^ d[55] ^ c[6] ^ d[39] ^ d[5] ^ d[32] ^ d[24] ^ d[16] ^ c[13] ^ c[7] ^ d[48] ^ d[33] ^ d[6] ^ d[25] ^ d[17] ^ c[14] ^ d[57] ^ c[8] ^ c[1] ^ d[34] ^ d[0] ^ c[31] ^ d[18] ^ c[15] ^ d[51] ^ c[9] ^ d[43] ^ d[19] ^ c[16] ^ d[60] ^ d[59] ^ d[52] ^ d[44] ^ c[25] ^ d[13] ^ d[61] ^ d[45] ^ d[30] ^ d[22] ^ c[26] ^ c[18] ^ d[38] ^ d[4] ;
+o[5] = d[23] ^ c[27] ^ c[19] ^ c[12] ^ d[63] ^ d[39] ^ d[24] ^ c[21] ^ d[56] ^ c[7] ^ c[29] ^ d[17] ^ c[22] ^ d[10] ^ c[14] ^ d[57] ^ c[8] ^ d[50] ^ d[42] ^ d[34] ^ d[0] ^ d[26] ^ c[31] ^ c[23] ^ d[58] ^ c[9] ^ d[43] ^ d[8] ^ d[35] ^ d[19] ^ d[12] ^ d[60] ^ d[59] ^ d[44] ^ d[9] ^ d[2] ^ d[21] ^ d[13] ^ c[17] ^ c[10] ^ d[53] ^ d[22] ^ d[14] ^ c[18] ^ d[62] ^ c[5] ^ d[4] ;
+o[6] = d[23] ^ c[20] ^ c[19] ^ d[55] ^ c[6] ^ d[16] ^ c[28] ^ c[13] ^ d[56] ^ d[41] ^ d[33] ^ d[25] ^ c[30] ^ c[22] ^ d[57] ^ c[8] ^ d[49] ^ d[42] ^ d[7] ^ d[34] ^ d[18] ^ c[23] ^ d[11] ^ c[15] ^ d[58] ^ c[9] ^ d[43] ^ d[8] ^ d[1] ^ d[20] ^ c[24] ^ d[12] ^ d[59] ^ d[52] ^ d[9] ^ d[21] ^ d[13] ^ c[10] ^ d[61] ^ d[3] ^ d[22] ^ c[18] ^ c[11] ^ d[62] ^ d[38] ;
+o[7] = c[19] ^ c[20] ^ d[63] ^ d[55] ^ d[47] ^ d[39] ^ d[40] ^ d[5] ^ d[24] ^ c[28] ^ d[16] ^ c[13] ^ d[56] ^ c[7] ^ d[48] ^ d[41] ^ c[0] ^ d[6] ^ d[17] ^ c[22] ^ c[14] ^ d[42] ^ d[7] ^ d[34] ^ d[26] ^ d[18] ^ d[11] ^ c[15] ^ d[58] ^ c[9] ^ c[2] ^ d[35] ^ d[20] ^ d[12] ^ c[24] ^ d[60] ^ d[9] ^ d[21] ^ c[25] ^ d[13] ^ c[10] ^ d[61] ^ d[53] ^ d[3] ^ d[29] ^ d[22] ^ c[26] ^ c[18] ^ c[11] ^ c[5] ^ d[38] ^ d[31] ;
+o[8] = d[23] ^ c[27] ^ c[19] ^ c[20] ^ d[63] ^ d[55] ^ c[6] ^ d[40] ^ d[32] ^ c[28] ^ c[13] ^ d[41] ^ c[0] ^ d[6] ^ d[25] ^ d[17] ^ c[22] ^ c[14] ^ c[8] ^ c[1] ^ d[0] ^ d[26] ^ c[31] ^ d[18] ^ d[11] ^ d[51] ^ c[2] ^ d[35] ^ d[20] ^ d[12] ^ d[60] ^ d[59] ^ d[52] ^ c[3] ^ d[9] ^ d[28] ^ d[21] ^ c[25] ^ d[13] ^ c[10] ^ d[53] ^ d[3] ^ d[30] ^ d[29] ^ c[18] ^ c[11] ^ d[62] ^ c[5] ^ d[46] ^ d[4] ^ d[31] ;
+o[9] = c[20] ^ c[19] ^ c[12] ^ c[6] ^ d[40] ^ d[39] ^ d[5] ^ d[24] ^ d[16] ^ c[28] ^ c[21] ^ c[7] ^ c[0] ^ d[25] ^ c[29] ^ d[17] ^ d[10] ^ c[14] ^ d[50] ^ c[1] ^ d[34] ^ c[23] ^ d[11] ^ c[15] ^ d[58] ^ c[9] ^ d[51] ^ c[2] ^ d[8] ^ d[27] ^ d[20] ^ d[19] ^ d[12] ^ d[59] ^ d[52] ^ c[3] ^ d[2] ^ d[28] ^ d[61] ^ c[4] ^ d[45] ^ d[3] ^ d[29] ^ d[30] ^ d[22] ^ c[26] ^ c[11] ^ d[62] ^ d[54] ^ d[31] ;
+o[10] = d[23] ^ c[27] ^ c[20] ^ d[63] ^ d[47] ^ d[5] ^ d[32] ^ d[24] ^ c[28] ^ c[7] ^ c[0] ^ c[30] ^ c[8] ^ d[49] ^ d[50] ^ c[1] ^ d[7] ^ d[34] ^ d[0] ^ c[31] ^ d[11] ^ c[23] ^ d[58] ^ d[8] ^ d[35] ^ d[27] ^ d[1] ^ c[24] ^ d[60] ^ c[3] ^ d[44] ^ d[28] ^ d[21] ^ d[13] ^ c[10] ^ d[61] ^ c[4] ^ d[37] ^ d[3] ^ d[30] ^ c[26] ^ c[18] ^ d[54] ^ d[4] ^ d[31] ;
+o[11] = d[23] ^ d[15] ^ c[27] ^ c[19] ^ c[12] ^ d[63] ^ d[47] ^ d[39] ^ d[5] ^ d[32] ^ d[16] ^ c[13] ^ d[48] ^ d[6] ^ c[22] ^ c[8] ^ d[49] ^ c[1] ^ d[7] ^ d[18] ^ c[23] ^ c[15] ^ d[51] ^ c[9] ^ d[43] ^ d[8] ^ d[35] ^ d[27] ^ d[20] ^ d[19] ^ d[12] ^ c[24] ^ c[16] ^ d[60] ^ d[59] ^ d[9] ^ d[36] ^ c[25] ^ d[13] ^ c[4] ^ d[37] ^ d[30] ^ d[22] ^ c[26] ^ c[18] ^ c[11] ^ d[62] ^ d[54] ^ d[46] ^ d[38] ^ d[4] ;
+o[12] = c[27] ^ c[19] ^ c[20] ^ d[63] ^ d[39] ^ d[32] ^ d[16] ^ c[21] ^ d[48] ^ d[33] ^ d[6] ^ c[29] ^ d[17] ^ c[22] ^ d[10] ^ c[14] ^ d[57] ^ d[50] ^ d[42] ^ d[7] ^ d[0] ^ c[31] ^ d[11] ^ c[15] ^ d[58] ^ d[51] ^ c[9] ^ d[12] ^ c[24] ^ d[59] ^ d[9] ^ d[36] ^ d[2] ^ d[21] ^ c[25] ^ d[13] ^ c[17] ^ c[10] ^ d[61] ^ d[45] ^ d[22] ^ d[14] ^ c[18] ^ d[62] ^ d[54] ^ d[46] ^ d[4] ;
+o[13] = d[15] ^ c[20] ^ c[19] ^ d[47] ^ d[32] ^ d[5] ^ d[16] ^ c[28] ^ c[21] ^ d[56] ^ d[41] ^ c[0] ^ d[6] ^ c[30] ^ d[10] ^ c[22] ^ d[57] ^ d[50] ^ d[49] ^ c[23] ^ d[11] ^ c[15] ^ d[58] ^ d[8] ^ d[35] ^ d[1] ^ d[20] ^ d[12] ^ c[16] ^ d[60] ^ d[44] ^ d[9] ^ d[21] ^ c[25] ^ d[13] ^ c[10] ^ d[61] ^ d[53] ^ d[45] ^ d[3] ^ c[26] ^ c[18] ^ c[11] ^ d[62] ^ d[38] ^ d[31] ;
+o[14] = c[27] ^ d[15] ^ c[19] ^ c[20] ^ c[12] ^ d[55] ^ d[40] ^ d[5] ^ c[21] ^ d[56] ^ d[48] ^ c[0] ^ c[29] ^ d[10] ^ c[22] ^ d[57] ^ d[49] ^ c[1] ^ d[7] ^ d[34] ^ d[0] ^ c[31] ^ d[11] ^ c[23] ^ d[43] ^ d[8] ^ d[19] ^ d[20] ^ c[24] ^ d[12] ^ c[16] ^ d[60] ^ d[59] ^ d[52] ^ d[44] ^ d[9] ^ d[2] ^ c[17] ^ d[61] ^ d[37] ^ d[30] ^ c[26] ^ d[14] ^ c[11] ^ d[46] ^ d[31] ^ d[4] ;
+o[15] = c[27] ^ c[20] ^ c[12] ^ d[55] ^ d[47] ^ d[39] ^ c[28] ^ c[21] ^ c[13] ^ d[56] ^ d[48] ^ d[6] ^ d[33] ^ c[30] ^ c[22] ^ d[10] ^ d[42] ^ c[1] ^ d[7] ^ d[18] ^ c[23] ^ d[11] ^ d[58] ^ d[51] ^ c[2] ^ d[43] ^ d[8] ^ d[1] ^ d[19] ^ c[24] ^ d[60] ^ d[59] ^ d[36] ^ d[9] ^ c[25] ^ d[13] ^ c[17] ^ d[45] ^ d[30] ^ d[3] ^ d[29] ^ d[14] ^ c[18] ^ d[54] ^ d[4] ;
+o[16] = d[15] ^ c[19] ^ c[12] ^ d[63] ^ d[55] ^ d[39] ^ d[16] ^ d[41] ^ c[0] ^ d[33] ^ d[6] ^ d[17] ^ c[14] ^ d[50] ^ d[42] ^ d[7] ^ d[34] ^ d[26] ^ c[15] ^ d[58] ^ d[51] ^ d[19] ^ d[12] ^ c[24] ^ c[16] ^ d[59] ^ c[3] ^ d[44] ^ d[28] ^ c[25] ^ d[37] ^ c[5] ^ d[46] ^ d[31] ;
+o[17] = d[15] ^ c[20] ^ c[6] ^ d[40] ^ d[32] ^ d[5] ^ d[16] ^ c[13] ^ d[41] ^ d[6] ^ d[33] ^ d[25] ^ d[57] ^ d[50] ^ d[49] ^ c[1] ^ d[18] ^ d[11] ^ c[15] ^ d[58] ^ d[43] ^ d[27] ^ c[16] ^ d[36] ^ c[25] ^ c[17] ^ c[4] ^ d[45] ^ d[30] ^ d[14] ^ c[26] ^ d[62] ^ d[54] ^ d[38] ;
+o[18] = c[27] ^ d[15] ^ d[40] ^ d[39] ^ d[5] ^ d[32] ^ d[24] ^ c[21] ^ d[56] ^ c[7] ^ d[48] ^ c[0] ^ d[17] ^ d[10] ^ c[14] ^ d[57] ^ d[49] ^ d[42] ^ d[26] ^ c[2] ^ d[35] ^ c[16] ^ d[44] ^ d[13] ^ c[17] ^ d[61] ^ d[53] ^ d[37] ^ d[29] ^ c[26] ^ d[14] ^ c[18] ^ c[5] ^ d[31] ^ d[4] ;
+o[19] = d[23] ^ c[27] ^ c[19] ^ d[55] ^ c[6] ^ d[47] ^ d[39] ^ c[28] ^ d[16] ^ d[56] ^ d[48] ^ d[41] ^ c[0] ^ d[25] ^ c[22] ^ c[8] ^ c[1] ^ d[34] ^ c[15] ^ d[43] ^ d[12] ^ d[60] ^ d[52] ^ c[3] ^ d[36] ^ d[9] ^ d[28] ^ d[13] ^ c[17] ^ d[30] ^ d[3] ^ d[14] ^ c[18] ^ d[38] ^ d[4] ^ d[31] ;
+o[20] = d[15] ^ c[20] ^ c[19] ^ d[55] ^ d[47] ^ d[40] ^ d[24] ^ c[28] ^ c[7] ^ d[33] ^ c[29] ^ c[1] ^ d[42] ^ d[11] ^ c[23] ^ c[9] ^ d[51] ^ c[2] ^ d[35] ^ d[8] ^ d[27] ^ d[12] ^ c[16] ^ d[59] ^ d[2] ^ d[13] ^ c[4] ^ d[37] ^ d[29] ^ d[3] ^ d[30] ^ d[22] ^ c[18] ^ d[54] ^ d[46] ^ d[38] ;
+o[21] = d[23] ^ c[19] ^ c[20] ^ d[39] ^ d[32] ^ c[21] ^ d[41] ^ c[30] ^ c[29] ^ d[10] ^ c[8] ^ d[50] ^ d[34] ^ d[7] ^ d[26] ^ d[11] ^ d[58] ^ c[2] ^ d[1] ^ c[24] ^ d[12] ^ c[3] ^ d[36] ^ d[28] ^ d[2] ^ d[21] ^ c[17] ^ c[10] ^ d[53] ^ d[45] ^ d[37] ^ d[29] ^ d[14] ^ d[54] ^ d[46] ^ c[5] ;
+o[22] = d[15] ^ c[20] ^ c[12] ^ d[63] ^ c[6] ^ d[47] ^ d[39] ^ d[40] ^ d[5] ^ d[32] ^ c[28] ^ d[16] ^ c[13] ^ d[6] ^ d[25] ^ c[29] ^ c[30] ^ d[49] ^ d[34] ^ d[26] ^ d[18] ^ d[11] ^ c[23] ^ c[15] ^ d[51] ^ c[9] ^ c[2] ^ d[8] ^ d[27] ^ d[1] ^ d[20] ^ d[19] ^ c[16] ^ d[52] ^ c[3] ^ d[44] ^ d[36] ^ d[2] ^ d[28] ^ c[25] ^ d[45] ^ c[4] ^ d[37] ^ d[3] ^ d[29] ^ d[22] ^ c[26] ^ c[11] ^ d[54] ^ c[5] ;
+o[23] = c[27] ^ d[63] ^ c[6] ^ d[47] ^ d[32] ^ d[24] ^ c[28] ^ d[16] ^ c[7] ^ d[48] ^ d[25] ^ c[30] ^ d[17] ^ c[22] ^ c[14] ^ d[57] ^ d[50] ^ d[7] ^ d[34] ^ c[23] ^ c[15] ^ c[2] ^ d[43] ^ d[8] ^ d[27] ^ d[1] ^ c[24] ^ c[3] ^ d[44] ^ d[9] ^ d[36] ^ d[28] ^ d[21] ^ d[13] ^ c[17] ^ c[10] ^ c[4] ^ d[37] ^ d[3] ^ d[29] ^ d[14] ^ c[18] ^ d[62] ^ d[54] ^ d[46] ^ d[4] ;
+o[24] = d[23] ^ d[15] ^ c[19] ^ d[47] ^ d[24] ^ d[16] ^ c[28] ^ d[56] ^ c[7] ^ c[0] ^ d[6] ^ d[33] ^ c[29] ^ c[8] ^ d[49] ^ d[42] ^ d[7] ^ d[26] ^ d[0] ^ c[31] ^ c[23] ^ c[15] ^ d[43] ^ d[8] ^ d[35] ^ d[27] ^ d[20] ^ c[24] ^ d[12] ^ c[16] ^ c[3] ^ d[36] ^ d[2] ^ d[28] ^ c[25] ^ d[13] ^ d[61] ^ d[53] ^ c[4] ^ d[45] ^ d[3] ^ c[18] ^ c[11] ^ d[62] ^ c[5] ^ d[46] ^ d[31] ;
+o[25] = d[23] ^ d[15] ^ c[19] ^ c[20] ^ c[12] ^ d[55] ^ c[6] ^ d[5] ^ d[32] ^ d[48] ^ d[41] ^ d[6] ^ d[25] ^ c[30] ^ c[29] ^ c[8] ^ c[1] ^ d[42] ^ d[7] ^ d[34] ^ d[26] ^ d[11] ^ c[9] ^ d[35] ^ d[1] ^ d[27] ^ d[19] ^ c[24] ^ d[12] ^ c[16] ^ d[60] ^ d[52] ^ d[44] ^ d[2] ^ c[25] ^ c[17] ^ d[61] ^ c[4] ^ d[45] ^ d[30] ^ d[22] ^ c[26] ^ d[14] ^ d[46] ^ c[5] ;
+o[26] = d[15] ^ c[27] ^ c[20] ^ c[12] ^ d[63] ^ c[6] ^ d[39] ^ d[40] ^ d[32] ^ d[24] ^ c[28] ^ d[16] ^ c[7] ^ d[41] ^ d[6] ^ d[25] ^ c[29] ^ c[30] ^ c[22] ^ d[57] ^ d[11] ^ c[23] ^ c[15] ^ c[9] ^ d[43] ^ d[8] ^ d[35] ^ d[1] ^ d[19] ^ c[16] ^ d[60] ^ d[59] ^ d[44] ^ d[9] ^ d[2] ^ d[21] ^ c[25] ^ c[17] ^ c[10] ^ d[53] ^ d[45] ^ d[37] ^ d[3] ^ d[22] ^ d[14] ^ d[38] ^ d[4] ;
+o[27] = d[23] ^ d[15] ^ d[40] ^ d[39] ^ d[5] ^ d[24] ^ c[28] ^ c[21] ^ c[13] ^ d[56] ^ c[7] ^ c[0] ^ c[29] ^ c[30] ^ d[10] ^ c[8] ^ d[42] ^ d[7] ^ d[34] ^ d[0] ^ c[31] ^ d[18] ^ c[23] ^ d[58] ^ d[43] ^ d[8] ^ d[1] ^ d[20] ^ c[24] ^ c[16] ^ d[59] ^ d[52] ^ d[44] ^ d[36] ^ d[2] ^ d[21] ^ d[13] ^ c[17] ^ c[10] ^ d[37] ^ d[3] ^ d[14] ^ c[26] ^ c[18] ^ c[11] ^ d[62] ^ d[38] ^ d[31] ;
+o[28] = d[23] ^ c[27] ^ c[19] ^ c[12] ^ d[55] ^ d[39] ^ d[41] ^ d[6] ^ d[33] ^ c[30] ^ c[29] ^ d[17] ^ c[22] ^ c[14] ^ d[57] ^ c[8] ^ c[1] ^ d[42] ^ d[7] ^ d[0] ^ c[31] ^ d[58] ^ c[9] ^ d[51] ^ d[43] ^ d[35] ^ d[1] ^ d[19] ^ d[20] ^ c[24] ^ d[12] ^ d[9] ^ d[36] ^ d[2] ^ d[13] ^ c[25] ^ c[17] ^ d[61] ^ d[37] ^ d[30] ^ d[22] ^ d[14] ^ c[18] ^ c[11] ^ d[38] ^ d[4] ;
+o[29] = c[19] ^ c[20] ^ c[12] ^ d[40] ^ d[5] ^ d[32] ^ c[28] ^ d[16] ^ c[13] ^ d[56] ^ d[41] ^ d[6] ^ c[30] ^ d[57] ^ d[50] ^ d[42] ^ d[34] ^ d[0] ^ d[18] ^ c[31] ^ c[23] ^ d[11] ^ c[15] ^ c[9] ^ c[2] ^ d[8] ^ d[35] ^ d[1] ^ d[19] ^ d[12] ^ d[60] ^ d[36] ^ d[21] ^ c[25] ^ d[13] ^ c[10] ^ d[37] ^ d[3] ^ d[29] ^ d[22] ^ c[26] ^ c[18] ^ d[54] ^ d[38] ;
+o[30] = c[27] ^ d[15] ^ c[20] ^ c[19] ^ d[55] ^ d[40] ^ d[39] ^ d[5] ^ c[21] ^ c[13] ^ d[56] ^ d[41] ^ c[0] ^ d[33] ^ d[17] ^ c[29] ^ d[10] ^ c[14] ^ d[49] ^ d[7] ^ d[34] ^ d[0] ^ c[31] ^ d[18] ^ d[11] ^ d[35] ^ d[20] ^ c[24] ^ d[12] ^ c[16] ^ d[59] ^ c[3] ^ d[36] ^ d[2] ^ d[28] ^ d[21] ^ c[10] ^ d[53] ^ d[37] ^ c[26] ^ c[11] ^ d[4] ^ d[31] ;
+o[31] = c[27] ^ c[20] ^ c[12] ^ d[55] ^ d[40] ^ d[39] ^ d[32] ^ d[16] ^ c[28] ^ c[21] ^ d[48] ^ d[6] ^ d[33] ^ c[30] ^ d[17] ^ d[10] ^ c[22] ^ c[14] ^ c[1] ^ d[34] ^ d[11] ^ c[15] ^ d[58] ^ d[35] ^ d[1] ^ d[27] ^ d[19] ^ d[20] ^ d[52] ^ d[9] ^ d[36] ^ c[25] ^ c[17] ^ c[4] ^ d[3] ^ d[30] ^ d[14] ^ c[11] ^ d[54] ^ d[38] ^ d[4] ;
+ crc8B = o;
+ end
+ endfunction // crc8B
+
+ ////////////////////////////////////////////////
+ // crc7B
+ ////////////////////////////////////////////////
+ function [31:0] crc7B (
+ input [31:0] c,
+ input [55:0] d
+ );
+ reg [31:0] o;
+ begin
+o[0] = d[23] ^ c[20] ^ d[55] ^ c[6] ^ d[39] ^ d[5] ^ d[24] ^ c[21] ^ c[13] ^ c[7] ^ c[0] ^ d[25] ^ c[30] ^ c[29] ^ d[10] ^ d[49] ^ c[8] ^ c[1] ^ d[7] ^ d[0] ^ d[26] ^ c[31] ^ d[18] ^ d[11] ^ c[23] ^ d[43] ^ c[2] ^ d[8] ^ d[1] ^ d[27] ^ c[24] ^ d[2] ^ d[21] ^ c[10] ^ c[4] ^ d[45] ^ d[30] ^ d[29] ^ c[26] ^ d[46] ^ c[5] ^ d[31] ;
+o[1] = c[27] ^ c[20] ^ d[55] ^ d[39] ^ d[5] ^ c[13] ^ d[48] ^ c[0] ^ d[6] ^ c[29] ^ d[17] ^ c[22] ^ c[14] ^ d[49] ^ d[42] ^ d[18] ^ d[11] ^ c[23] ^ c[9] ^ d[43] ^ d[8] ^ d[27] ^ d[20] ^ c[3] ^ d[44] ^ d[9] ^ d[2] ^ d[28] ^ d[21] ^ c[25] ^ c[10] ^ c[4] ^ d[22] ^ c[26] ^ c[11] ^ d[54] ^ d[46] ^ d[38] ^ d[31] ^ d[4] ;
+o[2] = d[23] ^ c[27] ^ c[20] ^ c[12] ^ d[55] ^ c[6] ^ d[47] ^ d[39] ^ d[24] ^ c[28] ^ d[16] ^ c[13] ^ c[7] ^ d[48] ^ c[0] ^ d[41] ^ d[25] ^ c[29] ^ d[17] ^ c[14] ^ d[49] ^ c[8] ^ d[42] ^ d[0] ^ c[31] ^ d[18] ^ d[11] ^ c[15] ^ c[2] ^ d[19] ^ d[20] ^ d[2] ^ d[53] ^ d[37] ^ d[3] ^ d[29] ^ c[11] ^ d[54] ^ d[46] ^ d[38] ^ d[31] ^ d[4] ;
+o[3] = d[23] ^ d[15] ^ c[12] ^ d[47] ^ d[40] ^ d[24] ^ c[28] ^ d[16] ^ c[21] ^ c[13] ^ d[48] ^ c[7] ^ d[41] ^ c[29] ^ c[30] ^ d[17] ^ d[10] ^ c[14] ^ c[8] ^ c[1] ^ d[18] ^ c[15] ^ c[9] ^ d[1] ^ d[19] ^ c[16] ^ d[52] ^ c[3] ^ d[36] ^ d[2] ^ d[28] ^ d[53] ^ d[45] ^ d[37] ^ d[30] ^ d[3] ^ d[22] ^ d[54] ^ d[46] ^ d[38] ;
+o[4] = d[15] ^ c[20] ^ d[55] ^ c[6] ^ d[47] ^ d[40] ^ d[5] ^ d[24] ^ d[16] ^ c[21] ^ c[7] ^ c[0] ^ d[25] ^ d[17] ^ d[10] ^ c[22] ^ c[14] ^ d[49] ^ c[1] ^ d[7] ^ d[26] ^ d[11] ^ c[23] ^ c[15] ^ c[9] ^ d[51] ^ d[43] ^ d[8] ^ d[35] ^ c[24] ^ c[16] ^ d[52] ^ d[44] ^ d[9] ^ d[36] ^ c[17] ^ d[53] ^ d[37] ^ d[30] ^ d[22] ^ c[26] ^ d[14] ^ c[5] ^ d[31] ;
+o[5] = c[27] ^ d[15] ^ c[20] ^ d[55] ^ d[5] ^ d[16] ^ c[13] ^ d[48] ^ c[0] ^ d[6] ^ c[30] ^ c[29] ^ c[22] ^ d[49] ^ d[50] ^ d[42] ^ d[34] ^ d[0] ^ d[26] ^ c[31] ^ d[18] ^ d[11] ^ c[15] ^ d[51] ^ d[35] ^ d[1] ^ d[27] ^ c[16] ^ d[52] ^ d[9] ^ d[36] ^ d[2] ^ d[13] ^ c[25] ^ c[17] ^ c[4] ^ d[45] ^ c[26] ^ d[14] ^ c[18] ^ d[54] ^ c[5] ^ d[31] ^ d[4] ;
+o[6] = d[15] ^ c[27] ^ c[19] ^ c[6] ^ d[47] ^ d[5] ^ c[28] ^ c[21] ^ d[48] ^ d[41] ^ d[33] ^ d[25] ^ c[30] ^ d[17] ^ d[10] ^ c[14] ^ d[50] ^ d[49] ^ c[1] ^ d[34] ^ d[0] ^ d[26] ^ c[31] ^ c[23] ^ d[51] ^ d[8] ^ d[35] ^ d[1] ^ d[12] ^ c[16] ^ d[44] ^ d[13] ^ c[17] ^ d[53] ^ d[30] ^ d[3] ^ c[26] ^ d[14] ^ c[18] ^ d[54] ^ c[5] ^ d[4] ;
+o[7] = d[23] ^ c[27] ^ c[19] ^ d[55] ^ d[47] ^ d[40] ^ d[39] ^ d[5] ^ d[32] ^ c[28] ^ d[16] ^ c[21] ^ c[13] ^ d[48] ^ c[0] ^ d[33] ^ c[30] ^ d[10] ^ c[22] ^ c[8] ^ d[50] ^ c[1] ^ d[34] ^ d[26] ^ d[18] ^ c[23] ^ c[15] ^ d[8] ^ d[1] ^ d[27] ^ d[12] ^ d[52] ^ d[9] ^ d[21] ^ d[13] ^ c[17] ^ c[10] ^ d[53] ^ c[4] ^ d[45] ^ d[3] ^ d[30] ^ c[26] ^ d[14] ^ c[18] ^ c[5] ^ d[31] ^ d[4] ;
+o[8] = d[23] ^ c[27] ^ d[15] ^ c[19] ^ d[55] ^ d[47] ^ d[5] ^ d[32] ^ d[24] ^ c[28] ^ c[21] ^ c[13] ^ c[7] ^ d[33] ^ c[30] ^ d[17] ^ d[10] ^ c[22] ^ c[14] ^ c[8] ^ d[18] ^ c[9] ^ d[51] ^ d[43] ^ d[1] ^ d[27] ^ d[20] ^ d[12] ^ c[16] ^ d[52] ^ d[44] ^ d[9] ^ d[21] ^ d[13] ^ c[10] ^ c[4] ^ d[45] ^ d[3] ^ d[22] ^ c[26] ^ c[18] ^ c[11] ^ d[54] ^ d[38] ^ d[4] ;
+o[9] = d[23] ^ c[27] ^ c[19] ^ c[20] ^ c[12] ^ d[32] ^ c[28] ^ d[16] ^ c[0] ^ c[29] ^ d[17] ^ c[22] ^ c[14] ^ c[8] ^ d[50] ^ d[42] ^ d[0] ^ d[26] ^ c[31] ^ c[23] ^ d[11] ^ c[15] ^ c[9] ^ d[51] ^ d[43] ^ d[8] ^ d[20] ^ d[19] ^ d[12] ^ d[44] ^ d[9] ^ d[2] ^ d[21] ^ c[17] ^ c[10] ^ d[53] ^ d[37] ^ d[3] ^ d[22] ^ d[14] ^ c[11] ^ d[54] ^ c[5] ^ d[46] ^ d[4] ^ d[31] ;
+o[10] = d[23] ^ d[15] ^ c[12] ^ d[55] ^ d[39] ^ d[5] ^ d[24] ^ c[28] ^ d[16] ^ c[7] ^ d[41] ^ c[8] ^ d[50] ^ d[42] ^ d[0] ^ d[26] ^ c[31] ^ c[15] ^ c[9] ^ c[2] ^ d[27] ^ d[19] ^ d[20] ^ c[16] ^ d[52] ^ d[36] ^ d[13] ^ d[53] ^ c[4] ^ d[3] ^ d[29] ^ d[22] ^ c[26] ^ c[18] ^ c[11] ^ d[46] ^ c[5] ;
+o[11] = c[27] ^ d[15] ^ c[19] ^ c[20] ^ c[12] ^ d[55] ^ d[40] ^ d[39] ^ d[5] ^ d[24] ^ c[21] ^ c[7] ^ c[0] ^ d[41] ^ c[30] ^ d[10] ^ c[1] ^ d[7] ^ d[0] ^ c[31] ^ d[11] ^ c[23] ^ c[9] ^ d[51] ^ d[43] ^ c[2] ^ d[8] ^ d[35] ^ d[1] ^ d[27] ^ d[19] ^ c[24] ^ d[12] ^ c[16] ^ d[52] ^ c[3] ^ d[28] ^ c[17] ^ c[4] ^ d[30] ^ d[29] ^ d[22] ^ c[26] ^ d[14] ^ d[54] ^ d[46] ^ d[38] ^ d[31] ^ d[4] ;
+o[12] = c[27] ^ d[55] ^ c[6] ^ d[40] ^ d[5] ^ d[24] ^ c[28] ^ c[7] ^ c[0] ^ d[6] ^ d[25] ^ c[30] ^ c[29] ^ c[22] ^ d[49] ^ d[50] ^ d[42] ^ d[34] ^ c[23] ^ d[51] ^ d[43] ^ d[8] ^ d[1] ^ c[3] ^ d[9] ^ d[2] ^ d[28] ^ d[13] ^ c[25] ^ c[17] ^ d[53] ^ d[37] ^ d[3] ^ c[26] ^ d[14] ^ c[18] ^ d[54] ^ d[46] ^ d[38] ^ d[31] ^ d[4] ;
+o[13] = d[23] ^ c[27] ^ c[19] ^ d[39] ^ d[5] ^ d[24] ^ c[28] ^ d[48] ^ c[7] ^ d[41] ^ d[33] ^ c[29] ^ c[30] ^ c[8] ^ d[50] ^ d[49] ^ d[42] ^ c[1] ^ d[7] ^ d[0] ^ c[31] ^ c[23] ^ d[8] ^ d[1] ^ d[27] ^ d[12] ^ c[24] ^ d[52] ^ d[36] ^ d[2] ^ d[13] ^ d[53] ^ c[4] ^ d[45] ^ d[37] ^ d[30] ^ d[3] ^ c[26] ^ c[18] ^ d[54] ^ d[4] ;
+o[14] = d[23] ^ c[27] ^ c[20] ^ c[19] ^ d[47] ^ d[40] ^ d[32] ^ c[28] ^ d[48] ^ d[41] ^ d[6] ^ c[29] ^ c[30] ^ c[8] ^ d[49] ^ d[7] ^ d[0] ^ d[26] ^ c[31] ^ d[11] ^ c[9] ^ d[51] ^ c[2] ^ d[35] ^ d[1] ^ c[24] ^ d[12] ^ d[52] ^ d[44] ^ d[36] ^ d[2] ^ c[25] ^ d[53] ^ d[29] ^ d[3] ^ d[22] ^ c[5] ^ d[38] ^ d[4] ;
+o[15] = c[20] ^ c[6] ^ d[47] ^ d[40] ^ d[39] ^ d[5] ^ c[28] ^ c[21] ^ d[48] ^ c[0] ^ d[6] ^ d[25] ^ c[30] ^ c[29] ^ d[10] ^ d[50] ^ d[34] ^ d[0] ^ c[31] ^ d[11] ^ c[9] ^ d[51] ^ d[43] ^ d[35] ^ d[1] ^ d[52] ^ c[3] ^ d[28] ^ d[2] ^ d[21] ^ c[25] ^ c[10] ^ d[37] ^ d[3] ^ d[22] ^ c[26] ^ d[46] ^ d[31] ;
+o[16] = d[23] ^ c[27] ^ c[20] ^ d[55] ^ c[6] ^ d[47] ^ c[13] ^ c[0] ^ d[33] ^ d[25] ^ c[22] ^ c[8] ^ d[50] ^ d[42] ^ d[7] ^ d[34] ^ d[26] ^ d[18] ^ d[11] ^ c[23] ^ d[51] ^ d[43] ^ c[2] ^ d[8] ^ d[20] ^ c[24] ^ d[9] ^ d[36] ^ d[29] ^ c[11] ^ c[5] ^ d[38] ^ d[31] ^ d[4] ;
+o[17] = c[12] ^ c[6] ^ d[32] ^ d[24] ^ c[28] ^ c[21] ^ c[7] ^ d[41] ^ d[6] ^ d[33] ^ d[25] ^ d[17] ^ d[10] ^ c[14] ^ d[50] ^ d[49] ^ d[42] ^ c[1] ^ d[7] ^ c[23] ^ c[9] ^ d[8] ^ d[35] ^ d[19] ^ c[24] ^ c[3] ^ d[28] ^ c[25] ^ d[37] ^ d[30] ^ d[3] ^ d[22] ^ d[54] ^ d[46] ;
+o[18] = d[23] ^ d[40] ^ d[5] ^ d[32] ^ d[24] ^ d[16] ^ c[13] ^ c[7] ^ d[48] ^ d[41] ^ c[0] ^ d[6] ^ c[29] ^ c[22] ^ c[8] ^ d[49] ^ d[7] ^ d[34] ^ d[18] ^ c[15] ^ c[2] ^ d[27] ^ c[24] ^ d[9] ^ d[36] ^ d[2] ^ d[21] ^ c[25] ^ c[10] ^ d[53] ^ c[4] ^ d[45] ^ d[29] ^ c[26] ^ d[31] ;
+o[19] = d[23] ^ c[27] ^ d[15] ^ d[47] ^ d[40] ^ d[39] ^ d[5] ^ d[48] ^ c[0] ^ d[6] ^ d[33] ^ c[30] ^ d[17] ^ c[14] ^ c[8] ^ c[1] ^ d[26] ^ c[23] ^ c[9] ^ d[8] ^ d[35] ^ d[1] ^ d[20] ^ c[16] ^ d[52] ^ c[3] ^ d[44] ^ d[28] ^ c[25] ^ d[30] ^ d[22] ^ c[26] ^ c[11] ^ c[5] ^ d[4] ^ d[31] ;
+o[20] = c[27] ^ c[12] ^ c[6] ^ d[47] ^ d[39] ^ d[5] ^ d[32] ^ c[28] ^ d[16] ^ d[25] ^ c[1] ^ d[7] ^ d[34] ^ d[0] ^ c[31] ^ c[15] ^ d[51] ^ c[9] ^ c[2] ^ d[43] ^ d[27] ^ d[19] ^ c[24] ^ d[21] ^ c[17] ^ c[10] ^ c[4] ^ d[3] ^ d[30] ^ d[29] ^ d[22] ^ c[26] ^ d[14] ^ d[46] ^ d[38] ^ d[4] ;
+o[21] = c[27] ^ d[15] ^ d[24] ^ c[28] ^ c[13] ^ c[7] ^ c[0] ^ d[6] ^ d[33] ^ c[29] ^ d[50] ^ d[42] ^ d[26] ^ d[18] ^ c[2] ^ d[20] ^ c[16] ^ c[3] ^ d[2] ^ d[28] ^ d[21] ^ c[25] ^ d[13] ^ c[10] ^ d[45] ^ d[37] ^ d[3] ^ d[29] ^ c[18] ^ c[11] ^ c[5] ^ d[46] ^ d[38] ^ d[4] ^ d[31] ;
+o[22] = c[19] ^ c[20] ^ c[12] ^ d[55] ^ d[39] ^ d[32] ^ d[24] ^ c[28] ^ c[21] ^ c[13] ^ c[7] ^ c[0] ^ d[41] ^ d[17] ^ d[10] ^ c[14] ^ d[7] ^ d[0] ^ d[26] ^ c[31] ^ d[18] ^ d[11] ^ c[23] ^ d[43] ^ c[2] ^ d[8] ^ d[19] ^ d[20] ^ c[24] ^ d[12] ^ c[3] ^ d[44] ^ d[36] ^ d[28] ^ d[21] ^ c[17] ^ c[10] ^ d[37] ^ d[3] ^ d[29] ^ d[14] ^ c[11] ^ d[46] ^ c[5] ^ d[31] ;
+o[23] = c[12] ^ d[55] ^ d[40] ^ d[39] ^ d[5] ^ d[24] ^ d[16] ^ c[7] ^ d[6] ^ c[30] ^ d[17] ^ c[22] ^ c[14] ^ d[49] ^ d[42] ^ d[0] ^ d[26] ^ c[31] ^ c[23] ^ c[15] ^ c[2] ^ d[8] ^ d[35] ^ d[1] ^ d[19] ^ d[20] ^ c[3] ^ d[9] ^ d[36] ^ d[28] ^ d[21] ^ d[13] ^ c[25] ^ c[10] ^ d[29] ^ c[26] ^ c[18] ^ c[11] ^ d[54] ^ d[46] ^ c[5] ^ d[38] ;
+o[24] = d[23] ^ d[15] ^ c[27] ^ c[19] ^ c[12] ^ c[6] ^ d[39] ^ d[5] ^ d[16] ^ c[13] ^ d[48] ^ d[41] ^ d[25] ^ c[8] ^ d[7] ^ d[34] ^ d[0] ^ d[18] ^ c[31] ^ c[23] ^ c[15] ^ d[8] ^ d[35] ^ d[27] ^ d[20] ^ d[19] ^ d[12] ^ c[24] ^ c[16] ^ c[3] ^ d[28] ^ d[53] ^ c[4] ^ d[45] ^ d[37] ^ c[26] ^ c[11] ^ d[54] ^ d[38] ^ d[4] ;
+o[25] = c[27] ^ d[15] ^ c[20] ^ c[12] ^ d[47] ^ d[40] ^ d[24] ^ c[28] ^ c[13] ^ c[7] ^ d[6] ^ d[33] ^ d[17] ^ c[14] ^ d[7] ^ d[34] ^ d[26] ^ d[18] ^ d[11] ^ c[9] ^ d[27] ^ d[19] ^ c[24] ^ c[16] ^ d[52] ^ d[44] ^ d[36] ^ c[25] ^ c[17] ^ d[53] ^ c[4] ^ d[37] ^ d[3] ^ d[22] ^ d[14] ^ c[5] ^ d[38] ^ d[4] ;
+o[26] = c[20] ^ d[55] ^ d[32] ^ d[24] ^ c[28] ^ d[16] ^ c[7] ^ c[0] ^ d[6] ^ d[33] ^ c[30] ^ d[17] ^ c[14] ^ d[49] ^ c[1] ^ d[7] ^ d[0] ^ c[31] ^ d[11] ^ c[23] ^ c[15] ^ d[51] ^ c[2] ^ d[8] ^ d[35] ^ d[1] ^ d[27] ^ c[24] ^ d[52] ^ d[36] ^ d[13] ^ c[25] ^ c[17] ^ c[4] ^ d[45] ^ d[37] ^ d[3] ^ d[30] ^ d[29] ^ d[14] ^ c[18] ^ d[31] ;
+o[27] = d[23] ^ d[15] ^ c[19] ^ d[5] ^ d[32] ^ d[16] ^ c[21] ^ d[48] ^ c[0] ^ d[6] ^ c[29] ^ d[10] ^ c[8] ^ d[50] ^ c[1] ^ d[7] ^ d[34] ^ d[0] ^ d[26] ^ c[31] ^ c[15] ^ d[51] ^ c[2] ^ d[35] ^ d[12] ^ c[24] ^ c[16] ^ c[3] ^ d[44] ^ d[36] ^ d[2] ^ d[28] ^ c[25] ^ d[13] ^ d[30] ^ d[29] ^ c[26] ^ c[18] ^ d[54] ^ c[5] ^ d[31] ;
+o[28] = c[27] ^ d[15] ^ c[20] ^ c[19] ^ d[47] ^ c[6] ^ d[5] ^ c[0] ^ d[6] ^ d[33] ^ d[25] ^ c[30] ^ c[22] ^ d[50] ^ d[49] ^ c[1] ^ d[34] ^ d[11] ^ c[9] ^ c[2] ^ d[43] ^ d[35] ^ d[1] ^ d[27] ^ d[12] ^ c[16] ^ c[3] ^ d[9] ^ d[28] ^ c[25] ^ c[17] ^ d[53] ^ c[4] ^ d[29] ^ d[30] ^ d[22] ^ c[26] ^ d[14] ^ d[4] ^ d[31] ;
+o[29] = c[27] ^ c[20] ^ d[5] ^ d[32] ^ d[24] ^ c[28] ^ c[21] ^ c[7] ^ d[48] ^ d[33] ^ d[10] ^ d[49] ^ c[1] ^ d[42] ^ d[34] ^ d[0] ^ d[26] ^ c[31] ^ c[23] ^ d[11] ^ c[2] ^ d[8] ^ d[27] ^ d[52] ^ c[3] ^ d[28] ^ d[21] ^ d[13] ^ c[17] ^ c[10] ^ c[4] ^ d[3] ^ d[30] ^ d[29] ^ c[26] ^ d[14] ^ c[18] ^ d[46] ^ c[5] ^ d[4] ;
+o[30] = d[23] ^ c[27] ^ c[19] ^ c[6] ^ d[47] ^ d[32] ^ c[28] ^ c[21] ^ d[48] ^ d[41] ^ c[0] ^ d[33] ^ d[25] ^ c[29] ^ c[22] ^ d[10] ^ c[8] ^ d[7] ^ d[26] ^ d[51] ^ c[2] ^ d[27] ^ d[20] ^ d[12] ^ c[24] ^ c[3] ^ d[9] ^ d[2] ^ d[28] ^ d[13] ^ d[45] ^ c[4] ^ d[3] ^ d[29] ^ c[18] ^ c[11] ^ c[5] ^ d[4] ^ d[31] ;
+o[31] = c[20] ^ c[19] ^ c[12] ^ c[6] ^ d[47] ^ d[40] ^ d[32] ^ d[24] ^ c[28] ^ c[7] ^ c[0] ^ d[6] ^ d[25] ^ c[29] ^ c[30] ^ c[22] ^ d[50] ^ c[1] ^ d[26] ^ c[23] ^ d[11] ^ c[9] ^ d[8] ^ d[1] ^ d[27] ^ d[19] ^ d[12] ^ d[44] ^ c[3] ^ d[9] ^ d[2] ^ d[28] ^ c[25] ^ c[4] ^ d[3] ^ d[30] ^ d[22] ^ c[5] ^ d[46] ^ d[31] ;
+ crc7B = o;
+ end
+ endfunction // crc7B
+
+ ////////////////////////////////////////////////
+ // crc6B
+ ////////////////////////////////////////////////
+ function [31:0] crc6B (
+ input [31:0] c,
+ input [47:0] d
+ );
+ reg [31:0] o;
+ begin
+o[0] = d[41] ^ d[23] ^ c[0] ^ d[15] ^ c[9] ^ c[10] ^ d[35] ^ d[17] ^ c[29] ^ c[12] ^ d[10] ^ c[14] ^ d[19] ^ d[37] ^ d[47] ^ d[3] ^ c[16] ^ d[22] ^ c[8] ^ c[18] ^ c[28] ^ d[16] ^ d[0] ^ c[21] ^ c[31] ^ d[18] ^ c[13] ^ d[2] ^ c[15] ^ d[21] ^ d[38] ^ d[13] ^ d[31] ;
+o[1] = d[23] ^ c[19] ^ c[12] ^ d[47] ^ d[40] ^ c[28] ^ c[21] ^ d[41] ^ c[0] ^ c[30] ^ d[10] ^ c[22] ^ c[8] ^ c[1] ^ d[34] ^ d[0] ^ c[31] ^ d[35] ^ d[1] ^ d[20] ^ d[19] ^ d[12] ^ d[9] ^ d[36] ^ d[13] ^ c[17] ^ d[3] ^ d[30] ^ d[14] ^ c[18] ^ c[11] ^ d[46] ^ d[38] ^ d[31] ;
+o[2] = d[23] ^ d[15] ^ c[20] ^ c[19] ^ d[47] ^ d[40] ^ d[39] ^ c[28] ^ d[16] ^ c[21] ^ d[41] ^ c[0] ^ d[33] ^ d[17] ^ d[10] ^ c[22] ^ c[14] ^ c[8] ^ c[1] ^ d[34] ^ d[11] ^ c[23] ^ c[15] ^ c[2] ^ d[8] ^ d[12] ^ c[16] ^ d[9] ^ d[21] ^ c[10] ^ d[45] ^ d[29] ^ d[3] ^ d[30] ^ d[46] ^ d[38] ^ d[31] ;
+o[3] = d[15] ^ c[20] ^ d[40] ^ d[39] ^ d[32] ^ d[16] ^ c[21] ^ d[33] ^ c[29] ^ d[10] ^ c[22] ^ c[1] ^ d[7] ^ c[23] ^ d[11] ^ c[15] ^ c[9] ^ c[2] ^ d[8] ^ d[20] ^ c[24] ^ c[16] ^ c[3] ^ d[44] ^ d[9] ^ d[28] ^ d[2] ^ c[17] ^ d[45] ^ d[37] ^ d[30] ^ d[29] ^ d[22] ^ d[14] ^ c[11] ^ d[46] ^ d[38] ;
+o[4] = d[23] ^ d[47] ^ d[39] ^ d[32] ^ c[28] ^ d[16] ^ c[13] ^ d[41] ^ d[6] ^ d[17] ^ c[29] ^ c[30] ^ c[22] ^ c[14] ^ c[8] ^ d[7] ^ d[0] ^ c[31] ^ d[18] ^ c[23] ^ c[15] ^ c[9] ^ c[2] ^ d[43] ^ d[35] ^ d[8] ^ d[1] ^ d[27] ^ c[24] ^ c[3] ^ d[44] ^ d[9] ^ d[36] ^ d[2] ^ d[28] ^ c[25] ^ c[17] ^ c[4] ^ d[45] ^ d[29] ^ d[3] ^ d[22] ^ d[14] ;
+o[5] = d[23] ^ c[12] ^ d[47] ^ d[40] ^ d[5] ^ c[28] ^ c[21] ^ c[13] ^ d[41] ^ d[6] ^ c[30] ^ d[10] ^ c[8] ^ d[42] ^ d[7] ^ d[34] ^ d[26] ^ d[18] ^ c[23] ^ d[43] ^ d[8] ^ d[1] ^ d[27] ^ d[19] ^ c[24] ^ c[3] ^ d[44] ^ d[28] ^ c[25] ^ c[4] ^ d[37] ^ d[3] ^ c[26] ^ c[5] ^ d[46] ;
+o[6] = c[27] ^ c[6] ^ d[40] ^ d[39] ^ d[5] ^ c[13] ^ d[41] ^ d[6] ^ d[33] ^ d[25] ^ c[29] ^ d[17] ^ c[22] ^ c[14] ^ d[42] ^ d[7] ^ d[0] ^ d[26] ^ c[31] ^ d[18] ^ c[9] ^ d[43] ^ d[27] ^ c[24] ^ d[9] ^ d[36] ^ d[2] ^ c[25] ^ c[4] ^ d[45] ^ d[22] ^ c[26] ^ d[46] ^ c[5] ^ d[4] ;
+o[7] = d[23] ^ c[27] ^ d[15] ^ c[12] ^ d[47] ^ c[6] ^ d[39] ^ d[40] ^ d[5] ^ d[32] ^ d[24] ^ c[21] ^ c[13] ^ c[7] ^ c[0] ^ d[6] ^ d[25] ^ c[29] ^ c[30] ^ d[10] ^ c[8] ^ d[42] ^ d[0] ^ d[26] ^ c[31] ^ d[18] ^ c[23] ^ c[9] ^ d[8] ^ d[1] ^ d[19] ^ c[16] ^ d[44] ^ d[2] ^ d[13] ^ c[25] ^ d[45] ^ d[37] ^ d[22] ^ c[26] ^ c[18] ^ c[5] ^ d[4] ^ d[31] ;
+o[8] = c[27] ^ d[15] ^ c[19] ^ c[12] ^ d[47] ^ c[6] ^ d[39] ^ d[5] ^ d[24] ^ d[16] ^ c[21] ^ c[7] ^ d[25] ^ c[29] ^ c[30] ^ d[10] ^ c[22] ^ c[1] ^ d[7] ^ c[15] ^ d[43] ^ d[35] ^ d[1] ^ d[19] ^ c[24] ^ d[12] ^ c[16] ^ d[44] ^ d[9] ^ d[36] ^ d[2] ^ d[13] ^ c[17] ^ d[37] ^ d[30] ^ c[26] ^ d[14] ^ c[18] ^ d[46] ^ d[4] ;
+o[9] = d[23] ^ c[27] ^ d[15] ^ c[19] ^ c[20] ^ d[24] ^ c[28] ^ c[13] ^ c[7] ^ d[6] ^ c[30] ^ c[22] ^ c[8] ^ d[42] ^ d[34] ^ d[0] ^ c[31] ^ d[18] ^ c[23] ^ d[11] ^ c[2] ^ d[43] ^ d[8] ^ d[35] ^ d[1] ^ d[12] ^ c[16] ^ d[9] ^ d[36] ^ c[25] ^ d[13] ^ c[17] ^ d[45] ^ d[3] ^ d[29] ^ d[14] ^ c[18] ^ d[46] ^ d[38] ^ d[4] ;
+o[10] = d[15] ^ c[20] ^ c[19] ^ c[12] ^ d[47] ^ d[5] ^ d[16] ^ c[13] ^ c[0] ^ d[33] ^ d[42] ^ d[7] ^ d[34] ^ d[18] ^ d[11] ^ c[23] ^ c[15] ^ d[8] ^ d[19] ^ c[24] ^ d[12] ^ c[16] ^ c[3] ^ d[44] ^ d[28] ^ d[21] ^ c[17] ^ c[10] ^ d[45] ^ c[26] ^ d[14] ^ d[38] ^ d[31] ;
+o[11] = d[23] ^ c[27] ^ c[20] ^ c[12] ^ d[47] ^ d[32] ^ c[28] ^ d[16] ^ c[0] ^ d[6] ^ d[33] ^ c[29] ^ c[8] ^ c[1] ^ d[7] ^ d[0] ^ c[31] ^ d[11] ^ c[15] ^ c[9] ^ d[43] ^ d[35] ^ d[27] ^ d[20] ^ d[19] ^ c[24] ^ d[44] ^ d[2] ^ d[21] ^ c[25] ^ c[17] ^ c[10] ^ c[4] ^ d[3] ^ d[30] ^ d[22] ^ d[14] ^ c[11] ^ d[46] ^ d[38] ^ d[4] ^ d[31] ;
+o[12] = d[23] ^ d[47] ^ d[5] ^ d[32] ^ d[16] ^ d[41] ^ d[6] ^ d[17] ^ c[30] ^ c[14] ^ c[8] ^ c[1] ^ d[42] ^ d[34] ^ d[0] ^ d[26] ^ c[31] ^ c[15] ^ c[2] ^ d[43] ^ d[35] ^ d[1] ^ d[20] ^ c[25] ^ d[45] ^ d[29] ^ d[30] ^ c[26] ^ c[11] ^ c[5] ^ d[46] ^ d[38] ;
+o[13] = c[27] ^ d[15] ^ c[12] ^ c[6] ^ d[40] ^ d[5] ^ d[16] ^ c[0] ^ d[41] ^ d[33] ^ d[25] ^ d[42] ^ d[34] ^ d[0] ^ c[31] ^ c[15] ^ c[9] ^ c[2] ^ d[19] ^ c[16] ^ c[3] ^ d[44] ^ d[28] ^ d[45] ^ d[37] ^ d[29] ^ d[22] ^ c[26] ^ d[46] ^ d[4] ^ d[31] ;
+o[14] = d[15] ^ c[27] ^ d[39] ^ d[40] ^ d[32] ^ d[24] ^ c[28] ^ c[13] ^ c[7] ^ d[41] ^ d[33] ^ c[1] ^ d[18] ^ d[43] ^ d[27] ^ c[16] ^ d[44] ^ c[3] ^ d[36] ^ d[28] ^ d[21] ^ c[17] ^ c[10] ^ d[45] ^ c[4] ^ d[3] ^ d[30] ^ d[14] ^ d[4] ;
+o[15] = d[23] ^ d[40] ^ d[39] ^ d[32] ^ c[28] ^ c[0] ^ c[29] ^ d[17] ^ c[14] ^ c[8] ^ d[42] ^ d[26] ^ c[2] ^ d[43] ^ d[35] ^ d[27] ^ d[20] ^ d[44] ^ d[2] ^ d[13] ^ c[17] ^ c[4] ^ d[3] ^ d[29] ^ d[14] ^ c[18] ^ c[11] ^ c[5] ^ d[38] ^ d[31] ;
+o[16] = d[23] ^ d[15] ^ c[19] ^ d[47] ^ c[6] ^ d[39] ^ c[28] ^ c[21] ^ c[13] ^ d[25] ^ d[17] ^ c[30] ^ d[10] ^ c[14] ^ c[8] ^ d[42] ^ c[1] ^ d[34] ^ d[0] ^ d[26] ^ c[31] ^ d[18] ^ d[43] ^ d[35] ^ d[1] ^ d[12] ^ c[16] ^ c[3] ^ d[28] ^ d[21] ^ c[10] ^ d[3] ^ d[30] ^ c[5] ;
+o[17] = c[20] ^ c[6] ^ d[24] ^ d[16] ^ c[7] ^ d[41] ^ d[33] ^ d[25] ^ c[29] ^ d[17] ^ c[22] ^ c[14] ^ d[42] ^ d[34] ^ d[0] ^ c[31] ^ d[11] ^ c[15] ^ c[9] ^ c[2] ^ d[27] ^ d[20] ^ d[9] ^ d[2] ^ c[17] ^ c[4] ^ d[29] ^ d[22] ^ d[14] ^ c[11] ^ d[46] ^ d[38] ;
+o[18] = d[23] ^ d[15] ^ c[12] ^ d[40] ^ d[32] ^ d[24] ^ d[16] ^ c[21] ^ c[7] ^ d[41] ^ d[33] ^ c[30] ^ d[10] ^ c[8] ^ d[26] ^ c[23] ^ c[15] ^ d[8] ^ d[1] ^ d[19] ^ c[16] ^ c[3] ^ d[28] ^ d[21] ^ d[13] ^ c[10] ^ d[45] ^ d[37] ^ c[18] ^ c[5] ;
+o[19] = d[23] ^ d[15] ^ c[19] ^ c[6] ^ d[39] ^ d[40] ^ d[32] ^ c[13] ^ c[0] ^ d[25] ^ c[22] ^ c[8] ^ d[7] ^ d[0] ^ c[31] ^ d[18] ^ c[9] ^ d[27] ^ d[20] ^ c[24] ^ d[12] ^ c[16] ^ d[44] ^ d[9] ^ d[36] ^ c[17] ^ c[4] ^ d[22] ^ d[14] ^ c[11] ^ d[31] ;
+o[20] = c[20] ^ c[12] ^ d[39] ^ d[24] ^ c[7] ^ c[0] ^ d[6] ^ d[17] ^ c[14] ^ c[1] ^ d[26] ^ d[11] ^ c[23] ^ c[9] ^ d[43] ^ d[8] ^ d[35] ^ d[19] ^ d[21] ^ d[13] ^ c[25] ^ c[17] ^ c[10] ^ d[30] ^ d[22] ^ d[14] ^ c[18] ^ c[5] ^ d[38] ^ d[31] ;
+o[21] = d[23] ^ c[19] ^ c[6] ^ d[5] ^ d[16] ^ c[21] ^ c[13] ^ d[25] ^ d[10] ^ c[8] ^ d[42] ^ c[1] ^ d[7] ^ d[34] ^ d[18] ^ c[15] ^ c[2] ^ d[20] ^ d[12] ^ c[24] ^ d[21] ^ d[13] ^ c[10] ^ d[37] ^ d[30] ^ d[29] ^ c[26] ^ c[18] ^ c[11] ^ d[38] ;
+o[22] = d[23] ^ c[27] ^ c[20] ^ c[19] ^ d[47] ^ d[24] ^ c[28] ^ d[16] ^ c[21] ^ c[13] ^ c[7] ^ c[0] ^ d[6] ^ d[33] ^ c[29] ^ d[10] ^ c[22] ^ c[8] ^ d[0] ^ c[31] ^ d[18] ^ d[11] ^ c[15] ^ c[2] ^ d[35] ^ d[20] ^ d[12] ^ c[3] ^ d[9] ^ d[36] ^ d[2] ^ d[28] ^ d[21] ^ d[13] ^ c[25] ^ c[10] ^ d[29] ^ d[3] ^ c[18] ^ c[11] ^ d[38] ^ d[4] ^ d[31] ;
+o[23] = c[20] ^ c[19] ^ d[47] ^ d[5] ^ d[32] ^ d[16] ^ c[13] ^ d[41] ^ c[0] ^ c[30] ^ c[22] ^ c[1] ^ d[34] ^ d[0] ^ c[31] ^ d[18] ^ d[11] ^ c[23] ^ c[15] ^ d[8] ^ d[1] ^ d[27] ^ d[20] ^ d[12] ^ c[3] ^ d[9] ^ d[28] ^ d[21] ^ d[13] ^ c[10] ^ c[4] ^ d[30] ^ c[26] ^ c[18] ^ c[11] ^ d[46] ^ d[38] ^ d[31] ;
+o[24] = c[27] ^ d[15] ^ c[19] ^ c[20] ^ c[12] ^ d[40] ^ c[21] ^ c[0] ^ d[33] ^ d[17] ^ d[10] ^ c[14] ^ c[1] ^ d[7] ^ d[0] ^ d[26] ^ c[31] ^ c[23] ^ d[11] ^ c[2] ^ d[8] ^ d[27] ^ d[19] ^ d[20] ^ c[24] ^ d[12] ^ c[16] ^ c[4] ^ d[45] ^ d[37] ^ d[30] ^ d[29] ^ c[11] ^ d[46] ^ c[5] ^ d[4] ^ d[31] ;
+o[25] = c[20] ^ c[12] ^ c[6] ^ d[39] ^ d[32] ^ c[28] ^ d[16] ^ c[21] ^ c[13] ^ d[6] ^ d[25] ^ c[22] ^ d[10] ^ c[1] ^ d[7] ^ d[26] ^ d[18] ^ d[11] ^ c[15] ^ c[2] ^ d[19] ^ c[24] ^ d[44] ^ c[3] ^ d[9] ^ d[36] ^ d[28] ^ c[25] ^ c[17] ^ d[45] ^ d[3] ^ d[30] ^ d[29] ^ d[14] ^ c[5] ;
+o[26] = d[23] ^ c[12] ^ d[47] ^ c[6] ^ d[5] ^ d[24] ^ c[28] ^ d[16] ^ c[7] ^ d[41] ^ d[6] ^ d[25] ^ c[22] ^ c[8] ^ d[0] ^ c[31] ^ c[23] ^ c[15] ^ c[9] ^ c[2] ^ d[43] ^ d[8] ^ d[27] ^ d[19] ^ c[3] ^ d[44] ^ d[9] ^ d[28] ^ d[21] ^ c[25] ^ c[10] ^ c[4] ^ d[37] ^ d[29] ^ d[3] ^ d[22] ^ c[26] ;
+o[27] = d[23] ^ c[27] ^ d[15] ^ d[40] ^ d[5] ^ d[24] ^ c[13] ^ c[7] ^ c[29] ^ c[8] ^ d[42] ^ d[7] ^ d[26] ^ d[18] ^ c[23] ^ c[9] ^ d[43] ^ d[8] ^ d[27] ^ d[20] ^ c[24] ^ c[16] ^ c[3] ^ d[36] ^ d[28] ^ d[2] ^ d[21] ^ c[10] ^ c[4] ^ d[22] ^ c[26] ^ c[11] ^ d[46] ^ c[5] ^ d[4] ;
+o[28] = d[23] ^ c[27] ^ c[12] ^ c[6] ^ d[39] ^ c[28] ^ d[41] ^ d[6] ^ d[25] ^ c[30] ^ d[17] ^ c[14] ^ c[8] ^ d[42] ^ d[7] ^ d[26] ^ c[9] ^ d[35] ^ d[27] ^ d[1] ^ d[20] ^ d[19] ^ c[24] ^ d[21] ^ c[25] ^ c[17] ^ c[10] ^ d[45] ^ c[4] ^ d[3] ^ d[22] ^ d[14] ^ c[11] ^ c[5] ^ d[4] ;
+o[29] = c[12] ^ c[6] ^ d[40] ^ d[5] ^ d[24] ^ d[16] ^ c[28] ^ c[13] ^ c[7] ^ d[41] ^ d[6] ^ d[25] ^ c[29] ^ d[34] ^ d[26] ^ d[0] ^ c[31] ^ d[18] ^ c[15] ^ c[9] ^ d[20] ^ d[19] ^ d[44] ^ d[2] ^ d[21] ^ c[25] ^ d[13] ^ c[10] ^ d[3] ^ d[22] ^ c[26] ^ c[18] ^ c[11] ^ c[5] ^ d[38] ;
+o[30] = d[23] ^ c[27] ^ d[15] ^ c[19] ^ c[12] ^ c[6] ^ d[40] ^ d[39] ^ d[5] ^ d[24] ^ c[13] ^ c[7] ^ d[33] ^ d[25] ^ c[30] ^ c[29] ^ d[17] ^ c[14] ^ c[8] ^ d[18] ^ d[43] ^ d[1] ^ d[19] ^ d[20] ^ d[12] ^ c[16] ^ d[2] ^ d[21] ^ c[10] ^ d[37] ^ c[26] ^ c[11] ^ d[4] ;
+o[31] = c[17] ^ d[23] ^ c[27] ^ c[9] ^ c[20] ^ c[30] ^ d[17] ^ c[12] ^ d[1] ^ d[20] ^ c[14] ^ d[19] ^ d[3] ^ d[22] ^ d[39] ^ d[14] ^ c[8] ^ d[32] ^ d[42] ^ d[24] ^ c[28] ^ c[11] ^ d[16] ^ d[0] ^ d[36] ^ d[18] ^ c[31] ^ c[13] ^ d[11] ^ c[15] ^ d[38] ^ d[4] ^ c[7] ;
+ crc6B = o;
+ end
+ endfunction // crc6B
+
+ ////////////////////////////////////////////////
+ // crc5B
+ ////////////////////////////////////////////////
+ function [31:0] crc5B (
+ input [31:0] c,
+ input [39:0] d
+ );
+ reg [31:0] o;
+ begin
+o[0] = c[17] ^ d[23] ^ d[33] ^ d[15] ^ c[20] ^ c[2] ^ c[29] ^ d[8] ^ d[27] ^ c[22] ^ c[4] ^ d[10] ^ c[24] ^ d[30] ^ d[29] ^ d[39] ^ c[16] ^ d[5] ^ c[26] ^ d[14] ^ c[8] ^ c[18] ^ c[1] ^ d[7] ^ c[21] ^ d[9] ^ d[2] ^ d[11] ^ c[23] ^ d[13] ;
+o[1] = d[23] ^ d[33] ^ d[15] ^ d[6] ^ c[27] ^ c[9] ^ c[19] ^ c[20] ^ c[29] ^ c[30] ^ d[27] ^ d[1] ^ c[4] ^ d[12] ^ d[30] ^ d[39] ^ c[16] ^ d[22] ^ d[5] ^ c[26] ^ c[8] ^ d[32] ^ c[1] ^ d[26] ^ c[3] ^ d[2] ^ d[11] ^ c[5] ^ d[28] ^ d[38] ^ c[25] ^ d[4] ;
+o[2] = d[23] ^ c[0] ^ d[33] ^ d[15] ^ c[10] ^ c[27] ^ c[9] ^ d[25] ^ c[29] ^ c[30] ^ d[8] ^ c[22] ^ d[1] ^ d[37] ^ d[3] ^ c[24] ^ d[30] ^ c[6] ^ d[39] ^ c[16] ^ d[22] ^ c[8] ^ d[32] ^ c[18] ^ c[1] ^ c[28] ^ d[7] ^ d[0] ^ d[26] ^ d[9] ^ c[31] ^ d[2] ^ c[23] ^ c[5] ^ d[21] ^ d[38] ^ d[4] ^ d[13] ^ d[31] ;
+o[3] = c[17] ^ c[0] ^ d[6] ^ c[9] ^ c[10] ^ c[19] ^ c[2] ^ d[25] ^ d[8] ^ c[29] ^ c[30] ^ d[1] ^ d[20] ^ d[37] ^ c[24] ^ d[3] ^ d[12] ^ d[29] ^ c[6] ^ d[30] ^ d[22] ^ d[32] ^ d[14] ^ d[24] ^ c[1] ^ c[11] ^ d[7] ^ c[28] ^ d[0] ^ c[31] ^ d[36] ^ d[2] ^ c[23] ^ d[38] ^ d[21] ^ c[25] ^ d[31] ^ c[7] ;
+o[4] = d[15] ^ c[12] ^ d[39] ^ d[24] ^ c[21] ^ c[7] ^ c[0] ^ d[33] ^ d[6] ^ c[30] ^ c[22] ^ d[10] ^ d[0] ^ c[31] ^ c[23] ^ d[8] ^ d[35] ^ d[27] ^ d[1] ^ d[20] ^ d[19] ^ c[16] ^ c[3] ^ d[9] ^ d[36] ^ d[28] ^ d[21] ^ c[25] ^ c[17] ^ c[10] ^ c[4] ^ d[37] ^ d[14] ^ c[11] ^ d[31] ;
+o[5] = d[15] ^ c[20] ^ c[12] ^ d[39] ^ d[32] ^ c[21] ^ c[13] ^ d[33] ^ c[29] ^ d[10] ^ d[34] ^ d[0] ^ d[26] ^ c[31] ^ d[18] ^ d[11] ^ c[2] ^ d[35] ^ d[20] ^ d[19] ^ c[16] ^ d[36] ^ d[2] ^ d[29] ^ c[11] ^ c[5] ^ d[38] ;
+o[6] = c[12] ^ c[6] ^ d[32] ^ c[21] ^ c[13] ^ c[0] ^ d[33] ^ d[25] ^ c[30] ^ d[17] ^ d[10] ^ c[22] ^ c[14] ^ d[34] ^ d[18] ^ d[35] ^ d[1] ^ d[19] ^ c[3] ^ d[9] ^ d[28] ^ c[17] ^ d[37] ^ d[14] ^ d[38] ^ d[31] ;
+o[7] = d[23] ^ d[15] ^ c[20] ^ d[39] ^ d[5] ^ d[32] ^ d[24] ^ d[16] ^ c[21] ^ c[13] ^ c[7] ^ c[0] ^ c[29] ^ d[17] ^ d[10] ^ c[14] ^ c[8] ^ d[7] ^ d[34] ^ d[0] ^ c[31] ^ d[18] ^ d[11] ^ c[15] ^ c[2] ^ c[24] ^ c[16] ^ d[36] ^ d[2] ^ c[17] ^ d[37] ^ d[29] ^ c[26] ^ d[14] ^ d[31] ;
+o[8] = c[0] ^ d[6] ^ c[27] ^ c[9] ^ c[20] ^ c[2] ^ c[29] ^ c[30] ^ d[8] ^ d[17] ^ d[35] ^ d[27] ^ d[1] ^ c[4] ^ c[14] ^ c[24] ^ d[29] ^ d[39] ^ d[22] ^ d[5] ^ c[26] ^ d[7] ^ d[16] ^ c[3] ^ d[36] ^ d[2] ^ d[11] ^ c[23] ^ d[28] ^ d[38] ^ c[15] ^ c[25] ^ d[4] ^ d[31] ;
+o[9] = c[27] ^ d[6] ^ d[15] ^ c[10] ^ c[30] ^ d[35] ^ d[1] ^ d[10] ^ d[27] ^ c[4] ^ d[37] ^ c[24] ^ d[3] ^ d[30] ^ c[16] ^ d[5] ^ c[26] ^ c[1] ^ d[7] ^ d[16] ^ c[28] ^ d[34] ^ d[26] ^ d[0] ^ c[21] ^ c[3] ^ c[31] ^ c[5] ^ d[28] ^ d[38] ^ c[15] ^ d[21] ^ d[4] ^ c[25] ;
+o[10] = d[23] ^ c[27] ^ c[20] ^ c[6] ^ d[39] ^ c[28] ^ c[21] ^ d[6] ^ d[25] ^ d[10] ^ c[8] ^ c[1] ^ d[7] ^ d[34] ^ d[0] ^ d[26] ^ c[31] ^ d[11] ^ c[23] ^ d[8] ^ d[20] ^ c[24] ^ d[36] ^ c[25] ^ d[13] ^ d[37] ^ d[3] ^ d[30] ^ c[18] ^ c[11] ^ c[5] ^ d[4] ;
+o[11] = c[17] ^ d[23] ^ d[15] ^ d[6] ^ c[9] ^ c[19] ^ c[20] ^ d[25] ^ d[8] ^ c[12] ^ d[35] ^ d[27] ^ c[4] ^ d[19] ^ d[3] ^ d[12] ^ d[30] ^ c[6] ^ d[39] ^ c[16] ^ d[22] ^ d[14] ^ c[8] ^ d[24] ^ c[18] ^ c[1] ^ c[28] ^ d[36] ^ d[11] ^ c[23] ^ d[38] ^ c[25] ^ c[7] ^ d[13] ;
+o[12] = d[33] ^ d[15] ^ c[10] ^ c[9] ^ c[19] ^ d[8] ^ d[35] ^ d[27] ^ c[22] ^ c[4] ^ d[37] ^ d[12] ^ d[30] ^ d[39] ^ c[16] ^ d[22] ^ d[24] ^ c[1] ^ d[34] ^ d[26] ^ d[9] ^ d[18] ^ c[13] ^ c[23] ^ c[5] ^ d[21] ^ d[38] ^ c[7] ;
+o[13] = c[17] ^ d[23] ^ c[10] ^ d[33] ^ c[20] ^ c[2] ^ d[25] ^ d[8] ^ d[17] ^ d[20] ^ c[14] ^ d[37] ^ c[24] ^ d[29] ^ c[6] ^ d[32] ^ d[14] ^ c[8] ^ c[11] ^ d[7] ^ d[34] ^ d[26] ^ d[36] ^ c[23] ^ d[11] ^ c[5] ^ d[38] ^ d[21] ;
+o[14] = c[0] ^ d[6] ^ c[9] ^ d[33] ^ d[25] ^ c[12] ^ d[35] ^ d[10] ^ d[37] ^ d[19] ^ d[20] ^ c[24] ^ c[6] ^ d[22] ^ d[32] ^ c[18] ^ d[24] ^ d[7] ^ d[16] ^ c[11] ^ c[21] ^ c[3] ^ d[36] ^ d[28] ^ c[15] ^ d[31] ^ d[13] ^ c[25] ^ c[7] ;
+o[15] = d[23] ^ c[0] ^ d[6] ^ d[15] ^ c[10] ^ c[19] ^ d[35] ^ c[12] ^ c[22] ^ d[27] ^ c[4] ^ d[19] ^ d[30] ^ d[12] ^ c[16] ^ d[5] ^ c[26] ^ c[8] ^ d[32] ^ d[24] ^ c[1] ^ d[34] ^ d[36] ^ d[18] ^ d[9] ^ c[13] ^ d[21] ^ c[25] ^ c[7] ^ d[31] ;
+o[16] = d[15] ^ c[27] ^ d[39] ^ c[21] ^ c[13] ^ c[0] ^ c[29] ^ d[17] ^ c[22] ^ d[10] ^ c[14] ^ d[7] ^ d[34] ^ d[26] ^ d[18] ^ c[9] ^ d[35] ^ d[27] ^ d[20] ^ c[24] ^ c[16] ^ d[9] ^ d[2] ^ d[13] ^ c[4] ^ d[22] ^ c[18] ^ c[11] ^ c[5] ^ d[4] ^ d[31] ;
+o[17] = c[17] ^ d[6] ^ d[33] ^ c[10] ^ c[19] ^ d[25] ^ d[8] ^ c[30] ^ d[17] ^ c[12] ^ d[1] ^ c[22] ^ c[14] ^ d[19] ^ d[3] ^ d[12] ^ c[6] ^ d[30] ^ d[14] ^ c[1] ^ d[16] ^ c[28] ^ d[34] ^ d[26] ^ d[9] ^ c[23] ^ c[5] ^ d[38] ^ c[15] ^ d[21] ^ c[25] ;
+o[18] = d[15] ^ d[33] ^ d[25] ^ c[20] ^ c[2] ^ c[29] ^ d[8] ^ d[37] ^ d[20] ^ c[24] ^ c[6] ^ d[29] ^ c[16] ^ d[5] ^ c[26] ^ d[32] ^ c[18] ^ d[24] ^ d[7] ^ d[16] ^ c[11] ^ d[0] ^ c[31] ^ d[18] ^ c[13] ^ d[2] ^ d[11] ^ c[23] ^ c[15] ^ d[13] ^ c[7] ;
+o[19] = c[17] ^ d[23] ^ c[0] ^ d[6] ^ d[15] ^ c[27] ^ c[19] ^ c[30] ^ d[17] ^ c[12] ^ d[1] ^ d[10] ^ c[14] ^ d[19] ^ d[12] ^ c[24] ^ c[16] ^ d[14] ^ d[32] ^ c[8] ^ d[24] ^ d[7] ^ c[21] ^ c[3] ^ d[36] ^ d[28] ^ c[25] ^ d[4] ^ c[7] ^ d[31] ;
+o[20] = d[23] ^ c[17] ^ c[0] ^ d[6] ^ c[9] ^ c[20] ^ d[35] ^ c[22] ^ d[27] ^ c[4] ^ d[3] ^ d[30] ^ d[22] ^ d[5] ^ c[26] ^ d[14] ^ c[8] ^ c[18] ^ c[1] ^ c[28] ^ d[16] ^ d[0] ^ c[31] ^ d[9] ^ d[18] ^ c[13] ^ d[11] ^ c[15] ^ d[13] ^ c[25] ^ d[31] ;
+o[21] = c[27] ^ c[9] ^ d[15] ^ c[10] ^ c[19] ^ c[2] ^ c[29] ^ d[8] ^ d[17] ^ d[10] ^ c[14] ^ d[12] ^ d[30] ^ d[29] ^ d[22] ^ c[16] ^ d[5] ^ c[26] ^ c[18] ^ c[1] ^ d[34] ^ c[21] ^ d[26] ^ d[2] ^ c[23] ^ c[5] ^ d[21] ^ d[4] ^ d[13] ;
+o[22] = d[23] ^ d[15] ^ c[10] ^ c[27] ^ c[19] ^ d[25] ^ c[29] ^ c[30] ^ d[8] ^ d[27] ^ d[1] ^ c[4] ^ d[10] ^ d[20] ^ d[3] ^ d[12] ^ d[30] ^ c[6] ^ d[39] ^ c[16] ^ d[5] ^ c[26] ^ c[8] ^ c[18] ^ c[1] ^ c[28] ^ c[11] ^ d[16] ^ c[21] ^ c[3] ^ d[2] ^ c[23] ^ d[28] ^ d[21] ^ c[15] ^ d[4] ^ d[13] ;
+o[23] = d[23] ^ d[33] ^ c[27] ^ c[9] ^ c[19] ^ c[30] ^ d[8] ^ c[12] ^ d[1] ^ d[10] ^ d[20] ^ d[19] ^ d[3] ^ d[12] ^ d[30] ^ d[39] ^ d[22] ^ d[5] ^ c[26] ^ c[8] ^ d[24] ^ c[18] ^ c[1] ^ c[28] ^ c[11] ^ d[0] ^ c[21] ^ d[26] ^ c[31] ^ c[23] ^ c[5] ^ d[38] ^ d[4] ^ c[7] ^ d[13] ;
+o[24] = d[23] ^ c[27] ^ c[9] ^ c[10] ^ c[20] ^ c[19] ^ c[2] ^ d[25] ^ c[29] ^ c[12] ^ c[22] ^ d[19] ^ d[37] ^ c[24] ^ d[3] ^ d[12] ^ d[29] ^ c[6] ^ d[22] ^ d[32] ^ c[8] ^ d[7] ^ c[28] ^ d[0] ^ c[31] ^ d[9] ^ d[18] ^ c[13] ^ d[2] ^ d[11] ^ d[38] ^ d[21] ^ d[4] ;
+o[25] = c[0] ^ d[6] ^ c[9] ^ c[10] ^ c[20] ^ c[30] ^ c[29] ^ d[8] ^ d[17] ^ d[1] ^ d[10] ^ d[37] ^ c[14] ^ d[20] ^ d[3] ^ d[22] ^ d[24] ^ c[28] ^ c[11] ^ c[21] ^ c[3] ^ d[18] ^ c[13] ^ d[36] ^ d[2] ^ d[11] ^ d[28] ^ c[23] ^ d[21] ^ d[31] ^ c[25] ^ c[7] ;
+o[26] = c[17] ^ d[33] ^ d[15] ^ c[10] ^ c[20] ^ c[2] ^ c[30] ^ d[8] ^ d[17] ^ c[12] ^ d[35] ^ d[1] ^ c[14] ^ d[20] ^ d[19] ^ d[29] ^ d[39] ^ c[16] ^ d[14] ^ c[18] ^ c[11] ^ d[16] ^ d[0] ^ c[31] ^ d[36] ^ d[11] ^ c[23] ^ d[21] ^ c[15] ^ d[13] ;
+o[27] = c[17] ^ d[15] ^ c[19] ^ c[12] ^ d[35] ^ d[10] ^ d[20] ^ d[19] ^ c[24] ^ d[12] ^ c[16] ^ d[32] ^ d[14] ^ c[18] ^ c[11] ^ d[7] ^ d[16] ^ d[34] ^ d[0] ^ c[21] ^ c[3] ^ c[31] ^ d[18] ^ c[13] ^ d[28] ^ d[38] ^ c[15] ^ d[13] ;
+o[28] = c[0] ^ c[17] ^ d[6] ^ d[15] ^ d[33] ^ c[19] ^ c[20] ^ c[12] ^ d[17] ^ c[22] ^ d[27] ^ c[4] ^ d[37] ^ d[19] ^ c[14] ^ d[12] ^ c[16] ^ d[14] ^ c[18] ^ d[34] ^ d[9] ^ d[18] ^ c[13] ^ d[11] ^ d[31] ^ d[13] ^ c[25] ;
+o[29] = c[17] ^ d[33] ^ c[19] ^ c[20] ^ d[8] ^ d[17] ^ d[10] ^ c[14] ^ d[30] ^ d[12] ^ d[5] ^ c[26] ^ d[14] ^ d[32] ^ c[1] ^ c[18] ^ d[16] ^ c[21] ^ d[26] ^ d[36] ^ d[18] ^ c[13] ^ c[23] ^ d[11] ^ c[5] ^ c[15] ^ d[13] ;
+o[30] = c[0] ^ c[27] ^ d[15] ^ c[20] ^ c[2] ^ d[25] ^ c[19] ^ d[35] ^ d[17] ^ d[10] ^ c[22] ^ c[14] ^ d[29] ^ c[24] ^ c[6] ^ d[12] ^ c[16] ^ d[32] ^ c[18] ^ d[7] ^ d[16] ^ c[21] ^ d[9] ^ d[11] ^ c[15] ^ d[4] ^ d[13] ^ d[31] ;
+o[31] = c[17] ^ c[0] ^ d[6] ^ d[15] ^ c[19] ^ c[20] ^ d[8] ^ d[10] ^ c[22] ^ d[3] ^ d[12] ^ d[30] ^ c[16] ^ d[14] ^ d[24] ^ c[1] ^ d[34] ^ d[16] ^ c[28] ^ c[21] ^ c[3] ^ d[9] ^ d[28] ^ c[23] ^ d[11] ^ c[15] ^ c[25] ^ c[7] ^ d[31] ;
+ crc5B = o;
+ end
+ endfunction // crc5B
+
+ ////////////////////////////////////////////////
+ // crc4B
+ ////////////////////////////////////////////////
+ function [31:0] crc4B (
+ input [31:0] c,
+ input [31:0] d
+ );
+ reg [31:0] o;
+ begin
+o[0] = c[0] ^ d[6] ^ d[15] ^ c[9] ^ c[10] ^ d[25] ^ c[30] ^ c[12] ^ c[29] ^ d[1] ^ d[19] ^ c[24] ^ d[3] ^ c[6] ^ c[16] ^ d[22] ^ d[5] ^ c[26] ^ d[7] ^ c[28] ^ d[0] ^ c[31] ^ d[2] ^ d[21] ^ d[31] ^ c[25] ;
+o[1] = c[0] ^ c[17] ^ c[27] ^ d[15] ^ c[9] ^ d[25] ^ c[12] ^ d[19] ^ d[20] ^ c[24] ^ d[3] ^ c[6] ^ d[30] ^ c[16] ^ d[22] ^ d[14] ^ d[24] ^ c[1] ^ d[7] ^ c[28] ^ c[11] ^ d[18] ^ c[13] ^ d[31] ^ d[4] ^ c[7] ;
+o[2] = c[0] ^ c[17] ^ d[23] ^ d[15] ^ c[9] ^ d[25] ^ c[2] ^ c[30] ^ d[17] ^ d[1] ^ c[14] ^ c[24] ^ c[6] ^ d[30] ^ d[29] ^ c[16] ^ d[22] ^ d[5] ^ c[26] ^ d[14] ^ c[8] ^ c[18] ^ d[24] ^ c[1] ^ d[7] ^ d[0] ^ c[31] ^ d[18] ^ c[13] ^ d[31] ^ d[13] ^ c[7] ;
+o[3] = c[17] ^ d[23] ^ d[6] ^ c[27] ^ c[10] ^ c[9] ^ c[19] ^ c[2] ^ d[17] ^ c[14] ^ d[30] ^ d[12] ^ d[29] ^ d[22] ^ d[14] ^ c[8] ^ d[24] ^ c[1] ^ c[18] ^ d[16] ^ d[0] ^ c[3] ^ c[31] ^ d[28] ^ d[21] ^ c[15] ^ c[25] ^ d[4] ^ c[7] ^ d[13] ;
+o[4] = c[0] ^ d[23] ^ d[6] ^ d[25] ^ c[19] ^ c[20] ^ c[2] ^ c[30] ^ c[12] ^ c[29] ^ d[1] ^ d[27] ^ c[4] ^ d[19] ^ d[20] ^ c[24] ^ c[6] ^ d[12] ^ d[29] ^ c[8] ^ c[18] ^ d[7] ^ d[16] ^ c[11] ^ d[0] ^ c[3] ^ c[31] ^ d[2] ^ d[11] ^ d[28] ^ c[15] ^ d[31] ^ d[13] ^ c[25] ;
+o[5] = c[0] ^ c[10] ^ d[25] ^ c[19] ^ c[20] ^ c[29] ^ d[10] ^ d[27] ^ c[4] ^ c[24] ^ d[3] ^ c[6] ^ d[12] ^ d[30] ^ d[24] ^ c[1] ^ d[7] ^ c[28] ^ c[21] ^ c[3] ^ d[26] ^ d[18] ^ c[13] ^ d[2] ^ d[11] ^ d[28] ^ c[5] ^ d[21] ^ d[31] ^ c[7] ;
+o[6] = d[23] ^ d[6] ^ c[20] ^ c[2] ^ d[25] ^ c[29] ^ c[30] ^ d[17] ^ c[22] ^ d[1] ^ d[10] ^ d[27] ^ c[4] ^ d[20] ^ c[14] ^ d[30] ^ d[29] ^ c[6] ^ c[8] ^ d[24] ^ c[1] ^ c[11] ^ c[21] ^ d[26] ^ d[9] ^ d[2] ^ d[11] ^ c[5] ^ c[25] ^ c[7] ;
+o[7] = c[0] ^ d[23] ^ d[6] ^ d[15] ^ c[10] ^ c[2] ^ c[29] ^ d[8] ^ d[10] ^ c[22] ^ c[24] ^ d[3] ^ d[29] ^ c[16] ^ c[8] ^ d[24] ^ d[7] ^ c[28] ^ d[16] ^ c[21] ^ c[3] ^ d[26] ^ d[9] ^ d[2] ^ c[23] ^ d[28] ^ c[5] ^ c[15] ^ d[21] ^ d[31] ^ c[25] ^ c[7] ;
+o[8] = c[0] ^ c[17] ^ d[23] ^ c[10] ^ c[12] ^ d[8] ^ c[22] ^ d[27] ^ c[4] ^ d[19] ^ d[20] ^ d[3] ^ d[30] ^ d[14] ^ c[8] ^ c[1] ^ c[28] ^ c[11] ^ d[0] ^ c[3] ^ c[31] ^ d[9] ^ c[23] ^ d[28] ^ d[21] ^ d[31] ;
+o[9] = c[9] ^ c[2] ^ c[29] ^ d[8] ^ c[12] ^ d[27] ^ c[4] ^ d[20] ^ d[19] ^ d[30] ^ d[29] ^ c[24] ^ d[22] ^ c[1] ^ c[18] ^ c[11] ^ d[7] ^ d[26] ^ d[18] ^ c[13] ^ d[2] ^ c[23] ^ c[5] ^ d[13] ;
+o[10] = c[0] ^ d[15] ^ c[9] ^ c[19] ^ c[2] ^ c[29] ^ d[17] ^ c[14] ^ d[3] ^ d[12] ^ d[29] ^ c[16] ^ d[22] ^ d[5] ^ c[26] ^ c[28] ^ d[0] ^ c[3] ^ d[26] ^ c[31] ^ d[18] ^ c[13] ^ d[2] ^ d[28] ^ c[5] ^ d[31] ;
+o[11] = c[0] ^ c[17] ^ c[27] ^ d[6] ^ d[15] ^ c[9] ^ c[20] ^ c[12] ^ d[17] ^ d[27] ^ c[4] ^ d[19] ^ c[14] ^ c[24] ^ d[3] ^ d[30] ^ c[16] ^ d[22] ^ d[5] ^ c[26] ^ d[14] ^ c[1] ^ d[7] ^ c[28] ^ d[16] ^ d[0] ^ c[3] ^ c[31] ^ d[11] ^ d[28] ^ c[15] ^ d[31] ^ d[4] ^ c[25] ;
+o[12] = c[0] ^ c[17] ^ c[27] ^ c[9] ^ d[25] ^ c[2] ^ c[30] ^ c[12] ^ d[1] ^ d[10] ^ d[27] ^ c[4] ^ d[19] ^ c[24] ^ c[6] ^ d[30] ^ d[29] ^ d[22] ^ d[14] ^ c[18] ^ c[1] ^ d[7] ^ d[16] ^ d[0] ^ c[21] ^ d[26] ^ c[31] ^ d[18] ^ c[13] ^ c[5] ^ c[15] ^ d[31] ^ d[13] ^ d[4] ;
+o[13] = d[6] ^ d[15] ^ c[10] ^ c[19] ^ c[2] ^ d[25] ^ d[17] ^ c[22] ^ c[14] ^ d[30] ^ d[12] ^ d[3] ^ d[29] ^ c[6] ^ c[16] ^ d[24] ^ c[1] ^ c[18] ^ c[28] ^ d[0] ^ c[3] ^ d[26] ^ d[18] ^ c[31] ^ d[9] ^ c[13] ^ d[28] ^ c[5] ^ d[21] ^ c[25] ^ c[7] ^ d[13] ;
+o[14] = d[23] ^ c[17] ^ c[20] ^ c[2] ^ c[19] ^ d[25] ^ d[17] ^ c[29] ^ d[8] ^ d[27] ^ c[4] ^ c[14] ^ d[20] ^ d[29] ^ d[12] ^ c[6] ^ d[5] ^ c[26] ^ d[14] ^ c[8] ^ d[24] ^ c[11] ^ d[16] ^ c[3] ^ d[11] ^ d[2] ^ c[23] ^ d[28] ^ c[15] ^ c[7] ;
+o[15] = d[23] ^ c[27] ^ c[9] ^ d[15] ^ c[20] ^ c[30] ^ c[12] ^ d[10] ^ d[1] ^ d[27] ^ c[4] ^ d[19] ^ c[24] ^ d[22] ^ c[16] ^ c[8] ^ c[18] ^ d[24] ^ d[16] ^ d[7] ^ c[21] ^ c[3] ^ d[26] ^ d[28] ^ d[11] ^ c[5] ^ c[15] ^ d[4] ^ d[13] ^ c[7] ;
+o[16] = c[0] ^ c[17] ^ d[23] ^ c[19] ^ c[30] ^ c[12] ^ c[29] ^ d[1] ^ d[10] ^ c[22] ^ d[27] ^ c[4] ^ d[19] ^ c[24] ^ d[12] ^ d[5] ^ c[26] ^ d[14] ^ c[8] ^ d[7] ^ c[21] ^ d[26] ^ d[9] ^ d[18] ^ c[13] ^ d[2] ^ c[5] ^ d[31] ;
+o[17] = d[6] ^ c[27] ^ c[9] ^ c[20] ^ d[25] ^ d[8] ^ c[30] ^ d[17] ^ c[22] ^ d[1] ^ c[14] ^ d[30] ^ c[6] ^ d[22] ^ c[1] ^ c[18] ^ d[0] ^ d[26] ^ d[18] ^ c[31] ^ d[9] ^ c[13] ^ c[23] ^ d[11] ^ c[5] ^ c[25] ^ d[4] ^ d[13] ;
+o[18] = c[10] ^ c[2] ^ d[25] ^ c[19] ^ d[17] ^ d[8] ^ d[10] ^ c[14] ^ d[29] ^ c[24] ^ d[3] ^ c[6] ^ d[12] ^ d[5] ^ c[26] ^ d[24] ^ d[7] ^ c[28] ^ d[16] ^ d[0] ^ c[21] ^ c[31] ^ c[23] ^ c[15] ^ d[21] ^ c[7] ;
+o[19] = d[23] ^ c[27] ^ d[6] ^ d[15] ^ c[20] ^ c[29] ^ c[22] ^ d[20] ^ c[24] ^ c[16] ^ c[8] ^ d[24] ^ d[16] ^ d[7] ^ c[11] ^ c[3] ^ d[9] ^ d[28] ^ d[2] ^ d[11] ^ c[15] ^ d[4] ^ c[25] ^ c[7] ;
+o[20] = d[23] ^ c[17] ^ d[15] ^ d[6] ^ c[9] ^ c[30] ^ d[8] ^ c[12] ^ d[27] ^ d[1] ^ c[4] ^ d[10] ^ d[19] ^ d[3] ^ c[16] ^ d[22] ^ d[5] ^ c[26] ^ d[14] ^ c[8] ^ c[28] ^ c[21] ^ c[23] ^ c[25] ;
+o[21] = c[17] ^ c[27] ^ c[9] ^ c[10] ^ c[29] ^ c[22] ^ c[24] ^ d[22] ^ d[14] ^ d[5] ^ c[26] ^ c[18] ^ d[7] ^ d[26] ^ d[0] ^ c[31] ^ d[9] ^ d[18] ^ c[13] ^ d[2] ^ c[5] ^ d[21] ^ d[4] ^ d[13] ;
+o[22] = c[0] ^ c[27] ^ d[15] ^ c[9] ^ c[19] ^ c[12] ^ c[29] ^ d[8] ^ d[17] ^ d[19] ^ d[20] ^ c[14] ^ c[24] ^ d[12] ^ c[16] ^ d[22] ^ d[5] ^ c[26] ^ c[18] ^ d[7] ^ c[11] ^ d[0] ^ c[31] ^ d[2] ^ c[23] ^ d[31] ^ d[13] ^ d[4] ;
+o[23] = c[0] ^ c[17] ^ c[27] ^ d[15] ^ c[9] ^ d[25] ^ c[19] ^ c[20] ^ c[29] ^ c[6] ^ d[12] ^ d[30] ^ c[16] ^ d[22] ^ d[5] ^ c[26] ^ d[14] ^ c[1] ^ d[16] ^ d[0] ^ c[31] ^ d[18] ^ c[13] ^ d[2] ^ d[11] ^ c[15] ^ d[31] ^ d[4] ;
+o[24] = c[17] ^ d[15] ^ c[27] ^ c[10] ^ c[20] ^ c[2] ^ c[30] ^ d[17] ^ d[1] ^ d[10] ^ c[14] ^ d[30] ^ d[3] ^ d[29] ^ c[16] ^ d[14] ^ d[24] ^ c[1] ^ c[18] ^ c[28] ^ c[21] ^ d[11] ^ d[21] ^ d[4] ^ c[7] ^ d[13] ;
+o[25] = d[23] ^ c[17] ^ c[2] ^ c[19] ^ c[29] ^ d[10] ^ c[22] ^ d[20] ^ d[29] ^ d[3] ^ d[12] ^ d[14] ^ c[8] ^ c[18] ^ c[28] ^ c[11] ^ d[16] ^ d[0] ^ c[21] ^ c[3] ^ c[31] ^ d[9] ^ d[2] ^ d[28] ^ c[15] ^ d[13] ;
+o[26] = c[0] ^ d[6] ^ c[10] ^ d[25] ^ c[19] ^ c[20] ^ d[8] ^ c[22] ^ d[27] ^ c[4] ^ c[24] ^ d[3] ^ c[6] ^ d[12] ^ d[5] ^ c[26] ^ c[18] ^ d[7] ^ c[28] ^ d[0] ^ c[3] ^ c[31] ^ d[9] ^ d[11] ^ d[28] ^ c[23] ^ d[21] ^ d[31] ^ d[13] ^ c[25] ;
+o[27] = d[6] ^ c[27] ^ c[19] ^ c[20] ^ c[29] ^ d[8] ^ d[10] ^ d[27] ^ c[4] ^ d[20] ^ d[30] ^ d[12] ^ c[24] ^ d[5] ^ c[26] ^ d[24] ^ c[1] ^ c[11] ^ d[7] ^ c[21] ^ d[26] ^ d[2] ^ c[23] ^ d[11] ^ c[5] ^ c[25] ^ d[4] ^ c[7] ;
+o[28] = d[23] ^ c[27] ^ d[6] ^ c[20] ^ c[2] ^ d[25] ^ c[30] ^ c[12] ^ d[1] ^ d[10] ^ c[22] ^ d[19] ^ d[29] ^ c[24] ^ d[3] ^ c[6] ^ d[5] ^ c[26] ^ c[8] ^ d[7] ^ c[28] ^ c[21] ^ d[26] ^ d[9] ^ d[11] ^ c[5] ^ d[4] ^ c[25] ;
+o[29] = c[27] ^ d[6] ^ c[9] ^ d[25] ^ c[29] ^ d[8] ^ d[10] ^ c[22] ^ d[3] ^ c[6] ^ d[22] ^ d[5] ^ c[26] ^ d[24] ^ c[28] ^ d[0] ^ c[21] ^ c[3] ^ c[31] ^ d[9] ^ d[18] ^ c[13] ^ d[28] ^ d[2] ^ c[23] ^ d[4] ^ c[25] ^ c[7] ;
+o[30] = d[23] ^ c[10] ^ c[27] ^ c[29] ^ c[30] ^ d[8] ^ d[17] ^ d[27] ^ c[22] ^ d[1] ^ c[4] ^ c[14] ^ d[3] ^ c[24] ^ d[5] ^ c[26] ^ c[8] ^ d[24] ^ c[28] ^ d[7] ^ d[9] ^ d[2] ^ c[23] ^ d[21] ^ d[4] ^ c[7] ;
+o[31] = d[23] ^ c[27] ^ d[6] ^ c[9] ^ d[8] ^ c[29] ^ c[30] ^ d[1] ^ d[20] ^ c[24] ^ d[3] ^ d[22] ^ c[8] ^ c[11] ^ d[7] ^ d[16] ^ c[28] ^ d[26] ^ d[0] ^ c[31] ^ d[2] ^ c[23] ^ c[5] ^ c[15] ^ d[4] ^ c[25] ;
+ crc4B = o;
+ end
+ endfunction // crc4B
+
+ ////////////////////////////////////////////////
+ // crc3B
+ ////////////////////////////////////////////////
+ function [31:0] crc3B (
+ input [31:0] c,
+ input [23:0] d
+ );
+ reg [31:0] o;
+ begin
+o[0] = d[23] ^ c[17] ^ c[20] ^ d[17] ^ c[14] ^ c[24] ^ c[8] ^ d[14] ^ c[18] ^ d[7] ^ d[11] ^ d[13] ;
+o[1] = d[23] ^ c[17] ^ d[6] ^ c[9] ^ c[20] ^ c[19] ^ d[17] ^ d[10] ^ c[14] ^ c[24] ^ d[12] ^ d[22] ^ d[14] ^ c[8] ^ d[7] ^ d[16] ^ c[21] ^ d[11] ^ c[15] ^ c[25] ;
+o[2] = d[23] ^ c[17] ^ d[6] ^ c[9] ^ d[15] ^ c[10] ^ d[17] ^ d[10] ^ c[22] ^ c[14] ^ c[24] ^ d[22] ^ c[16] ^ d[5] ^ c[26] ^ d[14] ^ c[8] ^ d[7] ^ d[16] ^ c[21] ^ d[9] ^ c[15] ^ d[21] ^ c[25] ;
+o[3] = c[17] ^ c[27] ^ d[6] ^ c[9] ^ d[15] ^ c[10] ^ d[8] ^ c[22] ^ d[20] ^ d[22] ^ c[16] ^ d[5] ^ c[26] ^ d[14] ^ c[18] ^ d[16] ^ c[11] ^ d[9] ^ c[23] ^ c[15] ^ d[21] ^ d[4] ^ c[25] ^ d[13] ;
+o[4] = d[23] ^ c[27] ^ d[15] ^ c[10] ^ c[20] ^ c[19] ^ d[17] ^ d[8] ^ c[12] ^ c[14] ^ d[20] ^ d[19] ^ d[3] ^ d[12] ^ c[16] ^ d[5] ^ c[26] ^ c[8] ^ c[28] ^ c[11] ^ d[11] ^ c[23] ^ d[21] ^ d[4] ;
+o[5] = d[23] ^ c[27] ^ c[9] ^ d[17] ^ c[29] ^ c[12] ^ d[10] ^ c[14] ^ d[20] ^ d[19] ^ d[3] ^ d[22] ^ c[8] ^ c[18] ^ c[28] ^ d[16] ^ c[11] ^ c[21] ^ d[18] ^ c[13] ^ d[2] ^ c[15] ^ d[4] ^ d[13] ;
+o[6] = c[9] ^ d[15] ^ c[10] ^ c[19] ^ c[30] ^ c[29] ^ c[12] ^ d[17] ^ d[1] ^ c[22] ^ d[19] ^ c[14] ^ d[3] ^ d[12] ^ d[22] ^ c[16] ^ d[16] ^ c[28] ^ d[9] ^ d[18] ^ c[13] ^ d[2] ^ c[15] ^ d[21] ;
+o[7] = d[23] ^ d[15] ^ c[10] ^ c[29] ^ c[30] ^ d[8] ^ d[1] ^ d[20] ^ c[24] ^ c[16] ^ c[8] ^ c[18] ^ d[7] ^ c[11] ^ d[16] ^ d[0] ^ c[31] ^ d[18] ^ c[13] ^ d[2] ^ c[23] ^ d[21] ^ c[15] ^ d[13] ;
+o[8] = d[23] ^ d[6] ^ c[9] ^ d[15] ^ c[20] ^ c[19] ^ c[30] ^ c[12] ^ d[1] ^ d[20] ^ d[19] ^ d[12] ^ d[22] ^ c[16] ^ c[8] ^ c[18] ^ c[11] ^ d[0] ^ c[31] ^ d[11] ^ d[13] ^ c[25] ;
+o[9] = c[17] ^ c[9] ^ c[10] ^ c[19] ^ c[20] ^ c[12] ^ d[10] ^ d[19] ^ d[12] ^ d[22] ^ d[5] ^ c[26] ^ d[14] ^ d[0] ^ c[21] ^ c[31] ^ d[18] ^ c[13] ^ d[11] ^ d[21] ;
+o[10] = d[23] ^ c[17] ^ c[27] ^ c[10] ^ c[22] ^ d[10] ^ d[20] ^ c[24] ^ d[14] ^ c[8] ^ d[7] ^ c[11] ^ c[21] ^ d[9] ^ d[18] ^ c[13] ^ d[21] ^ d[4] ;
+o[11] = d[23] ^ c[17] ^ d[6] ^ c[9] ^ c[20] ^ d[8] ^ c[12] ^ c[22] ^ d[20] ^ d[19] ^ c[24] ^ d[3] ^ d[22] ^ d[14] ^ c[8] ^ d[7] ^ c[28] ^ c[11] ^ d[9] ^ d[11] ^ c[23] ^ c[25] ;
+o[12] = d[23] ^ c[17] ^ d[6] ^ c[9] ^ c[10] ^ c[20] ^ d[17] ^ c[29] ^ d[8] ^ c[12] ^ d[10] ^ c[14] ^ d[19] ^ d[22] ^ d[5] ^ c[26] ^ d[14] ^ c[8] ^ c[21] ^ d[18] ^ c[13] ^ d[11] ^ d[2] ^ c[23] ^ d[21] ^ c[25] ;
+o[13] = c[27] ^ c[9] ^ c[10] ^ c[30] ^ d[17] ^ d[10] ^ d[1] ^ c[22] ^ d[20] ^ c[14] ^ c[24] ^ d[22] ^ d[5] ^ c[26] ^ c[18] ^ d[16] ^ d[7] ^ c[11] ^ c[21] ^ d[9] ^ d[18] ^ c[13] ^ c[15] ^ d[21] ^ d[4] ^ d[13] ;
+o[14] = d[15] ^ d[6] ^ c[10] ^ c[27] ^ c[19] ^ d[8] ^ c[12] ^ d[17] ^ c[22] ^ d[20] ^ d[19] ^ c[14] ^ d[3] ^ d[12] ^ c[16] ^ c[28] ^ c[11] ^ d[16] ^ d[0] ^ d[9] ^ c[31] ^ c[23] ^ d[21] ^ c[15] ^ c[25] ^ d[4] ;
+o[15] = c[17] ^ d[15] ^ c[20] ^ d[8] ^ c[29] ^ c[12] ^ d[20] ^ d[19] ^ c[24] ^ d[3] ^ c[16] ^ d[14] ^ d[5] ^ c[26] ^ c[11] ^ d[7] ^ c[28] ^ d[16] ^ d[18] ^ c[13] ^ d[2] ^ c[23] ^ d[11] ^ c[15] ;
+o[16] = d[23] ^ c[27] ^ d[6] ^ d[15] ^ c[20] ^ c[29] ^ c[30] ^ c[12] ^ d[1] ^ d[10] ^ d[19] ^ c[16] ^ c[8] ^ c[21] ^ d[18] ^ c[13] ^ d[11] ^ d[2] ^ d[4] ^ c[25] ;
+o[17] = c[17] ^ c[9] ^ c[30] ^ d[17] ^ d[10] ^ d[1] ^ c[22] ^ c[14] ^ d[3] ^ d[22] ^ d[5] ^ c[26] ^ d[14] ^ c[28] ^ d[0] ^ c[21] ^ c[31] ^ d[18] ^ d[9] ^ c[13] ;
+o[18] = c[10] ^ c[27] ^ c[29] ^ d[17] ^ d[8] ^ c[22] ^ c[14] ^ c[18] ^ d[16] ^ d[0] ^ d[9] ^ c[31] ^ d[2] ^ c[23] ^ d[21] ^ c[15] ^ d[4] ^ d[13] ;
+o[19] = d[15] ^ c[19] ^ d[8] ^ c[30] ^ d[1] ^ d[20] ^ c[24] ^ d[3] ^ d[12] ^ c[16] ^ c[11] ^ d[16] ^ d[7] ^ c[28] ^ c[23] ^ c[15] ;
+o[20] = c[17] ^ d[15] ^ d[6] ^ c[20] ^ c[12] ^ c[29] ^ d[19] ^ c[24] ^ c[16] ^ d[14] ^ d[7] ^ d[0] ^ c[31] ^ d[2] ^ d[11] ^ c[25] ;
+o[21] = c[17] ^ d[6] ^ c[30] ^ d[1] ^ d[10] ^ d[14] ^ d[5] ^ c[26] ^ c[18] ^ c[21] ^ d[18] ^ c[13] ^ c[25] ^ d[13] ;
+o[22] = d[23] ^ c[17] ^ c[27] ^ c[20] ^ c[19] ^ c[22] ^ c[24] ^ d[12] ^ d[5] ^ c[26] ^ d[14] ^ c[8] ^ d[7] ^ d[0] ^ c[31] ^ d[9] ^ d[11] ^ d[4] ;
+o[23] = d[23] ^ c[17] ^ c[27] ^ d[6] ^ c[9] ^ d[17] ^ d[8] ^ d[10] ^ c[14] ^ c[24] ^ d[3] ^ d[22] ^ d[14] ^ c[8] ^ d[7] ^ c[28] ^ c[21] ^ c[23] ^ d[4] ^ c[25] ;
+o[24] = c[0] ^ d[6] ^ c[9] ^ c[10] ^ c[29] ^ c[22] ^ c[24] ^ d[3] ^ d[22] ^ d[5] ^ c[26] ^ c[18] ^ d[16] ^ d[7] ^ c[28] ^ d[9] ^ d[2] ^ c[15] ^ d[21] ^ c[25] ^ d[13] ;
+o[25] = d[15] ^ d[6] ^ c[10] ^ c[27] ^ c[19] ^ c[29] ^ c[30] ^ d[8] ^ d[1] ^ d[20] ^ d[12] ^ c[16] ^ d[5] ^ c[26] ^ c[1] ^ c[11] ^ d[2] ^ c[23] ^ d[21] ^ c[25] ^ d[4] ;
+o[26] = d[23] ^ c[27] ^ c[2] ^ d[17] ^ c[30] ^ c[12] ^ d[1] ^ c[14] ^ d[20] ^ d[19] ^ d[3] ^ d[5] ^ c[26] ^ c[8] ^ c[18] ^ c[28] ^ c[11] ^ d[0] ^ c[31] ^ d[4] ^ d[13] ;
+o[27] = c[27] ^ c[9] ^ c[19] ^ c[29] ^ c[12] ^ d[19] ^ d[3] ^ d[12] ^ d[22] ^ d[16] ^ c[28] ^ d[0] ^ c[3] ^ c[31] ^ d[18] ^ c[13] ^ d[2] ^ c[15] ^ d[4] ;
+o[28] = d[15] ^ c[10] ^ c[20] ^ c[29] ^ c[30] ^ d[17] ^ d[1] ^ c[4] ^ c[14] ^ d[3] ^ c[16] ^ c[28] ^ d[18] ^ c[13] ^ d[2] ^ d[11] ^ d[21] ;
+o[29] = c[17] ^ c[29] ^ c[30] ^ d[17] ^ d[1] ^ d[10] ^ d[20] ^ c[14] ^ d[14] ^ c[11] ^ d[16] ^ d[0] ^ c[21] ^ c[31] ^ d[2] ^ c[5] ^ c[15] ;
+o[30] = d[15] ^ c[30] ^ c[12] ^ d[1] ^ c[22] ^ d[19] ^ c[6] ^ c[16] ^ c[18] ^ d[16] ^ d[0] ^ c[31] ^ d[9] ^ c[15] ^ d[13] ;
+o[31] = c[17] ^ d[15] ^ c[19] ^ d[8] ^ d[12] ^ c[16] ^ d[14] ^ d[0] ^ d[18] ^ c[31] ^ c[13] ^ c[23] ^ c[7] ;
+ crc3B = o;
+ end
+ endfunction // crc3B
+
+ ////////////////////////////////////////////////
+ // crc2B
+ ////////////////////////////////////////////////
+ function [31:0] crc2B (
+ input [31:0] c,
+ input [15:0] d
+ );
+ reg [31:0] o;
+ begin
+o[0] = d[9] ^ c[22] ^ d[5] ^ c[26] ^ d[15] ^ d[6] ^ d[3] ^ c[28] ^ c[25] ^ c[16] ;
+o[1] = c[17] ^ d[15] ^ d[6] ^ c[27] ^ c[29] ^ d[8] ^ c[22] ^ d[3] ^ c[16] ^ d[14] ^ c[28] ^ d[9] ^ c[23] ^ d[2] ^ d[4] ^ c[25] ;
+o[2] = c[17] ^ d[15] ^ d[6] ^ d[8] ^ c[29] ^ c[30] ^ c[22] ^ d[1] ^ c[24] ^ c[16] ^ d[14] ^ c[18] ^ d[7] ^ d[9] ^ d[2] ^ c[23] ^ c[25] ^ d[13] ;
+o[3] = c[17] ^ d[6] ^ c[19] ^ d[8] ^ c[30] ^ d[1] ^ c[24] ^ d[12] ^ d[14] ^ d[5] ^ c[26] ^ c[18] ^ d[7] ^ d[0] ^ c[31] ^ c[23] ^ d[13] ^ c[25] ;
+o[4] = d[15] ^ c[27] ^ c[20] ^ c[19] ^ c[22] ^ d[3] ^ c[24] ^ d[12] ^ c[16] ^ c[18] ^ c[28] ^ d[7] ^ d[0] ^ d[9] ^ c[31] ^ d[11] ^ d[13] ^ d[4] ;
+o[5] = c[17] ^ d[15] ^ c[19] ^ c[20] ^ d[8] ^ c[29] ^ c[22] ^ d[10] ^ d[12] ^ c[16] ^ d[5] ^ c[26] ^ d[14] ^ c[21] ^ d[9] ^ d[2] ^ c[23] ^ d[11] ;
+o[6] = c[17] ^ c[27] ^ c[20] ^ d[8] ^ c[30] ^ d[1] ^ c[22] ^ d[10] ^ c[24] ^ d[14] ^ c[18] ^ d[7] ^ c[21] ^ d[9] ^ c[23] ^ d[11] ^ d[4] ^ d[13] ;
+o[7] = d[15] ^ c[19] ^ d[8] ^ d[10] ^ c[24] ^ d[12] ^ c[16] ^ d[5] ^ c[26] ^ c[18] ^ d[7] ^ d[0] ^ c[21] ^ c[31] ^ c[23] ^ d[13] ;
+o[8] = c[17] ^ d[15] ^ c[27] ^ c[19] ^ c[20] ^ d[3] ^ d[12] ^ c[24] ^ c[16] ^ d[5] ^ c[26] ^ d[14] ^ c[28] ^ d[7] ^ d[11] ^ d[4] ;
+o[9] = c[17] ^ c[27] ^ d[6] ^ c[20] ^ c[29] ^ d[10] ^ d[3] ^ d[14] ^ c[18] ^ c[28] ^ c[21] ^ d[2] ^ d[11] ^ d[4] ^ d[13] ^ c[25] ;
+o[10] = d[15] ^ d[6] ^ c[19] ^ c[30] ^ c[29] ^ d[1] ^ d[10] ^ d[12] ^ c[16] ^ c[18] ^ c[21] ^ d[2] ^ c[25] ^ d[13] ;
+o[11] = c[17] ^ d[15] ^ d[6] ^ c[19] ^ c[20] ^ c[30] ^ d[1] ^ d[3] ^ d[12] ^ c[16] ^ d[14] ^ c[28] ^ d[0] ^ c[31] ^ d[11] ^ c[25] ;
+o[12] = c[17] ^ d[15] ^ d[6] ^ c[20] ^ c[29] ^ c[22] ^ d[10] ^ d[3] ^ c[16] ^ d[14] ^ c[18] ^ c[28] ^ d[0] ^ c[21] ^ d[9] ^ c[31] ^ d[2] ^ d[11] ^ c[25] ^ d[13] ;
+o[13] = c[17] ^ c[19] ^ d[8] ^ c[29] ^ c[30] ^ d[1] ^ d[10] ^ c[22] ^ d[12] ^ d[14] ^ d[5] ^ c[26] ^ c[18] ^ c[21] ^ d[9] ^ d[2] ^ c[23] ^ d[13] ;
+o[14] = c[27] ^ c[19] ^ c[20] ^ c[30] ^ d[8] ^ d[1] ^ c[22] ^ c[24] ^ d[12] ^ c[18] ^ d[7] ^ d[0] ^ c[31] ^ d[9] ^ d[11] ^ c[23] ^ d[13] ^ d[4] ;
+o[15] = d[6] ^ c[20] ^ c[19] ^ d[8] ^ d[10] ^ d[12] ^ c[24] ^ d[3] ^ d[7] ^ c[28] ^ d[0] ^ c[21] ^ c[31] ^ c[23] ^ d[11] ^ c[25] ;
+o[16] = c[0] ^ d[15] ^ c[20] ^ c[29] ^ d[10] ^ d[3] ^ c[24] ^ c[16] ^ c[28] ^ d[7] ^ c[21] ^ d[11] ^ d[2] ;
+o[17] = c[17] ^ d[6] ^ c[29] ^ c[30] ^ d[10] ^ d[1] ^ c[22] ^ d[14] ^ c[1] ^ c[21] ^ d[9] ^ d[2] ^ c[25] ;
+o[18] = c[2] ^ c[30] ^ d[8] ^ d[1] ^ c[22] ^ c[26] ^ d[5] ^ c[18] ^ d[0] ^ d[9] ^ c[31] ^ c[23] ^ d[13] ;
+o[19] = c[27] ^ c[19] ^ d[8] ^ d[12] ^ c[24] ^ d[7] ^ d[0] ^ c[3] ^ c[31] ^ c[23] ^ d[4] ;
+o[20] = d[6] ^ c[20] ^ c[4] ^ d[3] ^ c[24] ^ d[7] ^ c[28] ^ d[11] ^ c[25] ;
+o[21] = d[6] ^ c[29] ^ d[10] ^ c[26] ^ d[5] ^ c[21] ^ c[5] ^ d[2] ^ c[25] ;
+o[22] = d[15] ^ d[6] ^ c[27] ^ c[30] ^ d[1] ^ d[3] ^ c[6] ^ c[16] ^ c[28] ^ c[25] ^ d[4] ;
+o[23] = c[17] ^ d[15] ^ d[6] ^ c[29] ^ c[22] ^ c[16] ^ d[14] ^ d[0] ^ d[9] ^ c[31] ^ d[2] ^ c[25] ^ c[7] ;
+o[24] = d[14] ^ d[5] ^ c[26] ^ c[17] ^ d[1] ^ c[8] ^ c[23] ^ c[18] ^ d[8] ^ d[13] ^ c[30] ;
+o[25] = c[31] ^ c[27] ^ c[18] ^ c[9] ^ d[7] ^ c[24] ^ d[12] ^ c[19] ^ d[13] ^ d[4] ^ d[0] ;
+o[26] = d[15] ^ c[10] ^ c[20] ^ c[19] ^ c[22] ^ d[12] ^ c[16] ^ d[5] ^ c[26] ^ d[9] ^ d[11] ;
+o[27] = c[17] ^ c[27] ^ c[20] ^ d[8] ^ d[10] ^ d[14] ^ c[11] ^ c[21] ^ c[23] ^ d[11] ^ d[4] ;
+o[28] = c[12] ^ c[22] ^ d[10] ^ c[24] ^ d[3] ^ c[18] ^ d[7] ^ c[28] ^ c[21] ^ d[9] ^ d[13] ;
+o[29] = d[6] ^ c[19] ^ d[8] ^ c[29] ^ c[22] ^ d[12] ^ c[13] ^ d[9] ^ d[2] ^ c[23] ^ c[25] ;
+o[30] = d[5] ^ c[26] ^ d[1] ^ d[11] ^ c[23] ^ c[14] ^ c[20] ^ d[7] ^ c[24] ^ c[30] ^ d[8] ;
+o[31] = d[10] ^ c[31] ^ c[27] ^ d[6] ^ d[7] ^ c[24] ^ c[15] ^ d[4] ^ d[0] ^ c[21] ^ c[25] ;
+ crc2B = o;
+ end
+ endfunction // crc2B
+
+ ////////////////////////////////////////////////
+ // crc1B
+ ////////////////////////////////////////////////
+ function [31:0] crc1B (
+ input [31:0] c,
+ input [7:0] d
+ );
+ reg [31:0] o;
+ begin
+o[0] = d[1] ^ d[7] ^ c[24] ^ c[30] ;
+o[1] = d[1] ^ c[31] ^ d[6] ^ d[7] ^ c[24] ^ c[30] ^ d[0] ^ c[25] ;
+o[2] = d[1] ^ c[31] ^ d[5] ^ c[26] ^ d[6] ^ d[7] ^ c[24] ^ c[30] ^ d[0] ^ c[25] ;
+o[3] = c[31] ^ d[5] ^ c[26] ^ d[6] ^ c[27] ^ d[0] ^ c[25] ^ d[4] ;
+o[4] = d[1] ^ d[5] ^ c[26] ^ c[27] ^ d[7] ^ c[24] ^ d[3] ^ c[28] ^ c[30] ^ d[4] ;
+o[5] = c[27] ^ d[6] ^ c[30] ^ c[29] ^ d[1] ^ d[3] ^ c[24] ^ d[7] ^ c[28] ^ d[0] ^ c[31] ^ d[2] ^ d[4] ^ c[25] ;
+o[6] = d[6] ^ c[30] ^ c[29] ^ d[1] ^ d[3] ^ c[26] ^ d[5] ^ c[28] ^ d[0] ^ c[31] ^ d[2] ^ c[25] ;
+o[7] = d[5] ^ c[26] ^ c[31] ^ c[27] ^ d[2] ^ d[7] ^ c[24] ^ d[4] ^ c[29] ^ d[0] ;
+o[8] = c[0] ^ d[6] ^ c[27] ^ d[7] ^ c[24] ^ d[3] ^ c[28] ^ c[25] ^ d[4] ;
+o[9] = d[5] ^ c[26] ^ d[6] ^ d[2] ^ c[1] ^ d[3] ^ c[28] ^ c[25] ^ c[29] ;
+o[10] = d[5] ^ c[26] ^ c[27] ^ d[2] ^ d[7] ^ c[24] ^ c[2] ^ d[4] ^ c[29] ;
+o[11] = d[6] ^ c[27] ^ d[7] ^ c[24] ^ d[3] ^ c[28] ^ c[25] ^ d[4] ^ c[3] ;
+o[12] = d[6] ^ c[29] ^ c[30] ^ d[1] ^ c[4] ^ d[3] ^ c[24] ^ c[26] ^ d[5] ^ d[7] ^ c[28] ^ d[2] ^ c[25] ;
+o[13] = d[6] ^ c[27] ^ c[30] ^ c[29] ^ d[1] ^ c[26] ^ d[5] ^ d[0] ^ c[31] ^ c[5] ^ d[2] ^ d[4] ^ c[25] ;
+o[14] = d[5] ^ c[26] ^ d[1] ^ c[31] ^ c[27] ^ d[3] ^ c[28] ^ c[6] ^ d[4] ^ c[30] ^ d[0] ;
+o[15] = c[31] ^ c[27] ^ d[2] ^ d[3] ^ c[28] ^ d[4] ^ c[29] ^ d[0] ^ c[7] ;
+o[16] = c[8] ^ d[2] ^ d[7] ^ c[24] ^ d[3] ^ c[28] ^ c[29] ;
+o[17] = d[1] ^ d[6] ^ d[2] ^ c[9] ^ c[25] ^ c[29] ^ c[30] ;
+o[18] = d[5] ^ c[26] ^ d[1] ^ c[31] ^ c[10] ^ c[30] ^ d[0] ;
+o[19] = c[31] ^ c[27] ^ c[11] ^ d[4] ^ d[0] ;
+o[20] = d[3] ^ c[28] ^ c[12] ;
+o[21] = c[13] ^ d[2] ^ c[29] ;
+o[22] = c[14] ^ d[7] ^ c[24] ;
+o[23] = d[1] ^ d[6] ^ d[7] ^ c[24] ^ c[15] ^ c[30] ^ c[25] ;
+o[24] = c[31] ^ d[5] ^ c[26] ^ d[6] ^ d[0] ^ c[25] ^ c[16] ;
+o[25] = d[5] ^ c[26] ^ c[17] ^ c[27] ^ d[4] ;
+o[26] = d[1] ^ c[27] ^ c[18] ^ d[7] ^ c[24] ^ d[3] ^ c[28] ^ c[30] ^ d[4] ;
+o[27] = c[31] ^ d[6] ^ d[2] ^ d[3] ^ c[28] ^ c[19] ^ d[0] ^ c[25] ^ c[29] ;
+o[28] = d[5] ^ c[26] ^ d[1] ^ d[2] ^ c[20] ^ c[29] ^ c[30] ;
+o[29] = d[1] ^ c[31] ^ c[27] ^ d[4] ^ c[30] ^ d[0] ^ c[21] ;
+o[30] = c[31] ^ c[22] ^ d[3] ^ c[28] ^ d[0] ;
+o[31] = d[2] ^ c[23] ^ c[29] ;
+ crc1B = o;
+ end
+ endfunction // crc1B
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/hdl_cores/freedom/fpga-shells/wit-manifest.json b/hdl_cores/freedom/fpga-shells/wit-manifest.json
new file mode 100644
index 0000000..56bd80b
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/wit-manifest.json
@@ -0,0 +1,32 @@
+[
+ {
+ "commit": "50b9d6ffdfbff683fa25045d7f1ef3585a34f2dc",
+ "name": "api-generator-sifive",
+ "source": "git@github.com:sifive/api-generator-sifive.git"
+ },
+ {
+ "commit": "4374e58fc282f9670605ce5a741436d18242e520",
+ "name": "sifive-blocks",
+ "source": "git@github.com:sifive/sifive-blocks.git"
+ },
+ {
+ "commit": "e44e22beccdd5e1e43fd8a35f7c9c5687c821326",
+ "name": "rocket-chip",
+ "source": "git@github.com:chipsalliance/rocket-chip.git"
+ },
+ {
+ "commit": "e1aa5f3f5c0cdeb204047c3ca50801d9f7ea25f1",
+ "name": "chisel3",
+ "source": "git@github.com:freechipsproject/chisel3.git"
+ },
+ {
+ "commit": "228c9a4b7432ac52178d63b8f27fe064aec71e9c",
+ "name": "firrtl",
+ "source": "git@github.com:freechipsproject/firrtl.git"
+ },
+ {
+ "commit": "9c4bcd00b1d3c2ca667e330303ee8fa26432d687",
+ "name": "api-scala-sifive",
+ "source": "git@github.com:sifive/api-scala-sifive.git"
+ }
+]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/Makefile b/hdl_cores/freedom/fpga-shells/xilinx/Makefile
new file mode 100644
index 0000000..1416927
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/Makefile
@@ -0,0 +1,42 @@
+VIVADO ?= vivado
+VIVADOFLAGS := \
+ -nojournal -mode batch \
+ -source $(fpga_board_script_dir)/board.tcl \
+ -source $(fpga_common_script_dir)/prologue.tcl
+
+# Path to a program in raw binary format to be flashed into the address that the
+# bootrom jumps to.
+# FIXME: This variable should probably be communicated by a higher-level Makefile
+FLASHED_PROGRAM ?=
+
+# Init project
+init = $(FPGA_BUILD_DIR)/.init
+$(init): $(fpga_common_script_dir)/init.tcl
+ mkdir -p $(FPGA_BUILD_DIR) && \
+ cd $(FPGA_BUILD_DIR) && \
+ VSRCS="$(VSRCS)" IPVIVADOTCLS="$(IPVIVADOTCLS)" $(VIVADO) $(VIVADOFLAGS) -source $<
+
+.PHONY: init
+init: $(init)
+
+# Generate bitstream
+bit := $(FPGA_BUILD_DIR)/obj/$(FPGA_TOP_SYSTEM).bit
+$(bit): $(fpga_common_script_dir)/vivado.tcl $(init)
+ cd $(FPGA_BUILD_DIR) && \
+ VSRCS="$(VSRCS)" $(VIVADO) $(VIVADOFLAGS) -source $<
+
+.PHONY: bit
+bit: $(bit)
+
+# Generate mcs
+mcs := $(FPGA_BUILD_DIR)/obj/system.mcs
+$(mcs): $(bit)
+ cd $(FPGA_BUILD_DIR) && \
+ $(VIVADO) $(VIVADOFLAGS) $(fpga_common_script_dir)/write_cfgmem.tcl -tclargs $(BOARD) $@ $^ $(FLASHED_PROGRAM)
+
+.PHONY: mcs
+mcs: $(mcs)
+
+.PHONY: clean
+clean::
+ rm -rf $(FPGA_BUILD_DIR)
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/arty/constraints/arty-config.xdc b/hdl_cores/freedom/fpga-shells/xilinx/arty/constraints/arty-config.xdc
new file mode 100644
index 0000000..a455c22
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/arty/constraints/arty-config.xdc
@@ -0,0 +1,5 @@
+set_property -dict [list \
+ CONFIG_VOLTAGE {3.3} \
+ CFGBVS {VCCO} \
+ BITSTREAM.CONFIG.SPI_BUSWIDTH {4} \
+ ] [current_design]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/arty/constraints/arty-master.xdc b/hdl_cores/freedom/fpga-shells/xilinx/arty/constraints/arty-master.xdc
new file mode 100644
index 0000000..c434697
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/arty/constraints/arty-master.xdc
@@ -0,0 +1,240 @@
+## This file is a general .xdc for the ARTY Rev. B
+## To use it in a project:
+## - uncomment the lines corresponding to used pins
+## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
+
+## Clock signal
+
+set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100]
+create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {CLK100MHZ}];
+create_clock -add -name JTCK -period 100 -waveform {0 50} [get_ports {jd_2}];
+
+##Switches
+
+set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { sw_0 }]; #IO_L12N_T1_MRCC_16 Sch=sw[0]
+set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { sw_1 }]; #IO_L13P_T2_MRCC_16 Sch=sw[1]
+set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { sw_2 }]; #IO_L13N_T2_MRCC_16 Sch=sw[2]
+set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { sw_3 }]; #IO_L14P_T2_SRCC_16 Sch=sw[3]
+
+##RGB LEDs
+
+set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { led0_b }]; #IO_L18N_T2_35 Sch=led0_b
+set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { led0_g }]; #IO_L19N_T3_VREF_35 Sch=led0_g
+set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { led0_r }]; #IO_L19P_T3_35 Sch=led0_r
+set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { led1_b }]; #IO_L20P_T3_35 Sch=led1_b
+set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { led1_g }]; #IO_L21P_T3_DQS_35 Sch=led1_g
+set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { led1_r }]; #IO_L20N_T3_35 Sch=led1_r
+set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { led2_b }]; #IO_L21N_T3_DQS_35 Sch=led2_b
+set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { led2_g }]; #IO_L22N_T3_35 Sch=led2_g
+set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { led2_r }]; #IO_L22P_T3_35 Sch=led2_r
+#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { led3_b }]; #IO_L23P_T3_35 Sch=led3_b
+#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { led3_g }]; #IO_L24P_T3_35 Sch=led3_g
+#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { led3_r }]; #IO_L23N_T3_35 Sch=led3_r
+
+##LEDs
+
+set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { led_0 }]; #IO_L24N_T3_35 Sch=led[4]
+set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { led_1 }]; #IO_25_35 Sch=led[5]
+set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { led_2 }]; #IO_L24P_T3_A01_D17_14 Sch=led[6]
+set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { led_3 }]; #IO_L24N_T3_A00_D16_14 Sch=led[7]
+
+##Buttons
+
+set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { btn_0 }]; #IO_L6N_T0_VREF_16 Sch=btn[0]
+set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { btn_1 }]; #IO_L11P_T1_SRCC_16 Sch=btn[1]
+set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { btn_2 }]; #IO_L11N_T1_SRCC_16 Sch=btn[2]
+set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { btn_3 }]; #IO_L12P_T1_MRCC_16 Sch=btn[3]
+
+##Pmod Header JA
+
+set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { ja_0 }]; #IO_0_15 Sch=ja[1]
+set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { ja_1 }]; #IO_L4P_T0_15 Sch=ja[2]
+set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { ja_2 }]; #IO_L4N_T0_15 Sch=ja[3]
+set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { ja_3 }]; #IO_L6P_T0_15 Sch=ja[4]
+set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { ja_4 }]; #IO_L6N_T0_VREF_15 Sch=ja[7]
+set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { ja_5 }]; #IO_L10P_T1_AD11P_15 Sch=ja[8]
+set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { ja_6 }]; #IO_L10N_T1_AD11N_15 Sch=ja[9]
+set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { ja_7 }]; #IO_25_15 Sch=ja[10]
+
+##Pmod Header JB
+
+#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { jb_0 }]; #IO_L11P_T1_SRCC_15 Sch=jb_p[1]
+#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { jb_1 }]; #IO_L11N_T1_SRCC_15 Sch=jb_n[1]
+#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { jb_2 }]; #IO_L12P_T1_MRCC_15 Sch=jb_p[2]
+#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { jb_3 }]; #IO_L12N_T1_MRCC_15 Sch=jb_n[2]
+#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { jb_4 }]; #IO_L23P_T3_FOE_B_15 Sch=jb_p[3]
+#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { jb_5 }]; #IO_L23N_T3_FWE_B_15 Sch=jb_n[3]
+#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { jb_6 }]; #IO_L24P_T3_RS1_15 Sch=jb_p[4]
+#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { jb_7 }]; #IO_L24N_T3_RS0_15 Sch=jb_n[4]
+
+##Pmod Header JC
+
+set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { jc_0 }]; #IO_L20P_T3_A08_D24_14 Sch=jc_p[1]
+set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { jc_1 }]; #IO_L20N_T3_A07_D23_14 Sch=jc_n[1]
+set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { jc_2 }]; #IO_L21P_T3_DQS_14 Sch=jc_p[2]
+set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { jc_3 }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=jc_n[2]
+set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { jc_4 }]; #IO_L22P_T3_A05_D21_14 Sch=jc_p[3]
+set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { jc_5 }]; #IO_L22N_T3_A04_D20_14 Sch=jc_n[3]
+set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { jc_6 }]; #IO_L23P_T3_A03_D19_14 Sch=jc_p[4]
+set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { jc_7 }]; #IO_L23N_T3_A02_D18_14 Sch=jc_n[4]
+
+##Pmod Header JD
+
+set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { jd_0 }]; #IO_L11N_T1_SRCC_35 Sch=jd[1]
+set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { jd_1 }]; #IO_L12N_T1_MRCC_35 Sch=jd[2]
+set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { jd_2 }]; #IO_L13P_T2_MRCC_35 Sch=jd[3]
+#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd_3 }]; #IO_L13N_T2_MRCC_35 Sch=jd[4]
+set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { jd_4 }]; #IO_L14P_T2_SRCC_35 Sch=jd[7]
+set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { jd_5 }]; #IO_L14N_T2_SRCC_35 Sch=jd[8]
+set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd_6 }]; #IO_L15P_T2_DQS_35 Sch=jd[9]
+#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { jd_7 }]; #IO_L15N_T2_DQS_35 Sch=jd[10]
+
+##USB-UART Interface (FTDI FT2232H)
+
+set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L19N_T3_VREF_16 Sch=uart_rxd_out
+set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L14N_T2_SRCC_16 Sch=uart_txd_in
+
+
+##ChipKit Single Ended Analog Inputs
+##NOTE: The ck_an_p pins can be used as single ended analog inputs with voltages from 0-3.3V (Chipkit Analog pins A0-A5).
+## These signals should only be connected to the XADC core. When using these pins as digital I/O, use pins ck_io[14-19].
+
+#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[0] }]; #IO_L1N_T0_AD4N_35 Sch=ck_an_n[0]
+#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[0] }]; #IO_L1P_T0_AD4P_35 Sch=ck_an_p[0]
+#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=ck_an_n[1]
+#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[1] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=ck_an_p[1]
+#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[2] }]; #IO_L7N_T1_AD6N_35 Sch=ck_an_n[2]
+#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[2] }]; #IO_L7P_T1_AD6P_35 Sch=ck_an_p[2]
+#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[3] }]; #IO_L9N_T1_DQS_AD7N_35 Sch=ck_an_n[3]
+#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[3] }]; #IO_L9P_T1_DQS_AD7P_35 Sch=ck_an_p[3]
+#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[4] }]; #IO_L10N_T1_AD15N_35 Sch=ck_an_n[4]
+#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[4] }]; #IO_L10P_T1_AD15P_35 Sch=ck_an_p[4]
+#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[5] }]; #IO_L1N_T0_AD0N_15 Sch=ck_an_n[5]
+#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[5] }]; #IO_L1P_T0_AD0P_15 Sch=ck_an_p[5]
+
+##ChipKit Digital I/O Low
+
+set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { ck_io_0 }]; #IO_L16P_T2_CSI_B_14 Sch=ck_io[0]
+set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { ck_io_1 }]; #IO_L18P_T2_A12_D28_14 Sch=ck_io[1]
+set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { ck_io_2 }]; #IO_L8N_T1_D12_14 Sch=ck_io[2]
+set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { ck_io_3 }]; #IO_L19P_T3_A10_D26_14 Sch=ck_io[3]
+set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { ck_io_4 }]; #IO_L5P_T0_D06_14 Sch=ck_io[4]
+set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { ck_io_5 }]; #IO_L14P_T2_SRCC_14 Sch=ck_io[5]
+set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { ck_io_6 }]; #IO_L14N_T2_SRCC_14 Sch=ck_io[6]
+set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { ck_io_7 }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=ck_io[7]
+set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { ck_io_8 }]; #IO_L11P_T1_SRCC_14 Sch=ck_io[8]
+set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { ck_io_9 }]; #IO_L10P_T1_D14_14 Sch=ck_io[9]
+set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { ck_io_10 }]; #IO_L18N_T2_A11_D27_14 Sch=ck_io[10]
+set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { ck_io_11 }]; #IO_L17N_T2_A13_D29_14 Sch=ck_io[11]
+set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { ck_io_12 }]; #IO_L12N_T1_MRCC_14 Sch=ck_io[12]
+set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { ck_io_13 }]; #IO_L12P_T1_MRCC_14 Sch=ck_io[13]
+
+##ChipKit Digital I/O On Outer Analog Header
+##NOTE: These pins should be used when using the analog header signals A0-A5 as digital I/O (Chipkit digital pins 14-19)
+
+set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { ck_io_14 }]; #IO_0_35 Sch=ck_a[0]
+set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { ck_io_15 }]; #IO_L4P_T0_35 Sch=ck_a[1]
+set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { ck_io_16 }]; #IO_L4N_T0_35 Sch=ck_a[2]
+set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { ck_io_17 }]; #IO_L6P_T0_35 Sch=ck_a[3]
+set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { ck_io_18 }]; #IO_L6N_T0_VREF_35 Sch=ck_a[4]
+set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { ck_io_19 }]; #IO_L11P_T1_SRCC_35 Sch=ck_a[5]
+
+##ChipKit Digital I/O On Inner Analog Header
+##NOTE: These pins will need to be connected to the XADC core when used as differential analog inputs (Chipkit analog pins A6-A11)
+
+#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { ck_io[20] }]; #IO_L2P_T0_AD12P_35 Sch=ad_p[12]
+#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { ck_io[21] }]; #IO_L2N_T0_AD12N_35 Sch=ad_n[12]
+#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { ck_io[22] }]; #IO_L5P_T0_AD13P_35 Sch=ad_p[13]
+#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { ck_io[23] }]; #IO_L5N_T0_AD13N_35 Sch=ad_n[13]
+#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { ck_io[24] }]; #IO_L8P_T1_AD14P_35 Sch=ad_p[14]
+#set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { ck_io[25] }]; #IO_L8N_T1_AD14N_35 Sch=ad_n[14]
+
+##ChipKit Digital I/O High
+
+#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { ck_io[26] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=ck_io[26]
+#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[27] }]; #IO_L16N_T2_A15_D31_14 Sch=ck_io[27]
+#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { ck_io[28] }]; #IO_L6N_T0_D08_VREF_14 Sch=ck_io[28]
+#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { ck_io[29] }]; #IO_25_14 Sch=ck_io[29]
+#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { ck_io[30] }]; #IO_0_14 Sch=ck_io[30]
+#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { ck_io[31] }]; #IO_L5N_T0_D07_14 Sch=ck_io[31]
+#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[32] }]; #IO_L13N_T2_MRCC_14 Sch=ck_io[32]
+#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[33] }]; #IO_L13P_T2_MRCC_14 Sch=ck_io[33]
+#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[34] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=ck_io[34]
+#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[35] }]; #IO_L11N_T1_SRCC_14 Sch=ck_io[35]
+#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { ck_io[36] }]; #IO_L8P_T1_D11_14 Sch=ck_io[36]
+#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[37] }]; #IO_L17P_T2_A14_D30_14 Sch=ck_io[37]
+#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[38] }]; #IO_L7N_T1_D10_14 Sch=ck_io[38]
+#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[39] }]; #IO_L7P_T1_D09_14 Sch=ck_io[39]
+#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[40] }]; #IO_L9N_T1_DQS_D13_14 Sch=ck_io[40]
+#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[41] }]; #IO_L9P_T1_DQS_14 Sch=ck_io[41]
+
+## ChipKit SPI
+
+set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { ck_miso }]; #IO_L17N_T2_35 Sch=ck_miso
+set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { ck_mosi }]; #IO_L17P_T2_35 Sch=ck_mosi
+set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { ck_sck }]; #IO_L18P_T2_35 Sch=ck_sck
+set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { ck_ss }]; #IO_L16N_T2_35 Sch=ck_ss
+
+## ChipKit I2C
+
+#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { ck_scl }]; #IO_L4P_T0_D04_14 Sch=ck_scl
+#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { ck_sda }]; #IO_L4N_T0_D05_14 Sch=ck_sda
+#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports { scl_pup }]; #IO_L9N_T1_DQS_AD3N_15 Sch=scl_pup
+#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVCMOS33 } [get_ports { sda_pup }]; #IO_L9P_T1_DQS_AD3P_15 Sch=sda_pup
+
+##Misc. ChipKit signals
+
+#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { ck_ioa }]; #IO_L10N_T1_D15_14 Sch=ck_ioa
+set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { ck_rst }]; #IO_L16P_T2_35 Sch=ck_rst
+
+##SMSC Ethernet PHY
+
+#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { eth_col }]; #IO_L16N_T2_A27_15 Sch=eth_col
+#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { eth_crs }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=eth_crs
+#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { eth_mdc }]; #IO_L14N_T2_SRCC_15 Sch=eth_mdc
+#set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { eth_mdio }]; #IO_L17P_T2_A26_15 Sch=eth_mdio
+#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { eth_ref_clk }]; #IO_L22P_T3_A17_15 Sch=eth_ref_clk
+#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L20P_T3_A20_15 Sch=eth_rstn
+#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { eth_rx_clk }]; #IO_L14P_T2_SRCC_15 Sch=eth_rx_clk
+#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { eth_rx_dv }]; #IO_L13N_T2_MRCC_15 Sch=eth_rx_dv
+#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L21N_T3_DQS_A18_15 Sch=eth_rxd[0]
+#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L16P_T2_A28_15 Sch=eth_rxd[1]
+#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[2] }]; #IO_L21P_T3_DQS_15 Sch=eth_rxd[2]
+#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[3] }]; #IO_L18N_T2_A23_15 Sch=eth_rxd[3]
+#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L20N_T3_A19_15 Sch=eth_rxerr
+#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { eth_tx_clk }]; #IO_L13P_T2_MRCC_15 Sch=eth_tx_clk
+#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { eth_tx_en }]; #IO_L19N_T3_A21_VREF_15 Sch=eth_tx_en
+#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L15P_T2_DQS_15 Sch=eth_txd[0]
+#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L19P_T3_A22_15 Sch=eth_txd[1]
+#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[2] }]; #IO_L17N_T2_A25_15 Sch=eth_txd[2]
+#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[3] }]; #IO_L18P_T2_A24_15 Sch=eth_txd[3]
+
+##Quad SPI Flash
+
+set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 IOB TRUE } [get_ports { qspi_sck }];
+create_clock -add -name qspi_sck_pin -period 20.00 -waveform {0 10} [get_ports { qspi_sck }];
+set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 IOB TRUE } [get_ports { qspi_cs }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_cs
+set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_0 }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
+set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_1 }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
+set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_2 }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
+set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_3 }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
+
+##Power Measurements
+
+#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports { vsnsvu_n }]; #IO_L7N_T1_AD2N_15 Sch=ad_n[2]
+#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports { vsnsvu_p }]; #IO_L7P_T1_AD2P_15 Sch=ad_p[2]
+#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vsns5v0_n }]; #IO_L3N_T0_DQS_AD1N_15 Sch=ad_n[1]
+#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { vsns5v0_p }]; #IO_L3P_T0_DQS_AD1P_15 Sch=ad_p[1]
+#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { isns5v0_n }]; #IO_L5N_T0_AD9N_15 Sch=ad_n[9]
+#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { isns5v0_p }]; #IO_L5P_T0_AD9P_15 Sch=ad_p[9]
+#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports { isns0v95_n }]; #IO_L8N_T1_AD10N_15 Sch=ad_n[10]
+#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { isns0v95_p }]; #IO_L8P_T1_AD10P_15 Sch=ad_p[10]
+
+set_clock_groups -asynchronous \
+ -group [list \
+ [get_clocks -include_generated_clocks -of_objects [get_ports jd_2]]] \
+ -group [list \
+ [get_clocks -of_objects [get_pins ip_mmcm/inst/mmcm_adv_inst/CLKOUT0]]] \
+ -group [list \
+ [get_clocks -of_objects [get_pins ip_mmcm/inst/mmcm_adv_inst/CLKOUT1]] \
+ [get_clocks -of_objects [get_pins ip_mmcm/inst/mmcm_adv_inst/CLKOUT2]]]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/arty/tcl/board.tcl b/hdl_cores/freedom/fpga-shells/xilinx/arty/tcl/board.tcl
new file mode 100644
index 0000000..4eaed96
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/arty/tcl/board.tcl
@@ -0,0 +1,5 @@
+# See LICENSE for license details.
+set name {arty}
+set part_fpga {xc7a35ticsg324-1L}
+set part_board {digilentinc.com:arty:part0:1.1}
+set bootrom_inst {rom}
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/arty/tcl/ip.tcl b/hdl_cores/freedom/fpga-shells/xilinx/arty/tcl/ip.tcl
new file mode 100644
index 0000000..fe07c37
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/arty/tcl/ip.tcl
@@ -0,0 +1,44 @@
+# See LICENSE for license details.
+
+create_ip -vendor xilinx.com -library ip -name clk_wiz -module_name mmcm -dir $ipdir -force
+set_property -dict [list \
+ CONFIG.PRIMITIVE {MMCM} \
+ CONFIG.RESET_TYPE {ACTIVE_LOW} \
+ CONFIG.CLKOUT1_USED {true} \
+ CONFIG.CLKOUT2_USED {true} \
+ CONFIG.CLKOUT3_USED {true} \
+ CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {8.388} \
+ CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {65.000} \
+ CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {32.500} \
+ ] [get_ips mmcm]
+
+create_ip -vendor xilinx.com -library ip -name proc_sys_reset -module_name reset_sys -dir $ipdir -force
+set_property -dict [list \
+ CONFIG.C_EXT_RESET_HIGH {false} \
+ CONFIG.C_AUX_RESET_HIGH {false} \
+ CONFIG.C_NUM_BUS_RST {1} \
+ CONFIG.C_NUM_PERP_RST {1} \
+ CONFIG.C_NUM_INTERCONNECT_ARESETN {1} \
+ CONFIG.C_NUM_PERP_ARESETN {1} \
+ ] [get_ips reset_sys]
+
+create_ip -vendor xilinx.com -library ip -name ila -module_name ila -dir $ipdir -force
+set_property -dict [list \
+ CONFIG.C_NUM_OF_PROBES {1} \
+ CONFIG.C_TRIGOUT_EN {false} \
+ CONFIG.C_TRIGIN_EN {false} \
+ CONFIG.C_MONITOR_TYPE {Native} \
+ CONFIG.C_ENABLE_ILA_AXI_MON {false} \
+ CONFIG.C_PROBE0_WIDTH {4} \
+ CONFIG.C_PROBE10_TYPE {1} \
+ CONFIG.C_PROBE10_WIDTH {32} \
+ CONFIG.C_PROBE11_TYPE {1} \
+ CONFIG.C_PROBE11_WIDTH {32} \
+ CONFIG.C_PROBE12_TYPE {1} \
+ CONFIG.C_PROBE12_WIDTH {64} \
+ CONFIG.C_PROBE13_TYPE {1} \
+ CONFIG.C_PROBE13_WIDTH {64} \
+ CONFIG.C_PROBE14_TYPE {1} \
+ CONFIG.C_PROBE14_WIDTH {97} \
+ ] [get_ips ila]
+
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/constraints/arty-config.xdc b/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/constraints/arty-config.xdc
new file mode 100644
index 0000000..a455c22
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/constraints/arty-config.xdc
@@ -0,0 +1,5 @@
+set_property -dict [list \
+ CONFIG_VOLTAGE {3.3} \
+ CFGBVS {VCCO} \
+ BITSTREAM.CONFIG.SPI_BUSWIDTH {4} \
+ ] [current_design]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/constraints/arty-master.xdc b/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/constraints/arty-master.xdc
new file mode 100644
index 0000000..c434697
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/constraints/arty-master.xdc
@@ -0,0 +1,240 @@
+## This file is a general .xdc for the ARTY Rev. B
+## To use it in a project:
+## - uncomment the lines corresponding to used pins
+## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
+
+## Clock signal
+
+set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100]
+create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {CLK100MHZ}];
+create_clock -add -name JTCK -period 100 -waveform {0 50} [get_ports {jd_2}];
+
+##Switches
+
+set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { sw_0 }]; #IO_L12N_T1_MRCC_16 Sch=sw[0]
+set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { sw_1 }]; #IO_L13P_T2_MRCC_16 Sch=sw[1]
+set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { sw_2 }]; #IO_L13N_T2_MRCC_16 Sch=sw[2]
+set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { sw_3 }]; #IO_L14P_T2_SRCC_16 Sch=sw[3]
+
+##RGB LEDs
+
+set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { led0_b }]; #IO_L18N_T2_35 Sch=led0_b
+set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { led0_g }]; #IO_L19N_T3_VREF_35 Sch=led0_g
+set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { led0_r }]; #IO_L19P_T3_35 Sch=led0_r
+set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { led1_b }]; #IO_L20P_T3_35 Sch=led1_b
+set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { led1_g }]; #IO_L21P_T3_DQS_35 Sch=led1_g
+set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { led1_r }]; #IO_L20N_T3_35 Sch=led1_r
+set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { led2_b }]; #IO_L21N_T3_DQS_35 Sch=led2_b
+set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { led2_g }]; #IO_L22N_T3_35 Sch=led2_g
+set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { led2_r }]; #IO_L22P_T3_35 Sch=led2_r
+#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { led3_b }]; #IO_L23P_T3_35 Sch=led3_b
+#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { led3_g }]; #IO_L24P_T3_35 Sch=led3_g
+#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { led3_r }]; #IO_L23N_T3_35 Sch=led3_r
+
+##LEDs
+
+set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { led_0 }]; #IO_L24N_T3_35 Sch=led[4]
+set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { led_1 }]; #IO_25_35 Sch=led[5]
+set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { led_2 }]; #IO_L24P_T3_A01_D17_14 Sch=led[6]
+set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { led_3 }]; #IO_L24N_T3_A00_D16_14 Sch=led[7]
+
+##Buttons
+
+set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { btn_0 }]; #IO_L6N_T0_VREF_16 Sch=btn[0]
+set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { btn_1 }]; #IO_L11P_T1_SRCC_16 Sch=btn[1]
+set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { btn_2 }]; #IO_L11N_T1_SRCC_16 Sch=btn[2]
+set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { btn_3 }]; #IO_L12P_T1_MRCC_16 Sch=btn[3]
+
+##Pmod Header JA
+
+set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { ja_0 }]; #IO_0_15 Sch=ja[1]
+set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { ja_1 }]; #IO_L4P_T0_15 Sch=ja[2]
+set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { ja_2 }]; #IO_L4N_T0_15 Sch=ja[3]
+set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { ja_3 }]; #IO_L6P_T0_15 Sch=ja[4]
+set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { ja_4 }]; #IO_L6N_T0_VREF_15 Sch=ja[7]
+set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { ja_5 }]; #IO_L10P_T1_AD11P_15 Sch=ja[8]
+set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { ja_6 }]; #IO_L10N_T1_AD11N_15 Sch=ja[9]
+set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { ja_7 }]; #IO_25_15 Sch=ja[10]
+
+##Pmod Header JB
+
+#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { jb_0 }]; #IO_L11P_T1_SRCC_15 Sch=jb_p[1]
+#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { jb_1 }]; #IO_L11N_T1_SRCC_15 Sch=jb_n[1]
+#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { jb_2 }]; #IO_L12P_T1_MRCC_15 Sch=jb_p[2]
+#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { jb_3 }]; #IO_L12N_T1_MRCC_15 Sch=jb_n[2]
+#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { jb_4 }]; #IO_L23P_T3_FOE_B_15 Sch=jb_p[3]
+#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { jb_5 }]; #IO_L23N_T3_FWE_B_15 Sch=jb_n[3]
+#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { jb_6 }]; #IO_L24P_T3_RS1_15 Sch=jb_p[4]
+#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { jb_7 }]; #IO_L24N_T3_RS0_15 Sch=jb_n[4]
+
+##Pmod Header JC
+
+set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { jc_0 }]; #IO_L20P_T3_A08_D24_14 Sch=jc_p[1]
+set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { jc_1 }]; #IO_L20N_T3_A07_D23_14 Sch=jc_n[1]
+set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { jc_2 }]; #IO_L21P_T3_DQS_14 Sch=jc_p[2]
+set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { jc_3 }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=jc_n[2]
+set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { jc_4 }]; #IO_L22P_T3_A05_D21_14 Sch=jc_p[3]
+set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { jc_5 }]; #IO_L22N_T3_A04_D20_14 Sch=jc_n[3]
+set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { jc_6 }]; #IO_L23P_T3_A03_D19_14 Sch=jc_p[4]
+set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { jc_7 }]; #IO_L23N_T3_A02_D18_14 Sch=jc_n[4]
+
+##Pmod Header JD
+
+set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { jd_0 }]; #IO_L11N_T1_SRCC_35 Sch=jd[1]
+set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { jd_1 }]; #IO_L12N_T1_MRCC_35 Sch=jd[2]
+set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { jd_2 }]; #IO_L13P_T2_MRCC_35 Sch=jd[3]
+#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd_3 }]; #IO_L13N_T2_MRCC_35 Sch=jd[4]
+set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { jd_4 }]; #IO_L14P_T2_SRCC_35 Sch=jd[7]
+set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { jd_5 }]; #IO_L14N_T2_SRCC_35 Sch=jd[8]
+set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd_6 }]; #IO_L15P_T2_DQS_35 Sch=jd[9]
+#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { jd_7 }]; #IO_L15N_T2_DQS_35 Sch=jd[10]
+
+##USB-UART Interface (FTDI FT2232H)
+
+set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L19N_T3_VREF_16 Sch=uart_rxd_out
+set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L14N_T2_SRCC_16 Sch=uart_txd_in
+
+
+##ChipKit Single Ended Analog Inputs
+##NOTE: The ck_an_p pins can be used as single ended analog inputs with voltages from 0-3.3V (Chipkit Analog pins A0-A5).
+## These signals should only be connected to the XADC core. When using these pins as digital I/O, use pins ck_io[14-19].
+
+#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[0] }]; #IO_L1N_T0_AD4N_35 Sch=ck_an_n[0]
+#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[0] }]; #IO_L1P_T0_AD4P_35 Sch=ck_an_p[0]
+#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=ck_an_n[1]
+#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[1] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=ck_an_p[1]
+#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[2] }]; #IO_L7N_T1_AD6N_35 Sch=ck_an_n[2]
+#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[2] }]; #IO_L7P_T1_AD6P_35 Sch=ck_an_p[2]
+#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[3] }]; #IO_L9N_T1_DQS_AD7N_35 Sch=ck_an_n[3]
+#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[3] }]; #IO_L9P_T1_DQS_AD7P_35 Sch=ck_an_p[3]
+#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[4] }]; #IO_L10N_T1_AD15N_35 Sch=ck_an_n[4]
+#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[4] }]; #IO_L10P_T1_AD15P_35 Sch=ck_an_p[4]
+#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[5] }]; #IO_L1N_T0_AD0N_15 Sch=ck_an_n[5]
+#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[5] }]; #IO_L1P_T0_AD0P_15 Sch=ck_an_p[5]
+
+##ChipKit Digital I/O Low
+
+set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { ck_io_0 }]; #IO_L16P_T2_CSI_B_14 Sch=ck_io[0]
+set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { ck_io_1 }]; #IO_L18P_T2_A12_D28_14 Sch=ck_io[1]
+set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { ck_io_2 }]; #IO_L8N_T1_D12_14 Sch=ck_io[2]
+set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { ck_io_3 }]; #IO_L19P_T3_A10_D26_14 Sch=ck_io[3]
+set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { ck_io_4 }]; #IO_L5P_T0_D06_14 Sch=ck_io[4]
+set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { ck_io_5 }]; #IO_L14P_T2_SRCC_14 Sch=ck_io[5]
+set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { ck_io_6 }]; #IO_L14N_T2_SRCC_14 Sch=ck_io[6]
+set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { ck_io_7 }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=ck_io[7]
+set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { ck_io_8 }]; #IO_L11P_T1_SRCC_14 Sch=ck_io[8]
+set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { ck_io_9 }]; #IO_L10P_T1_D14_14 Sch=ck_io[9]
+set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { ck_io_10 }]; #IO_L18N_T2_A11_D27_14 Sch=ck_io[10]
+set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { ck_io_11 }]; #IO_L17N_T2_A13_D29_14 Sch=ck_io[11]
+set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { ck_io_12 }]; #IO_L12N_T1_MRCC_14 Sch=ck_io[12]
+set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { ck_io_13 }]; #IO_L12P_T1_MRCC_14 Sch=ck_io[13]
+
+##ChipKit Digital I/O On Outer Analog Header
+##NOTE: These pins should be used when using the analog header signals A0-A5 as digital I/O (Chipkit digital pins 14-19)
+
+set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { ck_io_14 }]; #IO_0_35 Sch=ck_a[0]
+set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { ck_io_15 }]; #IO_L4P_T0_35 Sch=ck_a[1]
+set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { ck_io_16 }]; #IO_L4N_T0_35 Sch=ck_a[2]
+set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { ck_io_17 }]; #IO_L6P_T0_35 Sch=ck_a[3]
+set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { ck_io_18 }]; #IO_L6N_T0_VREF_35 Sch=ck_a[4]
+set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { ck_io_19 }]; #IO_L11P_T1_SRCC_35 Sch=ck_a[5]
+
+##ChipKit Digital I/O On Inner Analog Header
+##NOTE: These pins will need to be connected to the XADC core when used as differential analog inputs (Chipkit analog pins A6-A11)
+
+#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { ck_io[20] }]; #IO_L2P_T0_AD12P_35 Sch=ad_p[12]
+#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { ck_io[21] }]; #IO_L2N_T0_AD12N_35 Sch=ad_n[12]
+#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { ck_io[22] }]; #IO_L5P_T0_AD13P_35 Sch=ad_p[13]
+#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { ck_io[23] }]; #IO_L5N_T0_AD13N_35 Sch=ad_n[13]
+#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { ck_io[24] }]; #IO_L8P_T1_AD14P_35 Sch=ad_p[14]
+#set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { ck_io[25] }]; #IO_L8N_T1_AD14N_35 Sch=ad_n[14]
+
+##ChipKit Digital I/O High
+
+#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { ck_io[26] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=ck_io[26]
+#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[27] }]; #IO_L16N_T2_A15_D31_14 Sch=ck_io[27]
+#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { ck_io[28] }]; #IO_L6N_T0_D08_VREF_14 Sch=ck_io[28]
+#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { ck_io[29] }]; #IO_25_14 Sch=ck_io[29]
+#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { ck_io[30] }]; #IO_0_14 Sch=ck_io[30]
+#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { ck_io[31] }]; #IO_L5N_T0_D07_14 Sch=ck_io[31]
+#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[32] }]; #IO_L13N_T2_MRCC_14 Sch=ck_io[32]
+#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[33] }]; #IO_L13P_T2_MRCC_14 Sch=ck_io[33]
+#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[34] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=ck_io[34]
+#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[35] }]; #IO_L11N_T1_SRCC_14 Sch=ck_io[35]
+#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { ck_io[36] }]; #IO_L8P_T1_D11_14 Sch=ck_io[36]
+#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[37] }]; #IO_L17P_T2_A14_D30_14 Sch=ck_io[37]
+#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[38] }]; #IO_L7N_T1_D10_14 Sch=ck_io[38]
+#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[39] }]; #IO_L7P_T1_D09_14 Sch=ck_io[39]
+#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[40] }]; #IO_L9N_T1_DQS_D13_14 Sch=ck_io[40]
+#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[41] }]; #IO_L9P_T1_DQS_14 Sch=ck_io[41]
+
+## ChipKit SPI
+
+set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { ck_miso }]; #IO_L17N_T2_35 Sch=ck_miso
+set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { ck_mosi }]; #IO_L17P_T2_35 Sch=ck_mosi
+set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { ck_sck }]; #IO_L18P_T2_35 Sch=ck_sck
+set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { ck_ss }]; #IO_L16N_T2_35 Sch=ck_ss
+
+## ChipKit I2C
+
+#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { ck_scl }]; #IO_L4P_T0_D04_14 Sch=ck_scl
+#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { ck_sda }]; #IO_L4N_T0_D05_14 Sch=ck_sda
+#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports { scl_pup }]; #IO_L9N_T1_DQS_AD3N_15 Sch=scl_pup
+#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVCMOS33 } [get_ports { sda_pup }]; #IO_L9P_T1_DQS_AD3P_15 Sch=sda_pup
+
+##Misc. ChipKit signals
+
+#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { ck_ioa }]; #IO_L10N_T1_D15_14 Sch=ck_ioa
+set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { ck_rst }]; #IO_L16P_T2_35 Sch=ck_rst
+
+##SMSC Ethernet PHY
+
+#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { eth_col }]; #IO_L16N_T2_A27_15 Sch=eth_col
+#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { eth_crs }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=eth_crs
+#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { eth_mdc }]; #IO_L14N_T2_SRCC_15 Sch=eth_mdc
+#set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { eth_mdio }]; #IO_L17P_T2_A26_15 Sch=eth_mdio
+#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { eth_ref_clk }]; #IO_L22P_T3_A17_15 Sch=eth_ref_clk
+#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L20P_T3_A20_15 Sch=eth_rstn
+#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { eth_rx_clk }]; #IO_L14P_T2_SRCC_15 Sch=eth_rx_clk
+#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { eth_rx_dv }]; #IO_L13N_T2_MRCC_15 Sch=eth_rx_dv
+#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L21N_T3_DQS_A18_15 Sch=eth_rxd[0]
+#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L16P_T2_A28_15 Sch=eth_rxd[1]
+#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[2] }]; #IO_L21P_T3_DQS_15 Sch=eth_rxd[2]
+#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[3] }]; #IO_L18N_T2_A23_15 Sch=eth_rxd[3]
+#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L20N_T3_A19_15 Sch=eth_rxerr
+#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { eth_tx_clk }]; #IO_L13P_T2_MRCC_15 Sch=eth_tx_clk
+#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { eth_tx_en }]; #IO_L19N_T3_A21_VREF_15 Sch=eth_tx_en
+#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L15P_T2_DQS_15 Sch=eth_txd[0]
+#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L19P_T3_A22_15 Sch=eth_txd[1]
+#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[2] }]; #IO_L17N_T2_A25_15 Sch=eth_txd[2]
+#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[3] }]; #IO_L18P_T2_A24_15 Sch=eth_txd[3]
+
+##Quad SPI Flash
+
+set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 IOB TRUE } [get_ports { qspi_sck }];
+create_clock -add -name qspi_sck_pin -period 20.00 -waveform {0 10} [get_ports { qspi_sck }];
+set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 IOB TRUE } [get_ports { qspi_cs }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_cs
+set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_0 }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
+set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_1 }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
+set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_2 }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
+set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_3 }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
+
+##Power Measurements
+
+#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports { vsnsvu_n }]; #IO_L7N_T1_AD2N_15 Sch=ad_n[2]
+#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports { vsnsvu_p }]; #IO_L7P_T1_AD2P_15 Sch=ad_p[2]
+#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vsns5v0_n }]; #IO_L3N_T0_DQS_AD1N_15 Sch=ad_n[1]
+#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { vsns5v0_p }]; #IO_L3P_T0_DQS_AD1P_15 Sch=ad_p[1]
+#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { isns5v0_n }]; #IO_L5N_T0_AD9N_15 Sch=ad_n[9]
+#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { isns5v0_p }]; #IO_L5P_T0_AD9P_15 Sch=ad_p[9]
+#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports { isns0v95_n }]; #IO_L8N_T1_AD10N_15 Sch=ad_n[10]
+#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { isns0v95_p }]; #IO_L8P_T1_AD10P_15 Sch=ad_p[10]
+
+set_clock_groups -asynchronous \
+ -group [list \
+ [get_clocks -include_generated_clocks -of_objects [get_ports jd_2]]] \
+ -group [list \
+ [get_clocks -of_objects [get_pins ip_mmcm/inst/mmcm_adv_inst/CLKOUT0]]] \
+ -group [list \
+ [get_clocks -of_objects [get_pins ip_mmcm/inst/mmcm_adv_inst/CLKOUT1]] \
+ [get_clocks -of_objects [get_pins ip_mmcm/inst/mmcm_adv_inst/CLKOUT2]]]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/tcl/board.tcl b/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/tcl/board.tcl
new file mode 100644
index 0000000..70635da
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/tcl/board.tcl
@@ -0,0 +1,5 @@
+# See LICENSE for license details.
+set name {arty-a7-100}
+set part_fpga {xc7a100ticsg324-1L}
+set part_board {digilentinc.com:arty-a7-100:part0:1.0}
+set bootrom_inst {rom}
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/tcl/ip.tcl b/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/tcl/ip.tcl
new file mode 100644
index 0000000..3dc9faa
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/arty_a7_100/tcl/ip.tcl
@@ -0,0 +1,43 @@
+# See LICENSE for license details.
+
+create_ip -vendor xilinx.com -library ip -name clk_wiz -module_name mmcm -dir $ipdir -force
+set_property -dict [list \
+ CONFIG.PRIMITIVE {MMCM} \
+ CONFIG.RESET_TYPE {ACTIVE_LOW} \
+ CONFIG.CLKOUT1_USED {true} \
+ CONFIG.CLKOUT2_USED {true} \
+ CONFIG.CLKOUT3_USED {true} \
+ CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {8.388} \
+ CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {65.000} \
+ CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {32.500} \
+ ] [get_ips mmcm]
+
+create_ip -vendor xilinx.com -library ip -name proc_sys_reset -module_name reset_sys -dir $ipdir -force
+set_property -dict [list \
+ CONFIG.C_EXT_RESET_HIGH {false} \
+ CONFIG.C_AUX_RESET_HIGH {false} \
+ CONFIG.C_NUM_BUS_RST {1} \
+ CONFIG.C_NUM_PERP_RST {1} \
+ CONFIG.C_NUM_INTERCONNECT_ARESETN {1} \
+ CONFIG.C_NUM_PERP_ARESETN {1} \
+ ] [get_ips reset_sys]
+
+create_ip -vendor xilinx.com -library ip -name ila -module_name ila -dir $ipdir -force
+set_property -dict [list \
+ CONFIG.C_NUM_OF_PROBES {1} \
+ CONFIG.C_TRIGOUT_EN {false} \
+ CONFIG.C_TRIGIN_EN {false} \
+ CONFIG.C_MONITOR_TYPE {Native} \
+ CONFIG.C_ENABLE_ILA_AXI_MON {false} \
+ CONFIG.C_PROBE0_WIDTH {4} \
+ CONFIG.C_PROBE10_TYPE {1} \
+ CONFIG.C_PROBE10_WIDTH {32} \
+ CONFIG.C_PROBE11_TYPE {1} \
+ CONFIG.C_PROBE11_WIDTH {32} \
+ CONFIG.C_PROBE12_TYPE {1} \
+ CONFIG.C_PROBE12_WIDTH {64} \
+ CONFIG.C_PROBE13_TYPE {1} \
+ CONFIG.C_PROBE13_WIDTH {64} \
+ CONFIG.C_PROBE14_TYPE {1} \
+ CONFIG.C_PROBE14_WIDTH {97} \
+ ] [get_ips ila]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/bitstream.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/bitstream.tcl
new file mode 100644
index 0000000..bf223f6
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/bitstream.tcl
@@ -0,0 +1,10 @@
+# See LICENSE for license details.
+
+# Write a bitstream for the current design
+write_bitstream -force [file join $wrkdir "${top}.bit"]
+
+# Save the timing delays for cells in the design in SDF format
+write_sdf -force [file join $wrkdir "${top}.sdf"]
+
+# Export the current netlist in verilog format
+write_verilog -mode timesim -force [file join ${wrkdir} "${top}.v"]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/boards.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/boards.tcl
new file mode 100644
index 0000000..af1c686
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/boards.tcl
@@ -0,0 +1,9 @@
+# See LICENSE for license details.
+
+namespace eval ::program::boards {}
+
+set ::program::boards::spec [dict create \
+ arty [dict create iface spix4 size 16 bitaddr 0x0 memdev {n25q128-3.3v-spi-x1_x2_x4}] \
+ arty_a7_100 [dict create iface spix4 size 16 bitaddr 0x0 memdev {s25fl128sxxxxxx0-spi-x1_x2_x4}] \
+ vc707 [dict create iface bpix16 size 128 bitaddr 0x3000000 ] \
+ vcu118 [dict create iface spix8 size 256 bitaddr 0x0 memdev {mt25qu01g-spi-x1_x2_x4_x8}]]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/init.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/init.tcl
new file mode 100644
index 0000000..1ea645f
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/init.tcl
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+# Include helper functions
+source [file join $scriptdir "util.tcl"]
+
+# Create the directory for IPs
+file mkdir $ipdir
+
+# Update the IP catalog
+update_ip_catalog -rebuild
+
+# Generate IP implementations. Vivado TCL emitted from Chisel Blackboxes
+foreach ip_vivado_tcl $ip_vivado_tcls {
+ source $ip_vivado_tcl
+}
+# Optional board-specific ip script
+set boardiptcl [file join $boarddir tcl ip.tcl]
+if {[file exists $boardiptcl]} {
+ source $boardiptcl
+}
+
+# AR 58526
+set xci_files [get_files -all {*.xci}]
+foreach xci_file $xci_files {
+ set_property GENERATE_SYNTH_CHECKPOINT {false} -quiet $xci_file
+}
+
+# Get a list of IPs in the current design
+set obj [get_ips]
+
+# Generate target data for the included IPs in the design
+generate_target all $obj
+
+# Export the IP user files
+export_ip_user_files -of_objects $obj -no_script -force
+
+# Get the list of active source and constraint files
+set obj [current_fileset]
+
+#Xilinx bug workaround
+#scrape IP tree for directories containing .vh files
+#[get_property include_dirs] misses all IP core subdirectory includes if user has specified -dir flag in create_ip
+set property_include_dirs [get_property include_dirs $obj]
+
+# Include generated files for the IPs in the design
+set ip_include_dirs [concat $property_include_dirs [findincludedir $ipdir "*.vh"]]
+set ip_include_dirs [concat $ip_include_dirs [findincludedir $srcdir "*.h"]]
+set ip_include_dirs [concat $ip_include_dirs [findincludedir $srcdir "*.vh"]]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/opt.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/opt.tcl
new file mode 100644
index 0000000..81bf4ad
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/opt.tcl
@@ -0,0 +1,7 @@
+# See LICENSE for license details.
+
+# Optimize the netlist
+opt_design -directive Explore
+
+# Checkpoint the current design
+write_checkpoint -force [file join $wrkdir post_opt]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/place.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/place.tcl
new file mode 100644
index 0000000..ccc862a
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/place.tcl
@@ -0,0 +1,13 @@
+# See LICENSE for license details.
+
+# Place the current design
+place_design -directive Explore
+
+# Optimize the current placed netlist
+phys_opt_design -directive Explore
+
+# Optimize dynamic power using intelligent clock gating
+power_opt_design
+
+# Checkpoint the current design
+write_checkpoint -force [file join $wrkdir post_place]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/prologue.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/prologue.tcl
new file mode 100644
index 0000000..b513f41
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/prologue.tcl
@@ -0,0 +1,138 @@
+# See LICENSE for license details.
+
+# Process command line arguments
+# http://wiki.tcl.tk/1730
+set ip_vivado_tcls {}
+
+while {[llength $argv]} {
+ set argv [lassign $argv[set argv {}] flag]
+ switch -glob $flag {
+ -top-module {
+ set argv [lassign $argv[set argv {}] top]
+ }
+ -F {
+ # This should be a simple file format with one filepath per line
+ set argv [lassign $argv[set argv {}] vsrc_manifest]
+ }
+ -include_dirs {
+ # This should be a simple file format with one filepath per line
+ set argv [lassign $argv[set argv {}] incdir_manifest]
+ }
+
+ -board {
+ set argv [lassign $argv[set argv {}] board]
+ }
+ -ip-vivado-tcls {
+ set argv [lassign $argv[set argv {}] ip_vivado_tcls]
+ }
+ -pre-impl-debug-tcl {
+ set argv [lassign $argv[set argv {}] pre_impl_debug_tcl]
+ }
+ -post-impl-debug-tcl {
+ set argv [lassign $argv[set argv {}] post_impl_debug_tcl]
+ }
+ -env-var-srcs {
+ set argv [lassign $argv[set argv {}] env_var_srcs]
+ }
+ default {
+ return -code error [list {unknown option} $flag]
+ }
+ }
+}
+# tcl-env-srcs: Command line argument to pass the name of an environment variable that contains additional vsrcs
+# (from what is contained in .F file) that you want to have read in
+
+if {![info exists top]} {
+ return -code error [list {--top-module option is required}]
+}
+
+if {![info exists vsrc_manifest]} {
+ return -code error [list {-F option is required}]
+}
+
+if {![info exists board]} {
+ return -code error [list {--board option is required}]
+}
+
+# Set the variable for all the common files
+set commondir [file dirname $scriptdir]
+
+# Set the variable that points to board specific files
+set boarddir [file join [file dirname $commondir] $board]
+source [file join $boarddir tcl board.tcl]
+
+# Set the variable that points to board constraint files
+set constraintsdir [file join $boarddir constraints]
+
+# Set the variable that points to common verilog sources
+set srcdir [file join $commondir vsrc]
+
+# Creates a work directory
+set wrkdir [file join [pwd] obj]
+
+# Create the directory for IPs
+set ipdir [file join $wrkdir ip]
+
+# Create an in-memory project
+create_project -part $part_fpga -force $top
+
+set_param messaging.defaultLimit 1000000
+
+# Set the board part, target language, default library, and IP directory
+# paths for the current project
+set_property -dict [list \
+ BOARD_PART $part_board \
+ TARGET_LANGUAGE {Verilog} \
+ DEFAULT_LIB {xil_defaultlib} \
+ IP_REPO_PATHS $ipdir \
+ ] [current_project]
+
+if {[get_filesets -quiet sources_1] eq ""} {
+ create_fileset -srcset sources_1
+}
+set obj [current_fileset]
+
+# Add verilog files from manifest
+proc load_vsrc_manifest {obj vsrc_manifest} {
+ set fp [open $vsrc_manifest r]
+ set files [lsearch -not -exact -all -inline [split [read $fp] "\n"] {}]
+ set relative_files {}
+ foreach path $files {
+ if {[string match {/*} $path]} {
+ lappend relative_files $path
+ } elseif {![string match {#*} $path]} {
+ lappend relative_files [file join [file dirname $vsrc_manifest] $path]
+ }
+ }
+ # Read environment variable vsrcs and append to relative_files
+ if {[info exists env_var_srcs)]} {
+ if {[info exists ::env($env_var_srcs)]} {
+ set resources [split $::env($env_var_srcs) :]
+ set relative_files [list {*}$relative_files {*}$resources]
+ }
+ }
+ add_files -norecurse -fileset $obj {*}$relative_files
+ close $fp
+}
+
+load_vsrc_manifest $obj $vsrc_manifest
+
+# Add IP Vivado TCL
+if {$ip_vivado_tcls ne {}} {
+ # Split string into words even with multiple consecutive spaces
+ # http://wiki.tcl.tk/989
+ set ip_vivado_tcls [regexp -inline -all -- {\S+} $ip_vivado_tcls]
+}
+
+if {[get_filesets -quiet sim_1] eq ""} {
+ create_fileset -simset sim_1
+}
+set obj [current_fileset -simset]
+
+if {[get_filesets -quiet constrs_1] eq ""} {
+ create_fileset -constrset constrs_1
+}
+
+set obj [current_fileset -constrset]
+add_files -quiet -norecurse -fileset $obj [lsort [glob -directory $constraintsdir -nocomplain {*.tcl}]]
+add_files -quiet -norecurse -fileset $obj [lsort [glob -directory $constraintsdir -nocomplain {*.xdc}]]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/report.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/report.tcl
new file mode 100644
index 0000000..a499537
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/report.tcl
@@ -0,0 +1,44 @@
+# See LICENSE for license details.
+
+# Create a report directory
+set rptdir [file join $wrkdir report]
+file mkdir $rptdir
+
+# Create a datasheet for the current design
+report_datasheet -file [file join $rptdir datasheet.txt]
+
+# Report utilization of the current device
+set rptutil [file join $rptdir utilization.txt]
+report_utilization -hierarchical -file $rptutil
+
+# Report information about clock nets in the design
+report_clock_utilization -file $rptutil -append
+
+# Report the RAM resources utilized in the implemented design
+report_ram_utilization -file $rptutil -append -detail
+
+# Report timing summary for a max of 10 paths per group
+report_timing_summary -file [file join $rptdir timing.txt] -max_paths 10
+
+# Report the highest fanout of nets in the implemented design
+report_high_fanout_nets -file [file join $rptdir fanout.txt] -timing -load_types -max_nets 25
+
+# Run DRC
+report_drc -file [file join $rptdir drc.txt]
+
+# Report details of the IO banks in the design
+report_io -file [file join $rptdir io.txt]
+
+# Report a table of all clocks in the design
+report_clocks -file [file join $rptdir clocks.txt]
+
+# Fail loudly if timing not met
+#
+# We would ideally elevate critical warning Route 35-39 to an error, but it is
+# currently not being emitted with our flow for some reason.
+# https://forums.xilinx.com/t5/Implementation/Making-timing-violations-fatal-to-the-Vivado-build/m-p/716957#M15979
+set timing_slack [get_property SLACK [get_timing_paths]]
+if {$timing_slack < 0} {
+ puts "Failed to meet timing by $timing_slack, see [file join $rptdir timing.txt]"
+ exit 1
+}
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/route.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/route.tcl
new file mode 100644
index 0000000..68fc84a
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/route.tcl
@@ -0,0 +1,10 @@
+# See LICENSE for license details.
+
+# Route the current design
+route_design -directive Explore
+
+# Optimize the current design post routing
+phys_opt_design -directive Explore
+
+# Checkpoint the current design
+write_checkpoint -force [file join $wrkdir post_route]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/synth.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/synth.tcl
new file mode 100644
index 0000000..14be6ba
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/synth.tcl
@@ -0,0 +1,25 @@
+# See LICENSE for license details.
+
+# Create the include dirs
+proc load_incdirs_manifest {incdir_manifest} {
+ set fp [open $incdir_manifest r]
+ set files [lsearch -not -exact -all -inline [split [read $fp] "\n"] {}]
+
+ close $fp
+ return $files
+
+}
+
+# Read the specified list of IP files
+read_ip [glob -directory $ipdir [file join * {*.xci}]]
+
+# Capture the include directories
+set include_directories [load_incdirs_manifest $incdir_manifest]
+
+puts "DEBUG: include_directories = $include_directories"
+
+# Synthesize the design
+synth_design -top $top -flatten_hierarchy rebuilt -include_dirs $include_directories
+
+# Checkpoint the current design
+write_checkpoint -force [file join $wrkdir post_synth]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/util.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/util.tcl
new file mode 100644
index 0000000..eda723f
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/util.tcl
@@ -0,0 +1,24 @@
+# See LICENSE for license details.
+
+# Helper function that recursively includes files given a directory and a
+# pattern/suffix extensions
+proc recglob { basedir pattern } {
+ set dirlist [glob -nocomplain -directory $basedir -type d *]
+ set findlist [glob -nocomplain -directory $basedir $pattern]
+ foreach dir $dirlist {
+ set reclist [recglob $dir $pattern]
+ set findlist [concat $findlist $reclist]
+ }
+ return $findlist
+}
+
+# Helper function to find all subdirectories containing ".vh" files
+proc findincludedir { basedir pattern } {
+ set vhfiles [recglob $basedir $pattern]
+ set vhdirs {}
+ foreach match $vhfiles {
+ lappend vhdirs [file dir $match]
+ }
+ set uniquevhdirs [lsort -unique $vhdirs]
+ return $uniquevhdirs
+}
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/vivado.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/vivado.tcl
new file mode 100644
index 0000000..46f2614
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/vivado.tcl
@@ -0,0 +1,43 @@
+# See LICENSE for license details.
+
+# Set the variable for the directory that includes all scripts
+set scriptdir [file dirname [info script]]
+
+# Set up variables and Vivado objects
+source [file join $scriptdir "prologue.tcl"]
+
+# Initialize Vivado project files
+source [file join $scriptdir "init.tcl"]
+
+# Synthesize the design
+source [file join $scriptdir "synth.tcl"]
+
+# Pre-implementation debug
+if {[info exists pre_impl_debug_tcl]} {
+ source [file join $scriptdir $pre_impl_debug_tcl]
+}
+
+# Post synthesis optimization
+source [file join $scriptdir "opt.tcl"]
+
+# Post-opt debug
+if {[info exists post_opt_debug_tcl]} {
+ source [file join $scriptdir $post_opt_debug_tcl]
+}
+
+# Place the design
+source [file join $scriptdir "place.tcl"]
+
+# Route the design
+source [file join $scriptdir "route.tcl"]
+
+# Generate bitstream and save verilog netlist
+source [file join $scriptdir "bitstream.tcl"]
+
+# Post-implementation debug
+if {[info exists post_impl_debug_tcl]} {
+ source [file join $scriptdir $post_impl_debug_tcl]
+}
+
+# Create reports for the current implementation
+source [file join $scriptdir "report.tcl"]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/write_cfgmem.tcl b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/write_cfgmem.tcl
new file mode 100644
index 0000000..ebce010
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/tcl/write_cfgmem.tcl
@@ -0,0 +1,26 @@
+# See LICENSE for license details.
+#
+# Create an MCS-format memory configuration file from a bitstream and an
+# optional data file.
+
+set script_program_dir [file dirname [info script]]
+source [file join $script_program_dir {boards.tcl}]
+
+if {$argc < 3 || $argc > 4} {
+ puts $argc
+ puts {Error: Invalid number of arguments}
+ puts {Usage: write_cfgmem.tcl board mcsfile bitfile [datafile]}
+ exit 1
+}
+lassign $argv board mcsfile bitfile datafile
+
+if {![dict exists $::program::boards::spec $board]} {
+ puts {Unsupported board}
+ exit 1
+}
+set board [dict get $::program::boards::spec $board]
+
+write_cfgmem -format mcs -interface [dict get $board iface] -size [dict get $board size] \
+ -loadbit "up [dict get $board bitaddr] $bitfile" \
+ -loaddata [expr {$datafile ne "" ? "up 0x400000 $datafile" : ""}] \
+ -file $mcsfile -force
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/common/vsrc/PowerOnResetFPGAOnly.v b/hdl_cores/freedom/fpga-shells/xilinx/common/vsrc/PowerOnResetFPGAOnly.v
new file mode 100644
index 0000000..0355596
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/common/vsrc/PowerOnResetFPGAOnly.v
@@ -0,0 +1,16 @@
+// See LICENSE file for license details.
+(* keep_hierarchy = "yes" *) module PowerOnResetFPGAOnly(
+ input clock,
+ (* dont_touch = "true" *) output power_on_reset
+);
+ reg reset;
+ assign power_on_reset = reset;
+
+ initial begin
+ reset <= 1'b1;
+ end
+
+ always @(posedge clock) begin
+ reset <= 1'b0;
+ end
+endmodule
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/vc707/constraints/vc707-master.xdc b/hdl_cores/freedom/fpga-shells/xilinx/vc707/constraints/vc707-master.xdc
new file mode 100644
index 0000000..b972196
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/vc707/constraints/vc707-master.xdc
@@ -0,0 +1,6 @@
+#-------------- MCS Generation ----------------------
+set_property CFGBVS GND [current_design]
+set_property CONFIG_VOLTAGE 1.8 [current_design]
+
+set_property EXTRACT_ENABLE YES [get_cells dut_/spi_0_1/mac/phy/txd_reg*]
+set_property EXTRACT_ENABLE YES [get_cells dut_/spi_0_1/mac/phy/sck_reg]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/vc707/tcl/board.tcl b/hdl_cores/freedom/fpga-shells/xilinx/vc707/tcl/board.tcl
new file mode 100644
index 0000000..1043fa2
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/vc707/tcl/board.tcl
@@ -0,0 +1,4 @@
+# See LICENSE for license details.
+set name {vc707}
+set part_fpga {xc7vx485tffg1761-2}
+set part_board {xilinx.com:vc707:part0:1.3}
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/vc707/tcl/clocks.tcl b/hdl_cores/freedom/fpga-shells/xilinx/vc707/tcl/clocks.tcl
new file mode 100644
index 0000000..c62158d
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/vc707/tcl/clocks.tcl
@@ -0,0 +1,60 @@
+if { [llength [get_ports -quiet chiplink_b2c_clk]] > 0 } {
+ create_clock -name chiplink_b2c_clock -period 10 [get_ports chiplink_b2c_clk]
+ create_generated_clock -name {chiplink_c2b_clock} \
+ -divide_by 1 \
+ -source [ get_pins { vc707_sys_clock_mmcm0/inst/mmcm_adv_inst/CLKOUT6 } ] \
+ [ get_ports { chiplink_c2b_clk } ]
+
+ # RX side: want to latch almost anywhere except on the rising edge of the clock
+ # The data signals coming from Aloe have: clock - 1.2 <= transition <= clock + 0.8
+ # Let's add 0.6ns of safety for trace jitter+skew on both sides:
+ # min = hold = - 1.2 - 0.6
+ # max = period - setup = 0.8 + 0.6
+ set_input_delay -min -1.8 -clock {chiplink_b2c_clock} [ get_ports { chiplink_b2c_data* chiplink_b2c_rst chiplink_b2c_send } ]
+ set_input_delay -max 1.4 -clock {chiplink_b2c_clock} [ get_ports { chiplink_b2c_data* chiplink_b2c_rst chiplink_b2c_send } ]
+
+ # TX side: want to transition almost anywhere except on the rising edge of the clock
+ # The data signals going to Aloe must have: clock - 1.85 <= NO transition <= clock + 0.65
+ # Let's add 1ns of safey for trace jitter+skew on both sides:
+ # min = -hold = -0.65 - 0.6
+ # max = setup = 1.85 + 0.6
+ set_output_delay -min -1.25 -clock {chiplink_c2b_clock} [ get_ports { chiplink_c2b_data* chiplink_c2b_rst chiplink_c2b_send } ]
+ set_output_delay -max 2.45 -clock {chiplink_c2b_clock} [ get_ports { chiplink_c2b_data* chiplink_c2b_rst chiplink_c2b_send } ]
+}
+
+set group_mem [get_clocks -quiet {clk_pll_i}]
+set group_sys [get_clocks -quiet {sys_diff_clk \
+ clk_out*_vc707_sys_clock_mmcm1 \
+ clk_out*_vc707_sys_clock_mmcm2 \
+ chiplink_c2b_clock}]
+set group_cl [get_clocks -quiet {chiplink_b2c_clock \
+ clk_out*_vc707_sys_clock_mmcm3}]
+set group_pci [get_clocks -quiet {userclk1 txoutclk}]
+
+create_clock -add -name JTCK -period 100 -waveform {0 50} [get_ports {jtag_TCK}]
+if { [llength [get_ports -quiet {ulpi_clk}]] > 0 } { create_clock -add -name ULPI_CLK -period 16.667 [get_ports {ulpi_clk}] }
+
+set group_jtag [get_clocks -quiet {JTCK}]
+
+if { [llength [get_ports -quiet {ulpi_clk}]] > 0 } { set group_ulpi [get_clocks -quiet {ULPI_CLK}] }
+else {set group_ulpi {} }
+
+puts "group_mem: $group_mem"
+puts "group_sys: $group_sys"
+puts "group_pci: $group_pci"
+puts "group_cl: $group_cl"
+puts "group_jtag: $group_jtag"
+puts "group_ulpi: $group_ulpi"
+
+set groups [list]
+if { [llength $group_mem] > 0 } { lappend groups -group $group_mem }
+if { [llength $group_sys] > 0 } { lappend groups -group $group_sys }
+if { [llength $group_pci] > 0 } { lappend groups -group $group_pci }
+if { [llength $group_cl] > 0 } { lappend groups -group $group_cl }
+if { [llength $group_jtag] > 0 } { lappend groups -group $group_jtag }
+if { [llength $group_ulpi] > 0 } { lappend groups -group $group_ulpi }
+
+puts "set_clock_groups -asynchronous $groups"
+set_clock_groups -asynchronous {*}$groups
+
+set_false_path -from [get_clocks JTCK] -to [get_clocks -of_objects [get_pins lazysys/xilinxvc707mig_1/island/blackbox/u_vc707mig4gb_mig/u_iodelay_ctrl/clk_ref_mmcm_gen.mmcm_i/CLKOUT1]]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/vc707/tcl/ios.tcl b/hdl_cores/freedom/fpga-shells/xilinx/vc707/tcl/ios.tcl
new file mode 100644
index 0000000..915b683
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/vc707/tcl/ios.tcl
@@ -0,0 +1,68 @@
+#---------------Physical Constraints-----------------
+
+#get_port_part_pins
+#clk_n clk_p dip_switches_tri_i_0 dip_switches_tri_i_1 dip_switches_tri_i_2 dip_switches_tri_i_3 dip_switches_tri_i_4 dip_switches_tri_i_5 dip_switches_tri_i_6 dip_switches_tri_i_7 iic_main_scl_i iic_main_sda_i lcd_7bits_tri_o_0 lcd_7bits_tri_o_1 lcd_7bits_tri_o_2 lcd_7bits_tri_o_3 lcd_7bits_tri_o_4 lcd_7bits_tri_o_5 lcd_7bits_tri_o_6 leds_8bits_tri_o_0 leds_8bits_tri_o_1 leds_8bits_tri_o_2 leds_8bits_tri_o_3 leds_8bits_tri_o_4 leds_8bits_tri_o_5 leds_8bits_tri_o_6 leds_8bits_tri_o_7 linear_flash_addr_1 linear_flash_addr_10 linear_flash_addr_11 linear_flash_addr_12 linear_flash_addr_13 linear_flash_addr_14 linear_flash_addr_15 linear_flash_addr_16 linear_flash_addr_17 linear_flash_addr_18 linear_flash_addr_19 linear_flash_addr_2 linear_flash_addr_20 linear_flash_addr_21 linear_flash_addr_22 linear_flash_addr_23 linear_flash_addr_24 linear_flash_addr_25 linear_flash_addr_26 linear_flash_addr_3 linear_flash_addr_4 linear_flash_addr_5 linear_flash_addr_6 linear_flash_addr_7 linear_flash_addr_8 linear_flash_addr_9 linear_flash_adv_ldn linear_flash_ce_n linear_flash_dq_i_0 linear_flash_dq_i_1 linear_flash_dq_i_10 linear_flash_dq_i_11 linear_flash_dq_i_12 linear_flash_dq_i_13 linear_flash_dq_i_14 linear_flash_dq_i_15 linear_flash_dq_i_2 linear_flash_dq_i_3 linear_flash_dq_i_4 linear_flash_dq_i_5 linear_flash_dq_i_6 linear_flash_dq_i_7 linear_flash_dq_i_8 linear_flash_dq_i_9 linear_flash_oen linear_flash_wen mdc mdio_i phy_rst_out push_buttons_5bits_tri_i_0 push_buttons_5bits_tri_i_1 push_buttons_5bits_tri_i_2 push_buttons_5bits_tri_i_3 push_buttons_5bits_tri_i_4 reset rotary_inca_push_incb_tri_i_0 rotary_inca_push_incb_tri_i_1 rotary_inca_push_incb_tri_i_2 rs232_uart_rxd rs232_uart_txd sfp_rxn sfp_rxp sfp_sgmii_txn sfp_sgmii_txp sgmii_mgt_clkn sgmii_mgt_clkp sgmii_rxn sgmii_rxp sgmii_txn sgmii_txp sma_lvds_rxn sma_lvds_rxp sma_lvds_txn sma_lvds_txp sma_mgt_clkn sma_mgt_clkp sma_sfp_rxn sma_sfp_rxp sma_sfp_txn sma_sfp_txp
+
+set_property BOARD_PIN {clk_p} [get_ports sys_diff_clock_clk_p]
+set_property BOARD_PIN {clk_n} [get_ports sys_diff_clock_clk_n]
+set_property BOARD_PIN {reset} [get_ports reset]
+
+create_clock -name sys_diff_clk -period 5.0 [get_ports sys_diff_clock_clk_p]
+set_input_jitter [get_clocks -of_objects [get_ports sys_diff_clock_clk_p]] 0.5
+
+set_property BOARD_PIN {leds_8bits_tri_o_0} [get_ports led_0]
+set_property BOARD_PIN {leds_8bits_tri_o_1} [get_ports led_1]
+set_property BOARD_PIN {leds_8bits_tri_o_2} [get_ports led_2]
+set_property BOARD_PIN {leds_8bits_tri_o_3} [get_ports led_3]
+set_property BOARD_PIN {leds_8bits_tri_o_4} [get_ports led_4]
+set_property BOARD_PIN {leds_8bits_tri_o_5} [get_ports led_5]
+set_property BOARD_PIN {leds_8bits_tri_o_6} [get_ports led_6]
+set_property BOARD_PIN {leds_8bits_tri_o_7} [get_ports led_7]
+
+set_property BOARD_PIN {push_buttons_5bits_tri_i_0} [get_ports btn_0]
+set_property BOARD_PIN {push_buttons_5bits_tri_i_1} [get_ports btn_1]
+set_property BOARD_PIN {push_buttons_5bits_tri_i_2} [get_ports btn_2]
+set_property BOARD_PIN {push_buttons_5bits_tri_i_3} [get_ports btn_3]
+
+set_property BOARD_PIN {dip_switches_tri_i_0} [get_ports sw_0]
+set_property BOARD_PIN {dip_switches_tri_i_1} [get_ports sw_1]
+set_property BOARD_PIN {dip_switches_tri_i_2} [get_ports sw_2]
+set_property BOARD_PIN {dip_switches_tri_i_3} [get_ports sw_3]
+set_property BOARD_PIN {dip_switches_tri_i_4} [get_ports sw_4]
+set_property BOARD_PIN {dip_switches_tri_i_5} [get_ports sw_5]
+set_property BOARD_PIN {dip_switches_tri_i_6} [get_ports sw_6]
+set_property BOARD_PIN {dip_switches_tri_i_7} [get_ports sw_7]
+
+set_property PACKAGE_PIN AU33 [get_ports uart_rx]
+set_property IOSTANDARD LVCMOS18 [get_ports uart_rx]
+set_property IOB TRUE [get_cells -of_objects [all_fanout -flat -endpoints_only [get_ports uart_rx]]]
+set_property PACKAGE_PIN AT32 [get_ports uart_ctsn]
+set_property IOSTANDARD LVCMOS18 [get_ports uart_ctsn]
+set_property IOB TRUE [get_ports uart_ctsn]
+set_property PACKAGE_PIN AU36 [get_ports uart_tx]
+set_property IOSTANDARD LVCMOS18 [get_ports uart_tx]
+set_property IOB TRUE [get_cells -of_objects [all_fanin -flat -startpoints_only [get_ports uart_tx]]]
+set_property PACKAGE_PIN AR34 [get_ports uart_rtsn]
+set_property IOSTANDARD LVCMOS18 [get_ports uart_rtsn]
+set_property IOB TRUE [get_ports uart_rtsn]
+
+# PCI Express
+#FMC 1 refclk
+set_property PACKAGE_PIN A10 [get_ports {pcie_REFCLK_rxp}]
+set_property PACKAGE_PIN A9 [get_ports {pcie_REFCLK_rxn}]
+create_clock -name pcie_ref_clk -period 10 [get_ports pcie_REFCLK_rxp]
+set_input_jitter [get_clocks -of_objects [get_ports pcie_REFCLK_rxp]] 0.5
+
+set_property PACKAGE_PIN H4 [get_ports {pcie_pci_exp_txp}]
+set_property PACKAGE_PIN H3 [get_ports {pcie_pci_exp_txn}]
+
+set_property PACKAGE_PIN G6 [get_ports {pcie_pci_exp_rxp}]
+set_property PACKAGE_PIN G5 [get_ports {pcie_pci_exp_rxn}]
+
+# SDIO
+set_property -dict { PACKAGE_PIN AN30 IOSTANDARD LVCMOS18 IOB TRUE } [get_ports {sdio_clk}]
+set_property -dict { PACKAGE_PIN AP30 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_cmd}]
+set_property -dict { PACKAGE_PIN AR30 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_dat[0]}]
+set_property -dict { PACKAGE_PIN AU31 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_dat[1]}]
+set_property -dict { PACKAGE_PIN AV31 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_dat[2]}]
+set_property -dict { PACKAGE_PIN AT30 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_dat[3]}]
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/vc707/vsrc/sdio.v b/hdl_cores/freedom/fpga-shells/xilinx/vc707/vsrc/sdio.v
new file mode 100644
index 0000000..9528410
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/vc707/vsrc/sdio.v
@@ -0,0 +1,58 @@
+// See LICENSE for license details.
+`timescale 1ns/1ps
+`default_nettype none
+
+module sdio_spi_bridge (
+ input wire clk,
+ input wire reset,
+ // SDIO
+ inout wire sd_cmd,
+ inout wire [3:0] sd_dat,
+ output wire sd_sck,
+ // QUAD SPI
+ input wire spi_sck,
+ input wire [3:0] spi_dq_o,
+ output wire [3:0] spi_dq_i,
+ output wire spi_cs
+);
+
+ wire mosi, miso;
+(* extract_reset = "yes" *) reg miso_sync [1:0];
+ assign mosi = spi_dq_o[0];
+ assign spi_dq_i = {2'b00, miso_sync[1], 1'b0};
+
+ assign sd_sck = spi_sck;
+
+ IOBUF buf_cmd (
+ .IO(sd_cmd),
+ .I(mosi),
+ .O(),
+ .T(1'b0)
+ );
+
+ IOBUF buf_dat0 (
+ .IO(sd_dat[0]),
+ .I(),
+ .O(miso),
+ .T(1'b1)
+ );
+
+ IOBUF buf_dat3 (
+ .IO(sd_dat[3]),
+ .I(spi_cs),
+ .O(),
+ .T(1'b0)
+ );
+
+ always @(posedge clk) begin
+ if (reset) begin
+ miso_sync[0] <= 1'b0;
+ miso_sync[1] <= 1'b0;
+ end else begin
+ miso_sync[0] <= miso;
+ miso_sync[1] <= miso_sync[0];
+ end
+ end
+endmodule
+
+`default_nettype wire
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/vc707/vsrc/vc707reset.v b/hdl_cores/freedom/fpga-shells/xilinx/vc707/vsrc/vc707reset.v
new file mode 100644
index 0000000..8501027
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/vc707/vsrc/vc707reset.v
@@ -0,0 +1,78 @@
+// See LICENSE for license details.
+`timescale 1ns/1ps
+`default_nettype none
+`define RESET_SYNC 4
+`define DEBOUNCE_BITS 8
+
+module vc707reset(
+ // Asynchronous reset input, should be held high until
+ // all clocks are locked and power is stable.
+ input wire areset,
+ // Clock domains are brought up in increasing order
+ // All clocks are reset for at least 2^DEBOUNCE_BITS * period(clock1)
+ input wire clock1,
+ output wire reset1,
+ input wire clock2,
+ output wire reset2,
+ input wire clock3,
+ output wire reset3,
+ input wire clock4,
+ output wire reset4
+);
+ sifive_reset_hold hold_clock0(areset, clock1, reset1);
+ sifive_reset_sync sync_clock2(reset1, clock2, reset2);
+ sifive_reset_sync sync_clock3(reset2, clock3, reset3);
+ sifive_reset_sync sync_clock4(reset3, clock4, reset4);
+endmodule
+
+// Assumes that areset is held for more than one clock
+// Allows areset to be deasserted asynchronously
+module sifive_reset_sync(
+ input wire areset,
+ input wire clock,
+ output wire reset
+);
+ reg [`RESET_SYNC-1:0] gen_reset = {`RESET_SYNC{1'b1}};
+ always @(posedge clock, posedge areset) begin
+ if (areset) begin
+ gen_reset <= {`RESET_SYNC{1'b1}};
+ end else begin
+ gen_reset <= {1'b0,gen_reset[`RESET_SYNC-1:1]};
+ end
+ end
+ assign reset = gen_reset[0];
+endmodule
+
+module sifive_reset_hold(
+ input wire areset,
+ input wire clock,
+ output wire reset
+);
+ wire raw_reset;
+ reg [`RESET_SYNC-1:0] sync_reset = {`RESET_SYNC{1'b1}};
+ reg [`DEBOUNCE_BITS:0] debounce_reset = {`DEBOUNCE_BITS{1'b1}};
+ wire out_reset;
+
+ // Captures reset even if clock is not running
+ sifive_reset_sync capture(areset, clock, raw_reset);
+
+ // Remove any glitches due to runt areset
+ always @(posedge clock) begin
+ sync_reset <= {raw_reset,sync_reset[`RESET_SYNC-1:1]};
+ end
+
+ // Debounce the reset
+ assign out_reset = debounce_reset[`DEBOUNCE_BITS];
+ always @(posedge clock) begin
+ if (sync_reset[0]) begin
+ debounce_reset <= {(`DEBOUNCE_BITS+1){1'b1}};
+ end else begin
+ debounce_reset <= debounce_reset - out_reset;
+ end
+ end
+
+ assign reset = out_reset;
+
+endmodule
+
+`default_nettype wire
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/vcu118/constraints/vcu118-master.xdc b/hdl_cores/freedom/fpga-shells/xilinx/vcu118/constraints/vcu118-master.xdc
new file mode 100644
index 0000000..87d2324
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/vcu118/constraints/vcu118-master.xdc
@@ -0,0 +1,12 @@
+#-------------- MCS Generation ----------------------
+set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN div-1 [current_design]
+set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
+set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 8 [current_design]
+set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
+set_property BITSTREAM.CONFIG.UNUSEDPIN Pullnone [current_design]
+set_property CFGBVS GND [current_design]
+set_property CONFIG_VOLTAGE 1.8 [current_design]
+set_property CONFIG_MODE SPIx8 [current_design]
+
+
+
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/vcu118/tcl/board.tcl b/hdl_cores/freedom/fpga-shells/xilinx/vcu118/tcl/board.tcl
new file mode 100644
index 0000000..d2b3b9c
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/vcu118/tcl/board.tcl
@@ -0,0 +1,6 @@
+# See LICENSE for license details.
+set name {vcu118}
+set part_fpga {xcvu9p-flga2104-2L-e}
+# Board: xilinx.com:vcu118:part0:2.0
+# However, if we set this we cannot control PCIe locations
+set part_board {}
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/vcu118/vsrc/sdio.v b/hdl_cores/freedom/fpga-shells/xilinx/vcu118/vsrc/sdio.v
new file mode 100644
index 0000000..ff7ebc8
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/vcu118/vsrc/sdio.v
@@ -0,0 +1,59 @@
+// See LICENSE for license details.
+`timescale 1ns/1ps
+`default_nettype none
+
+module sdio_spi_bridge (
+ input wire clk,
+ input wire reset,
+ // SDIO
+ inout wire sd_cmd,
+ inout wire [3:0] sd_dat,
+ output wire sd_sck,
+ // QUAD SPI
+ input wire spi_sck,
+ input wire [3:0] spi_dq_o,
+ output wire [3:0] spi_dq_i,
+ output wire spi_cs
+);
+
+ wire mosi, miso;
+ reg miso_sync [1:0];
+
+ assign mosi = spi_dq_o[0];
+ assign spi_dq_i = {2'b00, miso_sync[1], 1'b0};
+
+ assign sd_sck = spi_sck;
+
+ IOBUF buf_cmd (
+ .IO(sd_cmd),
+ .I(mosi),
+ .O(),
+ .T(1'b0)
+ );
+
+ IOBUF buf_dat0 (
+ .IO(sd_dat[0]),
+ .I(),
+ .O(miso),
+ .T(1'b1)
+ );
+
+ IOBUF buf_dat3 (
+ .IO(sd_dat[3]),
+ .I(spi_cs),
+ .O(),
+ .T(1'b0)
+ );
+
+ always @(posedge clk) begin
+ if (reset) begin
+ miso_sync[0] <= 1'b0;
+ miso_sync[1] <= 1'b0;
+ end else begin
+ miso_sync[0] <= miso;
+ miso_sync[1] <= miso_sync[0];
+ end
+ end
+endmodule
+
+`default_nettype wire
diff --git a/hdl_cores/freedom/fpga-shells/xilinx/vcu118/vsrc/vcu118reset.v b/hdl_cores/freedom/fpga-shells/xilinx/vcu118/vsrc/vcu118reset.v
new file mode 100644
index 0000000..1e7d42d
--- /dev/null
+++ b/hdl_cores/freedom/fpga-shells/xilinx/vcu118/vsrc/vcu118reset.v
@@ -0,0 +1,78 @@
+// See LICENSE for license details.
+`timescale 1ns/1ps
+`default_nettype none
+`define RESET_SYNC 4
+`define DEBOUNCE_BITS 8
+
+module vcu118reset(
+ // Asynchronous reset input, should be held high until
+ // all clocks are locked and power is stable.
+ input wire areset,
+ // Clock domains are brought up in increasing order
+ // All clocks are reset for at least 2^DEBOUNCE_BITS * period(clock1)
+ input wire clock1,
+ output wire reset1,
+ input wire clock2,
+ output wire reset2,
+ input wire clock3,
+ output wire reset3,
+ input wire clock4,
+ output wire reset4
+);
+ sifive_reset_hold hold_clock0(areset, clock1, reset1);
+ sifive_reset_sync sync_clock2(reset1, clock2, reset2);
+ sifive_reset_sync sync_clock3(reset2, clock3, reset3);
+ sifive_reset_sync sync_clock4(reset3, clock4, reset4);
+endmodule
+
+// Assumes that areset is held for more than one clock
+// Allows areset to be deasserted asynchronously
+module sifive_reset_sync(
+ input wire areset,
+ input wire clock,
+ output wire reset
+);
+ reg [`RESET_SYNC-1:0] gen_reset = {`RESET_SYNC{1'b1}};
+ always @(posedge clock, posedge areset) begin
+ if (areset) begin
+ gen_reset <= {`RESET_SYNC{1'b1}};
+ end else begin
+ gen_reset <= {1'b0,gen_reset[`RESET_SYNC-1:1]};
+ end
+ end
+ assign reset = gen_reset[0];
+endmodule
+
+module sifive_reset_hold(
+ input wire areset,
+ input wire clock,
+ output wire reset
+);
+ wire raw_reset;
+ reg [`RESET_SYNC-1:0] sync_reset = {`RESET_SYNC{1'b1}};
+ reg [`DEBOUNCE_BITS:0] debounce_reset = {`DEBOUNCE_BITS{1'b1}};
+ wire out_reset;
+
+ // Captures reset even if clock is not running
+ sifive_reset_sync capture(areset, clock, raw_reset);
+
+ // Remove any glitches due to runt areset
+ always @(posedge clock) begin
+ sync_reset <= {raw_reset,sync_reset[`RESET_SYNC-1:1]};
+ end
+
+ // Debounce the reset
+ assign out_reset = debounce_reset[`DEBOUNCE_BITS];
+ always @(posedge clock) begin
+ if (sync_reset[0]) begin
+ debounce_reset <= {(`DEBOUNCE_BITS+1){1'b1}};
+ end else begin
+ debounce_reset <= debounce_reset - out_reset;
+ end
+ end
+
+ assign reset = out_reset;
+
+endmodule
+
+`default_nettype wire
diff --git a/hdl_cores/freedom/mitll-blocks/src/main/scala/aes.scala b/hdl_cores/freedom/mitll-blocks/src/main/scala/aes.scala
index a8d7c57..480ae7b 100644
--- a/hdl_cores/freedom/mitll-blocks/src/main/scala/aes.scala
+++ b/hdl_cores/freedom/mitll-blocks/src/main/scala/aes.scala
@@ -9,7 +9,9 @@
//--------------------------------------------------------------------------------------
package mitllBlocks.aes
-import Chisel._
+import chisel3._
+import chisel3.util._
+import chisel3.experimental.{IntParam, BaseModule}
import freechips.rocketchip.config.Field
import freechips.rocketchip.subsystem.{BaseSubsystem, PeripheryBusKey}
import freechips.rocketchip.config.Parameters
@@ -20,43 +22,62 @@ import freechips.rocketchip.tilelink._
import mitllBlocks.cep_addresses._
//--------------------------------------------------------------------------------------
-// BEGIN: Classes, Objects, and Traits to support connecting to TileLink
+// BEGIN: AES "Periphery" connections
//--------------------------------------------------------------------------------------
-case object PeripheryAESKey extends Field[Seq[AESParams]]
-trait HasPeripheryAES { this: BaseSubsystem =>
- val AESNodes = p(PeripheryAESKey).map { ps =>
- AES.attach(AESAttachParams(ps, pbus))
- }
-}
+// The following class is used to pass paramaters down into the core
+case class COREParams(
+ slave_base_addr : BigInt,
+ slave_depth : BigInt,
+ llki_base_addr : BigInt,
+ llki_depth : BigInt,
+ dev_name : String
+)
-case class AESParams(address: BigInt)
+// The following parameter pass attachment info to the lower level objects/classes/etc.
+case class COREAttachParams(
+ coreparams : COREParams,
+ llki_bus : TLBusWrapper,
+ slave_bus : TLBusWrapper,
+)
-case class AESAttachParams(
- aesparams : AESParams,
- controlBus : TLBusWrapper)
- (implicit val p : Parameters)
+// Parameters associated with the core
+case object PeripheryAESKey extends Field[Seq[COREParams]]
-class TLAES(busWidthBytes: Int, params: AESParams)(implicit p: Parameters)
- extends AES(busWidthBytes, params) with HasTLControlRegMap
+// This trait "connects" the core to the Rocket Chip and passes the parameters down
+// to the instantiation
+trait HasPeripheryAES { this: BaseSubsystem =>
+ val node = p(PeripheryAESKey).map { params =>
-object AES {
+ // Initialize the attachment parameters
+ val coreattachparams = COREAttachParams(
+ coreparams = params,
+ llki_bus = pbus,
+ slave_bus = pbus
+ )
- def attach(params: AESAttachParams): TLAES = {
- implicit val p = params.p
- val aes = LazyModule(new TLAES(params.controlBus.beatBytes, params.aesparams))
+ // Instantiate th TL module. Note: This name shows up in the generated verilog hiearchy
+ // and thus should be unique to this core and NOT a verilog reserved keyword
+ val aesmodule = LazyModule(new TLModule(coreattachparams)(p))
- params.controlBus.coupleTo(s"slave_named_aes") {
- aes.controlXing(NoCrossing) := TLFragmenter(params.controlBus.beatBytes, params.controlBus.blockBytes) := _
+ // Perform the slave "attachments" to the slave bus
+ coreattachparams.slave_bus.coupleTo(coreattachparams.coreparams.dev_name + "_slave") {
+ aesmodule.slave_node :*=
+ TLFragmenter(coreattachparams.slave_bus.beatBytes, coreattachparams.slave_bus.blockBytes) :*= _
}
- InModuleBody { aes.module.clock := params.controlBus.module.clock }
- InModuleBody { aes.module.reset := params.controlBus.module.reset }
+ // Perform the slave "attachments" to the llki bus
+ coreattachparams.llki_bus.coupleTo(coreattachparams.coreparams.dev_name + "_llki_slave") {
+ aesmodule.llki_node :*=
+ TLSourceShrinker(16) :*= _
+ }
- aes
- }
+ // Explicitly connect the clock and reset (the module will be clocked off of the slave bus)
+ InModuleBody { aesmodule.module.reset := coreattachparams.slave_bus.module.reset }
+ InModuleBody { aesmodule.module.clock := coreattachparams.slave_bus.module.clock }
+
+}}
-}
//--------------------------------------------------------------------------------------
// END: Classes, Objects, and Traits to support connecting to TileLink
//--------------------------------------------------------------------------------------
@@ -65,130 +86,216 @@ object AES {
//--------------------------------------------------------------------------------------
// BEGIN: AES TileLink Module
//--------------------------------------------------------------------------------------
-abstract class AES(busWidthBytes: Int, val c: AESParams)(implicit p: Parameters)
- extends RegisterRouter (
- RegisterRouterParams(
- name = "aes",
- compat = Seq("mitll,aes"),
- base = c.address,
- size = 0x10000, // Size should be an even power of two, otherwise the compilation causes an undefined exception
- beatBytes = busWidthBytes))
- {
-
- ResourceBinding {Resource(ResourceAnchors.aliases, "aes").bind(ResourceAlias(device.label))}
-
- lazy val module = new LazyModuleImp(this) {
-
- // Instantitate the AES blackbox
- val blackbox = Module(new aes_192)
-
- // Instantiate registers for the blackbox inputs
- val start = RegInit(0.U(1.W))
-
- // Class and companion Object to support instantiation and initialization of
- // state due to the need to have subword assignment for vectors > 64-bits
- //
- // Fields in the bundle enumerate from to low. When converting this bundle
- // to UInt it is equivalent to Cat(Word1, Word0) or if subword assignment
- // was supported:
- //
- // state(127,64) := word0
- // state(63,0) := word1
- //
- class State_Class extends Bundle {
- val word0 = UInt(64.W)
- val word1 = UInt(64.W)
- }
- object State_Class {
- def init: State_Class = {
- val wire = Wire(new State_Class)
- wire.word0 := 0.U
- wire.word1 := 0.U
- wire
- }
- }
- val state = RegInit(State_Class.init)
-
- // Class and companion Object to support instantiation and initialization of
- // key due to the need to have subword assignment for vectors > 64-bits
- class Key_Class extends Bundle {
- val word0 = UInt(64.W)
- val word1 = UInt(64.W)
- val word2 = UInt(64.W)
- }
- object Key_Class {
- def init: Key_Class = {
- val wire = Wire(new Key_Class)
- wire.word0 := 0.U
- wire.word1 := 0.U
- wire.word2 := 0.U
- wire
- }
- }
- val key = RegInit(Key_Class.init)
-
- // Instantiate wires for the blackbox outputs
- val out0 = Wire(UInt(64.W))
- val out1 = Wire(UInt(64.W))
- val out_valid = Wire(Bool())
-
- // Map the blackbox I/O
- blackbox.io.clk := clock // Implicit module clock
- blackbox.io.rst := reset // Implicit module reset
- blackbox.io.start := start // Positive edge already exists in AES core (aes_192.v)
- blackbox.io.state := state.asUInt // Convert State_Class bundle to UInt(bit vector)
- blackbox.io.key := key.asUInt // Convert Key_Class bundle to UInt(bit vector)
- out0 := blackbox.io.out(127,64) // Reading subwords in Chisel is OK
- out1 := blackbox.io.out(63,0) // Reading subwords in Chisel is OK
- out_valid := blackbox.io.out_valid // Out is valid until start is again asserted
-
- // Define the register map
- // Registers with .r suffix to RegField are Read Only (otherwise, Chisel will assume they are R/W)
- regmap (
- AESAddresses.aes_ctrlstatus_addr -> RegFieldGroup("aes_ctrlstatus", Some("AES Control/Status Register"),Seq(
- RegField (1, start, RegFieldDesc("start", "")),
- RegField.r (1, out_valid, RegFieldDesc("out_valid", "", volatile=true)))),
- AESAddresses.aes_pt0_addr -> RegFieldGroup("aes_pt1", Some("AES Plaintext Word 1"), Seq(RegField(64, state.word0))),
- AESAddresses.aes_pt1_addr -> RegFieldGroup("aes_pt1", Some("AES Plaintext Word 1"), Seq(RegField(64, state.word1))),
- AESAddresses.aes_ct0_addr -> RegFieldGroup("aes_ct0", Some("AES Ciphertext Word 0"), Seq(RegField.r(64, out0))),
- AESAddresses.aes_ct1_addr -> RegFieldGroup("aes_ct1", Some("AES Ciphertext Word 1"), Seq(RegField.r(64, out1))),
- AESAddresses.aes_key0_addr -> RegFieldGroup("aes_key0", Some("AES Key Word 0"), Seq(RegField(64, key.word0))),
- AESAddresses.aes_key1_addr -> RegFieldGroup("aes_key1", Some("AES Key Word 1"), Seq(RegField(64, key.word1))),
- AESAddresses.aes_key2_addr -> RegFieldGroup("aes_key2", Some("AES Key Word 2"), Seq(RegField(64, key.word2)))
- ) // regmap
-
- } // lazy val module
- } // abstract class AES
-//--------------------------------------------------------------------------------------
-// END: AES TileLink Module
-//--------------------------------------------------------------------------------------
+class TLModule(coreattachparams: COREAttachParams)(implicit p: Parameters) extends LazyModule {
+ // Create a Manager / Slave / Sink node
+ // The OpenTitan-based Tilelink interfaces support 4 beatbytes only
+ val llki_node = TLManagerNode(Seq(TLSlavePortParameters.v1(
+ Seq(TLSlaveParameters.v1(
+ address = Seq(AddressSet(
+ coreattachparams.coreparams.llki_base_addr,
+ coreattachparams.coreparams.llki_depth)),
+ resources = new SimpleDevice(coreattachparams.coreparams.dev_name + "-llki-slave",
+ Seq("mitll," + coreattachparams.coreparams.dev_name + "-llki-slave")).reg,
+ regionType = RegionType.IDEMPOTENT,
+ supportsGet = TransferSizes(1, coreattachparams.llki_bus.blockBytes),
+ supportsPutFull = TransferSizes(1, coreattachparams.llki_bus.blockBytes),
+ supportsPutPartial = TransferSizes(1, coreattachparams.llki_bus.blockBytes),
+ fifoId = Some(0))), // requests are handled in order
+ beatBytes = coreattachparams.llki_bus.beatBytes)))
-//--------------------------------------------------------------------------------------
-// BEGIN: Black box wrapper for Verilog Module
-//
-// Note: Name must match Verilog module name, signal names
-// declared within much match the name, width, and direction of
-// the Verilog module.
-//--------------------------------------------------------------------------------------
-class aes_192() extends BlackBox {
+ // Create the RegisterRouter node
+ val slave_node = TLRegisterNode(
+ address = Seq(AddressSet(
+ coreattachparams.coreparams.slave_base_addr,
+ coreattachparams.coreparams.slave_depth)),
+ device = new SimpleDevice(coreattachparams.coreparams.dev_name + "-slave",
+ Seq("mitll," + coreattachparams.coreparams.dev_name + "-slave")),
+ beatBytes = coreattachparams.slave_bus.beatBytes
+ )
+
+ // Instantiate the implementation
+ lazy val module = new TLModuleImp(coreattachparams.coreparams, this)
+
+}
+
+class TLModuleImp(coreparams: COREParams, outer: TLModule) extends LazyModuleImp(outer) {
+
+ // "Connect" to llki node's signals and parameters
+ val (llki, llkiEdge) = outer.llki_node.in(0)
+
+ // Define the LLKI Protocol Processing blackbox and its associated IO
+ class llki_pp_wrapper(val llki_ctrlsts_addr: BigInt, llki_sendrecv_addr: BigInt) extends BlackBox(
+ Map(
+ "CTRLSTS_ADDR" -> IntParam(llki_ctrlsts_addr), // Base address of the TL slave
+ "SENDRECV_ADDR" -> IntParam(llki_sendrecv_addr) // Address depth of the TL slave
+ )
+ ) {
+
+ val io = IO(new Bundle {
+ // Clock and Reset
+ val clk = Input(Clock())
+ val rst = Input(Bool())
+
+ // Slave - Tilelink A Channel (Signal order/names from Tilelink Specification v1.8.0)
+ val slave_a_opcode = Input(UInt(3.W))
+ val slave_a_param = Input(UInt(3.W))
+ val slave_a_size = Input(UInt(LLKITilelinkParameters.SizeBits.W))
+ val slave_a_source = Input(UInt(LLKITilelinkParameters.SourceBits.W))
+ val slave_a_address = Input(UInt(LLKITilelinkParameters.AddressBits.W))
+ val slave_a_mask = Input(UInt(LLKITilelinkParameters.BeatBytes.W))
+ val slave_a_data = Input(UInt((LLKITilelinkParameters.BeatBytes * 8).W))
+ val slave_a_corrupt = Input(Bool())
+ val slave_a_valid = Input(Bool())
+ val slave_a_ready = Output(Bool())
- val io = IO(new Bundle {
- // Clock and Reset
- val clk = Clock(INPUT)
- val rst = Bool(INPUT)
+ // Slave - Tilelink D Channel (Signal order/names from Tilelink Specification v1.8.0)
+ val slave_d_opcode = Output(UInt(3.W))
+ val slave_d_param = Output(UInt(3.W))
+ val slave_d_size = Output(UInt(LLKITilelinkParameters.SizeBits.W))
+ val slave_d_source = Output(UInt(LLKITilelinkParameters.SourceBits.W))
+ val slave_d_sink = Output(UInt(LLKITilelinkParameters.SinkBits.W))
+ val slave_d_denied = Output(Bool())
+ val slave_d_data = Output(UInt((LLKITilelinkParameters.BeatBytes * 8).W))
+ val slave_d_corrupt = Output(Bool())
+ val slave_d_valid = Output(Bool())
+ val slave_d_ready = Input(Bool())
- // Inputs
- val start = Bool(INPUT)
- val state = Bits(INPUT,128)
- val key = Bits(INPUT,192)
+ // LLKI discrete interface
+ val llkid_key_data = Output(UInt(64.W))
+ val llkid_key_valid = Output(Bool())
+ val llkid_key_ready = Input(Bool())
+ val llkid_key_complete = Input(Bool())
+ val llkid_clear_key = Output(Bool())
+ val llkid_clear_key_ack = Input(Bool())
+
+ })
+ } // end class llki_pp_wrapper
+
+ // Instantiate the LLKI Protocol Processing Block with CORE SPECIFIC decode constants
+ val llki_pp_inst = Module(new llki_pp_wrapper(CEPBaseAddresses.aes_llki_ctrlsts_addr,
+ CEPBaseAddresses.aes_llki_sendrecv_addr))
+
+ // The following "requires" are included to avoid size mismatches between the
+ // the Rocket Chip buses and the SRoT Black Box. The expected values are inhereited
+ // from the cep_addresses package and must match those in "top_pkg.sv", borrowed from OpenTitan
+ //
+ // Exceptions:
+ // - llkiEdge address gets optimized down to 31-bits during chisel generation
+ // - llkiEdge sink bits are 1, but masterEdge sink bits are 2
+ // - llkiEdge size bits are 3, but masterEdge size bits are 4
+ //
+ require(llkiEdge.bundle.addressBits == LLKITilelinkParameters.AddressBits - 1, s"SROT: llkiEdge addressBits exp/act ${LLKITilelinkParameters.AddressBits - 1}/${llkiEdge.bundle.addressBits}")
+ require(llkiEdge.bundle.dataBits == LLKITilelinkParameters.BeatBytes * 8, s"SROT: llkiEdge dataBits exp/act ${LLKITilelinkParameters.BeatBytes * 8}/${llkiEdge.bundle.dataBits}")
+ require(llkiEdge.bundle.sourceBits == LLKITilelinkParameters.SourceBits, s"SROT: llkiEdge sourceBits exp/act ${LLKITilelinkParameters.SourceBits}/${llkiEdge.bundle.sourceBits}")
+ require(llkiEdge.bundle.sinkBits == LLKITilelinkParameters.SinkBits - 1, s"SROT: llkiEdge sinkBits exp/act ${LLKITilelinkParameters.SinkBits - 1}/${llkiEdge.bundle.sinkBits}")
+ require(llkiEdge.bundle.sizeBits == LLKITilelinkParameters.SizeBits, s"SROT: llkiEdge sizeBits exp/act ${LLKITilelinkParameters.SizeBits}/${llkiEdge.bundle.sizeBits}")
+
+ // Connect the Clock and Reset
+ llki_pp_inst.io.clk := clock
+ llki_pp_inst.io.rst := reset
+
+ // Connect the Slave A Channel to the Black box IO
+ llki_pp_inst.io.slave_a_opcode := llki.a.bits.opcode
+ llki_pp_inst.io.slave_a_param := llki.a.bits.param
+ llki_pp_inst.io.slave_a_size := llki.a.bits.size
+ llki_pp_inst.io.slave_a_source := llki.a.bits.source
+ llki_pp_inst.io.slave_a_address := Cat(0.U(1.W), llki.a.bits.address)
+ llki_pp_inst.io.slave_a_mask := llki.a.bits.mask
+ llki_pp_inst.io.slave_a_data := llki.a.bits.data
+ llki_pp_inst.io.slave_a_corrupt := llki.a.bits.corrupt
+ llki_pp_inst.io.slave_a_valid := llki.a.valid
+ llki.a.ready := llki_pp_inst.io.slave_a_ready
+
+ // Connect the Slave D Channel to the Black Box IO
+ llki.d.bits.opcode := llki_pp_inst.io.slave_d_opcode
+ llki.d.bits.param := llki_pp_inst.io.slave_d_param
+ llki.d.bits.size := llki_pp_inst.io.slave_d_size
+ llki.d.bits.source := llki_pp_inst.io.slave_d_source
+ llki.d.bits.sink := llki_pp_inst.io.slave_d_sink(0)
+ llki.d.bits.denied := llki_pp_inst.io.slave_d_denied
+ llki.d.bits.data := llki_pp_inst.io.slave_d_data
+ llki.d.bits.corrupt := llki_pp_inst.io.slave_d_corrupt
+ llki.d.valid := llki_pp_inst.io.slave_d_valid
+ llki_pp_inst.io.slave_d_ready := llki.d.ready
+
+ // Define blackbox and its associated IO
+ class aes_192_mock_tss() extends BlackBox {
+
+ val io = IO(new Bundle {
+ // Clock and Reset
+ val clk = Input(Clock())
+ val rst = Input(Bool())
+
+ // Inputs
+ val start = Input(Bool())
+ val state = Input(UInt(128.W))
+ val key = Input(UInt(192.W))
// Outputs
- val out = Bits(OUTPUT,128)
- val out_valid = Bool(OUTPUT)
- })
+ val out = Output(UInt(128.W))
+ val out_valid = Output(Bool())
-}
+ // LLKI discrete interface
+ val llkid_key_data = Input(UInt(64.W))
+ val llkid_key_valid = Input(Bool())
+ val llkid_key_ready = Output(Bool())
+ val llkid_key_complete = Output(Bool())
+ val llkid_clear_key = Input(Bool())
+ val llkid_clear_key_ack = Output(Bool())
+
+ })
+
+ }
+
+ // Instantiate the blackbox
+ val aes_192_mock_tss_inst = Module(new aes_192_mock_tss())
+
+ // Map the LLKI discrete blackbox IO between the core_inst and llki_pp_inst
+ aes_192_mock_tss_inst.io.llkid_key_data := llki_pp_inst.io.llkid_key_data
+ aes_192_mock_tss_inst.io.llkid_key_valid := llki_pp_inst.io.llkid_key_valid
+ llki_pp_inst.io.llkid_key_ready := aes_192_mock_tss_inst.io.llkid_key_ready
+ llki_pp_inst.io.llkid_key_complete := aes_192_mock_tss_inst.io.llkid_key_complete
+ aes_192_mock_tss_inst.io.llkid_clear_key := llki_pp_inst.io.llkid_clear_key
+ llki_pp_inst.io.llkid_clear_key_ack := aes_192_mock_tss_inst.io.llkid_clear_key_ack
+
+ // Instantiate registers for the blackbox inputs
+ val start = RegInit(0.U(1.W))
+ val state0 = RegInit(0.U(64.W))
+ val state1 = RegInit(0.U(64.W))
+ val key0 = RegInit(0.U(64.W))
+ val key1 = RegInit(0.U(64.W))
+ val key2 = RegInit(0.U(64.W))
+ val out = Wire(UInt(128.W))
+ val out_valid = Wire(Bool())
+
+ // Map the core specific blackbox IO
+ aes_192_mock_tss_inst.io.clk := clock
+ aes_192_mock_tss_inst.io.rst := reset
+ aes_192_mock_tss_inst.io.start := start
+ aes_192_mock_tss_inst.io.state := Cat(state0, state1)
+ aes_192_mock_tss_inst.io.key := Cat(key0, key1, key2)
+ out := aes_192_mock_tss_inst.io.out
+ out_valid := aes_192_mock_tss_inst.io.out_valid
+
+ // Define the register map
+ // Registers with .r suffix to RegField are Read Only (otherwise, Chisel will assume they are R/W)
+ outer.slave_node.regmap (
+ AESAddresses.aes_ctrlstatus_addr -> RegFieldGroup("aes_ctrlstatus", Some("AES Control/Status Register"),Seq(
+ RegField (1, start, RegFieldDesc("start", "")),
+ RegField.r (1, out_valid, RegFieldDesc("out_valid", "", volatile=true)))),
+ AESAddresses.aes_pt0_addr -> RegFieldGroup("aes_pt0", Some("AES Plaintext Word 0"), Seq(RegField(64, state0))),
+ AESAddresses.aes_pt1_addr -> RegFieldGroup("aes_pt1", Some("AES Plaintext Word 1"), Seq(RegField(64, state1))),
+ AESAddresses.aes_ct0_addr -> RegFieldGroup("aes_ct0", Some("AES Ciphertext Word 0"), Seq(RegField.r(64, out(127,64)))),
+ AESAddresses.aes_ct1_addr -> RegFieldGroup("aes_ct1", Some("AES Ciphertext Word 1"), Seq(RegField.r(64, out(63,0)))),
+ AESAddresses.aes_key0_addr -> RegFieldGroup("aes_key0", Some("AES Key Word 0"), Seq(RegField(64, key0))),
+ AESAddresses.aes_key1_addr -> RegFieldGroup("aes_key1", Some("AES Key Word 1"), Seq(RegField(64, key1))),
+ AESAddresses.aes_key2_addr -> RegFieldGroup("aes_key2", Some("AES Key Word 2"), Seq(RegField(64, key2)))
+ ) // regmap
+
+} // end TLAESModuleImp
//--------------------------------------------------------------------------------------
-// END: Black box wrapper for Verilog Module
+// END: AES TileLink Module
//--------------------------------------------------------------------------------------
+
+
diff --git a/hdl_cores/freedom/mitll-blocks/src/main/scala/cep_addresses.scala b/hdl_cores/freedom/mitll-blocks/src/main/scala/cep_addresses.scala
index 61fa234..bb69061 100644
--- a/hdl_cores/freedom/mitll-blocks/src/main/scala/cep_addresses.scala
+++ b/hdl_cores/freedom/mitll-blocks/src/main/scala/cep_addresses.scala
@@ -5,17 +5,42 @@
// File : cep_addresses.scala
// Project : Common Evaluation Platform (CEP)
// Description : Defines the addresses used within CEP Cores
+// Constants related to "Functional" register decode, which occurrs in
+// the Chisel world, can be found in this package.
+// For each CEP core, there are the following two pairs of constants:
+// - _base_addr - Functional registers base address
+// - _base_depth - Functional registers address depth/size
+// - _llki_base_addr - LLKI interface base address
+// - _llki_base_depth - LLKI interface address depth/size
+//
+// Additional address constants related to the functional registers can
+// be found in this file, within the relevant object (e.g., AESAddresses)
+//
+// LLKI related address constants can be found in llki_pkg.sv as all LLKI
+// functionality exists in the SystemVerilog world.
//
//--------------------------------------------------------------------------------------
package mitllBlocks.cep_addresses
+import freechips.rocketchip.diplomacy._
+
object CEPVersion {
- val CEP_MAJOR_VERSION = 0x02
- val CEP_MINOR_VERSION = 0x71
+ val CEP_MAJOR_VERSION = 0x03
+ val CEP_MINOR_VERSION = 0x00
}
object CEPBaseAddresses {
- val aes_base_addr = 0x70000000L
+ val cep_cores_base_addr = 0x70000000L
+
+ // New (v3.0+) Address constants related to the AES Core
+ val aes_base_addr = 0x70000000L
+ val aes_depth = 0x00007fffL
+ val aes_llki_base_addr = 0x70008000L
+ val aes_llki_ctrlsts_addr = 0x70008000L
+ val aes_llki_sendrecv_addr = 0x70008008L
+ val aes_llki_depth = 0x000000ffL
+
+ // Legacy (pre-v3.0 address constants)
val md5_base_addr = 0x70010000L
val sha256_base_addr = 0x70020000L
val rsa_base_addr = 0x70030000L
@@ -23,13 +48,16 @@ object CEPBaseAddresses {
val dft_base_addr = 0x70050000L
val idft_base_addr = 0x70060000L
val fir_base_addr = 0x70070000L
- val iir_base_addr = 0x70080000L
+ val iir_base_addr = 0x70080000L
val gps_base_addr = 0x70090000L
val cepregisters_base_addr = 0x700F0000L
+ val cep_cores_depth = 0x000FFFFFL
+ val srot_base_addr = 0x70100000L
+ val srot_base_depth = 0x00007fffL
}
object AESAddresses {
- val aes_ctrlstatus_addr = 0x0000
+ val aes_ctrlstatus_addr = 0x0000
val aes_pt0_addr = 0x0008
val aes_pt1_addr = 0x0010
val aes_ct0_addr = 0x0018
@@ -69,20 +97,20 @@ object MD5Addresses {
}
object SHA256Addresses{
- val sha256_ctrlstatus_addr = 0x0000
- val sha256_block_w0 = 0x0008
- val sha256_block_w1 = 0x0010
- val sha256_block_w2 = 0x0018
- val sha256_block_w3 = 0x0020
- val sha256_block_w4 = 0x0028
- val sha256_block_w5 = 0x0030
- val sha256_block_w6 = 0x0038
- val sha256_block_w7 = 0x0040
- val sha256_done = 0x0048
- val sha256_digest_w0 = 0x0050
- val sha256_digest_w1 = 0x0058
- val sha256_digest_w2 = 0x0060
- val sha256_digest_w3 = 0x0068
+ val sha256_ctrlstatus_addr = 0x0000
+ val sha256_block_w0 = 0x0008
+ val sha256_block_w1 = 0x0010
+ val sha256_block_w2 = 0x0018
+ val sha256_block_w3 = 0x0020
+ val sha256_block_w4 = 0x0028
+ val sha256_block_w5 = 0x0030
+ val sha256_block_w6 = 0x0038
+ val sha256_block_w7 = 0x0040
+ val sha256_done = 0x0048
+ val sha256_digest_w0 = 0x0050
+ val sha256_digest_w1 = 0x0058
+ val sha256_digest_w2 = 0x0060
+ val sha256_digest_w3 = 0x0068
}
object RSAAddresses{
@@ -144,12 +172,12 @@ object IIRAddresses{
}
object FIRAddresses {
- val fir_ctrlstatus_addr = 0x0000
- val fir_datain_addr_addr = 0x0008
- val fir_datain_data_addr = 0x0010
- val fir_dataout_addr_addr = 0x0018
- val fir_dataout_data_addr = 0x0020
- val fir_reset_addr = 0x0028
+ val fir_ctrlstatus_addr = 0x0000
+ val fir_datain_addr_addr = 0x0008
+ val fir_datain_data_addr = 0x0010
+ val fir_dataout_addr_addr = 0x0018
+ val fir_dataout_data_addr = 0x0020
+ val fir_reset_addr = 0x0028
}
object CEPRegisterAddresses {
@@ -168,4 +196,18 @@ object CEPRegisterAddresses {
val core1_status = 0x0208
val core2_status = 0x0210
val core3_status = 0x0218
+ val scratch32_w0 = 0x0220
+}
+
+// These are intended to be the universal TL parameters
+// for all the LLKI-enabled cores (including the SRoT).
+// They need to match those values called out in top_pkg.sv
+// Exceptions (when needed) are explictly coded into
+// the specific TLModuleImp
+object LLKITilelinkParameters {
+ val BeatBytes = 8 // Should be = TL_DW / 8
+ val AddressBits = 32 // Should be = TL_DW
+ val SourceBits = 4 // Should be = TL_AIW
+ val SinkBits = 2 // Should be = TL_DIW
+ val SizeBits = 3 // Should be = TL_SZW
}
\ No newline at end of file
diff --git a/hdl_cores/freedom/mitll-blocks/src/main/scala/cep_registers.scala b/hdl_cores/freedom/mitll-blocks/src/main/scala/cep_registers.scala
index d1d2660..d018064 100644
--- a/hdl_cores/freedom/mitll-blocks/src/main/scala/cep_registers.scala
+++ b/hdl_cores/freedom/mitll-blocks/src/main/scala/cep_registers.scala
@@ -109,6 +109,7 @@ abstract class CEPREGS(busWidthBytes: Int, val c: CEPREGSParams)(implicit p: Par
val word5 = UInt(64.W)
val word6 = UInt(64.W)
val word7 = UInt(64.W)
+ val word32_0 = UInt(32.W)
}
object scratch_Class {
def init: scratch_Class = {
@@ -121,6 +122,7 @@ abstract class CEPREGS(busWidthBytes: Int, val c: CEPREGSParams)(implicit p: Par
wire.word5 := 0.U
wire.word6 := 0.U
wire.word7 := 0.U
+ wire.word32_0 := 0.U
wire
}
}
@@ -241,7 +243,7 @@ abstract class CEPREGS(busWidthBytes: Int, val c: CEPREGSParams)(implicit p: Par
CEPRegisterAddresses.core0_status -> RegFieldGroup("core0 Status", Some("core0 status"), Seq(RegField (64, core0_status))),
CEPRegisterAddresses.core1_status -> RegFieldGroup("core1 Status", Some("core0 status"), Seq(RegField (64, core1_status))),
CEPRegisterAddresses.core2_status -> RegFieldGroup("core2 Status", Some("core0 status"), Seq(RegField (64, core2_status))),
- CEPRegisterAddresses.core3_status -> RegFieldGroup("core3 Status", Some("core0 status"), Seq(RegField (64, core3_status))),
+ CEPRegisterAddresses.core3_status -> RegFieldGroup("core3 Status", Some("core0 status"), Seq(RegField (64, core3_status)))
)
}
}
diff --git a/hdl_cores/freedom/mitll-blocks/src/main/scala/srot.scala b/hdl_cores/freedom/mitll-blocks/src/main/scala/srot.scala
new file mode 100644
index 0000000..09bf1ef
--- /dev/null
+++ b/hdl_cores/freedom/mitll-blocks/src/main/scala/srot.scala
@@ -0,0 +1,280 @@
+//--------------------------------------------------------------------------------------
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX short identifier: BSD-2-Clause
+//
+// File : srot.scala
+// Project : Common Evaluation Platform (CEP)
+// Description : TileLink interface to the Surrogate Root of Trust (SRoT)
+// The Surrogate Root of Trust serves as a slave on the periphery
+// bus AND a master on the Front Bus
+//
+//--------------------------------------------------------------------------------------
+package mitllBlocks.srot
+
+import chisel3._
+import chisel3.util._
+import chisel3.experimental.{IntParam, BaseModule}
+import freechips.rocketchip.config.Field
+import freechips.rocketchip.subsystem.{BaseSubsystem, PeripheryBusKey}
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.regmapper._
+import freechips.rocketchip.tilelink._
+
+import mitllBlocks.cep_addresses._
+
+//--------------------------------------------------------------------------------------
+// BEGIN: SRoT "Periphery" connections
+//--------------------------------------------------------------------------------------
+
+// The following class is used to pass paramaters down into the SROT
+case class SROTParams(
+ slave_address : BigInt,
+ slave_depth : BigInt
+)
+
+// The following parameter pass attachment info to the lower level objects/classes/etc.
+case class SROTAttachParams(
+ srotparams : SROTParams,
+ slave_bus : TLBusWrapper,
+ master_bus : TLBusWrapper
+)
+
+// Parameters associated with the SROT
+case object SROTKey extends Field[Seq[SROTParams]]
+
+// This trait "connects" the SRoT to the Rocket Chip and passes the parameters down
+// to the instantiation
+trait HasSROT { this: BaseSubsystem =>
+ val SROTNodes = p(SROTKey).map { params =>
+
+ // Initialize the attachment parameters
+ val srotattachparams = SROTAttachParams(
+ srotparams = params,
+ slave_bus = pbus,
+ master_bus = fbus
+ )
+
+ // Define the SRoT Tilelink module
+ val srotModule = LazyModule(new TLSROTModule(srotattachparams)(p))
+
+ // Perform the slave "attachments" to the periphery bus
+ srotattachparams.slave_bus.coupleTo("srot_slave") {
+ srotModule.slave_node :*=
+ TLSourceShrinker(16) :*= _
+ }
+
+ // Perform the master "attachments" to the front bus
+ srotattachparams.master_bus.coupleFrom("srot_master") {
+ _ :=
+ srotModule.master_node
+ }
+
+ // Explicitly connect the clock and reset (the module will be clocked off of the slave bus)
+ InModuleBody { srotModule.module.clock := srotattachparams.slave_bus.module.clock }
+ InModuleBody { srotModule.module.reset := srotattachparams.slave_bus.module.reset }
+
+}}
+
+//--------------------------------------------------------------------------------------
+// END: SRoT "Periphery" connections
+//--------------------------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------------------------
+// BEGIN: Tilelink SROT Module and Module Implementation Declerations
+//
+// Note: If one does not explicitly put "supportsPutFull" and/or "supportsPullPartial"
+// in the slave parameters, the manager will be instantiated as Read Only (and will
+// show up as such in the device tree. Also, the chisel optimization that gets
+// "kicked off" because of the inclusion of diplomacy widgets will result in the A
+// channel data bus being tied to ZERO.
+//--------------------------------------------------------------------------------------
+class TLSROTModule(srotattachparams: SROTAttachParams)(implicit p: Parameters) extends LazyModule {
+
+ // Create a Manager / Slave / Sink node
+ val slave_node = TLManagerNode(Seq(TLSlavePortParameters.v1(
+ Seq(TLSlaveParameters.v1(
+ address = Seq(AddressSet(
+ srotattachparams.srotparams.slave_address,
+ srotattachparams.srotparams.slave_depth)),
+ resources = new SimpleDevice("srot-slave", Seq("mitll,srot-slave")).reg,
+ regionType = RegionType.IDEMPOTENT,
+ supportsGet = TransferSizes(1, srotattachparams.slave_bus.blockBytes),
+ supportsPutFull = TransferSizes(1, srotattachparams.slave_bus.blockBytes),
+ supportsPutPartial = TransferSizes(1, srotattachparams.slave_bus.blockBytes),
+ fifoId = Some(0))), // requests are handled in order
+ beatBytes = LLKITilelinkParameters.BeatBytes)))
+
+ // Create a Client / Master / Source node
+ // The sourceID paramater assumes there are two masters on the fbus (Debug Module, SRoT)
+ // This client node is "constained" to only talk to the CEP cores (via the visibility
+ // parameter)
+ val master_node = TLClientNode(Seq(TLMasterPortParameters.v1(
+ Seq(TLMasterParameters.v1(
+ name = "srot_master0",
+ sourceId = IdRange(0, 15),
+ requestFifo = true,
+ visibility = Seq(AddressSet(CEPBaseAddresses.cep_cores_base_addr, CEPBaseAddresses.cep_cores_depth))
+ ))
+ )))
+
+ // Instantiate the implementation
+ lazy val module = new TLSROTModuleImp(srotattachparams.srotparams, this)
+
+} // end TLSROTModule
+
+class TLSROTModuleImp(srotparams: SROTParams, outer: TLSROTModule) extends LazyModuleImp(outer) {
+
+ // "Connect" to Slave Node's signals and parameters
+ val (slave, slaveEdge) = outer.slave_node.in(0)
+
+ // "Connect" to Master Node's signals and parameters
+ val (master, masterEdge) = outer.master_node.out(0)
+
+ // Define srot_wrapper blackbox and its associated IO
+ class srot_wrapper(val address: BigInt, depth: BigInt) extends BlackBox(
+ Map(
+ "ADDRESS" -> IntParam(address), // Base address of the TL slave
+ "DEPTH" -> IntParam(depth) // Address depth of the TL slave
+ )
+ ) {
+
+ val io = IO(new Bundle {
+ // Clock and Reset
+ val clk = Input(Clock())
+ val rst = Input(Bool())
+
+ // Slave - Tilelink A Channel (Signal order/names from Tilelink Specification v1.8.0)
+ val slave_a_opcode = Input(UInt(3.W))
+ val slave_a_param = Input(UInt(3.W))
+ val slave_a_size = Input(UInt(LLKITilelinkParameters.SizeBits.W))
+ val slave_a_source = Input(UInt(LLKITilelinkParameters.SourceBits.W))
+ val slave_a_address = Input(UInt(LLKITilelinkParameters.AddressBits.W))
+ val slave_a_mask = Input(UInt(LLKITilelinkParameters.BeatBytes.W))
+ val slave_a_data = Input(UInt((LLKITilelinkParameters.BeatBytes * 8).W))
+ val slave_a_corrupt = Input(Bool())
+ val slave_a_valid = Input(Bool())
+ val slave_a_ready = Output(Bool())
+
+ // Slave - Tilelink D Channel (Signal order/names from Tilelink Specification v1.8.0)
+ val slave_d_opcode = Output(UInt(3.W))
+ val slave_d_param = Output(UInt(3.W))
+ val slave_d_size = Output(UInt(LLKITilelinkParameters.SizeBits.W))
+ val slave_d_source = Output(UInt(LLKITilelinkParameters.SourceBits.W))
+ val slave_d_sink = Output(UInt(LLKITilelinkParameters.SinkBits.W))
+ val slave_d_denied = Output(Bool())
+ val slave_d_data = Output(UInt((LLKITilelinkParameters.BeatBytes * 8).W))
+ val slave_d_corrupt = Output(Bool())
+ val slave_d_valid = Output(Bool())
+ val slave_d_ready = Input(Bool())
+
+ // Master - Tilelink A Channel (Signal order/names from Tilelink Specification v1.8.0)
+ val master_a_opcode = Output(UInt(3.W))
+ val master_a_param = Output(UInt(3.W))
+ val master_a_size = Output(UInt(LLKITilelinkParameters.SizeBits.W))
+ val master_a_source = Output(UInt(LLKITilelinkParameters.SourceBits.W))
+ val master_a_address = Output(UInt(LLKITilelinkParameters.AddressBits.W))
+ val master_a_mask = Output(UInt(LLKITilelinkParameters.BeatBytes.W))
+ val master_a_data = Output(UInt((LLKITilelinkParameters.BeatBytes * 8).W))
+ val master_a_corrupt = Output(Bool())
+ val master_a_valid = Output(Bool())
+ val master_a_ready = Input(Bool())
+
+ // Master - Tilelink D Channel (Signal order/names from Tilelink Specification v1.8.0)
+ val master_d_opcode = Input(UInt(3.W))
+ val master_d_param = Input(UInt(3.W))
+ val master_d_size = Input(UInt(LLKITilelinkParameters.SizeBits.W))
+ val master_d_source = Input(UInt(LLKITilelinkParameters.SourceBits.W))
+ val master_d_sink = Input(UInt(LLKITilelinkParameters.SinkBits.W))
+ val master_d_denied = Input(Bool())
+ val master_d_data = Input(UInt((LLKITilelinkParameters.BeatBytes * 8).W))
+ val master_d_corrupt = Input(Bool())
+ val master_d_valid = Input(Bool())
+ val master_d_ready = Output(Bool())
+
+ })
+ } // end class srot_wrapper
+
+
+ // Instantiate the srot_wrapper
+ val srot_wrapper_inst = Module(new srot_wrapper(srotparams.slave_address, srotparams.slave_depth))
+
+ // The following "requires" are included to avoid size mismatches between the
+ // the Rocket Chip buses and the SRoT Black Box. The expected values are inhereited
+ // from the cep_addresses package and must match those in "top_pkg.sv", borrowed from OpenTitan
+ //
+ // Exceptions:
+ // - slaveEdge address gets optimized down to 31-bits during chisel generation
+ // - slaveEdge sink bits are 1, but masterEdge sink bits are 2
+ // - slaveEdge size bits are 3, but masterEdge size bits are 4
+ //
+ require(slaveEdge.bundle.addressBits == LLKITilelinkParameters.AddressBits - 1, s"SROT: slaveEdge addressBits exp/act ${LLKITilelinkParameters.AddressBits - 1}/${slaveEdge.bundle.addressBits}")
+ require(slaveEdge.bundle.dataBits == LLKITilelinkParameters.BeatBytes * 8, s"SROT: slaveEdge dataBits exp/act ${LLKITilelinkParameters.BeatBytes * 8}/${slaveEdge.bundle.dataBits}")
+ require(slaveEdge.bundle.sourceBits == LLKITilelinkParameters.SourceBits, s"SROT: slaveEdge sourceBits exp/act ${LLKITilelinkParameters.SourceBits}/${slaveEdge.bundle.sourceBits}")
+ require(slaveEdge.bundle.sinkBits == LLKITilelinkParameters.SinkBits - 1, s"SROT: slaveEdge sinkBits exp/act ${LLKITilelinkParameters.SinkBits - 1}/${slaveEdge.bundle.sinkBits}")
+ require(slaveEdge.bundle.sizeBits == LLKITilelinkParameters.SizeBits, s"SROT: slaveEdge sizeBits exp/act ${LLKITilelinkParameters.SizeBits}/${slaveEdge.bundle.sizeBits}")
+
+ require(masterEdge.bundle.addressBits == LLKITilelinkParameters.AddressBits, s"SROT: masterEdge addressBits exp/act ${LLKITilelinkParameters.AddressBits}/${masterEdge.bundle.addressBits}")
+ require(masterEdge.bundle.dataBits == LLKITilelinkParameters.BeatBytes * 8, s"SROT: masterEdge dataBits exp/act ${LLKITilelinkParameters.BeatBytes * 8}/${masterEdge.bundle.dataBits}")
+ require(masterEdge.bundle.sourceBits == LLKITilelinkParameters.SourceBits, s"SROT: masterEdge sourceBits exp/act ${LLKITilelinkParameters.SourceBits}/${masterEdge.bundle.sourceBits}")
+ require(masterEdge.bundle.sinkBits == LLKITilelinkParameters.SinkBits, s"SROT: masterEdge sinkBits exp/act ${LLKITilelinkParameters.SinkBits}/${masterEdge.bundle.sinkBits}")
+ require(masterEdge.bundle.sizeBits == LLKITilelinkParameters.SizeBits + 1, s"SROT: masterEdge sizeBits exp/act ${LLKITilelinkParameters.SizeBits + 1}/${masterEdge.bundle.sizeBits}")
+
+ // Connect the Clock and Reset
+ srot_wrapper_inst.io.clk := clock
+ srot_wrapper_inst.io.rst := reset
+
+ // Connect the Slave A Channel to the Black box IO
+ srot_wrapper_inst.io.slave_a_opcode := slave.a.bits.opcode
+ srot_wrapper_inst.io.slave_a_param := slave.a.bits.param
+ srot_wrapper_inst.io.slave_a_size := slave.a.bits.size
+ srot_wrapper_inst.io.slave_a_source := slave.a.bits.source
+ srot_wrapper_inst.io.slave_a_address := Cat(0.U(1.W), slave.a.bits.address)
+ srot_wrapper_inst.io.slave_a_mask := slave.a.bits.mask
+ srot_wrapper_inst.io.slave_a_data := slave.a.bits.data
+ srot_wrapper_inst.io.slave_a_corrupt := slave.a.bits.corrupt
+ srot_wrapper_inst.io.slave_a_valid := slave.a.valid
+ slave.a.ready := srot_wrapper_inst.io.slave_a_ready
+
+ // Connect the Slave D Channel to the Black Box IO
+ slave.d.bits.opcode := srot_wrapper_inst.io.slave_d_opcode
+ slave.d.bits.param := srot_wrapper_inst.io.slave_d_param
+ slave.d.bits.size := srot_wrapper_inst.io.slave_d_size
+ slave.d.bits.source := srot_wrapper_inst.io.slave_d_source
+ slave.d.bits.sink := srot_wrapper_inst.io.slave_d_sink(0)
+ slave.d.bits.denied := srot_wrapper_inst.io.slave_d_denied
+ slave.d.bits.data := srot_wrapper_inst.io.slave_d_data
+ slave.d.bits.corrupt := srot_wrapper_inst.io.slave_d_corrupt
+ slave.d.valid := srot_wrapper_inst.io.slave_d_valid
+ srot_wrapper_inst.io.slave_d_ready := slave.d.ready
+
+ // Connect the Master A channel to the Black Box IO
+ master.a.bits.opcode := srot_wrapper_inst.io.master_a_opcode
+ master.a.bits.param := srot_wrapper_inst.io.master_a_param
+ master.a.bits.size := Cat(0.U(1.W), srot_wrapper_inst.io.master_a_size)
+ master.a.bits.source := srot_wrapper_inst.io.master_a_source
+ master.a.bits.address := srot_wrapper_inst.io.master_a_address
+ master.a.bits.mask := srot_wrapper_inst.io.master_a_mask
+ master.a.bits.data := srot_wrapper_inst.io.master_a_data
+ master.a.bits.corrupt := srot_wrapper_inst.io.master_a_corrupt
+ master.a.valid := srot_wrapper_inst.io.master_a_valid
+ srot_wrapper_inst.io.master_a_ready := master.a.ready
+
+ // Connect the Master D channel to the Black Box IO
+ srot_wrapper_inst.io.master_d_opcode := master.d.bits.opcode
+ srot_wrapper_inst.io.master_d_param := master.d.bits.param
+ srot_wrapper_inst.io.master_d_size := master.d.bits.size(2,0)
+ srot_wrapper_inst.io.master_d_source := master.d.bits.source
+ srot_wrapper_inst.io.master_d_sink := master.d.bits.sink
+ srot_wrapper_inst.io.master_d_denied := master.d.bits.denied
+ srot_wrapper_inst.io.master_d_data := master.d.bits.data
+ srot_wrapper_inst.io.master_d_corrupt := master.d.bits.corrupt
+ srot_wrapper_inst.io.master_d_valid := master.d.valid
+ master.d.ready := srot_wrapper_inst.io.master_d_ready
+
+} // end TLSROTModuleImp
+//--------------------------------------------------------------------------------------
+// END: Tilelink SROT Module and Module Implementation Declerations
+//--------------------------------------------------------------------------------------
+
diff --git a/hdl_cores/freedom/src/main/scala/unleashed/DevKitConfigs.scala b/hdl_cores/freedom/src/main/scala/unleashed/DevKitConfigs.scala
index 3c2cf47..3381f85 100644
--- a/hdl_cores/freedom/src/main/scala/unleashed/DevKitConfigs.scala
+++ b/hdl_cores/freedom/src/main/scala/unleashed/DevKitConfigs.scala
@@ -26,12 +26,15 @@ import mitllBlocks.des3._
import mitllBlocks.md5._
import mitllBlocks.gps._
import mitllBlocks.dft._
+import mitllBlocks.srot._
// Default FreedomU500Config
class FreedomU500Config extends Config(
new WithJtagDTM ++
new WithNMemoryChannels(1) ++
new WithNBigCores(4) ++
+ new WithoutTLMonitors ++
+ new WithDTS("mit-ll,rocketchip-cep", Nil) ++
new BaseConfig
)
@@ -45,10 +48,16 @@ class U500DevKitPeripherals extends Config((site, here, up) => {
GPIOParams(address = BigInt(0x64002000L), width = 4))
case PeripheryMaskROMKey => List(
MaskROMParams(address = 0x10000, name = "BootROM", depth = 4096))
-case PeripheryDES3Key => List(
+ case PeripheryDES3Key => List(
DES3Params(address = BigInt(CEPBaseAddresses.des3_base_addr)))
case PeripheryAESKey => List(
- AESParams(address = BigInt(CEPBaseAddresses.aes_base_addr)))
+ COREParams(
+ slave_base_addr = BigInt(CEPBaseAddresses.aes_base_addr),
+ slave_depth = BigInt(CEPBaseAddresses.aes_depth),
+ llki_base_addr = BigInt(CEPBaseAddresses.aes_llki_base_addr),
+ llki_depth = BigInt(CEPBaseAddresses.aes_llki_depth),
+ dev_name = s"aes"
+ ))
case PeripheryIIRKey => List(
IIRParams(address = BigInt(CEPBaseAddresses.iir_base_addr)))
case PeripheryIDFTKey => List(
@@ -67,6 +76,11 @@ case PeripheryDES3Key => List(
RSAParams(address = BigInt(CEPBaseAddresses.rsa_base_addr)))
case PeripheryCEPRegistersKey => List(
CEPREGSParams(address = BigInt(CEPBaseAddresses.cepregisters_base_addr)))
+ case SROTKey => List(
+ SROTParams(
+ slave_address = BigInt(CEPBaseAddresses.srot_base_addr),
+ slave_depth = BigInt(CEPBaseAddresses.srot_base_depth)
+ ))
})
// Freedom U500 Dev Kit
diff --git a/hdl_cores/freedom/src/main/scala/unleashed/DevKitFPGADesign.scala b/hdl_cores/freedom/src/main/scala/unleashed/DevKitFPGADesign.scala
index 87105c3..9b213aa 100644
--- a/hdl_cores/freedom/src/main/scala/unleashed/DevKitFPGADesign.scala
+++ b/hdl_cores/freedom/src/main/scala/unleashed/DevKitFPGADesign.scala
@@ -38,6 +38,7 @@ import mitllBlocks.des3._
import mitllBlocks.md5._
import mitllBlocks.gps._
import mitllBlocks.dft._
+import mitllBlocks.srot._
object PinGen {
def apply(): BasePin = {
@@ -92,6 +93,7 @@ class DevKitFPGADesign(wranglerNode: ClockAdapterNode, corePLL: PLLNode)(implici
with HasPeripheryDES3
with HasPeripheryGPS
with HasPeripheryMD5
+ with HasSROT
{
val tlclock = new FixedClockResource("tlclk", p(DevKitFPGAFrequencyKey))
diff --git a/hdl_cores/gps/gps_clkgen.v b/hdl_cores/gps/gps_clkgen.v
index dcf4df1..1803789 100644
--- a/hdl_cores/gps/gps_clkgen.v
+++ b/hdl_cores/gps/gps_clkgen.v
@@ -23,6 +23,8 @@ output gps_clk_fast;
output gps_clk_slow;
output gps_rst;
+reg [2:0] count = 3'h0;
+reg enable_slow_clk;
`ifdef SYNTHESIS
wire clk_fb;
diff --git a/hdl_cores/llki/llki_pkg.sv b/hdl_cores/llki/llki_pkg.sv
new file mode 100644
index 0000000..c3e390d
--- /dev/null
+++ b/hdl_cores/llki/llki_pkg.sv
@@ -0,0 +1,258 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX short identifier: BSD-2-Clause
+//
+// File Name: llki_pkg.sv
+// Program: Common Evaluation Platform (CEP)
+// Description: LLKI related parameters and such.
+// Notes: Addresses must reside "within" the corresponding
+// range as specified in cep_addresses.scala.
+//
+// Example: For the Surrogate Root of Trust (SRoT)
+// cep_addresses.scala specifies
+// val srot_base_addr = 0x70100000L
+// val srot_base_depth = 0x00007fffL
+// As a result, the SROT_XXXX addresses must
+// reside in this ranges (due to hierarchical decode)
+//
+// The address and bitmappings here should match
+// those in CEP.h (to allow for SW access)
+//
+//************************************************************************
+
+package llki_pkg;
+
+ // SROT Control / Status Register
+ localparam SROT_CTRLSTS_ADDR = 32'h7010_0000;
+ localparam SROT_CTRLSTS_MODEBIT_0 = 0; // If either mode bit is set, TileLink access to the Key and Key Index RAMs are disabled
+ localparam SROT_CTRLSTS_MODEBIT_1 = 1; // These bits are SET ONLY
+ localparam SROT_CTRLSTS_RESP_WAITING = 2; // Indicates that a message/response is available in the SROT_RESPONSE_ADDR register
+ localparam SROT_LLKIC2_SENDRECV_ADDR = 32'h7010_0008;
+
+ // All LLKI Protocol Processing blocks will use the same SystemVerilog code, and thus
+ // will have their decode addresses uniquified through module parameters. These will be
+ // passed down from the Chisel level of the design (and ths the addresses are contained
+ // in cep_addresses.scala). Common parameters (such as the LLKI_CTRLSTS_RESP_WAITING
+ // bit mapped will be contained here)
+
+ localparam LLKIKL_CTRLSTS_RESP_WAITING = 0; // Indicates that a message/response is available
+ // in the LLKI PP control/status register
+ localparam LLKIKL_CTRLSTS_READY_FOR_KEY = 1; // The LLKI-PP provides minimal buffering for
+ // messages (and key words) received from
+ // Thus, the SRoT can poll the ready for key
+ // bit in the LLKI-PP Control/Status register
+ // to determine that the LLKI-PP (and TSS) is
+ // ready to receive the next key word
+
+
+ // The Key Index RAM holds single word identifiers that contain
+ // metadata for all the keys stored in the Key RAM
+ //
+ // 63 62 40 39 32 31 16 15 0
+ // +-+---------------------+-----------+----------------+----------------+
+ // |V| Reserved | Core Indx | High Pointer | Low Pointer |
+ // +-+---------------------+-----------+----------------+----------------+
+ //
+ // Field descriptions:
+ // - Valid : Indicates a valid key index and valid key material in the
+ // range identified to by the high and low pointers
+ // - Core Indx : Pointer to an entry in LLKI_CORE_INDEX_ROM that determines
+ // which LLKI-enabled core is the target of the current operation
+ // - High Pointer : Upper Key RAM addr
+ // - Low Pointer : Lower Key RAM addr
+ //
+ // For a valid key index, the key data words should be located in the
+ // Key RAM as described here: Higher Pointer >= Key#N >= Low Pointer
+ //
+ // This error condition as well as other are checked in the ST_RETRIEVE_KEY_INDEX state
+ // of the SRoT state machine (in srot_wrapper.sv)
+ //
+ localparam SROT_KEYINDEXRAM_ADDR = 32'h7010_0100;
+ localparam SROT_KEYINDEXRAM_SIZE = 32'h0000_0020;
+
+ // Holds the LLKI keys as referenced by the those words in the KeyIndex RAM
+ localparam SROT_KEYRAM_ADDR = 32'h7010_0120;
+ localparam SROT_KEYRAM_SIZE = 32'h0000_0100;
+
+ // Generate a list of all the valid LLKI Key Load interface
+ // address pairs: One for send/receive, one for control/status
+ // Ensure these match the equivalent constants in cep_addresses.scala
+ localparam AES_LLKIKL_CTRLSTS_ADDR = 32'h7000_8000;
+ localparam AES_LLKIKL_SENDRECV_ADDR = 32'h7000_8008;
+
+ localparam LLKI_CTRLSTS_INDEX = 0;
+ localparam LLKI_SENDRECV_INDEX = 1;
+
+ localparam [31:0] LLKI_CORE_INDEX_ARRAY [0:0][0:1] = '{
+ {AES_LLKIKL_CTRLSTS_ADDR, AES_LLKIKL_SENDRECV_ADDR}
+ };
+
+ //
+ // The LLKI is comprised of the following three interface types:
+ // LLKI-C2 : Using Tilelink, it supports the following message types:
+ // C2LoadKeyReq : Load a key into the specified Core
+ // C2ClearKeyReq : Clear the key from the specified Core
+ // C2KeyStatusReq : Request key status from the specified Core
+ // C2LoadKeyAck : Load key acknowledgement
+ // C2ClearKeyAck : Clear key acknowledgement
+ // C2KeyStatusResp : Response to the Key Status Requests
+ // LLKI-KL : Using Tilelink, it supports the following message types:
+ // KLLoadKeyReq : Load a key into the specified Core
+ // KLClearKeyReq : Clear the key from the specified Core
+ // KLKeyStatusReq : Request key status from the specified Core
+ // KLLoadKeyAck : Load key acknowledgement
+ // KLClearKeyAck : Clear key acknowledgement
+ // KLKeyStatusResp : Response to the Key Status Requests
+ // LLKI-Discrete : Discrete signals for connecting the LLKI to Technique Specific Shims
+ // llkid_key_data : Key Data Bits, greater key widths loaded over multiple clock cycles
+ // llkid_key_valid : Indicates that the key data is valid
+ // llkid_key_ready : Indicates that the TSS is ready to receive key data
+ // llkid_key_complete : Indicates that the TSS has received all the required key bits
+ // llkid_clear_key : Assert to instruct the TSS to clear its internal key-state, thus "locking" the core
+ // llkid_clear_key_ack : When asserted by the TSS, it indicates that the key has been cleared
+ //
+ //
+ // LLKI C2 RISCV -> SRoT Message Format
+ //
+ // Word#
+ // 63 32 31 24 23 16 15 8 7 0
+ // +----------------------------------+-------+---------+--------+--------+
+ // | Reserved |Key Idx| MSG LEN | STATUS | MSG ID | 1
+ // +----------------------------------+-------+---------+--------+--------+
+
+ //
+ // MSG ID : Only the following message IDs are valid on the LLKIC2 request interface:
+ // - LLKI_MID_C2LOADKEYREQ
+ // - LLKI_MID_C2CLEARKEYREQ
+ // - LLKI_MID_C2KEYSTATUSREQ
+ //
+ // STATUS :
+ // - Unused for C2 RISCV -> SRoT Messages
+ //
+ // MSG LEN :
+ // - Should be 1 for all C2 RISCV -> SRoT Messages
+ //
+ // Key Idx : Specifies the index of the key to be referenced by the request. This
+ // becomes a direct index into the Key Index RAM, which contains all the key
+ // specific metadata. See Key Index RAM format above for more information.
+ // LLKI Message ID constants
+ localparam LLKI_MID_C2LOADKEYREQ = 8'h00;
+ localparam LLKI_MID_C2CLEARKEYREQ = 8'h01;
+ localparam LLKI_MID_C2KEYSTATUSREQ = 8'h02;
+ localparam LLKI_MID_C2LOADKEYACK = 8'h03;
+ localparam LLKI_MID_C2CLEARKEYACK = 8'h04;
+ localparam LLKI_MID_C2KEYSTATUSRESP = 8'h05;
+ localparam LLKI_MID_C2ERRORRESP = 8'h06;
+
+
+ // LLKI KL SRoT -> LLKI PP Message Format
+ // NOTE: Each word transferred is a SEPERATE Tilelink transaction
+ //
+ // Word#
+ // 63 24 23 16 15 8 7 0
+ // +------------------------------------------+---------+--------+--------+
+ // | Reserved | MSG LEN | STATUS | MSG ID | 1
+ // +------------------------------------------+---------+--------+--------+
+ // ...
+ // +----------------------------------------------------------------------+
+ // | Key Word #1 (LLKI_MID_KLLOADKEYREQ message only) | 2
+ // +----------------------------------------------------------------------+
+ // ...
+ // +----------------------------------------------------------------------+
+ // | Key Word #N (LLKI_MID_KLLOADKEYREQ message only) | N + 1
+ // +----------------------------------------------------------------------+
+ //
+ //
+ // MSG ID : Only the following message IDs are valid on the LLKIC2 request interface:
+ // - LLKI_MID_C2LOADKEYREQ
+ // - LLKI_MID_C2CLEARKEYREQ
+ // - LLKI_MID_C2KEYSTATUSREQ
+ localparam LLKI_MID_KLLOADKEYREQ = 8'h07;
+ localparam LLKI_MID_KLCLEARKEYREQ = 8'h08;
+ localparam LLKI_MID_KLKEYSTATUSREQ = 8'h09;
+ localparam LLKI_MID_KLLOADKEYACK = 8'h0A;
+ localparam LLKI_MID_KLCLEARKEYACK = 8'h0B;
+ localparam LLKI_MID_KLKEYSTATUSRESP = 8'h0C;
+ localparam LLKI_MID_KLERRORRESP = 8'h06;
+
+ // LLKI Status Constants
+ localparam LLKI_STATUS_GOOD = 8'h00;
+ localparam LLKI_STATUS_KEY_PRESENT = 8'h01;
+ localparam LLKI_STATUS_KEY_NOT_PRESENT = 9'h02;
+
+ localparam LLKI_STATUS_BAD_MSG_ID = 8'h20;
+ localparam LLKI_STATUS_BAD_MSG_LEN = 8'h21;
+ localparam LLKI_STATUS_KEY_INDX_EXCEED = 8'h22; // Specified key index exceeds size
+ // of key index ram
+ localparam LLKI_STATUS_KEY_INDEX_INVALID = 8'h23;
+ localparam LLKI_STATUS_BAD_POINTER_PAIR = 8'h24;
+ localparam LLKI_STATUS_BAD_CORE_INDEX = 8'h25;
+ localparam LLKI_STATUS_KL_REQ_BAD_MSG_ID = 8'h26; // The LLKI PP received a bad message ID from the SRoT
+ localparam LLKI_STATUS_KL_REQ_BAD_MSG_LEN = 8'h27;
+ localparam LLKI_STATUS_KL_RESP_BAD_MSG_ID = 8'h28; // The LLKI PP response had a bad message ID
+ localparam LLKI_STATUS_KL_TILELINK_ERROR = 8'h29;
+ localparam LLKI_STATUS_KL_LOSS_OF_SYNC = 8'h30;
+ localparam LLKI_STATUS_UNKNOWN_ERROR = 8'hFF;
+
+ // Value is used to initalize the SRoT STM wait state
+ // counter. This mitigates spamming the SRoT host
+ // interface while waiting for a response from the
+ // selected LLKI-KP
+ localparam SROT_WAIT_STATE_COUNTER_INIT = 8'h0A;
+
+ // Enumerated type for Surrogate Root of Trust state machine. State
+ // decscriptions can be found in srot_wrapper.sv
+ typedef enum {
+ ST_SROT_IDLE,
+ ST_SROT_MESSAGE_CHECK,
+ ST_SROT_RETRIEVE_KEY_INDEX,
+
+ ST_SROT_KL_REQ_HEADER,
+ ST_SROT_KL_REQ_ISSUE,
+ ST_SROT_KL_REQ_WAIT_FOR_ACK,
+
+ ST_SROT_KL_READ_READY_STATUS,
+ ST_SROT_KL_CHECK_READY_STATUS,
+ ST_SROT_KL_READY_WAIT_STATE,
+ ST_SROT_KL_LOAD_KEY_WORD,
+ ST_SROT_KL_LOAD_KEY_WORD_WAIT_FOR_ACK,
+
+ ST_SROT_KL_READ_RESP_STATUS,
+ ST_SROT_KL_CHECK_RESP_STATUS,
+ ST_SROT_KL_RESP_WAIT_STATE,
+
+ ST_SROT_KL_RESP_READ,
+
+ ST_SROT_C2_RESPONSE
+ } SROT_STATE_TYPE;
+
+ // Enumerate type for the LLKI Protocol Processing block state machine
+ typedef enum {
+ ST_LLKIPP_IDLE,
+ ST_LLKIPP_MESSAGE_CHECK,
+ ST_LLKIPP_LOAD_KEY_WORDS,
+ ST_LLKIPP_CLEAR_KEY,
+ ST_LLKIPP_RESPONSE
+ } LLKIPP_STATE_TYPE;
+
+ // The following parameters are XOR'd with the key words loaded
+ // into the corresponding mock TSS
+ localparam AES_MOCK_TSS_KEY_0 = 64'h0123456789ABCDEF;
+ localparam AES_MOCK_TSS_KEY_1 = 64'hFEDCBA9876543210;
+
+ // The Mock TSS introduces artificial wait states to demonstrate
+ // a delay when loading or clearing keys
+ typedef enum {
+ ST_MOCKTSS_IDLE,
+ ST_MOCKTSS_WAIT_STATE0,
+ ST_MOCKTSS_KEY0_LOADED,
+ ST_MOCKTSS_WAIT_STATE1,
+ ST_MOCKTSS_KEY1_LOADED,
+ ST_MOCKTSS_CLEAR_KEY,
+ ST_MOCKTSS_WAIT_STATE2
+ } MOCKTSS_STATE_TYPE;
+
+ localparam MOCKTSS_WAIT_STATE_COUNTER_INIT = 8'h0A;
+
+
+endpackage
diff --git a/hdl_cores/llki/llki_pp_wrapper.sv b/hdl_cores/llki/llki_pp_wrapper.sv
new file mode 100644
index 0000000..95a7c80
--- /dev/null
+++ b/hdl_cores/llki/llki_pp_wrapper.sv
@@ -0,0 +1,466 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name: llki_pp_wrapper.sv
+// Program: Common Evaluation Platform (CEP)
+// Description: This file provides a Verilog <-> SystemVerilog adapter
+// allowing connection of TL-UL interface to the Chisel
+// blackbox.
+//
+// It also implements the LLKI Protocol Processing
+// block's State Machine.
+// Notes: The underlying TL-UL package is from the OpenTitan
+// project
+//
+// The "tl" parameters have been taken from the
+// OpenTitan ecosystem
+//
+// Send / Recv FIFOs have specifically NOT been
+// implemented here in an effort to minimize the number
+// of memory blocks that ever touch key material.
+//
+// The LLKI Protocol Procesing block is intended to be
+// common across ALL LLKI enabled cores. Unique address
+// decoding will be facilitated through the use of the
+// CTRLSTS_ADDR and SENDRECV_ADDR parameters (which are
+// passed down from Chisel)
+//
+//************************************************************************
+`timescale 1ns/1ns
+
+module llki_pp_wrapper import tlul_pkg::*; import llki_pkg::*; #(
+ parameter int CTRLSTS_ADDR = 32'h00000000, // These default values MUST be overwritten
+ parameter int SENDRECV_ADDR = 32'h00000008 // These default values MUST be overwritten
+ ) (
+
+ // Clock and reset
+ input clk,
+ input rst,
+
+ // Slave Interface - A channel
+ input [2:0] slave_a_opcode,
+ input [2:0] slave_a_param,
+ input [top_pkg::TL_SZW-1:0] slave_a_size,
+ input [top_pkg::TL_AIW-1:0] slave_a_source,
+ input [top_pkg::TL_AW-1:00] slave_a_address,
+ input [top_pkg::TL_DBW-1:0] slave_a_mask,
+ input [top_pkg::TL_DW-1:0] slave_a_data,
+ input slave_a_corrupt,
+ input slave_a_valid,
+ output slave_a_ready,
+
+ // Slave interface D channel
+ output [2:0] slave_d_opcode,
+ output [2:0] slave_d_param,
+ output [top_pkg::TL_SZW-1:0] slave_d_size,
+ output [top_pkg::TL_AIW-1:0] slave_d_source,
+ output [top_pkg::TL_DIW-1:0] slave_d_sink,
+ output slave_d_denied,
+ output [top_pkg::TL_DW-1:0] slave_d_data,
+ output slave_d_corrupt,
+ output slave_d_valid,
+ input slave_d_ready,
+
+ // LLKI discrete I/O
+ output reg [63:0] llkid_key_data,
+ output reg llkid_key_valid,
+ input llkid_key_ready,
+ input llkid_key_complete,
+ output reg llkid_clear_key,
+ input llkid_clear_key_ack
+
+);
+
+ // Create the structures for communicating with OpenTitan-based Tilelink
+ tl_h2d_t slave_tl_h2d;
+ tl_d2h_t slave_tl_d2h;
+
+ // Make Slave A channel connections
+ assign slave_tl_h2d.a_valid = slave_a_valid;
+ assign slave_tl_h2d.a_opcode = ( slave_a_opcode == 3'h0) ? PutFullData :
+ ((slave_a_opcode == 3'h1) ? PutPartialData :
+ ((slave_a_opcode == 3'h4) ? Get :
+ Get));
+ assign slave_tl_h2d.a_param = slave_a_param;
+ assign slave_tl_h2d.a_size = slave_a_size;
+ assign slave_tl_h2d.a_source = slave_a_source;
+ assign slave_tl_h2d.a_address = slave_a_address;
+ assign slave_tl_h2d.a_mask = slave_a_mask;
+ assign slave_tl_h2d.a_data = slave_a_data;
+ assign slave_tl_h2d.a_user = tl_a_user_t'('0); // User field is unused by Rocket Chip
+ assign slave_tl_h2d.d_ready = slave_d_ready;
+
+ // Make Slave D channel connections
+ // Converting from the OpenTitan enumerated type to specific bit mappings
+ assign slave_d_opcode = ( slave_tl_d2h.d_opcode == AccessAck) ? 3'h0 :
+ ((slave_tl_d2h.d_opcode == AccessAckData) ? 3'h1 :
+ 3'h0);
+ assign slave_d_param = slave_tl_d2h.d_param;
+ assign slave_d_size = slave_tl_d2h.d_size;
+ assign slave_d_source = slave_tl_d2h.d_source;
+ assign slave_d_sink = slave_tl_d2h.d_sink;
+ assign slave_d_denied = slave_tl_d2h.d_error; // Open
+ assign slave_d_data = slave_tl_d2h.d_data;
+ assign slave_d_corrupt = slave_tl_d2h.d_error;
+ assign slave_d_valid = slave_tl_d2h.d_valid;
+ assign slave_a_ready = slave_tl_d2h.a_ready;
+
+ // Define some of the wires and registers associated with the tlul_adapter_reg
+ wire reg_we_o;
+ wire reg_re_o;
+ wire [top_pkg::TL_AW-1:0] reg_addr_o;
+ wire [top_pkg::TL_DW-1:0] reg_wdata_o;
+ reg [top_pkg::TL_DW-1:0] reg_rdata_i;
+ reg reg_error_i;
+
+ // Misc. signals
+ reg [top_pkg::TL_DW-1:0] llkipp_ctrlstatus_register; // Bit definition can be found in llki_pkg.sv
+ reg write_error;
+ reg read_error;
+
+ //------------------------------------------------------------------------
+ // Instantitate a tlul_adapter_reg to adapt the TL Slave Interface
+ //------------------------------------------------------------------------
+ tlul_adapter_reg #(
+ .RegAw (top_pkg::TL_AW ),
+ .RegDw (top_pkg::TL_DW )
+ ) u_tlul_adapter_reg_inst (
+ .clk_i (clk ),
+ .rst_ni (~rst ),
+
+ .tl_i (slave_tl_h2d ),
+ .tl_o (slave_tl_d2h ),
+
+ .we_o (reg_we_o ),
+ .re_o (reg_re_o ),
+ .addr_o (reg_addr_o ),
+ .wdata_o (reg_wdata_o ),
+ .be_o ( ), // Accesses are assumed to be word-wide
+ .rdata_i (reg_rdata_i ),
+ .error_i (reg_error_i )
+ );
+
+ // The reg_error_i will be asserted if either a read or write error occurs
+ assign reg_error_i = read_error || write_error;
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // Write Decode Process (writing to the state machine sendrecv address
+ // be handled in the LLKI PP state machine)
+ //------------------------------------------------------------------------
+ reg llkipp_response_waiting;
+ reg [top_pkg::TL_DW-1:0] llkipp_response_word;
+
+ always @(posedge clk or posedge rst)
+ begin
+ if (rst) begin
+ llkipp_ctrlstatus_register <= '0;
+ write_error <= 1'b0;
+ end else begin
+
+ // Default signal assignments
+ write_error <= 1'b0;
+
+ // Capture the message available state (setting and clearing
+ // of the source bit will occur within the state machine always block)
+ llkipp_ctrlstatus_register[LLKIKL_CTRLSTS_RESP_WAITING] <= llkipp_response_waiting;
+
+ // The LLKI-PP provides minimal buffering for messages (and key words) received from
+ // Thus, the SRoT can poll the ready for key bit in the LLKI-PP Control/Status register
+ // to determine that the LLKI-PP (and TSS) is ready to receive the next key word
+ llkipp_ctrlstatus_register[LLKIKL_CTRLSTS_READY_FOR_KEY] <= llkid_key_ready;
+
+ if (reg_we_o) begin
+ case (reg_addr_o)
+ // Currently, no Ctrl/Status bits are writeable via TileLink
+ CTRLSTS_ADDR : begin
+ ;
+ end
+ // Write to Send/Recv Address - Data "capture" occurs within the
+ // LLKI PP State Machine block, thus we have a null action here
+ SENDRECV_ADDR : begin
+ ;
+ end
+ // Trap State - Currently, the control/status register has no
+ // LLKI-PP writable bits and thus c
+ default : begin
+ write_error <= 1'b1;
+ end
+ endcase
+ end // end if (reg_we_o)
+
+ end // end if (rst)
+ end // end always
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // Read decode process
+ //------------------------------------------------------------------------
+ always @*
+ begin
+
+ // Default signal assignments
+ reg_rdata_i = '0;
+ read_error = 1'b0;
+
+ if (reg_re_o) begin
+ case (reg_addr_o)
+ // Currently, no Ctrl/Status bits are writeable via TileLink
+ CTRLSTS_ADDR : begin
+ reg_rdata_i = llkipp_ctrlstatus_register;
+ end
+ // Write to Send/Recv Address - Data "capture" occurs within the
+ // LLKI PP State Machine block, thus we have a null action here
+ SENDRECV_ADDR : begin
+ reg_rdata_i = llkipp_response_word;
+ end
+ // Trap State - Currently, the control/status register has no
+ // LLKI-PP writable bits and thus c
+ default : begin
+ read_error = 1'b1;
+ end
+ endcase
+ end // end if (reg_re_o)
+ end // end always
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // LLKI PP State Machine
+ //------------------------------------------------------------------------
+ LLKIPP_STATE_TYPE llkipp_current_state;
+ reg [7:0] msg_id;
+ reg [7:0] status;
+ reg [7:0] msg_len;
+
+ always @(posedge clk or posedge rst)
+ begin
+ if (rst) begin
+ llkid_key_data <= '0;
+ llkid_key_valid <= '0;
+ llkid_clear_key <= '0;
+ llkipp_response_waiting <= '0;
+ llkipp_response_word <= '0;
+ msg_id <= '0;
+ status <= '0;
+ msg_len <= '0;
+ llkipp_current_state <= ST_LLKIPP_IDLE;
+ end else begin
+ case (llkipp_current_state)
+ //------------------------------------------------------------------
+ // IDLE State
+ //------------------------------------------------------------------
+ ST_LLKIPP_IDLE : begin
+ // Default signal assignments
+ llkid_key_data <= '0;
+ llkid_key_valid <= '0;
+ llkid_clear_key <= '0;
+ llkipp_response_waiting <= '0;
+ llkipp_response_word <= '0;
+ msg_id <= '0;
+ status <= '0;
+ msg_len <= '0;
+ llkipp_current_state <= ST_LLKIPP_IDLE;
+
+ // If a write occurs AND it's to the SENDRECV_ADDR
+ if (reg_we_o && reg_addr_o == SENDRECV_ADDR) begin
+ msg_id <= reg_wdata_o[7:0];
+ status <= reg_wdata_o[15:8];
+ msg_len <= reg_wdata_o[23:16];
+
+ // Now that we have captured the message, time to process
+ llkipp_current_state <= ST_LLKIPP_MESSAGE_CHECK;
+
+ end // end if (reg_we_o && reg_addr_o == SENDRECV_ADDR)
+
+ end // ST_LLKIPP_IDLE
+ //------------------------------------------------------------------
+ // Message Check State
+ //------------------------------------------------------------------
+ ST_LLKIPP_MESSAGE_CHECK : begin
+ // Default signal assignments
+ llkid_key_data <= '0;
+ llkid_key_valid <= '0;
+ llkid_clear_key <= '0;
+ llkipp_response_waiting <= '0;
+ llkipp_response_word <= '0;
+ llkipp_current_state <= ST_LLKIPP_MESSAGE_CHECK;
+
+ // Make some checks and decision based on the Message ID
+ case (msg_id)
+ LLKI_MID_KLLOADKEYREQ : begin
+ // A message length of 1 (or zero) for a load key request
+ // is invalid
+ if (msg_len <= 1) begin
+ msg_id <= LLKI_MID_KLERRORRESP;
+ status <= LLKI_STATUS_KL_REQ_BAD_MSG_LEN;
+ llkipp_current_state <= ST_LLKIPP_RESPONSE;
+ // A load key request has been issued, jump to the
+ // load key words and wait for the next word (which
+ // will be treated as a key word)
+ end else
+ llkipp_current_state <= ST_LLKIPP_LOAD_KEY_WORDS;
+ end
+ LLKI_MID_KLCLEARKEYREQ : begin
+ // The only valid message length is 1
+ if (msg_len != 1) begin
+ msg_id <= LLKI_MID_KLERRORRESP;
+ status <= LLKI_STATUS_KL_REQ_BAD_MSG_LEN;
+ llkipp_current_state <= ST_LLKIPP_RESPONSE;
+ end else
+ llkipp_current_state <= ST_LLKIPP_CLEAR_KEY;
+ end
+ LLKI_MID_KLKEYSTATUSREQ : begin
+ // The only valid message length is 1
+ if (msg_len != 1) begin
+ msg_id <= LLKI_MID_KLERRORRESP;
+ status <= LLKI_STATUS_KL_REQ_BAD_MSG_LEN;
+ llkipp_current_state <= ST_LLKIPP_RESPONSE;
+ end else begin
+ msg_id <= LLKI_MID_KLKEYSTATUSRESP;
+ // Set the status based on what state the LLKI-Discrete
+ // interface indicates
+ if (llkid_key_complete)
+ status <= LLKI_STATUS_KEY_PRESENT;
+ else
+ status <= LLKI_STATUS_KEY_NOT_PRESENT;
+ llkipp_current_state <= ST_LLKIPP_RESPONSE;
+ end
+ end
+ // All other message ID (error condition)
+ default : begin
+ msg_id <= LLKI_MID_KLERRORRESP;
+ status <= LLKI_STATUS_KL_REQ_BAD_MSG_ID;
+ llkipp_current_state <= ST_LLKIPP_RESPONSE;
+ end
+ endcase // msg id
+ end // ST_LLKIPP_MESSAGE_CHECK
+ //------------------------------------------------------------------
+ // Load Key Words State - This state will "pass" the key words
+ // received over the LLKI-PP TileLink interface and pass them
+ // to the LLKI-Discrete interface.
+ //
+ // It is the responsibility of the SRoT to read the status of the
+ // key ready bit between EACH KEY WORD before sending the next one
+ //------------------------------------------------------------------
+ ST_LLKIPP_LOAD_KEY_WORDS : begin
+ // Default signal assignments
+ llkid_key_data <= '0;
+ llkid_key_valid <= '0;
+ llkid_clear_key <= '0;
+ llkipp_response_waiting <= '0;
+ llkipp_response_word <= '0;
+ llkipp_current_state <= ST_LLKIPP_LOAD_KEY_WORDS;
+
+ // Another key word has been received, time to do some checks
+ if (reg_we_o && reg_addr_o == SENDRECV_ADDR) begin
+
+ // If for some reason, the LLKI-Discrete is not ready, we'll
+ // ignore the key word, and send an error response (which the
+ // SRoT will need to check for)
+ if (~llkid_key_ready) begin
+ msg_id <= LLKI_MID_KLERRORRESP;
+ status <= LLKI_STATUS_KL_LOSS_OF_SYNC;
+ llkipp_current_state <= ST_LLKIPP_RESPONSE;
+ // If a key word has been received and msg_len == 2, then this
+ // is the LAST word of the load key request (understanding the
+ // msg_len also includes the header and we are using it for
+ // a counter.
+ end else if (msg_len == 2) begin
+ llkid_key_data <= reg_wdata_o;
+ llkid_key_valid <= 1;
+
+ msg_id <= LLKI_MID_KLLOADKEYACK;
+ status <= LLKI_STATUS_GOOD;
+ llkipp_current_state <= ST_LLKIPP_RESPONSE;
+ // This is not the last word of the key load, load the key word
+ // via the LLKI-Discrete and just wait for the next word
+ end else begin
+ llkid_key_data <= reg_wdata_o;
+ llkid_key_valid <= 1;
+
+ // Decrement the message length (be used to count the remaining
+ // number of key words to load)
+ msg_len <= msg_len - 1;
+ end // end if (~llkid_key_ready)
+ end // end if (reg_we_o && reg_addr_o == SENDRECV_ADDR)
+
+ end // ST_LLKIPP_LOAD_KEY_WORDS
+ //------------------------------------------------------------------
+ // Clear Key State
+ //------------------------------------------------------------------
+ ST_LLKIPP_CLEAR_KEY : begin
+ // Default signal assignments
+ llkid_key_data <= '0;
+ llkid_key_valid <= '0;
+ llkid_clear_key <= '1; // Instruct TSS to clear the key
+ llkipp_response_waiting <= '0;
+ llkipp_response_word <= '0;
+ llkipp_current_state <= ST_LLKIPP_CLEAR_KEY;
+
+ // Clear Key has been acknowledged, time to send the response
+ if (llkid_clear_key_ack) begin
+ msg_id <= LLKI_MID_KLCLEARKEYACK;
+ status <= LLKI_STATUS_GOOD;
+ llkipp_current_state <= ST_LLKIPP_RESPONSE;
+ end
+
+ end
+ //------------------------------------------------------------------
+ // Response Message state
+ //
+ // As there is no FIFO in the LLKI-PP, the State Machine more
+ // closurely tracks the message exchange. Here, when we are
+ // sending a response, the STM will advance when the response
+ // is read.
+ //
+ //------------------------------------------------------------------
+ ST_LLKIPP_RESPONSE : begin
+ // Default signal assignments
+ llkid_key_data <= '0;
+ llkid_key_valid <= '0;
+ llkid_clear_key <= '0;
+ llkipp_response_waiting <= '0;
+ llkipp_response_word <= '0;
+ llkipp_current_state <= ST_LLKIPP_RESPONSE;
+
+ // Build the response word and indicate that a response is waiting (remember, no FIFOs)
+ llkipp_response_word[7:0] <= msg_id;
+ llkipp_response_word[15:8] <= status;
+ llkipp_response_word[23:16] <= 1; // All responses have a message len of 1
+ llkipp_response_waiting <= '1;
+
+ // When the SEND/RECV address is read via the register interface, we can return to idle
+ if (reg_re_o && reg_addr_o == SENDRECV_ADDR) begin
+ llkipp_current_state <= ST_LLKIPP_IDLE;
+ end // end if (reg_re_o && reg_addr_o == SENDRECV_ADDR)
+
+ end
+ //------------------------------------------------------------------
+ // Trap State
+ //------------------------------------------------------------------
+ default : begin
+ // Default signal assignments
+ llkid_key_data <= '0;
+ llkid_key_valid <= '0;
+ llkid_clear_key <= '0;
+ llkipp_response_waiting <= '0;
+ llkipp_response_word <= '0;
+ msg_id <= '0;
+ status <= '0;
+ msg_len <= '0;
+ llkipp_current_state <= ST_LLKIPP_IDLE;
+ end
+ endcase // llkipp_current_state
+ end // end if (rst)
+ end // end always
+ //------------------------------------------------------------------------
+
+
+endmodule // endmodule llki_pp_wrapper
diff --git a/hdl_cores/llki/srot_wrapper.sv b/hdl_cores/llki/srot_wrapper.sv
new file mode 100644
index 0000000..43b89a5
--- /dev/null
+++ b/hdl_cores/llki/srot_wrapper.sv
@@ -0,0 +1,1304 @@
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX short identifier: BSD-2-Clause
+//
+// File Name: srot_wrapper.sv
+// Program: Common Evaluation Platform (CEP)
+// Description: This file provides a Verilog <-> SystemVerilog adapter
+// allowing connection of TL-UL interface to the Chisel
+// blackbox.
+// Notes: The underlying TL-UL package is from the OpenTitan
+// project
+//
+// The "tl" parameters have been taken from the
+// OpenTitan ecosystem
+//************************************************************************
+`timescale 1ns/1ns
+
+module srot_wrapper import tlul_pkg::*; import llki_pkg::*; #(
+ parameter int ADDRESS = 32'h00000000, // Currently unused as address selected occurs @ the SRoT Chisel Code
+ parameter int DEPTH = 32'h00000100, // Currently unused as address selected occurs @ the SRoT Chisel Code
+ parameter int FIFO_DEPTH = 8, // Define the depth of the LLKI FIFOs
+
+ // Derived parameters
+ localparam int DepthW = prim_util_pkg::vbits(FIFO_DEPTH + 1)
+ ) (
+
+ // Clock and reset
+ input clk,
+ input rst,
+
+ // Slave interface A channel
+ input [2:0] slave_a_opcode,
+ input [2:0] slave_a_param,
+ input [top_pkg::TL_SZW-1:0] slave_a_size,
+ input [top_pkg::TL_AIW-1:0] slave_a_source,
+ input [top_pkg::TL_AW-1:00] slave_a_address,
+ input [top_pkg::TL_DBW-1:0] slave_a_mask,
+ input [top_pkg::TL_DW-1:0] slave_a_data,
+ input slave_a_corrupt,
+ input slave_a_valid,
+ output slave_a_ready,
+
+ // Slave interface D channel
+ output [2:0] slave_d_opcode,
+ output [2:0] slave_d_param,
+ output [top_pkg::TL_SZW-1:0] slave_d_size,
+ output [top_pkg::TL_AIW-1:0] slave_d_source,
+ output [top_pkg::TL_DIW-1:0] slave_d_sink,
+ output slave_d_denied,
+ output [top_pkg::TL_DW-1:0] slave_d_data,
+ output slave_d_corrupt,
+ output slave_d_valid,
+ input slave_d_ready,
+
+ // Master interface A channel
+ output [2:0] master_a_opcode,
+ output [2:0] master_a_param,
+ output [top_pkg::TL_SZW-1:0] master_a_size,
+ output [top_pkg::TL_AIW-1:0] master_a_source,
+ output [top_pkg::TL_AW-1:00] master_a_address,
+ output [top_pkg::TL_DBW-1:0] master_a_mask,
+ output [top_pkg::TL_DW-1:0] master_a_data,
+ output master_a_corrupt,
+ output master_a_valid,
+ input master_a_ready,
+
+ // Master interface D channel
+ input [2:0] master_d_opcode,
+ input [2:0] master_d_param,
+ input [top_pkg::TL_SZW-1:0] master_d_size,
+ input [top_pkg::TL_AIW-1:0] master_d_source,
+ input [top_pkg::TL_DIW-1:0] master_d_sink,
+ input master_d_denied,
+ input [top_pkg::TL_DW-1:0] master_d_data,
+ input master_d_corrupt,
+ input master_d_valid,
+ output master_d_ready
+
+);
+
+ // Create the structures for communicating with OpenTitan-based Tilelink
+ tl_h2d_t slave_tl_h2d;
+ tl_d2h_t slave_tl_d2h;
+ tl_h2d_t master_tl_h2d;
+ tl_d2h_t master_tl_d2h;
+
+ // Make Slave A channel connections
+ assign slave_tl_h2d.a_valid = slave_a_valid;
+ assign slave_tl_h2d.a_opcode = ( slave_a_opcode == 3'h0) ? PutFullData :
+ ((slave_a_opcode == 3'h1) ? PutPartialData :
+ ((slave_a_opcode == 3'h4) ? Get :
+ Get));
+ assign slave_tl_h2d.a_param = slave_a_param;
+ assign slave_tl_h2d.a_size = slave_a_size;
+ assign slave_tl_h2d.a_source = slave_a_source;
+ assign slave_tl_h2d.a_address = slave_a_address;
+ assign slave_tl_h2d.a_mask = slave_a_mask;
+ assign slave_tl_h2d.a_data = slave_a_data;
+ assign slave_tl_h2d.a_user = tl_a_user_t'('0); // User field is unused by Rocket Chip
+ assign slave_tl_h2d.d_ready = slave_d_ready;
+
+ // Make Slave D channel connections
+ // Converting from the OpenTitan enumerated type to specific bit mappings
+ assign slave_d_opcode = ( slave_tl_d2h.d_opcode == AccessAck) ? 3'h0 :
+ ((slave_tl_d2h.d_opcode == AccessAckData) ? 3'h1 :
+ 3'h0);
+ assign slave_d_param = slave_tl_d2h.d_param;
+ assign slave_d_size = slave_tl_d2h.d_size;
+ assign slave_d_source = slave_tl_d2h.d_source;
+ assign slave_d_sink = slave_tl_d2h.d_sink;
+ assign slave_d_denied = slave_tl_d2h.d_error; // Open
+ assign slave_d_data = slave_tl_d2h.d_data;
+ assign slave_d_corrupt = slave_tl_d2h.d_error;
+ assign slave_d_valid = slave_tl_d2h.d_valid;
+ assign slave_a_ready = slave_tl_d2h.a_ready;
+
+ // Make Master A channel connections
+ assign master_a_opcode = ( master_tl_h2d.a_opcode == PutFullData) ? 3'h0 :
+ ((master_tl_h2d.a_opcode == PutPartialData) ? 3'h1 :
+ ((master_tl_h2d.a_opcode == Get) ? 3'h4 :
+ 3'h4));
+ assign master_a_param = master_tl_h2d.a_param;
+ assign master_a_size = master_tl_h2d.a_size;
+ assign master_a_source = master_tl_h2d.a_source;
+ assign master_a_address = master_tl_h2d.a_address;
+ assign master_a_mask = master_tl_h2d.a_mask;
+ assign master_a_data = master_tl_h2d.a_data;
+ assign master_a_corrupt = 0;
+ assign master_a_valid = master_tl_h2d.a_valid;
+ assign master_d_ready = master_tl_h2d.d_ready;
+
+ // Make Master D channel connections
+ assign master_tl_d2h.d_opcode = ( master_d_opcode == 3'h0) ? AccessAck :
+ ((master_d_opcode == 3'h1) ? AccessAckData :
+ AccessAck);
+ assign master_tl_d2h.d_param = master_d_param;
+ assign master_tl_d2h.d_size = master_d_size;
+ assign master_tl_d2h.d_source = master_d_source;
+ assign master_tl_d2h.d_sink = master_d_sink;
+ assign master_tl_d2h.d_data = master_d_data;
+ assign master_tl_d2h.d_user = tl_a_user_t'('0);
+ assign master_tl_d2h.d_error = master_d_corrupt || master_d_denied;
+ assign master_tl_d2h.d_valid = master_d_valid;
+ assign master_tl_d2h.a_ready = master_a_ready;
+
+ // Define some of the wires and registers associated with the tlul_adapter_reg
+ wire reg_we_o;
+ wire reg_re_o;
+ wire [top_pkg::TL_AW-1:0] reg_addr_o;
+ wire [top_pkg::TL_DW-1:0] reg_wdata_o;
+ reg [top_pkg::TL_DW-1:0] reg_rdata_i;
+ reg reg_error_i;
+
+ // Define some of the wires and registers associated with the tlul_adapter_host
+ reg host_req_i;
+ wire host_gnt_o;
+ reg host_we_i;
+ reg [top_pkg::TL_AW-1:0] host_addr_i;
+ reg [top_pkg::TL_DW-1:0] host_wdata_i;
+ wire host_valid_o;
+ wire [top_pkg::TL_DW-1:0] host_rdata_o;
+ wire host_err_o;
+
+ // Misc. signals
+ reg [top_pkg::TL_DW-1:0] srot_ctrlstatus_register; // Bit definition can be found in llki_pkg.sv
+ reg write_error;
+ reg read_error;
+
+ //------------------------------------------------------------------------
+ // Instantitate a tlul_adapter_reg to adapt the TL Slave Interface
+ //------------------------------------------------------------------------
+ tlul_adapter_reg #(
+ .RegAw (top_pkg::TL_AW ),
+ .RegDw (top_pkg::TL_DW )
+ ) u_tlul_adapter_reg_inst (
+ .clk_i (clk ),
+ .rst_ni (~rst ),
+
+ .tl_i (slave_tl_h2d ),
+ .tl_o (slave_tl_d2h ),
+
+ .we_o (reg_we_o ),
+ .re_o (reg_re_o ),
+ .addr_o (reg_addr_o ),
+ .wdata_o (reg_wdata_o ),
+ .be_o ( ), // Accesses are assumed to be word-wide
+ .rdata_i (reg_rdata_i ),
+ .error_i (reg_error_i )
+ );
+
+ // The reg_error_i will be asserted if either a read or write error occurs
+ assign reg_error_i = read_error || write_error;
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // Instantiate a tlul_adapter_host fo connecting to the master interface
+ //
+ // Per the notes in tlul_adapter_host.sv, setting MAX_REQS = 1 results
+ // in a purely combinatorial component.
+ //------------------------------------------------------------------------
+ tlul_adapter_host #(
+ .MAX_REQS(1)
+ ) u_tlul_adapter_host_inst (
+ .clk_i (clk ),
+ .rst_ni (~rst ),
+ .req_i (host_req_i ),
+ .gnt_o (host_gnt_o ),
+ .addr_i (host_addr_i ),
+ .we_i (host_we_i ),
+ .wdata_i (host_wdata_i ),
+ .be_i ('1 ), // All bytes always enabled
+ .valid_o (host_valid_o ),
+ .rdata_o (host_rdata_o ),
+ .err_o (host_err_o ),
+ .tl_o (master_tl_h2d ),
+ .tl_i (master_tl_d2h )
+ );
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // Instantiate the LLKI C2 Send Message FIFO
+ //------------------------------------------------------------------------
+ // Define signals associated with the LLKI C2 Send Message FIFO
+ reg llkic2_reqfifo_clr_i;
+ reg llkic2_reqfifo_wvalid_i;
+ wire llkic2_reqfifo_wready_o;
+ reg [top_pkg::TL_DW - 1:0] llkic2_reqfifo_wdata_i;
+ wire llkic2_reqfifo_rvalid_o;
+ reg llkic2_reqfifo_rready_i;
+ wire [top_pkg::TL_DW - 1:0] llkic2_reqfifo_rdata_o;
+ wire [DepthW - 1 :0] llkic2_reqfifo_depth_o;
+ wire llkic2_reqfifo_empty;
+ wire llkic2_reqfifo_full;
+
+ // Instantiate the FIFO
+ prim_fifo_sync #(
+ .Width (top_pkg::TL_DW),
+ .Pass (1'b0),
+ .Depth (FIFO_DEPTH),
+ .OutputZeroIfEmpty (1'b0) // Enables "first word fall through"
+ ) llkic2_reqfifo_inst (
+ .clk_i (clk),
+ .rst_ni (~rst),
+
+ // Synchronous clear/flush
+ .clr_i (llkic2_reqfifo_clr_i),
+
+ // Write Port
+ .wvalid_i (llkic2_reqfifo_wvalid_i),
+ .wready_o (llkic2_reqfifo_wready_o),
+ .wdata_i (llkic2_reqfifo_wdata_i),
+
+ // Read Port
+ .rvalid_o (llkic2_reqfifo_rvalid_o),
+ .rready_i (llkic2_reqfifo_rready_i),
+ .rdata_o (llkic2_reqfifo_rdata_o),
+
+ // Occupancy
+ .depth_o (llkic2_reqfifo_depth_o)
+ );
+
+ // Generate the full and empty signals for the LLKIC2 Send FIFO
+ assign llkic2_reqfifo_empty = llkic2_reqfifo_depth_o == '0;
+ assign llkic2_reqfifo_full = llkic2_reqfifo_depth_o == FIFO_DEPTH;
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // Instantiate the LLKI C2 Receive Message FIFO
+ //------------------------------------------------------------------------
+ // Define signals associated with the LLKI C2 Received Message FIFO
+ reg llkic2_respfifo_clr_i;
+ reg llkic2_respfifo_wvalid_i;
+ wire llkic2_respfifo_wready_o;
+ reg [top_pkg::TL_DW - 1:0] llkic2_respfifo_wdata_i;
+ wire llkic2_respfifo_rvalid_o;
+ reg llkic2_respfifo_rready_i;
+ reg [top_pkg::TL_DW - 1:0] llkic2_respfifo_rdata_o;
+ wire [DepthW - 1:0] llkic2_respfifo_depth_o;
+ wire llkic2_respfifo_empty;
+ wire llkic2_respfifo_full;
+
+ // Instantiate the FIFO
+ prim_fifo_sync #(
+ .Width (top_pkg::TL_DW),
+ .Pass (1'b0),
+ .Depth (FIFO_DEPTH),
+ .OutputZeroIfEmpty (1'b0) // Enables "first word fall through"
+ ) llkic2_respfifo_inst (
+ .clk_i (clk),
+ .rst_ni (~rst),
+
+ // Synchronous clear/flush
+ .clr_i (llkic2_respfifo_clr_i),
+
+ // Write Port
+ .wvalid_i (llkic2_respfifo_wvalid_i),
+ .wready_o (llkic2_respfifo_wready_o),
+ .wdata_i (llkic2_respfifo_wdata_i),
+
+ // Read Port
+ .rvalid_o (llkic2_respfifo_rvalid_o),
+ .rready_i (llkic2_respfifo_rready_i),
+ .rdata_o (llkic2_respfifo_rdata_o),
+
+ // Occupancy
+ .depth_o (llkic2_respfifo_depth_o)
+ );
+
+ // Generate the full and empty signals for the Rx FIFO
+ assign llkic2_respfifo_empty = llkic2_respfifo_depth_o == '0;
+ assign llkic2_respfifo_full = llkic2_respfifo_depth_o == FIFO_DEPTH;
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // Key Index RAM
+ //------------------------------------------------------------------------
+ reg keyindexram_a_write_i;
+ reg [top_pkg::TL_AW-1:0] keyindexram_a_addr_i;
+ reg [top_pkg::TL_DW-1:0] keyindexram_a_wdata_i;
+ wire [top_pkg::TL_DW-1:0] keyindexram_a_rdata_o;
+
+ reg [top_pkg::TL_AW-1:0] keyindexram_b_addr_i;
+ wire [top_pkg::TL_DW-1:0] keyindexram_b_rdata_o;
+
+ prim_generic_ram_2p #(
+ .Width (top_pkg::TL_DW),
+ .Depth (SROT_KEYINDEXRAM_SIZE)
+ ) key_index_ram_inst (
+ .clk_a_i (clk),
+ .clk_b_i (clk),
+
+ .a_req_i (1'b1), // Always selected
+ .a_write_i (keyindexram_a_write_i),
+ .a_addr_i (keyindexram_a_addr_i[$clog2(SROT_KEYINDEXRAM_SIZE) - 1:0]),
+ .a_wdata_i (keyindexram_a_wdata_i),
+ .a_wmask_i ('1), // Mask is unused
+ .a_rdata_o (keyindexram_a_rdata_o),
+
+ .b_req_i (1'b1), // Always selected
+ .b_write_i (1'b0), // Port B is Read Only
+ .b_addr_i (keyindexram_b_addr_i[$clog2(SROT_KEYINDEXRAM_SIZE) - 1:0]),
+ .b_wdata_i ('0), // Port B is Read Only
+ .b_wmask_i ('1), // Mask is unused
+ .b_rdata_o (keyindexram_b_rdata_o)
+
+ );
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // Key RAM
+ //------------------------------------------------------------------------
+ reg keyram_a_write_i;
+ reg [top_pkg::TL_AW-1:0] keyram_a_addr_i;
+ reg [top_pkg::TL_DW-1:0] keyram_a_wdata_i;
+ wire [top_pkg::TL_DW-1:0] keyram_a_rdata_o;
+
+ reg [top_pkg::TL_AW-1:0] keyram_b_addr_i;
+ wire [top_pkg::TL_DW-1:0] keyram_b_rdata_o;
+
+ prim_generic_ram_2p #(
+ .Width (top_pkg::TL_DW),
+ .Depth (SROT_KEYRAM_SIZE)
+ ) key_ram_inst (
+ .clk_a_i (clk),
+ .clk_b_i (clk),
+
+ .a_req_i (1'b1), // Always selected
+ .a_write_i (keyram_a_write_i),
+ .a_addr_i (keyram_a_addr_i[$clog2(SROT_KEYRAM_SIZE) - 1:0]),
+ .a_wdata_i (keyram_a_wdata_i),
+ .a_wmask_i ('1), // Mask is unused
+ .a_rdata_o (keyram_a_rdata_o),
+
+ .b_req_i (1'b1), // Always selected
+ .b_write_i (1'b0), // Port B is Read Only
+ .b_addr_i (keyram_b_addr_i[$clog2(SROT_KEYRAM_SIZE) - 1:0]),
+ .b_wdata_i ('0), // Port B is Read Only
+ .b_wmask_i ('1), // Mask is unused
+ .b_rdata_o (keyram_b_rdata_o)
+
+ );
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // Write Decode Process
+ //------------------------------------------------------------------------
+ always @(posedge clk or posedge rst)
+ begin
+ if (rst) begin
+ srot_ctrlstatus_register <= '0;
+ write_error <= 1'b0;
+ keyindexram_a_write_i <= 1'b0;
+ keyram_a_write_i <= 1'b0;
+ keyindexram_a_addr_i <= '0;
+ keyindexram_a_wdata_i <= '0;
+ keyram_a_addr_i <= '0;
+ keyram_a_wdata_i <= '0;
+ llkic2_reqfifo_wvalid_i <= 1'b0;
+ llkic2_reqfifo_wdata_i <= 1'b0;
+ end else begin
+
+ // Default signal assignments
+ write_error <= 1'b0;
+ keyindexram_a_write_i <= 1'b0;
+ keyram_a_write_i <= 1'b0;
+ llkic2_reqfifo_wvalid_i <= 1'b0;
+ llkic2_reqfifo_wdata_i <= 1'b0;
+
+ // The Key Index and Key RAM A ports are registered to
+ // align them with the corresponding write enables
+ keyindexram_a_addr_i <= (reg_addr_o - SROT_KEYINDEXRAM_ADDR) >> 3;
+ keyindexram_a_wdata_i <= reg_wdata_o;
+ keyram_a_addr_i <= (reg_addr_o - SROT_KEYRAM_ADDR) >> 3;
+ keyram_a_wdata_i <= reg_wdata_o;
+
+ // Implement other bits of the Control / Status Register
+ srot_ctrlstatus_register[SROT_CTRLSTS_RESP_WAITING] <= ~llkic2_respfifo_empty;
+
+ // A write has been requested
+ if (reg_we_o) begin
+
+ // Read or Writes to either RAMs while in operational mode should cause an error of some
+ // sort, but we do not currently have a means of handling tilelink errors. Thus, the
+ // acccess will just be ignored
+
+ // Decode to the Key RAM
+ // Note: Addresses are in terms of bytes and the datapath is 64-bit wide
+ if (reg_addr_o >= SROT_KEYRAM_ADDR && reg_addr_o <= (SROT_KEYRAM_ADDR + (SROT_KEYRAM_SIZE * 8) - 1)) begin
+
+ // Both mode bits MUST BE ZERO to allow access to the key and key index RAMs
+ if (srot_ctrlstatus_register[SROT_CTRLSTS_MODEBIT_0] || srot_ctrlstatus_register[SROT_CTRLSTS_MODEBIT_1])
+ ;
+ else
+ keyram_a_write_i <= 1'b1;
+
+ // Decode to the Key Index RAM
+ end else if (reg_addr_o >= SROT_KEYINDEXRAM_ADDR && reg_addr_o <= (SROT_KEYINDEXRAM_ADDR + (SROT_KEYINDEXRAM_SIZE * 8) - 1)) begin
+
+ // Both mode bits MUST BE ZERO to allow access to the key and key index RAMs
+ if (srot_ctrlstatus_register[SROT_CTRLSTS_MODEBIT_0] || srot_ctrlstatus_register[SROT_CTRLSTS_MODEBIT_1])
+ ;
+ else
+ keyindexram_a_write_i <= 1'b1;
+
+ // All other write decode events
+ end else begin
+ case (reg_addr_o)
+ //
+ // SROT Control Status Register
+ //
+ SROT_CTRLSTS_ADDR : begin
+ if (reg_wdata_o[SROT_CTRLSTS_MODEBIT_0]) srot_ctrlstatus_register[SROT_CTRLSTS_MODEBIT_0] <= 1'b1;
+ if (reg_wdata_o[SROT_CTRLSTS_MODEBIT_1]) srot_ctrlstatus_register[SROT_CTRLSTS_MODEBIT_1] <= 1'b1;
+ end // end SROT_CTRLSTS_ADDR
+
+ // Write to the LLKIC2 Send FIFO (writing to a full FIFO will cause an error)
+ SROT_LLKIC2_SENDRECV_ADDR : begin
+ // Overflow condition
+ if (llkic2_reqfifo_full) begin
+ write_error <= 1'b1;
+ end else begin
+ llkic2_reqfifo_wdata_i <= reg_wdata_o;
+ llkic2_reqfifo_wvalid_i <= 1'b1;
+ end // end else llkic2_reqfifo_full
+ end // end SROT_LLKIC2_SEND_ADDR
+
+ //
+ // All other decodes
+ //
+ default :
+ write_error <= 1'b1;
+ endcase // endcase reg_addr_o
+ end // end if aaddress decode
+ end else begin
+
+ // No writes, no errors.
+ write_error <= 1'b0;
+
+ end // end if reg_we_o
+ end // end else if (rst)
+ end // end always
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // Read decode process
+ //------------------------------------------------------------------------
+ always @*
+ begin
+
+ // Default signal assignments
+ reg_rdata_i = '0;
+ read_error = 1'b0;
+ llkic2_respfifo_clr_i = 1'b0;
+ llkic2_respfifo_rready_i = 1'b0;
+
+ // A read has been requested
+ if (reg_re_o) begin
+
+ // Read or Writes to either RAMs while in operational mode should cause an error of some
+ // sort, but we do not currently have a means of handling tilelink errors. Thus, the
+ // acccess will just be ignored
+
+ // Decode to the Key RAM
+ // Note: Addresses are in terms of bytes and the datapath is 64-bit wide
+ if (reg_addr_o >= SROT_KEYRAM_ADDR && reg_addr_o <= (SROT_KEYRAM_ADDR + (SROT_KEYRAM_SIZE * 8) - 1)) begin
+
+ // Both mode bits MUST BE ZERO to allow access to the key and key index RAMs
+ if (srot_ctrlstatus_register[SROT_CTRLSTS_MODEBIT_0] || srot_ctrlstatus_register[SROT_CTRLSTS_MODEBIT_1])
+ ;
+ else
+ reg_rdata_i = keyram_a_rdata_o;
+
+ // Decode to the Key Index RAM
+ end else if (reg_addr_o >= SROT_KEYINDEXRAM_ADDR && reg_addr_o <= (SROT_KEYINDEXRAM_ADDR + (SROT_KEYINDEXRAM_SIZE * 8) - 1)) begin
+
+ // Both mode bits MUST BE ZERO to allow access to the key and key index RAMs
+ if (srot_ctrlstatus_register[SROT_CTRLSTS_MODEBIT_0] || srot_ctrlstatus_register[SROT_CTRLSTS_MODEBIT_1])
+ ;
+ else
+ reg_rdata_i = keyindexram_a_rdata_o;
+
+ // All other write decode events
+ end else begin
+ case (reg_addr_o)
+ //
+ // SROT Control Status Register
+ //
+ SROT_CTRLSTS_ADDR : begin
+ reg_rdata_i = srot_ctrlstatus_register;
+ end // end SROT_CTRLSTS_ADDR
+ //
+ // Decode to the Receive FIFO
+ //
+ SROT_LLKIC2_SENDRECV_ADDR : begin
+ if (llkic2_respfifo_empty) begin
+ read_error = 1'b1;
+ end else begin
+ llkic2_respfifo_rready_i = 1'b1;
+ reg_rdata_i = llkic2_respfifo_rdata_o;
+ end // end llkic2_respfifo_empty
+ end // SROT_LLKIC2_RECV_ADDR
+ //
+ // All other decodes
+ //
+ default : begin
+ read_error <= 1'b1;
+ end // end default
+ endcase // endcase reg_addr_o
+ end // end if address decode
+ end // end if (reg_re_o)
+ end // end always @(reg_addr_o or reg_re_o)
+ //------------------------------------------------------------------------
+
+
+
+ //------------------------------------------------------------------------
+ // SRoT State Machine
+ // Processes messages received via the SEND message FIFO, initiates
+ // transactions with downstream LLKI Protocol Processing blocks via the
+ // TL host interface, receives downstream responses, then generates the
+ // responses back to the RISC-V. Once the RISC-V initiates an LLKIC2
+ // request, it should poll the SROT_CTRLSTS_RESP_WAITING bit in the
+ // SROT_CTRLSTS_ADDR register to determine when a response has been
+ // received.
+ //------------------------------------------------------------------------
+ SROT_STATE_TYPE srot_current_state;
+ reg [31:0] rsvd;
+ reg [7:0] msg_id;
+ reg [7:0] status;
+ reg [7:0] msg_len;
+ reg [7:0] key_index;
+ reg [15:0] low_pointer;
+ reg [15:0] high_pointer;
+ reg [15:0] current_pointer; // Used to track the currently selected
+ // Key RAM word
+ reg [7:0] core_index;
+ reg index_valid;
+ reg [7:0] wait_state_counter;
+
+ // Perform a continuous assignment of the key index RAM fields,
+ // making conding of the SRoT STM a bit cleaner
+ always @*
+ begin
+ low_pointer = keyindexram_b_rdata_o[15:0];
+ high_pointer = keyindexram_b_rdata_o[31:16];
+ core_index = keyindexram_b_rdata_o[39:32];
+ index_valid = keyindexram_b_rdata_o[63];
+ end // end always @*
+
+
+ always @(posedge clk or posedge rst)
+ begin
+ if (rst) begin
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyindexram_b_addr_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_clr_i <= 1'b0;
+ llkic2_reqfifo_rready_i <= 1'b0;
+ llkic2_respfifo_wvalid_i <= 1'b0;
+ llkic2_respfifo_wdata_i <= '0;
+ rsvd <= '0;
+ msg_id <= '0;
+ status <= '0;
+ msg_len <= '0;
+ key_index <= '0;
+ current_pointer <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_IDLE;
+ end else begin
+
+ // Case for the SRoT STM
+ case (srot_current_state)
+ //------------------------------------------------------------------
+ // IDLE State
+ //------------------------------------------------------------------
+ ST_SROT_IDLE : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyindexram_b_addr_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= 1'b0;
+ llkic2_respfifo_wvalid_i <= 1'b0;
+ llkic2_respfifo_wdata_i <= '0;
+ rsvd <= '0;
+ msg_id <= '0;
+ status <= '0;
+ msg_len <= '0;
+ key_index <= '0;
+ current_pointer <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_IDLE;
+
+ // The SRoT STM will stay idle until it determines that a message is
+ // present in the Send FIFO. All messages from RISC-V are expect to
+ // be one 64-bit word in length.
+ if (~llkic2_reqfifo_empty && llkic2_reqfifo_rvalid_o) begin
+
+ // Capture the message elements (incoming status is ignored)
+ msg_id <= llkic2_reqfifo_rdata_o[7:0];
+ msg_len <= llkic2_reqfifo_rdata_o[23:16];
+ key_index <= llkic2_reqfifo_rdata_o[31:24];
+ rsvd <= llkic2_reqfifo_rdata_o[63:32];
+
+ // Assert the Send FIFO read enable
+ llkic2_reqfifo_rready_i <= 1'b1;
+
+ // Jump to the next state
+ srot_current_state <= ST_SROT_MESSAGE_CHECK;
+ end // end if (~llkic2_reqfifo_empty)
+
+ end // end ST_SROT_IDLE
+ //------------------------------------------------------------------
+ // Message Check State
+ //------------------------------------------------------------------
+ ST_SROT_MESSAGE_CHECK : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyindexram_b_addr_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ current_pointer <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_IDLE;
+
+ case (msg_id)
+ // A valid request haas been received via the C2 RISCV -> SRoT Inteface
+ LLKI_MID_C2LOADKEYREQ,
+ LLKI_MID_C2CLEARKEYREQ,
+ LLKI_MID_C2KEYSTATUSREQ : begin
+ keyindexram_b_addr_i <= key_index;
+ srot_current_state <= ST_SROT_RETRIEVE_KEY_INDEX;
+ ;
+ end
+ // All other message ID (error condition)
+ // Clear the send FIFO as a precaution
+ default : begin
+ llkic2_reqfifo_clr_i <= 1'b1;
+ status <= LLKI_STATUS_BAD_MSG_ID;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ end
+ endcase // end case (msg_id)
+
+ // The only valid message length for requests is one
+ if (msg_len != 1) begin
+ llkic2_reqfifo_clr_i <= 1'b1;
+ status <= LLKI_STATUS_BAD_MSG_LEN;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ end // end if (msg_len != 1)
+
+ // The Key Index must >= 0 and < SROT_KEYINDEXRAM_SIZE
+ if (key_index >= SROT_KEYINDEXRAM_SIZE) begin
+ llkic2_reqfifo_clr_i <= 1'b1;
+ status <= LLKI_STATUS_KEY_INDX_EXCEED;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ end // end if (key_index >= SROT_KEYINDEXRAM_SIZE)
+
+ end // end ST_SROT_MESSAGE_CHECK
+ //------------------------------------------------------------------
+ // Retrieve (and check) key index State
+ //------------------------------------------------------------------
+ ST_SROT_RETRIEVE_KEY_INDEX : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ current_pointer <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_RETRIEVE_KEY_INDEX;
+
+ // Perform some error checking on the Key Index
+ // currently being referenced. Error checking
+ // is somewhat "hierchical in nature"
+ //
+ // Key Index is NOT valid
+ if (!index_valid) begin
+ llkic2_reqfifo_clr_i <= 1'b1;
+ status <= LLKI_STATUS_KEY_INDEX_INVALID;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ // Pointer related checks
+ end else if (low_pointer >= SROT_KEYRAM_SIZE || // Low pointer exceeds the key RAM
+ high_pointer >= SROT_KEYRAM_SIZE || // High pointer exceeds the key RAM
+ low_pointer > high_pointer) begin // Low pointer > high pointer
+ llkic2_reqfifo_clr_i <= 1'b1;
+ status <= LLKI_STATUS_BAD_POINTER_PAIR;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ // The specified target core index exceeds the maximum entry
+ // in the LLKI Core Index Array
+ end else if (core_index > $high(LLKI_CORE_INDEX_ARRAY)) begin
+ llkic2_reqfifo_clr_i <= 1'b1;
+ status <= LLKI_STATUS_BAD_CORE_INDEX;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ // The received message has been checked for errors and the selected key
+ // index looks ok.
+ end else begin
+ // Save the low pointer, as it will used to determine how many key
+ // words we will be sending
+ current_pointer <= low_pointer;
+
+ // Jump to the next state
+ srot_current_state <= ST_SROT_KL_REQ_HEADER;
+ end // end if (!index_valid)
+
+ end // ST_RETRIEVE_KEY_INDEX
+ //------------------------------------------------------------------
+ // Create Header for the request to the specified LLKI-PP
+ //------------------------------------------------------------------
+ ST_SROT_KL_REQ_HEADER : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_KL_REQ_ISSUE;
+
+ // Header generation is message specific
+ case (msg_id)
+ LLKI_MID_C2LOADKEYREQ : begin
+ host_wdata_i[7:0] <= LLKI_MID_KLLOADKEYREQ;
+ // For the Load Key Request Message length is equal
+ // to the 2 + (high_pointer - low pointer).
+ host_wdata_i[23:16] <= (high_pointer - low_pointer) + 2;
+ host_addr_i <= LLKI_CORE_INDEX_ARRAY[core_index][LLKI_SENDRECV_INDEX];
+ // Assert write enable and req (indicates a TL PutFullData operation)
+ host_req_i <= 1'b1;
+ host_we_i <= 1'b1;
+
+ end
+ LLKI_MID_C2CLEARKEYREQ : begin
+ host_wdata_i[7:0] <= LLKI_MID_KLCLEARKEYREQ;
+ host_wdata_i[23:16] <= 8'h01;
+ host_addr_i <= LLKI_CORE_INDEX_ARRAY[core_index][LLKI_SENDRECV_INDEX];
+ // Assert write enable and req (indicates a TL PutFullData operation)
+ host_req_i <= 1'b1;
+ host_we_i <= 1'b1;
+ end
+ LLKI_MID_C2KEYSTATUSREQ : begin
+ host_wdata_i[7:0] <= LLKI_MID_KLKEYSTATUSREQ;
+ host_wdata_i[23:16] <= 8'h01;
+ host_addr_i <= LLKI_CORE_INDEX_ARRAY[core_index][LLKI_SENDRECV_INDEX];
+ // Assert write enable and req (indicates a TL PutFullData operation)
+ host_req_i <= 1'b1;
+ host_we_i <= 1'b1;
+ end
+ // Since we already checked for valid message IDs,
+ // this truely is a trap condition
+ default : begin
+ llkic2_reqfifo_clr_i <= 1'b1;
+ status <= LLKI_STATUS_BAD_CORE_INDEX;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ end
+ endcase
+
+ end // ST_SROT_KL_CREATE_HEADER
+ //------------------------------------------------------------------
+ // Assert host request in order to send the LLKI-PP Request
+ //------------------------------------------------------------------
+ ST_SROT_KL_REQ_ISSUE : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_we_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_KL_REQ_ISSUE;
+
+ // Continue to assert write enable and req (indicates a TL PutFullData operation)
+ host_req_i <= 1'b1;
+ host_we_i <= 1'b1;
+
+ // Wait for grant indicating the write has been sent
+ if (host_gnt_o) begin
+ host_req_i <= 1'b0;
+ host_we_i <= 1'b0;
+
+ // Jump to the Request Wait for Ack state
+ srot_current_state <= ST_SROT_KL_REQ_WAIT_FOR_ACK;
+
+ // Did an error get asserted?
+ if (host_err_o) begin
+ msg_id <= LLKI_MID_C2ERRORRESP;
+ status <= LLKI_STATUS_KL_TILELINK_ERROR;
+ msg_len <= 8'h01;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ end
+ end // end if (host_gnt_o)
+ end // ST_SROT_KL_REQ_WAIT_FOR_GRANT
+ //------------------------------------------------------------------
+ // Using the OpenTitan tlul_adapter_host module, even writes get
+ // "acknowledged" through the assertion of the valid_o bit, which
+ // is directly mapped from the TL-UL D channel valid bit
+ //------------------------------------------------------------------
+ ST_SROT_KL_REQ_WAIT_FOR_ACK : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_we_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_KL_REQ_WAIT_FOR_ACK;
+
+ // The request has been acknowledged
+ if (host_valid_o) begin
+
+ // If this is a Load Key request, then we need to begin
+ // the cycle of reading the ready bit from the selected
+ // LLKI-PP block. When ready, we can issue a key word
+ // write. Once all the key words have be written, then
+ // we should look for a standard response from the LLKI-PP
+ if (msg_id == LLKI_MID_C2LOADKEYREQ)
+ srot_current_state <= ST_SROT_KL_READ_READY_STATUS;
+ else
+ srot_current_state <= ST_SROT_KL_READ_RESP_STATUS;
+
+ end // end if (host_valid_o)
+ end // ST_SROT_KL_REQ_WAIT_FOR_ACK
+ //------------------------------------------------------------------
+ // Before writing a key word to the select LLKI-PP block, we need
+ // read the ready bit
+ //------------------------------------------------------------------
+ ST_SROT_KL_READ_READY_STATUS : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_KL_READ_READY_STATUS;
+
+ // We want to read the selected LLKI-PP Control/Status Register
+ host_addr_i <= LLKI_CORE_INDEX_ARRAY[core_index][LLKI_CTRLSTS_INDEX];
+ host_req_i <= 1'b1;
+
+ // Did an error get asserted?
+ if (host_err_o) begin
+ msg_id <= LLKI_MID_C2ERRORRESP;
+ status <= LLKI_STATUS_KL_TILELINK_ERROR;
+ msg_len <= 8'h01;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ // Wait until the request has been granted, then jump to
+ // the check status state
+ end else if (host_gnt_o) begin
+ // Point the Key RAM to the current word
+ keyram_b_addr_i <= current_pointer;
+
+ // Jump to next
+ srot_current_state <= ST_SROT_KL_CHECK_READY_STATUS;
+ end
+ end // ST_SROT_KL_READ_READY_STATUS
+ //------------------------------------------------------------------
+ // The Ready Status has been read, now time to check it
+ //------------------------------------------------------------------
+ ST_SROT_KL_CHECK_READY_STATUS : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_KL_CHECK_READY_STATUS;
+
+ // Valid data has been returned
+ if (host_valid_o) begin
+
+ // The select LLKI-PP is ready for a key
+ if (host_rdata_o[LLKIKL_CTRLSTS_READY_FOR_KEY] == 1'b1) begin
+ // Issue the key write, understanding that if host_gnt_o is
+ // already asserted, this will only be set for a single clock cycle
+ host_addr_i <= LLKI_CORE_INDEX_ARRAY[core_index][LLKI_SENDRECV_INDEX];
+ host_wdata_i <= keyram_b_rdata_o;
+ host_req_i <= 1'b1;
+ host_we_i <= 1'b1;
+
+ srot_current_state <= ST_SROT_KL_LOAD_KEY_WORD;
+ // Response is NOT waiting, jump to wait state
+ end else begin
+ srot_current_state <= ST_SROT_KL_READY_WAIT_STATE;
+ end
+ end // end else if (host_err_o)
+ end // ST_SROT_KL_CHECK_READY_STATUS
+ //------------------------------------------------------------------
+ // Wait state to avoid spamming the LLKI-PP with requests
+ //------------------------------------------------------------------
+ ST_SROT_KL_READY_WAIT_STATE : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ srot_current_state <= ST_SROT_KL_READY_WAIT_STATE;
+
+ // Decrement the wait state counter
+ wait_state_counter <= wait_state_counter - 1;
+
+ // Did an error get asserted?
+ if (host_err_o) begin
+ msg_id <= LLKI_MID_C2ERRORRESP;
+ status <= LLKI_STATUS_KL_TILELINK_ERROR;
+ msg_len <= 8'h01;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ end else if (wait_state_counter == 0) begin
+ srot_current_state <= ST_SROT_KL_READ_READY_STATUS;
+ end
+
+ end // ST_SROT_KL_READY_WAIT_STATE
+ //------------------------------------------------------------------
+ // We know the LLKI-PP is ready for a key word, so let's send it
+ //------------------------------------------------------------------
+ ST_SROT_KL_LOAD_KEY_WORD : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_KL_LOAD_KEY_WORD;
+
+ // Hold the signals, until host_gnt_o is issued
+ host_addr_i <= LLKI_CORE_INDEX_ARRAY[core_index][LLKI_SENDRECV_INDEX];
+ host_wdata_i <= keyram_b_rdata_o;
+ host_req_i <= 1'b1;
+ host_we_i <= 1'b1;
+
+ // The write request has been granted
+ if (host_gnt_o) begin
+ // Clear up some signals
+ host_addr_i <= '0;
+ host_wdata_i <= '0;
+ host_req_i <= '0;
+ host_we_i <= '0;
+
+ // Jump to the next state
+ srot_current_state <= ST_SROT_KL_LOAD_KEY_WORD_WAIT_FOR_ACK;
+ end
+ end // ST_SROT_KL_LOAD_KEY_WORD
+ //------------------------------------------------------------------
+ // The key word write has been issued, we need to wait until it
+ // is acknowledged
+ //------------------------------------------------------------------
+ ST_SROT_KL_LOAD_KEY_WORD_WAIT_FOR_ACK : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_KL_LOAD_KEY_WORD_WAIT_FOR_ACK;
+
+ // The write has been acknowledged
+ if (host_valid_o) begin
+
+ // Is this the last word of the load? If yes, then jump to the
+ // read response status state
+ if (current_pointer == high_pointer) begin
+ srot_current_state <= ST_SROT_KL_READ_RESP_STATUS;
+ // We have more words. Increment the current pointer and
+ // read the LLKI-PP ready status
+ end else begin
+ current_pointer <= current_pointer + 1;
+ srot_current_state <= ST_SROT_KL_READ_READY_STATUS;
+ end // end if (current_pointer == high_pointer)
+
+ end
+ end // ST_SROT_KL_LOAD_KEY_WORD_WAIT_FOR_ACK
+ //------------------------------------------------------------------
+ // Now, the request has been sent, it is time to poll the response
+ // waiting bit in the target LLKI-PP
+ //------------------------------------------------------------------
+ ST_SROT_KL_READ_RESP_STATUS : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ current_pointer <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_KL_READ_RESP_STATUS;
+
+ // We want to read the selected LLKI-PP Control/Status Register
+ host_addr_i <= LLKI_CORE_INDEX_ARRAY[core_index][LLKI_CTRLSTS_INDEX];
+ host_req_i <= 1'b1;
+
+ // Did an error get asserted?
+ if (host_err_o) begin
+ msg_id <= LLKI_MID_C2ERRORRESP;
+ status <= LLKI_STATUS_KL_TILELINK_ERROR;
+ msg_len <= 8'h01;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ // Wait until the request has been granted, then jump to
+ // the check status state
+ end else if (host_gnt_o) begin
+ srot_current_state <= ST_SROT_KL_CHECK_RESP_STATUS;
+ end
+ end // ST_SROT_KL_RESP_READ_STATUS
+ //------------------------------------------------------------------
+ // The read request has been issued and granted, but now we need
+ // to wait until valid data is returned
+ //------------------------------------------------------------------
+ ST_SROT_KL_CHECK_RESP_STATUS : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ current_pointer <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_KL_CHECK_RESP_STATUS;
+
+ // Valid data has been returned
+ if (host_valid_o) begin
+
+ // Response is waiting in the LLKI PP. Initiate the request
+ // as we tranisition to the next state
+ if (host_rdata_o[LLKIKL_CTRLSTS_RESP_WAITING] == 1'b1) begin
+ // We want to read the selected LLKI-PP Send/Receive Queue
+ host_addr_i <= LLKI_CORE_INDEX_ARRAY[core_index][LLKI_SENDRECV_INDEX];
+ host_req_i <= 1'b1;
+
+ srot_current_state <= ST_SROT_KL_RESP_READ;
+ // Response is NOT waiting, jump to wait state
+ end else begin
+ srot_current_state <= ST_SROT_KL_RESP_WAIT_STATE;
+ end
+ end // end else if (host_err_o)
+ end // ST_SROT_KL_RESP_CHECK_STATUS
+ //------------------------------------------------------------------
+ // This wait state is used to avoid spaming the Host interface
+ // while waiting for the select LLKI-PP block to process a message
+ //------------------------------------------------------------------
+ ST_SROT_KL_RESP_WAIT_STATE : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ current_pointer <= '0;
+ srot_current_state <= ST_SROT_KL_RESP_WAIT_STATE;
+
+ // Decrement the wait state counter
+ wait_state_counter <= wait_state_counter - 1;
+
+ // Did an error get asserted?
+ if (host_err_o) begin
+ msg_id <= LLKI_MID_C2ERRORRESP;
+ status <= LLKI_STATUS_KL_TILELINK_ERROR;
+ msg_len <= 8'h01;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ end else if (wait_state_counter == 0) begin
+ srot_current_state <= ST_SROT_KL_READ_RESP_STATUS;
+ end
+
+ end // ST_SROT_KL_RESP_WAIT_STATE
+ //------------------------------------------------------------------
+ // Read LLKI-PP Reponse
+ //------------------------------------------------------------------
+ ST_SROT_KL_RESP_READ : begin
+ // Default signal assignment
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= 1'b0;
+ llkic2_respfifo_wvalid_i <= 1'b0;
+ llkic2_respfifo_wdata_i <= '0;
+ current_pointer <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_KL_RESP_READ;
+
+ // Did an error get asserted?
+ if (host_err_o) begin
+ msg_id <= LLKI_MID_C2ERRORRESP;
+ status <= LLKI_STATUS_KL_TILELINK_ERROR;
+ msg_len <= 8'h01;
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+ // Valid data has been received
+ end else if (host_valid_o) begin
+
+ // Deassert request and address signals
+ host_req_i <= '0;
+ host_addr_i <= '0;
+
+ // Capture the reponse fields from the LLKI-PP block
+ msg_id <= host_rdata_o[7:0];
+ status <= host_rdata_o[15:8];
+ msg_len <= host_rdata_o[23:16];
+
+ // Just to creating a C2 Response message
+ srot_current_state <= ST_SROT_C2_RESPONSE;
+
+ end // end else if (host_err_o)
+ end // end ST_SROT_KL_RESP_READ
+ //------------------------------------------------------------------
+ // Generate the LLKI C2 Response Message
+ //------------------------------------------------------------------
+ ST_SROT_C2_RESPONSE : begin
+ // Default signal states
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyindexram_b_addr_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_rready_i <= 1'b0;
+ llkic2_respfifo_wdata_i <= '0;
+ llkic2_respfifo_wvalid_i <= 1'b0;
+ key_index <= '0;
+ current_pointer <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_IDLE;
+
+ // Create the response message. Errors can be generated
+ // in the following ways:
+ // - LLKIC2 message is bad
+ // - The reference key index is bad
+ // - A response received via the LLKI-KL interface indicates an error
+ // - A tilelink error is indicated on the LLKI-KL interface
+ case (status)
+ //------------------------------------------------------------------
+ // Processing a good response received via the LLKI-KL interface
+ //------------------------------------------------------------------
+ LLKI_STATUS_GOOD,
+ LLKI_STATUS_KEY_PRESENT,
+ LLKI_STATUS_KEY_NOT_PRESENT : begin
+
+ // Set most of the LLKI-C2 response fields
+ llkic2_respfifo_wdata_i[15:8] <= status;
+ llkic2_respfifo_wdata_i[23:16] <= 8'h01;
+ llkic2_respfifo_wdata_i[63:32] <= rsvd;
+ llkic2_respfifo_wvalid_i <= 1'b1;
+
+ // Determine the LLKI C2 Response ID
+ case (msg_id)
+ LLKI_MID_KLLOADKEYACK : llkic2_respfifo_wdata_i[7:0] <= LLKI_MID_C2LOADKEYACK;
+ LLKI_MID_KLCLEARKEYACK : llkic2_respfifo_wdata_i[7:0] <= LLKI_MID_C2CLEARKEYACK;
+ LLKI_MID_KLKEYSTATUSRESP : llkic2_respfifo_wdata_i[7:0] <= LLKI_MID_C2KEYSTATUSRESP;
+ default : begin
+ llkic2_respfifo_wdata_i[7:0] <= LLKI_MID_KLERRORRESP;
+ llkic2_respfifo_wdata_i[15:8] <= LLKI_STATUS_KL_RESP_BAD_MSG_ID;
+ end
+ endcase
+ end
+ //------------------------------------------------------------------
+ // An expected error has occurred
+ //------------------------------------------------------------------
+ LLKI_STATUS_BAD_MSG_ID,
+ LLKI_STATUS_BAD_MSG_LEN,
+ LLKI_STATUS_KEY_INDX_EXCEED,
+ LLKI_STATUS_KEY_INDEX_INVALID,
+ LLKI_STATUS_BAD_POINTER_PAIR,
+ LLKI_STATUS_BAD_CORE_INDEX,
+ LLKI_STATUS_KL_REQ_BAD_MSG_ID,
+ LLKI_STATUS_KL_REQ_BAD_MSG_LEN,
+ LLKI_STATUS_KL_RESP_BAD_MSG_ID,
+ LLKI_STATUS_KL_TILELINK_ERROR : begin
+ llkic2_respfifo_wdata_i[7:0] <= LLKI_MID_C2ERRORRESP;
+ llkic2_respfifo_wdata_i[15:8] <= status;
+ llkic2_respfifo_wdata_i[23:16] <= 8'h01;
+ llkic2_respfifo_wdata_i[63:32] <= rsvd;
+ llkic2_respfifo_wvalid_i <= 1'b1;
+ end
+ //------------------------------------------------------------------
+ // Trap state - Create an LLKI-C2 message with an unknown error
+ //------------------------------------------------------------------
+ default : begin
+ llkic2_respfifo_wdata_i[7:0] <= LLKI_MID_C2ERRORRESP;
+ llkic2_respfifo_wdata_i[15:8] <= LLKI_STATUS_UNKNOWN_ERROR;
+ llkic2_respfifo_wdata_i[23:16] <= 8'h01;
+ llkic2_respfifo_wdata_i[63:32] <= rsvd;
+ llkic2_respfifo_wvalid_i <= 1'b1;
+ end
+ endcase // case (status)
+
+ // Return to IDLE
+ srot_current_state <= ST_SROT_IDLE;
+ end // ST_SROT_ERROR_RESPONSE
+ //------------------------------------------------------------------
+ // Trap State
+ //------------------------------------------------------------------
+ default : begin
+ host_req_i <= '0;
+ host_addr_i <= '0;
+ host_we_i <= '0;
+ host_wdata_i <= '0;
+ keyindexram_b_addr_i <= '0;
+ keyram_b_addr_i <= '0;
+ llkic2_reqfifo_clr_i <= '0;
+ llkic2_reqfifo_rready_i <= '0;
+ llkic2_respfifo_wvalid_i <= '0;
+ llkic2_respfifo_wdata_i <= '0;
+ rsvd <= '0;
+ msg_id <= '0;
+ status <= '0;
+ msg_len <= '0;
+ key_index <= '0;
+ current_pointer <= '0;
+ wait_state_counter <= SROT_WAIT_STATE_COUNTER_INIT;
+ srot_current_state <= ST_SROT_IDLE;
+ end
+ //------------------------------------------------------------------
+ endcase // endcase srot_current_state
+
+ end // end if rst
+ end // end always
+
+endmodule // endmodule srot_wrapper
diff --git a/hdl_cores/llki/tlul_err.sv b/hdl_cores/llki/tlul_err.sv
new file mode 100644
index 0000000..d028524
--- /dev/null
+++ b/hdl_cores/llki/tlul_err.sv
@@ -0,0 +1,113 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name: tlul_err.sv
+// Program: Common Evaluation Platform (CEP)
+// Description: OpenTitan tlul_err.sv customized for the Common
+// Evaluation Plafform
+// Notes: Updated to support 8-byte transfers
+//************************************************************************
+
+
+
+`include "prim_assert.sv"
+
+module tlul_err import tlul_pkg::*; (
+ input clk_i,
+ input rst_ni,
+
+ input tl_h2d_t tl_i,
+
+ output logic err_o
+);
+
+ localparam int IW = $bits(tl_i.a_source);
+ localparam int SZW = $bits(tl_i.a_size);
+ localparam int DW = $bits(tl_i.a_data);
+ localparam int MW = $bits(tl_i.a_mask);
+ localparam int SubAW = $clog2(DW/8);
+
+ logic opcode_allowed, a_config_allowed;
+
+ logic op_full, op_partial, op_get;
+ assign op_full = (tl_i.a_opcode == PutFullData);
+ assign op_partial = (tl_i.a_opcode == PutPartialData);
+ assign op_get = (tl_i.a_opcode == Get);
+
+ // Anything that doesn't fall into the permitted category, it raises an error
+ assign err_o = ~(opcode_allowed & a_config_allowed);
+
+ // opcode check
+ assign opcode_allowed = (tl_i.a_opcode == PutFullData)
+ | (tl_i.a_opcode == PutPartialData)
+ | (tl_i.a_opcode == Get);
+
+ // a channel configuration check
+ logic addr_sz_chk; // address and size alignment check
+ logic mask_chk; // inactive lane a_mask check
+ logic fulldata_chk; // PutFullData should have size match to mask
+
+ logic [MW-1:0] mask;
+
+ assign mask = (1 << tl_i.a_address[SubAW-1:0]);
+
+ always_comb begin
+ addr_sz_chk = 1'b0;
+ mask_chk = 1'b0;
+ fulldata_chk = 1'b0; // Only valid when opcode is PutFullData
+
+ if (tl_i.a_valid) begin
+ unique case (tl_i.a_size)
+ 'h0: begin // 1 Byte
+ addr_sz_chk = 1'b1;
+ mask_chk = ~|(tl_i.a_mask & ~mask);
+ fulldata_chk = |(tl_i.a_mask & mask);
+ end
+
+ 'h1: begin // 2 Byte
+ addr_sz_chk = ~tl_i.a_address[0];
+ // check inactive lanes if lower 2B, check a_mask[3:2], if uppwer 2B, a_mask[1:0]
+ mask_chk = (tl_i.a_address[1]) ? ~|(tl_i.a_mask & 4'b0011)
+ : ~|(tl_i.a_mask & 4'b1100);
+ fulldata_chk = (tl_i.a_address[1]) ? &tl_i.a_mask[3:2] : &tl_i.a_mask[1:0] ;
+ end
+
+ 'h2: begin // 4 Byte
+ addr_sz_chk = ~|tl_i.a_address[SubAW-1:0];
+ mask_chk = 1'b1;
+ fulldata_chk = &tl_i.a_mask[3:0];
+ end
+
+ 'h3: begin // 8 Byte
+ addr_sz_chk = ~|tl_i.a_address[SubAW-1:0];
+ mask_chk = 1'b1;
+ fulldata_chk = &tl_i.a_mask[7:0];
+ end
+
+ default: begin // else
+ addr_sz_chk = 1'b0;
+ mask_chk = 1'b0;
+ fulldata_chk = 1'b0;
+ end
+ endcase
+ end else begin
+ addr_sz_chk = 1'b0;
+ mask_chk = 1'b0;
+ fulldata_chk = 1'b0;
+ end
+ end
+
+ assign a_config_allowed = addr_sz_chk
+ & mask_chk
+ & (op_get | op_partial | fulldata_chk) ;
+
+ // Only 32 bit data width for current tlul_err
+ `ASSERT_INIT(dataWidthOnly32_A, DW == 32)
+
+endmodule
+
diff --git a/hdl_cores/llki/top_pkg.sv b/hdl_cores/llki/top_pkg.sv
new file mode 100644
index 0000000..bd93bdc
--- /dev/null
+++ b/hdl_cores/llki/top_pkg.sv
@@ -0,0 +1,42 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+//************************************************************************
+// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX License Identifier: MIT
+//
+// File Name: top_pkg.sv
+// Program: Common Evaluation Platform (CEP)
+// Description: OpenTitan top_pkg customized for the Common
+// Evaluation Plafform
+// Notes:
+//************************************************************************
+
+package top_pkg;
+
+// These should match the SROTTilelinkParameters called out in cep_addresses.scala
+localparam int TL_DW=64; // = TL_DBW * 8; TL_DBW must be a power-of-two
+localparam int TL_AW=32;
+localparam int TL_AIW=4; // a_source, d_source
+localparam int TL_DIW=2; // d_sink
+localparam int TL_SZW=3;
+
+
+localparam int TL_DUW=16; // d_user (unused in the CEP)
+localparam int TL_DBW=(TL_DW>>3);
+//localparam int TL_SZW=$clog2($clog2(TL_DBW)+1);
+localparam int FLASH_BANKS=2;
+localparam int FLASH_PAGES_PER_BANK=256;
+localparam int FLASH_WORDS_PER_PAGE=128;
+localparam int FLASH_INFO_TYPES = 2;
+localparam int FLASH_INFO_PER_BANK [FLASH_INFO_TYPES] = '{4, 4};
+localparam int FLASH_DATA_WIDTH=64;
+localparam int FLASH_METADATA_WIDTH=12;
+localparam int NUM_AST_ALERTS=7;
+localparam int NUM_IO_RAILS=2;
+localparam int ENTROPY_STREAM=4;
+localparam int ADC_CHANNELS=2;
+localparam int ADC_DATAW=10;
+
+endpackage
diff --git a/licenseLog.txt b/licenseLog.txt
index 8ddaff0..d69f948 100644
--- a/licenseLog.txt
+++ b/licenseLog.txt
@@ -166,3 +166,10 @@ License terms :
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Function : This core provides a standard SHA hash function, where the resulting hash value is 256 bits. It will be integrated as a HW accelerator into the SoC.
+Title : opentitan
+Source : https://github.com/lowRISC/opentitan
+CEP Directory : ./opentitan
+License Description : Apache License v2.0
+License Terms : https://github.com/lowRISC/opentitan/blob/master/LICENSE
+Function : OpenTitan is the first open source project building a transparent, high-quality reference design and integration guidelines for silicon root of trust (RoT) chips.
+ Main website: www.opentitan.org
diff --git a/unit_simulation/llki_supports/llki_discrete.sv b/unit_simulation/llki_supports/llki_discrete.sv
index 95ec206..4dcc359 100644
--- a/unit_simulation/llki_supports/llki_discrete.sv
+++ b/unit_simulation/llki_supports/llki_discrete.sv
@@ -1,6 +1,6 @@
//************************************************************************
// Copyright (C) 2020 Massachusetts Institute of Technology
-// SPDX License Identifier: MIT
+// SPDX short identifier: BSD-2-Clause
//
// File Name: llki_discrete.sv
// Program: Common Evaluation Platform (CEP)
diff --git a/unit_simulation/llki_supports/llki_rom.sv b/unit_simulation/llki_supports/llki_rom.sv
index b426ec5..6cb0b6b 100644
--- a/unit_simulation/llki_supports/llki_rom.sv
+++ b/unit_simulation/llki_supports/llki_rom.sv
@@ -1,5 +1,6 @@
//************************************************************************
// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX short identifier: BSD-2-Clause
//
// File Name: llki_rom.sv
// Program: Common Evaluation Platform (CEP)
diff --git a/unit_simulation/llki_supports/llki_struct.h b/unit_simulation/llki_supports/llki_struct.h
index d8f091f..1a87f2e 100644
--- a/unit_simulation/llki_supports/llki_struct.h
+++ b/unit_simulation/llki_supports/llki_struct.h
@@ -1,6 +1,6 @@
//************************************************************************
// Copyright (C) 2020 Massachusetts Institute of Technology
-// SPDX License Identifier: MIT
+// SPDX short identifier: BSD-2-Clause
//
// File Name: llki_struct.h
// Program: Common Evaluation Platform (CEP)
diff --git a/unit_simulation/llki_supports/llki_tl.sv b/unit_simulation/llki_supports/llki_tl.sv
index bbc493a..9a883a5 100644
--- a/unit_simulation/llki_supports/llki_tl.sv
+++ b/unit_simulation/llki_supports/llki_tl.sv
@@ -1,6 +1,6 @@
//************************************************************************
// Copyright (C) 2020 Massachusetts Institute of Technology
-// SPDX License Identifier: MIT
+// SPDX short identifier: BSD-2-Clause
//
// File Name: llki_tl.sv
// Program: Common Evaluation Platform (CEP)
diff --git a/unit_simulation/llki_supports/tlul_pkg.sv b/unit_simulation/llki_supports/tlul_pkg.sv
index 10096db..ef94162 100644
--- a/unit_simulation/llki_supports/tlul_pkg.sv
+++ b/unit_simulation/llki_supports/tlul_pkg.sv
@@ -1,5 +1,6 @@
//************************************************************************
// Copyright (C) 2020 Massachusetts Institute of Technology
+// SPDX short identifier: BSD-2-Clause
//
// File Name: tlul_pkg.sv
// Program: Common Evaluation Platform (CEP)