Install Modelsim
We will run our test in Modelsim PE -- we will use an evaluation copy for Windows (tested on a Windows 10 64-bits host).
Once we have installed Modelsim, we need to be sure that it's added to the system path.
Compile the Xilinx libraries
The WR-Core design is based on Xilinx devices, so we will need to be sure that the Xilinx HDL libraries are compiled for our simulator. In this case, we are using Xilinx 6-series devices, so we will use the tool provided by ISE for this purpose:
compxlib -s mti_pe -l vhdl -arch spartan6 -dir C:\modeltech_pe_10.5a\xilinx_libs
Not only the libraries will be installed in the path pointed by the -dir flag, but...
- ... modelsim.ini file will be created in the directroty from which we have executed compxlib.
- ... if a previous modelsim.ini exists in the folder, this will be updated with the new libraries.
We have two options to provide the custom modelsim.ini file:
- Replace the default modelsim.ini at the simulator installation directory.
- Use the modelsim_ini_path variable at Manifest.py to point to the path containing the custom file.
Example: WR PTP Core
Install and fix source code
CERN OHR moved to GitLab and the repository structure has changed. In order to get the WR-Cores we need to clone the repository from the new location:
git clone https://ohwr.org/project/wr-cores.git
The stable version for WRPC is 4.2, so we checkout the associated tag:
cd wr-cores
git checkout wrpc-v4.2
This version relies on Git submodule to grab the required IP Cores for simuation, but the repository links are broken after the migration to GitLab (see this for deeper information).
We can use HDLMake to fetch the appropriated versions for WRPC v4.2, but we will need to fix the code by applying this patch declaring the requisites as HDLMake remote modules: fix_hdlmake_testbench_remote_modules.patch
diff --git a/testbench/wrc_core/Manifest.py b/testbench/wrc_core/Manifest.py
index 0278e5c..589aa2f 100644
--- a/testbench/wrc_core/Manifest.py
+++ b/testbench/wrc_core/Manifest.py
@@ -12,11 +12,14 @@ files = [ "main.sv" ]
include_dirs = [ "../../sim" ]
-modules = { "local" : [ "../../",
- "../../modules/fabric",
- "../../ip_cores/general-cores",
- "../../ip_cores/etherbone-core",
- "../../ip_cores/gn4124-core" ]}
-
-
-
+modules = {
+ "local" : [
+ "../../",
+ "../../modules/fabric",
+ ],
+ "git" : [
+ "https://ohwr.org/project/general-cores.git@@5205d9754b1e0887df5914a47f8aa745e4f3c2fe",
+ "https://ohwr.org/project/gn4124-core.git@@9b9625bb4270114266cd357f199d649f3d799f04",
+ "https://ohwr.org/project/etherbone-core.git@@8489445985ff2afe6c72712014a92a271869f20a",
+ ],
+}
We will use the following demo simulation, that simulates a WR PTP Core receiving and processing synchronous Gigabit Ethernet frames:
cd testbench/wrc_core
In some version of Modelsim (e.g. Modelsim PE 10.5a), we will need to fix the declaration of the initialized variables in System Verilog testbenches. As an example, we can apply this patch
diff --git a/testbench/wrc_core/functions.svh b/testbench/wrc_core/functions.svh
index 33abf71..8ad1c8e 100644
--- a/testbench/wrc_core/functions.svh
+++ b/testbench/wrc_core/functions.svh
@@ -48,14 +48,14 @@ semaphore txPkt = new(1);
*/
task send_frames(WBPacketSource src, int n_packets, int ifg = 0 /*[us]*/);
// TODO: improve the IFG: allow to make it tighter
- int i, seed = 0,n1=0,n2=0;
- int cur_size, dir;
+ static int seed = 0,n1=0,n2=0;
+ int i, cur_size, dir;
EthPacket pkt, tmpl;
EthPacket to_ext[$], to_minic[$];
- EthPacketGenerator gen = new;
+ static EthPacketGenerator gen = new;
int random_ifg; //us
- int min_ifg = 1; //us
- int max_ifg = 100;//us
+ static int min_ifg = 1; //us
+ static int max_ifg = 100;//us
tmpl = new;
tmpl.src = '{'h22,'h33,'h44,'h44,'h55,'h66};
Run simulation
Once everything is ready, we can compile the design sources. As the SystemVerilog parser is not very accurate yet and it is not able to successfully solve the complete hierarchy, we will need to pass the -a flag to the makefile generation command so that all the files are parsed and passed to the compiler -- even if we cannot relate them to the top entity by using dependency relations:
hdlmake -a makefile
make
vsim -modelsimini modelsim.ini -L unisim -do run.do -i main
Alternatively, we can provide the full path to the Unisim library (required XIlinx sim components):
vsim -L c:\modeltech_pe_10.5a\xilinx_libs\unisim -do run.do -i main
If everything go OK, Modelsim window will open and we will see the waveform progress for the design under test.
Optional: build a RAM file for LM32
If we need a RAM file for the LM32 processor embedded in the FPGA, we can build one by following this process.
Install LM32 cross-compiler:
wget http://www.ohwr.org/attachments/download/1133/lm32.tar.xz
tar xJf lm32.tar.xz -C <your_lm32_location>
export CROSS_COMPILE="<your_lm32_location>/lm32/bin/lm32-elf-"
Grab and build the sources:
git clone https://ohwr.org/hdl-core-lib/wr-cores/wrpc-sw.git
cd wrpc-sw
git checkout wrpc-v4.2
make spec_defconfig
make
This will produce several outputs, including the wrc.ram, a file formated as a memory block and that need to be placed in the wr-cores/testbench/top_level to succesfully run the simulation.