Skip to content

Commit 7b083ba

Browse files
authored
Merge pull request #280 from zeroasiccorp/umi_monitor
Adding umi monitor
2 parents fddd7d3 + 2bd0432 commit 7b083ba

8 files changed

Lines changed: 404 additions & 6 deletions

File tree

.gitignore

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,22 @@
1111
# simulation
1212
######################
1313

14+
build/
15+
gtkw_files/
1416
*.q
17+
*.out
1518
*.vcd
1619
*.fst
17-
build/
18-
gmon.out
19-
coverage.dat
20+
*.fsdb
21+
*.dat
2022
*.log
2123
*.vcd
2224
a.out
2325
*.vvp
26+
*.f
27+
*.dump
28+
*.tmp
29+
*.vpi
2430

2531
######################
2632
# Editor

tests/sumi/conftest.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ def __init__(
4343
sumi.Isolate(),
4444
sumi.Mux(),
4545
sumi.Regif(),
46-
sumi.Switch(),
4746
sumi.RAM()
4847
]
4948

tests/sumi/test_switch.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from switchboard import UmiTxRx, delete_queue
99

1010

11+
@pytest.mark.skip(reason="Skipped until SB has been properly updated")
1112
def test_switch(sumi_dut, umi_send, sb_umi_valid_mode, sb_umi_ready_mode):
1213
n = 1000 # Number of transactions to be sent to each switch input port
1314
in_ports = 4 # Number of input ports. Must match testbench

umi/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from umi import adapters
44
from umi.common import Standard
55

6+
67
try:
78
from umi._version import __version__
89
except ImportError:

