Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions dv/d2d/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
UCIE_ROOT ?= $(abspath ../..)
SCALA_DIR ?= $(UCIE_ROOT)/scala
BUILD_DIR ?= $(UCIE_ROOT)/build/d2d-dv
GEN_DIR ?= $(BUILD_DIR)/generated
SIM_DIR ?= $(BUILD_DIR)/sim

DATA_BYTES ?= 32
SIDEBAND_WIDTH ?= 32

ELAB_MAIN ?= edu.berkeley.cs.uciedigital.d2dadapter.D2DAdapterDvElaborate
ELAB_TOP ?= D2DAdapterDvTop
TB_TOP ?= ucie_d2d_dv_top

VCS ?= vcs -full64
VCS_OPTS ?= \
-sverilog \
+v2k \
-timescale=1ns/1ps \
+lint=all,noVCDE,noONGS,noUI \
+vcs+lic+wait \
-debug_access+all \
-Mdir=$(SIM_DIR)/csrc \
-kdb \
-lca

DV_SRCS ?= \
$(UCIE_ROOT)/dv/d2d/tb/ucie_d2d_dv_pkg.sv \
$(UCIE_ROOT)/dv/d2d/tb/ucie_d2d_fdi_if.sv \
$(UCIE_ROOT)/dv/d2d/tb/ucie_d2d_rdi_if.sv \
$(UCIE_ROOT)/dv/d2d/tb/ucie_d2d_smoke_checkers.sv \
$(UCIE_ROOT)/dv/d2d/tb/ucie_d2d_dv_top.sv
RTL_FILELIST := $(SIM_DIR)/rtl.f
SIMV := $(SIM_DIR)/simv

.PHONY: elab force-elab vcs run clean

elab:
@if [ -f "$(GEN_DIR)/$(ELAB_TOP).sv" ]; then \
echo "Using existing elaborated RTL in $(GEN_DIR). Run 'make force-elab' to regenerate."; \
else \
$(MAKE) force-elab; \
fi

force-elab:
cd $(SCALA_DIR) && ./mill -i d2ddv.runMain $(ELAB_MAIN) \
--target-dir $(GEN_DIR) \
--data-bytes $(DATA_BYTES) \
--sideband-width $(SIDEBAND_WIDTH)

$(RTL_FILELIST): elab
mkdir -p $(SIM_DIR)
find $(GEN_DIR) -type f \( -name '*.sv' -o -name '*.v' \) \
! -path '$(GEN_DIR)/verification/*' | sort > $(RTL_FILELIST)

vcs: $(RTL_FILELIST)
$(VCS) $(VCS_OPTS) \
-f $(RTL_FILELIST) \
$(DV_SRCS) \
-top $(TB_TOP) \
-o $(SIMV) \
-l $(SIM_DIR)/vcs_compile.log

run: vcs
$(SIMV) -l $(SIM_DIR)/vcs_run.log

clean:
rm -rf $(BUILD_DIR)
59 changes: 59 additions & 0 deletions dv/d2d/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# D2D Adapter DV Flow

This directory is the entry point for SystemVerilog verification of the
elaborated D2D adapter.

The flow is intentionally split into two parts:

1. Elaborate the Chisel D2D adapter DV top with Mill.
2. Compile the emitted SystemVerilog plus DV sources with VCS.

The D2D adapter uses a narrow Mill module, `d2ddv`, so adapter elaboration does
not require the TileLink/Chipyard dependencies used by the full repo tests.

## Commands

From this directory:

```bash
make elab
```

This runs:

```bash
cd ../../scala
./mill -i d2ddv.runMain \
edu.berkeley.cs.uciedigital.d2dadapter.D2DAdapterDvElaborate \
--target-dir ../build/d2d-dv/generated \
--data-bytes 32 \
--sideband-width 32
```

Build a VCS simulator from the emitted RTL:

```bash
make vcs
```

Run it:

```bash
make run
```

By default, VCS compiles the emitted `D2DAdapterDvTop` under the stable
SystemVerilog wrapper `ucie_d2d_dv_top`. The wrapper exposes fixed `fdi` and
`rdi` interface instances for drivers, monitors, and SVA checkers.

Override widths as needed:

```bash
make elab DATA_BYTES=64 SIDEBAND_WIDTH=32
```

## Next Integration Step

Add new tests by extending or replacing `dv/d2d/tb/ucie_d2d_dv_top.sv`, or by
adding extra files through `DV_SRCS`. Keep tests and assertions pointed at the
wrapper/interface signals rather than generated internal hierarchy.
13 changes: 13 additions & 0 deletions dv/d2d/tb/ucie_d2d_dv_pkg.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ucie_d2d_dv_pkg;
localparam int DATA_BYTES = 32;
localparam int DATA_BITS = DATA_BYTES * 8;
localparam int SIDEBAND_WIDTH = 32;

localparam logic [3:0] RDI_STATE_RESET = 4'h0;
localparam logic [3:0] RDI_STATE_ACTIVE = 4'h1;
localparam logic [3:0] RDI_STATE_LINKERROR = 4'ha;
localparam logic [3:0] RDI_STATE_RETRAIN = 4'hb;

