Skip to content

Commit 69a925d

Browse files
committed
tests: examples: Add an RTL/UMI example
Signed-off-by: Edgar E. Iglesias <edgar@zeroasic.com>
1 parent 6ac9794 commit 69a925d

File tree

4 files changed

+238
-0
lines changed

4 files changed

+238
-0
lines changed

tests/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
SUBDIRS_EXAMPLES += example-rtl-axi4
2727
SUBDIRS_EXAMPLES += example-rtl-axi4lite
2828
SUBDIRS_EXAMPLES += example-rtl-mixed
29+
SUBDIRS_EXAMPLES += example-rtl-umi
2930

3031
SUBDIRS += $(SUBDIRS_EXAMPLES)
3132
SUBDIRS += tlm-modules

tests/example-rtl-umi/Makefile

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#
2+
# Copyright (c) 2024 Zero ASIC.
3+
# Written by Edgar E. Iglesias.
4+
#
5+
# SPDX-License-Identifier: MIT
6+
#
7+
-include ../../.config.mk
8+
include ../Rules.mk
9+
10+
UMI_DIR = ../../submodules/umi
11+
12+
# Create a SystemC executable
13+
VFLAGS = -exe -sc -build
14+
VFLAGS += -Wall -Wno-fatal --pins-bv 2
15+
VFLAGS += --trace
16+
VFLAGS += -y $(UMI_DIR)/umi/rtl/
17+
VFLAGS += -y $(UMI_DIR)/submodules/lambdalib/ramlib/rtl/
18+
VFLAGS += -y $(UMI_DIR)/submodules/lambdalib/stdlib/rtl/
19+
20+
CPPFLAGS += -I ../../../ -I ../../ -I .
21+
CXXFLAGS += -Wall -O3 -g
22+
23+
ALL_OBJS += $(EXAMPLE_RTL_UMI_OBJS)
24+
25+
VFILES = umi_dev.v
26+
SCFILES = example-rtl-umi.cc ../../trace/trace.cc
27+
28+
# Conditionalize build on having the UMI submodule.
29+
ifeq ($(shell test -d $(UMI_DIR) && echo -n yes),yes)
30+
TARGETS += $(VOBJ_DIR)/example-rtl-umi
31+
endif
32+
33+
all: $(TARGETS)
34+
35+
.PHONY: $(VOBJ_DIR)/example-rtl-umi
36+
$(VOBJ_DIR)/example-rtl-umi:
37+
verilator -CFLAGS "$(CPPFLAGS)" $(VFLAGS) $(SCFILES) $(VFILES) -o example-rtl-umi
38+
39+
clean:
40+
$(RM) -r $(VOBJ_DIR)
41+
$(RM) $(TARGETS:=.vcd)
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
* This is a small example showing howto connect an RTL UMI Device
3+
* to a SystemC/TLM simulation using the TLM-2-UMI bridge.
4+
*
5+
* Copyright (c) 2024 Zero ASIC.
6+
* Written by Edgar E. Iglesias
7+
*
8+
* SPDX-License-Identifier: MIT
9+
*/
10+
11+
#include <sstream>
12+
13+
#define SC_INCLUDE_DYNAMIC_PROCESSES
14+
15+
#include "systemc"
16+
using namespace sc_core;
17+
using namespace sc_dt;
18+
using namespace std;
19+
20+
#include "tlm.h"
21+
#include "tlm_utils/simple_initiator_socket.h"
22+
#include "tlm_utils/simple_target_socket.h"
23+
24+
#include "tlm-bridges/tlm2umi-bridge.h"
25+
#include "traffic-generators/tg-tlm.h"
26+
#include "traffic-generators/traffic-desc.h"
27+
28+
#include "test-modules/signals-umi.h"
29+
#include "test-modules/utils.h"
30+
#include "trace/trace.h"
31+
#if VM_TRACE
32+
#include <verilated_vcd_sc.h>
33+
#endif
34+
35+
#include "Vumi_dev.h"
36+
37+
using namespace utils;
38+
39+
#define DW 64
40+
41+
#define CONNECT_DUT(DUT, SIGS, SIGNAME) DUT.s00_axi_ ## SIGNAME(SIGS.SIGNAME)
42+
43+
TrafficDesc transactions(merge({
44+
// Write something to address 8
45+
Write(8, DATA(0x1, 0x2, 0x3, 0x4)),
46+
// Read it back and check that we get the expected data.
47+
Read(8, 4),
48+
Expect(DATA(0x1, 0x2, 0x3, 0x4), 4)
49+
}));
50+
51+
// Top simulation module.
52+
SC_MODULE(Top)
53+
{
54+
sc_clock clk;
55+
sc_signal<bool> rst;
56+
57+
TLMTrafficGenerator tg;
58+
UMISignals<DW> signals_req;
59+
UMISignals<DW> signals_resp;
60+
tlm2umi_bridge<DW> bridge;
61+
Vumi_dev dut;
62+
63+
void do_reset(void) {
64+
int i;
65+
66+
rst.write(false);
67+
for (i = 0; i < 2; i++) {
68+
wait(clk.posedge_event());
69+
}
70+
rst.write(true);
71+
for (i = 0; i < 4; i++) {
72+
wait(clk.posedge_event());
73+
}
74+
rst.write(false);
75+
}
76+
77+
SC_HAS_PROCESS(Top);
78+
Top(sc_module_name name) :
79+
clk("clk", sc_time(1, SC_US)),
80+
rst("rst"),
81+
tg("traffic_generator"),
82+
signals_req("signals_req"),
83+
signals_resp("signals_resp"),
84+
bridge("bridge"),
85+
dut("dut")
86+
{
87+
SC_THREAD(do_reset);
88+
89+
// Configure the Traffic generator.
90+
tg.setStartDelay(sc_time(8, SC_US));
91+
tg.enableDebug();
92+
tg.addTransfers(transactions);
93+
tg.socket.bind(bridge.socket);
94+
95+
// Wire up the clock and reset signals.
96+
bridge.clk(clk);
97+
bridge.rst(rst);
98+
dut.clk(clk);
99+
dut.rst(rst);
100+
101+
// Wire-up the bridge and checker.
102+
signals_req.connect(bridge, "req_");
103+
signals_resp.connect(bridge, "resp_");
104+
signals_req.connect(dut, "udev_req_");
105+
signals_resp.connect(dut, "udev_resp_");
106+
}
107+
};
108+
109+
int sc_main(int argc, char *argv[])
110+
{
111+
Top top("Top");
112+
113+
#if VM_TRACE
114+
// Before any evaluation, need to know to calculate those signals only used for tracing
115+
Verilated::traceEverOn(true);
116+
#endif
117+
118+
Verilated::commandArgs(argc, argv);
119+
120+
// You must do one evaluation before enabling waves, in order to allow
121+
// SystemC to interconnect everything for testing.
122+
sc_start(SC_ZERO_TIME);
123+
124+
sc_trace_file *trace_fp = sc_create_vcd_trace_file(argv[0]);
125+
trace(trace_fp, top, "top");
126+
127+
#if VM_TRACE
128+
// General logfile
129+
ios::sync_with_stdio();
130+
131+
// If verilator was invoked with --trace argument,
132+
// and if at run time passed the +trace argument, turn on tracing
133+
VerilatedVcdSc* tfp = nullptr;
134+
const char* flag = Verilated::commandArgsPlusMatch("trace");
135+
if (flag && 0 == std::strcmp(flag, "+trace")) {
136+
std::cout << "Enabling waves into logs/vlt_dump.vcd...\n";
137+
tfp = new VerilatedVcdSc;
138+
top.dut.trace(tfp, 99); // Trace 99 levels of hierarchy
139+
Verilated::mkdir("logs");
140+
tfp->open("logs/vlt_dump.vcd");
141+
142+
trace_fp = sc_create_vcd_trace_file(argv[0]);
143+
trace(trace_fp, top, "Top");
144+
}
145+
#endif
146+
147+
sc_start(140, SC_US);
148+
sc_stop();
149+
150+
#if VM_TRACE
151+
// Flush the wave files each cycle so we can immediately see the output
152+
// Don't do this in "real" programs, do it in an abort() handler instead
153+
if (tfp) tfp->flush();
154+
#endif
155+
if (trace_fp) {
156+
sc_close_vcd_trace_file(trace_fp);
157+
}
158+
return 0;
159+
}

