From 18a18eeb794f841e478e7e580a38156deac60302 Mon Sep 17 00:00:00 2001 From: Steven Herbst Date: Tue, 7 May 2024 08:51:35 -0700 Subject: [PATCH] Small fixes (#213) Fix #129, #131, #150, #151 --- random/mkqueues.py | 54 +++++++++++++++++++++ switchboard/switchboard.py | 32 ++++++++++++ switchboard/umi.py | 22 +++++++-- switchboard/verilog/fpga/umi_fpga_queues.sv | 5 +- switchboard/verilog/sim/umi_to_queue_sim.sv | 4 +- 5 files changed, 109 insertions(+), 8 deletions(-) create mode 100755 random/mkqueues.py diff --git a/random/mkqueues.py b/random/mkqueues.py new file mode 100755 index 00000000..39459365 --- /dev/null +++ b/random/mkqueues.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2024 Zero ASIC Corporation +# This code is licensed under Apache License 2.0 (see LICENSE for details) + +# Small script that generates sample queues for inspection with a command-line tool + +import numpy as np +from switchboard import PySbTx, PySbPacket, UmiTxRx, random_umi_packet + + +def main(): + ####################################### + # generate native switchboard packets # + ####################################### + + print('*** Native packets ***') + print() + + tx = PySbTx('sb.q', fresh=True) + + txp = PySbPacket( + destination=2, + flags=1, + data=np.arange(32, dtype=np.uint8) + ) + + for k in range(3): + print(txp) + tx.send(txp) + + txp.data += 1 + txp.flags = 1 - txp.flags + txp.destination = (txp.destination * 10) + (k + 3) + + print() + + ######################## + # generate UMI packets # + ######################## + + print('*** UMI packets ***') + print() + + tx = UmiTxRx(tx_uri='umi.q', fresh=True) + + for k in range(3): + txp = random_umi_packet() + print(txp) + tx.send(txp) + + +if __name__ == '__main__': + main() diff --git a/switchboard/switchboard.py b/switchboard/switchboard.py index b36c5e93..f3e63e12 100644 --- a/switchboard/switchboard.py +++ b/switchboard/switchboard.py @@ -11,11 +11,43 @@ def path(): return Path(__file__).resolve().parent +def inspect(file, format): + import shutil + import tempfile + + with tempfile.NamedTemporaryFile() as temp: + shutil.copyfile(file, temp.name) + + if format == 'sb': + from switchboard import PySbRx + rx = PySbRx(temp.name, fresh=False) + elif format == 'umi': + from switchboard import UmiTxRx + rx = UmiTxRx(rx_uri=temp.name, fresh=False) + else: + raise ValueError(f'Format not supported: "{format}"') + + while True: + rxp = rx.recv(False) + + if rxp is not None: + print(rxp) + else: + break + + def main(): parser = ArgumentParser() parser.add_argument('--path', action='store_true') + parser.add_argument('-i', '--inspect', type=str, default=None, help='Print the contents' + ' of the given switchboard queue.') + parser.add_argument('-f', '--format', type=str, default='sb', choices=['sb', 'umi'], + help='Format assumed for the contents of the switchboard queue passed via the' + ' -i/--inspect argument.') args = parser.parse_args() if args.path: print(path()) + elif args.inspect is not None: + inspect(file=args.inspect, format=args.format) diff --git a/switchboard/umi.py b/switchboard/umi.py index 96adf58d..0d4acb5b 100644 --- a/switchboard/umi.py +++ b/switchboard/umi.py @@ -596,14 +596,30 @@ def addr_aligned(addr: Integral, align: Integral) -> bool: def random_int_value(name, value, min, max, align=None): # determine the length of the transaction - if value is None: - value = random.randint(min, max) + if isinstance(value, range) or (value is None): + if isinstance(value, range): + a = value.start + b = value.stop - 1 + else: + a = min + b = max + + value = random.randint(a, b) + if align is not None: value >>= align value <<= align - elif isinstance(value, Iterable): + elif isinstance(value, (list, tuple, np.ndarray)): value = random.choice(value) + if isinstance(value, (range, list, tuple)): + # if we happen to pick a range object from the list/tuple, then run this + # function on the range object. this allows users to specify a collection + # of values and ranges to efficiently represent a discontinuous space + # of options. it is also possible to have lists of lists of ranges, to + # adjust the probabilities of drawing from each range + return random_int_value(name=name, value=value, min=min, max=max, align=align) + # validate result check_int_in_range(name, value, min=min, max=max) diff --git a/switchboard/verilog/fpga/umi_fpga_queues.sv b/switchboard/verilog/fpga/umi_fpga_queues.sv index 8a950db8..b23b3f5b 100644 --- a/switchboard/verilog/fpga/umi_fpga_queues.sv +++ b/switchboard/verilog/fpga/umi_fpga_queues.sv @@ -106,11 +106,13 @@ module umi_fpga_queues #( wire [NUM_TX_QUEUES*SB_DW-1:0] sb_tx_data; wire [NUM_TX_QUEUES*32-1:0] sb_tx_dest; + wire [NUM_TX_QUEUES-1:0] sb_tx_last; for (i = 0; i < NUM_TX_QUEUES; i = i + 1) begin assign sb_tx_data[i*SB_DW+:SB_DW] = { tx_data[i*DW+:DW], tx_srcaddr[i*AW+:AW], tx_dstaddr[i*AW+:AW], tx_cmd[i*CW+:CW] }; assign sb_tx_dest[i*32+:32] = {16'h0000, tx_dstaddr[i*AW+55:i*AW+40]}; + assign sb_tx_last[i] = tx_cmd[(i*CW)+22]; end sb_fpga_queues #( @@ -131,8 +133,7 @@ module umi_fpga_queues #( .tx_data(sb_tx_data), .tx_dest(sb_tx_dest), - // TODO: support burst mode - .tx_last({NUM_TX_QUEUES{1'b1}}), + .tx_last(sb_tx_last), .tx_ready(tx_ready), .tx_valid(tx_valid), diff --git a/switchboard/verilog/sim/umi_to_queue_sim.sv b/switchboard/verilog/sim/umi_to_queue_sim.sv index ab873801..fc87dbff 100644 --- a/switchboard/verilog/sim/umi_to_queue_sim.sv +++ b/switchboard/verilog/sim/umi_to_queue_sim.sv @@ -19,8 +19,6 @@ module umi_to_queue_sim #( input valid ); - // TODO: support burst mode (through "last") - sb_to_queue_sim #( .READY_MODE_DEFAULT(READY_MODE_DEFAULT), .DW(DW+AW+AW+CW), @@ -29,7 +27,7 @@ module umi_to_queue_sim #( .clk(clk), .data({data, srcaddr, dstaddr, cmd}), .dest({16'h0000, dstaddr[55:40]}), - .last(1'b1), + .last(cmd[22]), .ready(ready), .valid(valid) );