localparam logic [3:0] RDI_STATE_REQ_NOP = 4'h0;
localparam logic [3:0] RDI_STATE_REQ_ACTIVE = 4'h1;
endpackage
124 changes: 124 additions & 0 deletions dv/d2d/tb/ucie_d2d_dv_top.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
`timescale 1ns/1ps

module ucie_d2d_dv_top;
import ucie_d2d_dv_pkg::*;

logic clock;
logic reset;

ucie_d2d_fdi_if #(
.DATA_BITS(DATA_BITS),
.SIDEBAND_WIDTH(SIDEBAND_WIDTH)
) fdi();

ucie_d2d_rdi_if #(
.DATA_BITS(DATA_BITS),
.SIDEBAND_WIDTH(SIDEBAND_WIDTH)
) rdi();

D2DAdapterDvTop dut (
.clock (clock),
.reset (reset),
.io_fdi_lclk (fdi.lclk),
.io_fdi_lpIrdy (fdi.lpIrdy),
.io_fdi_lpValid (fdi.lpValid),
.io_fdi_lpData (fdi.lpData),
.io_fdi_plTrdy (fdi.plTrdy),
.io_fdi_plValid (fdi.plValid),
.io_fdi_plData (fdi.plData),
.io_fdi_lpStateReq (fdi.lpStateReq),
.io_fdi_lpLinkError (fdi.lpLinkError),
.io_fdi_plStateSts (fdi.plStateSts),
.io_fdi_plInbandPres (fdi.plInbandPres),
.io_fdi_plError (fdi.plError),
.io_fdi_plCError (fdi.plCError),
.io_fdi_plNfError (fdi.plNfError),
.io_fdi_plTrainError (fdi.plTrainError),
.io_fdi_plPhyInRecenter (fdi.plPhyInRecenter),
.io_fdi_plStallReq (fdi.plStallReq),
.io_fdi_lpStallAck (fdi.lpStallAck),
.io_fdi_plSpeedmode (fdi.plSpeedmode),
.io_fdi_plMaxSpeedmode (fdi.plMaxSpeedmode),
.io_fdi_plLnkCfg (fdi.plLnkCfg),
.io_fdi_plClkReq (fdi.plClkReq),
.io_fdi_plWakeAck (fdi.plWakeAck),
.io_fdi_plCfg (fdi.plCfg),
.io_fdi_plCfgVld (fdi.plCfgVld),
.io_fdi_plCfgCrd (fdi.plCfgCrd),
.io_fdi_lpCfg (fdi.lpCfg),
.io_fdi_lpCfgVld (fdi.lpCfgVld),
.io_fdi_lpCfgCrd (fdi.lpCfgCrd),
.io_rdi_lclk (rdi.lclk),
.io_rdi_lpIrdy (rdi.lpIrdy),
.io_rdi_lpValid (rdi.lpValid),
.io_rdi_lpData (rdi.lpData),
.io_rdi_plTrdy (rdi.plTrdy),
.io_rdi_plValid (rdi.plValid),
.io_rdi_plData (rdi.plData),
.io_rdi_lpStateReq (rdi.lpStateReq),
.io_rdi_lpLinkError (rdi.lpLinkError),
.io_rdi_plStateSts (rdi.plStateSts),
.io_rdi_plInbandPres (rdi.plInbandPres),
.io_rdi_plError (rdi.plError),
.io_rdi_plCError (rdi.plCError),
.io_rdi_plNfError (rdi.plNfError),
.io_rdi_plTrainError (rdi.plTrainError),
.io_rdi_plPhyInRecenter (rdi.plPhyInRecenter),
.io_rdi_plStallReq (rdi.plStallReq),
.io_rdi_lpStallAck (rdi.lpStallAck),
.io_rdi_plSpeedmode (rdi.plSpeedmode),
.io_rdi_plMaxSpeedmode (rdi.plMaxSpeedmode),
.io_rdi_plLnkCfg (rdi.plLnkCfg),
.io_rdi_plClkReq (rdi.plClkReq),
.io_rdi_lpClkAck (rdi.lpClkAck),
.io_rdi_lpWakeReq (rdi.lpWakeReq),
.io_rdi_plWakeAck (rdi.plWakeAck),
.io_rdi_plCfg (rdi.plCfg),
.io_rdi_plCfgVld (rdi.plCfgVld),
.io_rdi_plCfgCrd (rdi.plCfgCrd),
.io_rdi_lpCfg (rdi.lpCfg),
.io_rdi_lpCfgVld (rdi.lpCfgVld),
.io_rdi_lpCfgCrd (rdi.lpCfgCrd)
);

ucie_d2d_smoke_checkers checkers (
.clock (clock),
.reset (reset),
.fdi (fdi),
.rdi (rdi)
);

initial begin
clock = 1'b0;
forever #5 clock = ~clock;
end

initial begin
fdi.drive_idle();
rdi.drive_idle();
reset = 1'b1;
repeat (5) begin
@(posedge clock);
end
reset = 1'b0;

rdi.plInbandPres = 1'b1;
repeat (5) begin
@(posedge clock);
end
rdi.plStateSts = RDI_STATE_ACTIVE;
repeat (20) begin
@(posedge clock);
end

$display("D2D DV smoke completed");
$finish;
end

initial begin
repeat (1000) begin
@(posedge clock);
end
$fatal(1, "D2D DV smoke timeout");
end
endmodule
46 changes: 46 additions & 0 deletions dv/d2d/tb/ucie_d2d_fdi_if.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
interface ucie_d2d_fdi_if #(
parameter int DATA_BITS = 256,
parameter int SIDEBAND_WIDTH = 32
);
logic lclk;
logic lpIrdy;
logic lpValid;
logic [DATA_BITS-1:0] lpData;
logic plTrdy;
logic plValid;
logic [DATA_BITS-1:0] plData;
logic [3:0] lpStateReq;
logic lpLinkError;
logic [3:0] plStateSts;
logic plInbandPres;
logic plError;
logic plCError;
logic plNfError;
logic plTrainError;
logic plPhyInRecenter;
logic plStallReq;
logic lpStallAck;
logic [2:0] plSpeedmode;
logic plMaxSpeedmode;
logic [2:0] plLnkCfg;
logic plClkReq;
logic plWakeAck;
logic [SIDEBAND_WIDTH-1:0] plCfg;
logic plCfgVld;
logic plCfgCrd;
logic [SIDEBAND_WIDTH-1:0] lpCfg;
logic lpCfgVld;
logic lpCfgCrd;

task automatic drive_idle();
lpIrdy = 1'b0;
lpValid = 1'b0;
lpData = '0;
lpStateReq = 4'h0;
lpLinkError = 1'b0;
lpStallAck = 1'b0;
plCfgCrd = 1'b1;
lpCfg = '0;
lpCfgVld = 1'b0;
endtask
endinterface
58 changes: 58 additions & 0 deletions dv/d2d/tb/ucie_d2d_rdi_if.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
interface ucie_d2d_rdi_if #(
parameter int DATA_BITS = 256,
parameter int SIDEBAND_WIDTH = 32
);
logic lclk;
logic lpIrdy;
logic lpValid;
logic [DATA_BITS-1:0] lpData;
logic plTrdy;
logic plValid;
logic [DATA_BITS-1:0] plData;
logic [3:0] lpStateReq;
logic lpLinkError;
logic [3:0] plStateSts;
logic plInbandPres;
logic plError;
logic plCError;
logic plNfError;
logic plTrainError;
logic plPhyInRecenter;
logic plStallReq;
logic lpStallAck;
logic [2:0] plSpeedmode;
logic plMaxSpeedmode;
logic [2:0] plLnkCfg;
logic plClkReq;
logic lpClkAck;
logic lpWakeReq;
logic plWakeAck;
logic [SIDEBAND_WIDTH-1:0] plCfg;
logic plCfgVld;
logic plCfgCrd;
logic [SIDEBAND_WIDTH-1:0] lpCfg;
logic lpCfgVld;
logic lpCfgCrd;

task automatic drive_idle();
plTrdy = 1'b1;
plValid = 1'b0;
plData = '0;
plStateSts = 4'h0;
plInbandPres = 1'b0;
plError = 1'b0;
plCError = 1'b0;
plNfError = 1'b0;
plTrainError = 1'b0;
plPhyInRecenter = 1'b0;
plStallReq = 1'b0;
plSpeedmode = 3'h0;
plMaxSpeedmode = 1'b0;
plLnkCfg = 3'h0;
plClkReq = 1'b0;
plWakeAck = 1'b0;
plCfg = '0;
plCfgVld = 1'b0;
plCfgCrd = 1'b1;
endtask
endinterface
26 changes: 26 additions & 0 deletions dv/d2d/tb/ucie_d2d_smoke_checkers.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module ucie_d2d_smoke_checkers (
input logic clock,
input logic reset,
ucie_d2d_fdi_if fdi,
ucie_d2d_rdi_if rdi
);
import ucie_d2d_dv_pkg::*;

default clocking cb @(posedge clock);
endclocking

fdi_active_after_rdi_active: assert property (
disable iff (reset)
fdi.plStateSts == RDI_STATE_ACTIVE |-> rdi.plStateSts == RDI_STATE_ACTIVE
) else $error("FDI reached Active while RDI was not Active");

fdi_linkerror_after_rdi_linkerror: assert property (
disable iff (reset)
fdi.plStateSts == RDI_STATE_LINKERROR |-> rdi.plStateSts == RDI_STATE_LINKERROR
) else $error("FDI reached LinkError while RDI was not LinkError");

rdi_stall_ack_requires_stall_req: assert property (
disable iff (reset)
rdi.lpStallAck |-> rdi.plStallReq
) else $error("RDI lpStallAck asserted without plStallReq");
endmodule
Loading