-
Notifications
You must be signed in to change notification settings - Fork 100
Add Vivado xsim DPI-C co-simulation backend for RogueTcpStream, RogueTcpMemory, and RogueSideBand #1452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ruck314
wants to merge
4
commits into
ci-RogueTcpMemoryWrap-RogueTcpStreamWrap
Choose a base branch
from
cosim-xsim
base: ci-RogueTcpMemoryWrap-RogueTcpStreamWrap
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Add Vivado xsim DPI-C co-simulation backend for RogueTcpStream, RogueTcpMemory, and RogueSideBand #1452
Changes from 1 commit
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ ruckus | |
| ruckus/ | ||
| build/ | ||
| sim_build* | ||
| xsc.pb | ||
| .coverage* | ||
|
|
||
| # Local editor/agent state | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # Simlink | ||
|
|
||
| This directory holds three interchangeable Rogue co-simulation backends -- GHDL/VHPIDIRECT (`ghdl/`), Synopsys VCS/VHPI (`vcs/`), and Vivado xsim/DPI (`xsim/`) -- selected automatically by `ruckus.tcl` based on the active simulator. All three backends share the same `shared/` C cores and speak the same ZeroMQ wire protocol to a Rogue-side Python peer, so a testbench built against one backend behaves the same on any of the others. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - `libzmq >= 4.1.0` -- check with `pkg-config --modversion libzmq`. | ||
| - A Rogue-environment shell for the peer scripts (they `import pyrogue` / `import rogue`). | ||
|
|
||
| ## Running the Vivado xsim Co-Simulation | ||
|
|
||
| 1. Run `make gui` from the target directory. Ruckus auto-detects whichever of `RogueTcpStream.vhd`, `RogueTcpMemory.vhd`, or `RogueSideBand.vhd` is present in the sim sources, builds the combined `RogueTcpDpi.so` via `xsc`, and binds it with a single `-sv_lib RogueTcpDpi` -- no manual build step is required. | ||
| 2. Watch the Tcl/GUI console for the `xsc` build completing and, after `launch_simulation` / `run`, the module's `Listening on ports N & N+1` message -- that print is the ready-for-peer signal. | ||
| 3. In a separate terminal, start the matching Rogue-side driver script against that module's port. | ||
| 4. Watch the waveform -- data movement between the DPI adapter and the peer confirms the round trip. | ||
|
|
||
| | Module | Demo TB | Ports | Peer script | | ||
| |--------|---------|-------|-------------| | ||
| | RogueTcpStream | `RogueTcpStreamXsimDemoTb` | 9000 (push on 9001) | `prbsLoopbackDemo.py` | | ||
| | RogueTcpMemory | `RogueTcpMemoryXsimDemoTb` | 9100 (push on 9101) | `axiVersionMemoryDemo.py` | | ||
| | RogueSideBand | `RogueSideBandXsimDemoTb` | 9200 (push on 9201) | `sideBandDemo.py` | | ||
|
|
||
| ## Selecting a Module | ||
|
|
||
| Vivado elaborates one top per simulation fileset, so switching which module's demo runs is a single manual step: in the target's `ruckus.tcl`, comment/uncomment the desired `set_property top {...XsimDemoTb}` line, then run `make gui` again. This is the only manual step when switching between modules -- the DPI build and `-sv_lib` binding stay identical regardless of which module is selected. | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| **"libzmq package was not found"** | ||
| If the Tcl console prints: | ||
| ``` | ||
| libzmq package was not found | ||
| Please make sure that you have libzmq installed | ||
| or have sourced the necessary rogue setup scripts | ||
| ``` | ||
| install libzmq (or source the Rogue setup scripts that put it on `PKG_CONFIG_PATH`) and re-run `make gui`. | ||
|
|
||
| **Idle waveform, no data movement** | ||
| If the console printed `Listening on ports N & N+1` but the waveform never shows activity, the peer has not connected. Confirm the driver script is running, targeting the same host (loopback `127.0.0.1`) and port pair as the module under test, and that push/pull directions are not swapped. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| ############################################################################## | ||
| ## This file is part of 'SLAC Firmware Standard Library'. | ||
| ## It is subject to the license terms in the LICENSE.txt file found in the | ||
| ## top-level directory of this distribution and at: | ||
| ## https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. | ||
| ## No part of 'SLAC Firmware Standard Library', including this file, | ||
| ## may be copied, modified, propagated, or distributed except according to | ||
| ## the terms contained in the LICENSE.txt file. | ||
| ############################################################################## | ||
| # xsc-based build (Vivado xsim DPI-C), re-targeted from ghdl/Makefile's | ||
| # gcc -shared -fPIC + pkg-config libzmq pattern to the xsc two-step compile/ | ||
| # link flow. Builds the combined RogueTcpDpi.so from every module's DPI-C | ||
| # adapter (RogueTcpStream.c, RogueTcpMemory.c, RogueSideBand.c); a single | ||
| # "-sv_lib RogueTcpDpi" binds all of them. Each adapter keeps its own | ||
| # file-scope static data and name-prefixed | ||
| # functions, so linking them into one .so has no symbol collisions. The | ||
| # file is named RogueTcpDpi.so (no "lib" prefix): xelab's "-sv_lib | ||
| # RogueTcpDpi" resolves the DPI library as <name>.so, not lib<name>.so | ||
| # (per UG900). xsc stages its compiled object under its own implicit | ||
| # ./xsim.dir/work/xsc/ directory (no BUILD_DIR indirection like GHDL/VCS use). | ||
| ############################################################################## | ||
|
|
||
| CC := xsc | ||
| # -I../shared resolves the shared RogueTcp*Core.h headers that every backend | ||
| # includes; xsc's underlying gcc searches the including file's own dir | ||
| # first, so the xsim/ RogueTcp*.h still take precedence. svdpi.h is | ||
| # auto-found by xsc (adds $XILINX_VIVADO/data/xsim/include automatically). | ||
| CFLAGS := -I../shared $(shell pkg-config --cflags libzmq) | ||
| # Vivado <= 2024.1 bundles a gcc-9.3.0 whose link driver invokes its own | ||
| # binutils via -B and does not search the host multiarch lib dir, so the | ||
| # RogueTcpDpi.so link fails with "cannot find crti.o / -lzmq / -lm". Point both | ||
| # the startfile search (-B, for crt*.o) and the library search (-L) at the | ||
| # active gcc's lib dir, derived portably from `gcc -print-file-name=crti.o` | ||
| # (resolves to /usr/lib/x86_64-linux-gnu on Debian/Ubuntu, /usr/lib64 on RHEL). | ||
| # Harmless on Vivado >= 2024.2, whose xsc already resolves these. | ||
| MULTIARCH_DIR := $(dir $(shell gcc -print-file-name=crti.o)) | ||
| LFLAGS := $(shell pkg-config --libs libzmq) -B$(MULTIARCH_DIR) -L$(MULTIARCH_DIR) | ||
|
|
||
| LIB := RogueTcpDpi.so | ||
|
|
||
| all: $(LIB) | ||
|
|
||
| $(LIB): RogueTcpStream.c RogueTcpMemory.c RogueSideBand.c | ||
| $(CC) -c RogueTcpStream.c -gcc_compile_options "$(CFLAGS)" | ||
| $(CC) -c RogueTcpMemory.c -gcc_compile_options "$(CFLAGS)" | ||
| $(CC) -c RogueSideBand.c -gcc_compile_options "$(CFLAGS)" | ||
| $(CC) --shared -o $(LIB) -gcc_link_options "$(LFLAGS)" | ||
|
|
||
| clean: | ||
| rm -rf xsim.dir xsc.pb xsc.log $(LIB) | ||
|
|
||
| .PHONY: all clean |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| ////////////////////////////////////////////////////////////////////////////// | ||
| // This file is part of 'SLAC Firmware Standard Library'. | ||
| // It is subject to the license terms in the LICENSE.txt file found in the | ||
| // top-level directory of this distribution and at: | ||
| // https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. | ||
| // No part of 'SLAC Firmware Standard Library', including this file, | ||
| // may be copied, modified, propagated, or distributed except according to | ||
| // the terms contained in the LICENSE.txt file. | ||
| ////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // Vivado xsim DPI-C backend for the Rogue side-band model. The ZMQ transport | ||
| // (RogueSideBandRestart/Send/Recv) and the opcode/remData FSM | ||
| // (RogueSideBandStep) live in axi/simlink/shared/RogueSideBandCore.h, | ||
| // included by every backend. This file provides only the DPI-specific | ||
| // plumbing: a per-edge update function (rogueSideBandUpdate) that copies the | ||
| // DPI svBit/svBitVecVal parameters into the input snapshot, runs one FSM | ||
| // step, and writes the outputs back through the DPI output pointers. Unlike | ||
| // the GHDL VHPIDIRECT backend, every port here is <=32 bits, so each vector | ||
| // argument is a single svBitVecVal word -- no encode/decode loop is needed. | ||
| ////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #include <zmq.h> | ||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
| #include <string.h> | ||
| #include <unistd.h> | ||
| #include <errno.h> | ||
|
|
||
| #include "svdpi.h" | ||
| #include "RogueSideBand.h" | ||
| #include "RogueSideBandCore.h" | ||
|
|
||
| // Single instance for this simulation; file-scope statics are zero- | ||
| // initialized by C, replacing the src Init's malloc+memset. | ||
| static RogueSideBandData sideBandData; | ||
|
|
||
| // Per-edge update function, called from the RogueSideBandDpi SV leaf every | ||
| // rising_edge(clock) via import "DPI-C". Copies each DPI parameter straight | ||
| // into the input snapshot (the getInt seam), runs one shared FSM step, then | ||
| // writes the outputs back through the DPI output pointers. | ||
| void rogueSideBandUpdate(unsigned char reset, const svBitVecVal *portNum, | ||
| const svBitVecVal *txOpCode, unsigned char txOpCodeEn, const svBitVecVal *txRemData, | ||
| svBitVecVal *rxOpCode, unsigned char *rxOpCodeEn, svBitVecVal *rxRemData) { | ||
| RogueSideBandData *data = &sideBandData; | ||
| unsigned int reqPort = portNum[0] & 0xFFFF; | ||
|
|
||
| // DPI-C imports carry no per-instance context, so this backend hosts a | ||
| // single global sideBandData and supports only one RogueSideBand per | ||
| // simulation. A second instance would otherwise silently share this | ||
| // state and bind only the first port. Fail fast once a different, | ||
| // already-latched port is observed rather than corrupt state. | ||
| if ( data->port != 0 && reqPort != 0 && reqPort != data->port ) { | ||
| vhpi_printf("RogueSideBand: Vivado xsim DPI-C backend supports only one instance per simulation; observed ports %u and %u\n", data->port, reqPort); | ||
| vhpi_assert("RogueSideBand: multiple instances unsupported under Vivado xsim DPI-C", vhpiFatal); | ||
| return; | ||
| } | ||
|
|
||
| data->inSnap[s_reset] = reset ? 1 : 0; | ||
| data->inSnap[s_port] = reqPort; | ||
| data->inSnap[s_txOpCode] = txOpCode[0]; | ||
| data->inSnap[s_txOpCodeEn] = txOpCodeEn ? 1 : 0; | ||
| data->inSnap[s_txRemData] = txRemData[0]; | ||
|
|
||
| // RogueSideBandStep (shared FSM) calls RogueSideBandRecv, which uses | ||
| // ZMQ_DONTWAIT -- never make this a blocking call, or it freezes the | ||
| // whole Vivado xsim process, not just a background thread. | ||
| RogueSideBandStep(data); | ||
|
|
||
| rxOpCode[0] = data->outState[s_rxOpCode]; | ||
| *rxOpCodeEn = data->outState[s_rxOpCodeEn] ? 1 : 0; | ||
| rxRemData[0] = data->outState[s_rxRemData]; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| ////////////////////////////////////////////////////////////////////////////// | ||
| // This file is part of 'SLAC Firmware Standard Library'. | ||
| // It is subject to the license terms in the LICENSE.txt file found in the | ||
| // top-level directory of this distribution and at: | ||
| // https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. | ||
| // No part of 'SLAC Firmware Standard Library', including this file, | ||
| // may be copied, modified, propagated, or distributed except according to | ||
| // the terms contained in the LICENSE.txt file. | ||
| ////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #ifndef __ROGUE_SIDE_BAND_H__ | ||
| #define __ROGUE_SIDE_BAND_H__ | ||
|
|
||
| #include <stdint.h> | ||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
|
|
||
| // Signals | ||
| #define s_clock 0 | ||
| #define s_reset 1 | ||
| #define s_port 2 | ||
|
|
||
| #define s_txOpCode 3 | ||
| #define s_txOpCodeEn 4 | ||
| #define s_txRemData 5 | ||
|
|
||
| #define s_rxOpCode 6 | ||
| #define s_rxOpCodeEn 7 | ||
| #define s_rxRemData 8 | ||
|
|
||
| #define PORT_COUNT 9 | ||
|
|
||
| // Vivado xsim's DPI-C boundary has no VHPI (no vhpi_register_cb / value-change | ||
| // callbacks), so the VHPI print/assert calls in the transplanted FSM body are | ||
| // shimmed straight to printf/abort. The severity argument is accepted but | ||
| // never referenced, so no VHPI severity token (e.g. vhpiFatal) needs defining. | ||
| // This shim is backend-agnostic and is shared verbatim with the GHDL backend. | ||
| #define vhpi_printf(...) printf(__VA_ARGS__) | ||
| #define vhpi_assert(msg, sev) \ | ||
| do { \ | ||
| fprintf(stderr, "%s\n", (msg)); \ | ||
| abort(); \ | ||
| } while (0) | ||
|
|
||
| // Macros for get/set ints, redefined for the per-edge update-procedure model: | ||
| // getInt reads the input snapshot populated at update-procedure entry; | ||
| // setInt writes the output state read back through the DPI output pointers. | ||
| #define getInt(idx) (data->inSnap[idx]) | ||
| #define setInt(idx, val) (data->outState[idx] = (val)) | ||
|
|
||
| // Structure to track state | ||
| typedef struct { | ||
| uint16_t port; | ||
|
|
||
| uint8_t rxRemData; | ||
| uint8_t rxOpCode; | ||
| uint8_t rxOpCodeEn; | ||
|
|
||
| uint8_t txRemData; | ||
| uint8_t txRemDataChanged; | ||
| uint8_t txOpCode; | ||
| uint8_t txOpCodeEn; | ||
|
|
||
| unsigned int inSnap[PORT_COUNT]; | ||
| unsigned int outState[PORT_COUNT]; | ||
|
|
||
| void * zmqCtx; | ||
| void * zmqPull; | ||
| void * zmqPush; | ||
| } RogueSideBandData; | ||
|
|
||
| // Start/restart zeromq server | ||
| void RogueSideBandRestart(RogueSideBandData *data); | ||
|
|
||
| // Send a message | ||
| void RogueSideBandSend(RogueSideBandData *data); | ||
|
|
||
| // Receive data if it is available | ||
| int RogueSideBandRecv(RogueSideBandData *data); | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| ------------------------------------------------------------------------------- | ||
| -- Company : SLAC National Accelerator Laboratory | ||
| ------------------------------------------------------------------------------- | ||
| -- Description: Rogue Side Band Simulation Module | ||
| ------------------------------------------------------------------------------- | ||
| -- This file is part of 'SLAC Firmware Standard Library'. | ||
| -- It is subject to the license terms in the LICENSE.txt file found in the | ||
| -- top-level directory of this distribution and at: | ||
| -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. | ||
| -- No part of 'SLAC Firmware Standard Library', including this file, | ||
| -- may be copied, modified, propagated, or distributed except according to | ||
| -- the terms contained in the LICENSE.txt file. | ||
| ------------------------------------------------------------------------------- | ||
|
|
||
| library ieee; | ||
| use ieee.std_logic_1164.all; | ||
|
|
||
| entity RogueSideBand is | ||
| port ( | ||
| clock : in std_logic; | ||
| reset : in std_logic; | ||
| portNum : in std_logic_vector(15 downto 0); | ||
|
|
||
| txOpCode : in std_logic_vector(7 downto 0); | ||
| txOpCodeEn : in std_logic; | ||
| txRemData : in std_logic_vector(7 downto 0); | ||
| rxOpCode : out std_logic_vector(7 downto 0); | ||
| rxOpCodeEn : out std_logic; | ||
| rxRemData : out std_logic_vector(7 downto 0)); | ||
| end RogueSideBand; | ||
|
|
||
| -- Define architecture | ||
| architecture RogueSideBand of RogueSideBand is | ||
|
|
||
| ------------------------------------------------------------------------ | ||
| -- Vivado xsim has no VHPI, so this fork forwards to the DPI-C model via a | ||
| -- native mixed-language component instantiation of the SV leaf | ||
| -- RogueSideBandDpi (below), instead of GHDL's attribute foreign | ||
| -- VHPIDIRECT binding. VHPI original: axi/simlink/vcs/RogueSideBand.vhd | ||
| ------------------------------------------------------------------------ | ||
|
|
||
| component RogueSideBandDpi | ||
| port ( | ||
| clock : in std_logic; | ||
| reset : in std_logic; | ||
| portNum : in std_logic_vector(15 downto 0); | ||
|
|
||
| txOpCode : in std_logic_vector(7 downto 0); | ||
| txOpCodeEn : in std_logic; | ||
| txRemData : in std_logic_vector(7 downto 0); | ||
| rxOpCode : out std_logic_vector(7 downto 0); | ||
| rxOpCodeEn : out std_logic; | ||
| rxRemData : out std_logic_vector(7 downto 0)); | ||
| end component; | ||
|
|
||
| begin | ||
|
|
||
| U_Dpi : component RogueSideBandDpi | ||
| port map ( | ||
| clock => clock, | ||
| reset => reset, | ||
| portNum => portNum, | ||
| txOpCode => txOpCode, | ||
| txOpCodeEn => txOpCodeEn, | ||
| txRemData => txRemData, | ||
| rxOpCode => rxOpCode, | ||
| rxOpCodeEn => rxOpCodeEn, | ||
| rxRemData => rxRemData); | ||
|
|
||
| end RogueSideBand; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.