Skip to content
Merged
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
12 changes: 9 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@
# simulation
######################

build/
gtkw_files/
*.q
*.out
*.vcd
*.fst
build/
gmon.out
coverage.dat
*.fsdb
*.dat
*.log
*.vcd
a.out
*.vvp
*.f
*.dump
*.tmp
*.vpi

######################
# Editor
Expand Down
1 change: 0 additions & 1 deletion tests/sumi/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ def __init__(
sumi.Isolate(),
sumi.Mux(),
sumi.Regif(),
sumi.Switch(),
sumi.RAM()
]

Expand Down
1 change: 1 addition & 0 deletions tests/sumi/test_switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from switchboard import UmiTxRx, delete_queue


@pytest.mark.skip(reason="Skipped until SB has been properly updated")
def test_switch(sumi_dut, umi_send, sb_umi_valid_mode, sb_umi_ready_mode):
n = 1000 # Number of transactions to be sent to each switch input port
in_ports = 4 # Number of input ports. Must match testbench
Expand Down
1 change: 1 addition & 0 deletions umi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from umi import adapters
from umi.common import Standard


try:
from umi._version import __version__
except ImportError:
Expand Down
5 changes: 3 additions & 2 deletions umi/sumi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
from .umi_isolate.umi_isolate import Isolate
from .umi_memagent.umi_memagent import MemAgent
from .umi_memif.umi_memif import Memif
from .umi_monitor.umi_monitor import Monitor
from .umi_mux.umi_mux import Mux
from .umi_mux2.umi_mux2 import Mux2
from .umi_pack.umi_pack import Pack
from .umi_pipeline.umi_pipeline import Pipeline
from .umi_ram.umi_ram import RAM
from .umi_regif.umi_regif import Regif
from .umi_stream.umi_stream import Stream
from .umi_switch.umi_switch import Switch
# from .umi_switch.umi_switch import Switch
from .umi_tester.umi_tester import Tester
from .umi_unpack.umi_unpack import Unpack
from .umi_demux.umi_demux import Demux
Expand All @@ -29,14 +30,14 @@
'Isolate',
'MemAgent',
'Memif',
'Monitor',
'Mux',
'Mux2',
'Pack',
'Pipeline',
'RAM',
'Regif',
'Stream',
'Switch',
'Tester',
'Unpack',
'Demux']
130 changes: 130 additions & 0 deletions umi/sumi/umi_monitor/rtl/umi_monitor.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*******************************************************************************
* Copyright 2026 Zero ASIC Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----
*
* Documentation:
*
* Passive UMI bus monitor. Taps a UMI bus without driving any signals.
*
* Synthesis: produces a 1-cycle 'beat' pulse on every valid+ready
* handshake. Can be used for transaction counters, performance
* monitors, or activity indicators.
*
* Simulation: on negedge clock, displays the full transaction
* (opcode name, addresses, data) whenever a handshake occurs.
* Acts as a built-in protocol analyzer for debug.
*
******************************************************************************/

module umi_monitor
#(parameter CW = 32,
parameter AW = 64,
parameter DW = 128,
parameter TIMEOUT = 100, // simulation only
parameter VERBOSE = 0, // set to 1 always enable tracing
parameter [12*8-1:0] NAME = "umi") // short label for display (12 chars)
(// UMI bus tap
input valid,
input ready,
input [CW-1:0] cmd,
input [AW-1:0] dstaddr,
input [AW-1:0] srcaddr,
input [DW-1:0] data,
// clk, reset only used for simulation display
input clk,
input nreset,
// beat output
output beat
);

//##########################################
// A transaction has happened
//##########################################

`include "umi_messages.vh"

assign beat = valid & ready;

//##########################################
// Simulation only monitoring
//##########################################

`ifdef SIMULATION

// compile time enable of verbose tracing
`ifdef VERBOSE
localparam VERBOSE_SWITCH = 1;
`else
localparam VERBOSE_SWITCH = 0;
`endif

// sane printing
initial $timeformat(-9, 2, "ns", 0);

// Pad NAME with leading spaces for aligned display
reg [12*8-1:0] name_padded;
integer ni;
initial begin
name_padded = " "; // 12 spaces
for (ni = 0; ni < 12; ni = ni + 1)
if (NAME[ni*8+:8] != 0)
name_padded[ni*8+:8] = NAME[ni*8+:8];
end

wire [4:0] opcode;

assign opcode = cmd[4:0];

// Stall timeout: valid high but ready low for TIMEOUT cycles
integer stall_count;
always @(posedge clk or negedge nreset)
if (!nreset)
stall_count <= 0;
else if (valid & ~ready)
stall_count <= stall_count + 1;
else
stall_count <= 0;

always @(posedge clk) begin
if (nreset & (stall_count == TIMEOUT)) begin
$display("%10t %s WARNING: UMI_TIMEOUT: valid=%b ready=%b dst=0x%h src=0x%h cmd=0x%h (%0d cycles) (%m)",
$realtime, name_padded, valid, ready, dstaddr, srcaddr, cmd, stall_count);
end
end

if (VERBOSE | VERBOSE_SWITCH) begin
// Transaction display on handshake
always @(negedge clk) begin
if (nreset & beat) begin
case (opcode)
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
endcase
end
end
end
`endif

endmodule
Loading