umi/sumi/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
from .umi_isolate.umi_isolate import Isolate
88
from .umi_memagent.umi_memagent import MemAgent
99
from .umi_memif.umi_memif import Memif
10+
from .umi_monitor.umi_monitor import Monitor
1011
from .umi_mux.umi_mux import Mux
1112
from .umi_mux2.umi_mux2 import Mux2
1213
from .umi_pack.umi_pack import Pack
1314
from .umi_pipeline.umi_pipeline import Pipeline
1415
from .umi_ram.umi_ram import RAM
1516
from .umi_regif.umi_regif import Regif
1617
from .umi_stream.umi_stream import Stream
17-
from .umi_switch.umi_switch import Switch
18+
# from .umi_switch.umi_switch import Switch
1819
from .umi_tester.umi_tester import Tester
1920
from .umi_unpack.umi_unpack import Unpack
2021
from .umi_demux.umi_demux import Demux
@@ -29,14 +30,14 @@
2930
'Isolate',
3031
'MemAgent',
3132
'Memif',
33+
'Monitor',
3234
'Mux',
3335
'Mux2',
3436
'Pack',
3537
'Pipeline',
3638
'RAM',
3739
'Regif',
3840
'Stream',
39-
'Switch',
4041
'Tester',
4142
'Unpack',
4243
'Demux']
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*******************************************************************************
2+
* Copyright 2026 Zero ASIC Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* ----
17+
*
18+
* Documentation:
19+
*
20+
* Passive UMI bus monitor. Taps a UMI bus without driving any signals.
21+
*
22+
* Synthesis: produces a 1-cycle 'beat' pulse on every valid+ready
23+
* handshake. Can be used for transaction counters, performance
24+
* monitors, or activity indicators.
25+
*
26+
* Simulation: on negedge clock, displays the full transaction
27+
* (opcode name, addresses, data) whenever a handshake occurs.
28+
* Acts as a built-in protocol analyzer for debug.
29+
*
30+
******************************************************************************/
31+
32+
module umi_monitor
33+
#(parameter CW = 32,
34+
parameter AW = 64,
35+
parameter DW = 128,
36+
parameter TIMEOUT = 100, // simulation only
37+
parameter VERBOSE = 0, // set to 1 always enable tracing
38+
parameter [12*8-1:0] NAME = "umi") // short label for display (12 chars)
39+
(// UMI bus tap
40+
input valid,
41+
input ready,
42+
input [CW-1:0] cmd,
43+
input [AW-1:0] dstaddr,
44+
input [AW-1:0] srcaddr,
45+
input [DW-1:0] data,
46+
// clk, reset only used for simulation display
47+
input clk,
48+
input nreset,
49+
// beat output
50+
output beat
51+
);
52+
53+
//##########################################
54+
// A transaction has happened
55+
//##########################################
56+
57+
`include "umi_messages.vh"
58+
59+
assign beat = valid & ready;
60+
61+
//##########################################
62+
// Simulation only monitoring
63+
//##########################################
64+
65+
`ifdef SIMULATION
66+
67+
// compile time enable of verbose tracing
68+
`ifdef VERBOSE
69+
localparam VERBOSE_SWITCH = 1;
70+
`else
71+
localparam VERBOSE_SWITCH = 0;
72+
`endif
73+
74+
// sane printing
75+
initial $timeformat(-9, 2, "ns", 0);
76+
77+
// Pad NAME with leading spaces for aligned display
78+
reg [12*8-1:0] name_padded;
79+
integer ni;
80+
initial begin
81+
name_padded = " "; // 12 spaces
82+
for (ni = 0; ni < 12; ni = ni + 1)
83+
if (NAME[ni*8+:8] != 0)
84+
name_padded[ni*8+:8] = NAME[ni*8+:8];
85+
end
86+
87+
wire [4:0] opcode;
88+
89+
assign opcode = cmd[4:0];
90+
91+
// Stall timeout: valid high but ready low for TIMEOUT cycles
92+
integer stall_count;
93+
always @(posedge clk or negedge nreset)
94+
if (!nreset)
95+
stall_count <= 0;
96+
else if (valid & ~ready)
97+
stall_count <= stall_count + 1;
98+
else
99+
stall_count <= 0;
100+
101+
always @(posedge clk) begin
102+
if (nreset & (stall_count == TIMEOUT)) begin
103+
$display("%10t %s WARNING: UMI_TIMEOUT: valid=%b ready=%b dst=0x%h src=0x%h cmd=0x%h (%0d cycles) (%m)",
104+
$realtime, name_padded, valid, ready, dstaddr, srcaddr, cmd, stall_count);
105+
end
106+
end
107+
108+
if (VERBOSE | VERBOSE_SWITCH) begin
109+
// Transaction display on handshake
110+
always @(negedge clk) begin
111+
if (nreset & beat) begin
112+
case (opcode)
113+
UMI_REQ_READ: $display("%10t %s UMI_REQ_READ: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, dstaddr, srcaddr, data);
114+
UMI_REQ_WRITE: $display("%10t %s UMI_REQ_WRITE: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, dstaddr, srcaddr, data);
115+
UMI_REQ_POSTED: $display("%10t %s UMI_REQ_POSTED: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, dstaddr, srcaddr, data);
116+
UMI_RESP_READ: $display("%10t %s UMI_RESP_READ: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, dstaddr, srcaddr, data);
117+
UMI_RESP_WRITE: $display("%10t %s UMI_RESP_WRITE: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, dstaddr, srcaddr, data);
118+
UMI_REQ_ATOMIC: $display("%10t %s UMI_REQ_ATOMIC: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, dstaddr, srcaddr, data);
119+
UMI_REQ_RDMA: $display("%10t %s UMI_REQ_RDMA: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, dstaddr, srcaddr, data);
120+
UMI_REQ_USER0: $display("%10t %s UMI_REQ_USER0: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, dstaddr, srcaddr, data);
121+
UMI_REQ_ERROR: $display("%10t %s UMI_REQ_ERROR: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, dstaddr, srcaddr, data);
122+
UMI_REQ_LINK: $display("%10t %s UMI_REQ_LINK: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, dstaddr, srcaddr, data);
123+
default: $display("%10t %s UMI_OPCODE=0x%h: dst=0x%h src=0x%h data=0x%h (%m)", $realtime, name_padded, opcode, dstaddr, srcaddr, data);
124+
endcase
125+
end
126+
end
127+
end
128+
`endif
129+
130+
endmodule

0 commit comments

Comments
 (0)