tests/example-rtl-umi/umi_dev.v

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Wrapper around the UMI memory agent.
3+
*
4+
* Copyright (c) 2024 Zero ASIC.
5+
* Written by Edgar E. Iglesias
6+
*
7+
* SPDX-License-Identifier: MIT
8+
*/
9+
10+
module umi_dev
11+
#(
12+
parameter DW = 64,
13+
parameter AW = 64
14+
)(
15+
input clk,
16+
input rst,
17+
18+
input [31:0] udev_req_cmd,
19+
input [AW-1:0] udev_req_dstaddr,
20+
input [AW-1:0] udev_req_srcaddr,
21+
input [DW-1:0] udev_req_data,
22+
input udev_req_valid,
23+
output reg udev_req_ready,
24+
25+
output reg [31:0] udev_resp_cmd,
26+
output reg [AW-1:0] udev_resp_dstaddr,
27+
output reg [AW-1:0] udev_resp_srcaddr,
28+
output reg [DW-1:0] udev_resp_data,
29+
output reg udev_resp_valid,
30+
input udev_resp_ready
31+
);
32+
wire nreset = ~rst;
33+
34+
// See: submodules/umi/umi/rtl/umi_mem_agent.v
35+
wire [0:0] sram_ctrl;
36+
umi_mem_agent #(.AW(AW), .DW(DW), .CTRLW(1)) mem(.*);
37+
endmodule

0 commit comments

Comments
 (0)