diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..4c486d3 --- /dev/null +++ b/.flake8 @@ -0,0 +1,3 @@ +[flake8] +max-line-length = 120 +extend-ignore = diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..2385358 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,19 @@ +name: Lint UMI +on: + pull_request: + workflow_dispatch: + push: + branches: main + +jobs: + lint_python: + name: Lint Python Code + runs-on: ubuntu-latest + steps: + - name: Check out Git repository + uses: actions/checkout@v4 + - name: Lint with Flake8 + run: | + pip install --upgrade pip + pip install -r requirements.txt + flake8 --statistics . diff --git a/docs/umi_waveforms.py b/docs/umi_waveforms.py index 7a85455..a02c554 100644 --- a/docs/umi_waveforms.py +++ b/docs/umi_waveforms.py @@ -139,4 +139,3 @@ } """) svg.saveas("_images/example_rw_xaction.svg") - diff --git a/lumi/testbench/test_lumi.py b/lumi/testbench/test_lumi.py index 4379a26..9a9717a 100755 --- a/lumi/testbench/test_lumi.py +++ b/lumi/testbench/test_lumi.py @@ -4,6 +4,7 @@ # Copyright (C) 2023 Zero ASIC # This code is licensed under Apache License 2.0 (see LICENSE for details) +import time import random import numpy as np from pathlib import Path @@ -12,9 +13,6 @@ from lambdalib import lambdalib -THIS_DIR = Path(__file__).resolve().parent - - def build_testbench(topo="2d", trace=False): dut = SbDut('testbench', trace=True, trace_type='fst', default_main=True) @@ -22,9 +20,9 @@ def build_testbench(topo="2d", trace=False): # Set up inputs dut.input('testbench_lumi.sv') - if topo=='2d': + if topo == '2d': print("### Running 2D topology ###") - elif topo=='3d': + elif topo == '3d': print("### Running 3D topology ###") else: raise ValueError('Invalid topology') @@ -57,12 +55,13 @@ def build_testbench(topo="2d", trace=False): return dut -def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0.q", dut2host="dut2host_0.q", sb2dut="sb2dut_0.q", dut2sb="dut2sb_0.q"): +def main(topo="2d", vldmode="2", rdymode="2", trace=False, + host2dut="host2dut_0.q", dut2host="dut2host_0.q", sb2dut="sb2dut_0.q", dut2sb="dut2sb_0.q"): # clean up old queues if present for q in [host2dut, dut2host, sb2dut, dut2sb]: delete_queue(q) - dut = build_testbench(topo,trace) + dut = build_testbench(topo, trace) hostdly = random.randrange(500) devdly = random.randrange(500) @@ -96,9 +95,9 @@ def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0. print(f"Read: 0x{val32:08x}") assert val32 == 0x00000000 - if topo=='2d': + if topo == '2d': width = np.uint32(0x00000000) - if topo=='3d': + if topo == '3d': width = np.uint32(0x00030000) linkactive = 0 @@ -117,8 +116,7 @@ def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0. sb.write(0x60000010, np.uint32(0x0), posted=True) sb.write(0x70000010, np.uint32(0x0), posted=True) - import time - time.sleep (0.1) + time.sleep(0.1) print("### disable Rx ###") sb.write(0x70000014, np.uint32(0x0), posted=True) @@ -157,26 +155,22 @@ def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0. print("### Read loc Rx ctrl ###") val32 = sb.read(0x70000014, np.uint32) print(f"Read: 0x{val32:08x}") - #assert val32 == np.uint32(0x1) + width print("### Read loc Tx ctrl ###") val32 = sb.read(0x70000010, np.uint32) print(f"Read: 0x{val32:08x}") - #assert val32 == np.uint32(0x11) + width print("### Read rmt Rx ctrl ###") val32 = sb.read(0x60000014, np.uint32) print(f"Read: 0x{val32:08x}") - #assert val32 == np.uint32(0x1) + width print("### Read rmt Tx ctrl ###") val32 = sb.read(0x60000010, np.uint32) print(f"Read: 0x{val32:08x}") - #assert val32 == np.uint32(0x11) + width print("### UMI WRITES ###") -# host.write(0x70, np.arange(32, dtype=np.uint8), srcaddr=0x0000110000000000) + # host.write(0x70, np.arange(32, dtype=np.uint8), srcaddr=0x0000110000000000) host.write(0x70, np.uint64(0xBAADD70DCAFEFACE), srcaddr=0x0000110000000000) host.write(0x80, np.uint64(0xBAADD80DCAFEFACE), srcaddr=0x0000110000000000) host.write(0x90, np.uint64(0xBAADD90DCAFEFACE), srcaddr=0x0000110000000000) @@ -221,9 +215,6 @@ def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0. print(f"Read: 0x{val8:08x}") assert val8 == 0xBA -# import time -# time.sleep (5) - # 2 bytes rdbuf = host.read(0x40, 2, np.uint16, srcaddr=0x0000110000000000) val32 = rdbuf.view(np.uint32)[0] @@ -262,6 +253,7 @@ def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0. print("### TEST PASS ###") + if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('--trace', action='store_true', default=False, @@ -271,4 +263,7 @@ def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0. parser.add_argument('--rdymode', default='2') args = parser.parse_args() - main(topo=args.topo,vldmode=args.vldmode,rdymode=args.rdymode,trace=args.trace) + main(topo=args.topo, + vldmode=args.vldmode, + rdymode=args.rdymode, + trace=args.trace) diff --git a/lumi/testbench/test_lumi_rnd.py b/lumi/testbench/test_lumi_rnd.py index 94d90fc..f4291ff 100755 --- a/lumi/testbench/test_lumi_rnd.py +++ b/lumi/testbench/test_lumi_rnd.py @@ -4,6 +4,7 @@ # Copyright (C) 2023 Zero ASIC # This code is licensed under Apache License 2.0 (see LICENSE for details) +import time import random import numpy as np from pathlib import Path @@ -12,9 +13,6 @@ from lambdalib import lambdalib -THIS_DIR = Path(__file__).resolve().parent - - def build_testbench(topo="2d", trace=False): dut = SbDut('testbench', trace=True, trace_type='fst', default_main=True) @@ -22,9 +20,9 @@ def build_testbench(topo="2d", trace=False): # Set up inputs dut.input('testbench_lumi.sv') - if topo=='2d': + if topo == '2d': print("### Running 2D topology ###") - elif topo=='3d': + elif topo == '3d': print("### Running 3D topology ###") else: raise ValueError('Invalid topology') @@ -41,7 +39,6 @@ def build_testbench(topo="2d", trace=False): # Verilator configuration vlt_config = EX_DIR / 'testbench' / 'config.vlt' dut.set('tool', 'verilator', 'task', 'compile', 'file', 'config', vlt_config) -# dut.set('option', 'relax', True) dut.add('tool', 'verilator', 'task', 'compile', 'option', '--prof-cfuncs') dut.add('tool', 'verilator', 'task', 'compile', 'option', '-CFLAGS') dut.add('tool', 'verilator', 'task', 'compile', 'option', '-DVL_DEBUG') @@ -52,12 +49,14 @@ def build_testbench(topo="2d", trace=False): return dut -def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0.q", dut2host="dut2host_0.q", sb2dut="sb2dut_0.q", dut2sb="dut2sb_0.q"): + +def main(topo="2d", vldmode="2", rdymode="2", trace=False, + host2dut="host2dut_0.q", dut2host="dut2host_0.q", sb2dut="sb2dut_0.q", dut2sb="dut2sb_0.q"): # clean up old queues if present for q in [host2dut, dut2host, sb2dut, dut2sb]: delete_queue(q) - dut = build_testbench(topo,trace) + dut = build_testbench(topo, trace) hostdly = random.randrange(500) devdly = random.randrange(500) @@ -90,12 +89,12 @@ def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0. print(f"Read: 0x{val32:08x}") assert val32 == 0x00000000 - if topo=='2d': + if topo == '2d': width = np.uint32(0x00000000) - crdt = np.uint32(0x001A001A) - if topo=='3d': + crdt = np.uint32(0x001A001A) + if topo == '3d': width = np.uint32(0x00030000) - crdt = np.uint32(0x00070007) + crdt = np.uint32(0x00070007) linkactive = 0 while (linkactive == 0): @@ -113,8 +112,7 @@ def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0. sb.write(0x60000010, np.uint32(0x0), posted=True) sb.write(0x70000010, np.uint32(0x0), posted=True) - import time - time.sleep (0.1) + time.sleep(0.1) print("### disable Rx ###") sb.write(0x70000014, np.uint32(0x0), posted=True) @@ -159,45 +157,40 @@ def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0. print("### Read loc Rx ctrl ###") val32 = sb.read(0x70000014, np.uint32) print(f"Read: 0x{val32:08x}") - #assert val32 == np.uint32(0x1) + width print("### Read loc Tx ctrl ###") val32 = sb.read(0x70000010, np.uint32) print(f"Read: 0x{val32:08x}") - #assert val32 == np.uint32(0x11) + width print("### Read rmt Rx ctrl ###") val32 = sb.read(0x60000014, np.uint32) print(f"Read: 0x{val32:08x}") - #assert val32 == np.uint32(0x1) + width print("### Read rmt Tx ctrl ###") val32 = sb.read(0x60000010, np.uint32) print(f"Read: 0x{val32:08x}") - #assert val32 == np.uint32(0x11) + width print("### UMI WRITE/READ ###") - for count in range (100): + for count in range(100): # length should not cross the DW boundary - umi_mem_agent limitation - length = np.random.randint(0,511) - dst_addr = 32*random.randrange(2**(10-5)-1) # sb limitation - should align to bus width + length = np.random.randint(0, 511) + dst_addr = 32*random.randrange(2**(10-5)-1) # sb limitation - should align to bus width src_addr = 32*random.randrange(2**(10-5)-1) - data8 = np.random.randint(0,255,size=length,dtype=np.uint8) + data8 = np.random.randint(0, 255, size=length, dtype=np.uint8) print(f"umi writing {length+1} bytes to addr 0x{dst_addr:08x}") host.write(dst_addr, data8, srcaddr=src_addr) print(f"umi read from addr 0x{dst_addr:08x}") val8 = host.read(dst_addr, length, np.uint8, srcaddr=src_addr) if ~((val8 == data8).all()): print(f"ERROR umi read from addr 0x{dst_addr:08x}") - print(f"Expected:") - print(f"{data8}") - print(f"Actual:") - print(f"{val8}") + print(f"Expected: {data8}") + print(f"Actual: {val8}") assert (val8 == data8).all() print("### TEST PASS ###") + if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('--trace', action='store_true', default=False, @@ -207,4 +200,7 @@ def main(topo="2d", vldmode="2", rdymode="2", trace=False, host2dut="host2dut_0. parser.add_argument('--rdymode', default='2') args = parser.parse_args() - main(topo=args.topo,vldmode=args.vldmode,rdymode=args.rdymode,trace=args.trace) + main(topo=args.topo, + vldmode=args.vldmode, + rdymode=args.rdymode, + trace=args.trace) diff --git a/requirements.txt b/requirements.txt index 809ea3b..5f22179 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ lambdalib==0.1.5 switchboard-hw +flake8 == 6.0.0 \ No newline at end of file diff --git a/umi/testbench/test_crossbar.py b/umi/testbench/test_crossbar.py index be223ca..337dfa8 100755 --- a/umi/testbench/test_crossbar.py +++ b/umi/testbench/test_crossbar.py @@ -8,13 +8,12 @@ import numpy as np from pathlib import Path from argparse import ArgumentParser -from switchboard import (UmiTxRx, random_umi_packet, delete_queue, +from switchboard import ( + UmiTxRx, random_umi_packet, delete_queue, verilator_run, SbDut) from lambdalib import lambdalib -THIS_DIR = Path(__file__).resolve().parent - def build_testbench(): dut = SbDut('testbench', default_main=True) @@ -35,7 +34,6 @@ def build_testbench(): # Verilator configuration vlt_config = EX_DIR / 'testbench' / 'config.vlt' dut.set('tool', 'verilator', 'task', 'compile', 'file', 'config', vlt_config) -# dut.set('option', 'relax', True) dut.add('tool', 'verilator', 'task', 'compile', 'option', '--prof-cfuncs') dut.add('tool', 'verilator', 'task', 'compile', 'option', '-CFLAGS') dut.add('tool', 'verilator', 'task', 'compile', 'option', '-DVL_DEBUG') @@ -50,7 +48,8 @@ def build_testbench(): return dut.find_result('vexe', step='compile') -def umi_send(x,n,ports): + +def umi_send(x, n, ports): import os random.seed(os.getpid()) @@ -59,18 +58,20 @@ def umi_send(x,n,ports): umi = UmiTxRx(f'client2rtl_{x}.q', '') tee = UmiTxRx(f'tee_{x}.q', '') - for count in range (n): - dstport = random.randint(0,ports-1) - dstaddr = (2**8)*random.randint(0,(2**32)-1) + dstport*(2**40) - srcaddr = (2**8)*random.randint(0,(2**32)-1) + x*(2**40) - txp = random_umi_packet(dstaddr=dstaddr,srcaddr=srcaddr) - print(f"port {x} sending #{count} cmd: 0x{txp.cmd:08x} srcaddr: 0x{srcaddr:08x} dstaddr: 0x{dstaddr:08x} to port {dstport}") + for count in range(n): + dstport = random.randint(0, ports-1) + dstaddr = (2**8)*random.randint(0, (2**32)-1) + dstport*(2**40) + srcaddr = (2**8)*random.randint(0, (2**32)-1) + x*(2**40) + txp = random_umi_packet(dstaddr=dstaddr, srcaddr=srcaddr) + print(f"port {x} sending #{count} cmd: 0x{txp.cmd:08x} srcaddr: 0x{srcaddr:08x} " + f"dstaddr: 0x{dstaddr:08x} to port {dstport}") # send the packet to both simulation and local queues umi.send(txp) tee.send(txp) + def main(vldmode="2", rdymode="2", n=100, ports=4): - for x in range (ports): + for x in range(ports): delete_queue(f'rtl2client_{x}.q') delete_queue(f'client2rtl_{x}.q') delete_queue(f'tee_{x}.q') @@ -93,7 +94,7 @@ def main(vldmode="2", rdymode="2", n=100, ports=4): procs = [] for x in range(ports): - procs.append(multiprocessing.Process(target=umi_send, args=(x,n,ports,))) + procs.append(multiprocessing.Process(target=umi_send, args=(x, n, ports,))) for proc in procs: proc.start() @@ -109,7 +110,8 @@ def main(vldmode="2", rdymode="2", n=100, ports=4): raise Exception(f'Unexpected packet received {nrecv}') else: recv_src = (rxp.srcaddr >> 40) - print(f"port {i} receiving srcaddr: 0x{rxp.srcaddr:08x} dstaddr: 0x{rxp.dstaddr:08x} src: {recv_src} #{nrecv}") + print(f"port {i} receiving srcaddr: 0x{rxp.srcaddr:08x} " + f"dstaddr: 0x{rxp.dstaddr:08x} src: {recv_src} #{nrecv}") recv_queue[recv_src][i].append(rxp) nrecv += 1 @@ -120,12 +122,10 @@ def main(vldmode="2", rdymode="2", n=100, ports=4): raise Exception('Unexpected packet sent') else: send_dst = (txp.dstaddr >> 40) - #print(f"Tee port {i} dst: {send_dst} #{nsend}") send_queue[i][send_dst].append(txp) nsend += 1 # join running processes - for proc in procs: proc.join() @@ -134,19 +134,23 @@ def main(vldmode="2", rdymode="2", n=100, ports=4): if len(send_queue[i][j]) != len(recv_queue[i][j]): print(f"packets sent: {len(send_queue[i][j])} packets received: {len(recv_queue[i][j])}") assert len(send_queue[i][j]) == len(recv_queue[i][j]) - for txp, rxp in zip(send_queue[i][j],recv_queue[i][j]): - #print(f"{rxp} {txp}") + for txp, rxp in zip(send_queue[i][j], recv_queue[i][j]): assert txp == rxp print(f"compared {len(recv_queue[i][j])} packets from port {i} to port {j}") + print("TEST PASS") + if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('--vldmode', default='2') parser.add_argument('--rdymode', default='2') - parser.add_argument('-n', type=int, default=10, help='Number of' - ' transactions to send during the test.') + parser.add_argument('-n', type=int, default=10, + help='Number of transactions to send during the test.') parser.add_argument('-ports', type=int, default=4, help='Number of ports') args = parser.parse_args() - main(vldmode=args.vldmode,rdymode=args.rdymode, n=args.n, ports=args.ports) + main(vldmode=args.vldmode, + rdymode=args.rdymode, + n=args.n, + ports=args.ports) diff --git a/umi/testbench/test_fifo.py b/umi/testbench/test_fifo.py index b0f8a11..3d6a01e 100755 --- a/umi/testbench/test_fifo.py +++ b/umi/testbench/test_fifo.py @@ -49,7 +49,7 @@ def build_testbench(): return dut.find_result('vexe', step='compile') -def main(vldmode="2", rdymode="2", host2dut="host2dut_0.q", dut2host="dut2host_0.q",split="0"): +def main(vldmode="2", rdymode="2", host2dut="host2dut_0.q", dut2host="dut2host_0.q"): # clean up old queues if present for q in [host2dut, dut2host]: delete_queue(q) @@ -57,7 +57,6 @@ def main(vldmode="2", rdymode="2", host2dut="host2dut_0.q", dut2host="dut2host_0 verilator_bin = build_testbench() # launch the simulation - #verilator_run(verilator_bin, plusargs=['trace']) ret_val = verilator_run(verilator_bin, plusargs=['trace', ('valid_mode', vldmode), ('ready_mode', rdymode)]) # instantiate TX and RX queues. note that these can be instantiated without @@ -68,32 +67,31 @@ def main(vldmode="2", rdymode="2", host2dut="host2dut_0.q", dut2host="dut2host_0 print("### Statring test ###") - for count in range (100): + for _ in range(100): # length should not cross the DW boundary - umi_mem_agent limitation - length = np.random.randint(0,15) - dst_addr = 32*random.randrange(2**(10-5)-1) # sb limitation - should align to bus width + length = np.random.randint(0, 15) + dst_addr = 32*random.randrange(2**(10-5)-1) # sb limitation - should align to bus width src_addr = 32*random.randrange(2**(10-5)-1) - data8 = np.random.randint(0,255,size=length,dtype=np.uint8) + data8 = np.random.randint(0, 255, size=length, dtype=np.uint8) print(f"umi writing {length+1} bytes to addr 0x{dst_addr:08x}") host.write(dst_addr, data8, srcaddr=src_addr) print(f"umi read from addr 0x{dst_addr:08x}") val8 = host.read(dst_addr, length, np.uint8, srcaddr=src_addr) if ~((val8 == data8).all()): print(f"ERROR umi read from addr 0x{dst_addr:08x}") - print(f"Expected:") - print(f"{data8}") - print(f"Actual:") - print(f"{val8}") + print(f"Expected: {data8}") + print(f"Actual: {val8}") assert (val8 == data8).all() ret_val.wait() print("### TEST PASS ###") + if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('--vldmode', default='2') parser.add_argument('--rdymode', default='2') - parser.add_argument('--split', default='0') args = parser.parse_args() - main(vldmode=args.vldmode,rdymode=args.rdymode,split=args.split) + main(vldmode=args.vldmode, + rdymode=args.rdymode) diff --git a/umi/testbench/test_fifo_flex.py b/umi/testbench/test_fifo_flex.py index c059786..6b2d2b4 100755 --- a/umi/testbench/test_fifo_flex.py +++ b/umi/testbench/test_fifo_flex.py @@ -49,7 +49,7 @@ def build_testbench(): return dut.find_result('vexe', step='compile') -def main(vldmode="2", rdymode="2", host2dut="host2dut_0.q", dut2host="dut2host_0.q",split="0"): +def main(vldmode="2", rdymode="2", host2dut="host2dut_0.q", dut2host="dut2host_0.q"): # clean up old queues if present for q in [host2dut, dut2host]: delete_queue(q) @@ -57,7 +57,6 @@ def main(vldmode="2", rdymode="2", host2dut="host2dut_0.q", dut2host="dut2host_0 verilator_bin = build_testbench() # launch the simulation - #verilator_run(verilator_bin, plusargs=['trace']) ret_val = verilator_run(verilator_bin, plusargs=['trace', ('valid_mode', vldmode), ('ready_mode', rdymode)]) # instantiate TX and RX queues. note that these can be instantiated without @@ -68,32 +67,31 @@ def main(vldmode="2", rdymode="2", host2dut="host2dut_0.q", dut2host="dut2host_0 print("### Statring test ###") - for count in range (1000): + for count in range(1000): # length should not cross the DW boundary - umi_mem_agent limitation - length = np.random.randint(0,255) - dst_addr = 32*random.randrange(2**(10-5)-1) # sb limitation - should align to bus width + length = np.random.randint(0, 255) + dst_addr = 32*random.randrange(2**(10-5)-1) # sb limitation - should align to bus width src_addr = 32*random.randrange(2**(10-5)-1) - data8 = np.random.randint(0,255,size=length,dtype=np.uint8) + data8 = np.random.randint(0, 255, size=length, dtype=np.uint8) print(f"[{count}] umi writing {length} bytes to addr 0x{dst_addr:08x}") host.write(dst_addr, data8, srcaddr=src_addr, max_bytes=16) print(f"[{count}] umi read from addr 0x{dst_addr:08x}") val8 = host.read(dst_addr, length, np.uint8, srcaddr=src_addr, max_bytes=16) if ~((val8 == data8).all()): print(f"ERROR umi read from addr 0x{dst_addr:08x}") - print(f"Expected:") - print(f"{data8}") - print(f"Actual:") - print(f"{val8}") + print(f"Expected: {data8}") + print(f"Actual: {val8}") assert (val8 == data8).all() ret_val.wait() print("### TEST PASS ###") + if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('--vldmode', default='2') parser.add_argument('--rdymode', default='2') - parser.add_argument('--split', default='0') args = parser.parse_args() - main(vldmode=args.vldmode,rdymode=args.rdymode,split=args.split) + main(vldmode=args.vldmode, + rdymode=args.rdymode) diff --git a/umi/testbench/test_mem_agent.py b/umi/testbench/test_mem_agent.py index 93974a6..c82b02d 100755 --- a/umi/testbench/test_mem_agent.py +++ b/umi/testbench/test_mem_agent.py @@ -3,7 +3,6 @@ # Copyright (C) 2023 Zero ASIC # This code is licensed under Apache License 2.0 (see LICENSE for details) -import random import numpy as np from pathlib import Path from argparse import ArgumentParser @@ -62,21 +61,21 @@ def apply_atomic(origdata, atomicdata, operation, maxrange): elif (operation == 3): tempval = origdata ^ atomicdata elif (operation == 4): - if (origdata & (maxrange>>1)): + if (origdata & (maxrange >> 1)): origdata = int(origdata) - int(maxrange) else: origdata = int(origdata) - if (atomicdata & (maxrange>>1)): + if (atomicdata & (maxrange >> 1)): atomicdata = int(atomicdata) - int(maxrange) else: atomicdata = int(atomicdata) tempval = origdata if (origdata > atomicdata) else atomicdata elif (operation == 5): - if (origdata & (maxrange>>1)): + if (origdata & (maxrange >> 1)): origdata = int(origdata) - int(maxrange) else: origdata = int(origdata) - if (atomicdata & (maxrange>>1)): + if (atomicdata & (maxrange >> 1)): atomicdata = int(atomicdata) - int(maxrange) else: atomicdata = int(atomicdata) @@ -101,7 +100,6 @@ def main(vldmode="2", rdymode="2", n=100, host2dut="host2dut_0.q", dut2host="dut verilator_bin = build_testbench() # launch the simulation - #verilator_run(verilator_bin, plusargs=['trace']) verilator_run(verilator_bin, plusargs=['trace', ('valid_mode', vldmode), ('ready_mode', rdymode)]) # instantiate TX and RX queues. note that these can be instantiated without @@ -115,12 +113,11 @@ def main(vldmode="2", rdymode="2", n=100, host2dut="host2dut_0.q", dut2host="dut avail_datatype = [np.uint8, np.uint16, np.uint32] # un-aligned accesses - for count in range (n): + for _ in range(n): addr = np.random.randint(0, 512) - src_addr = random.randrange(2**64-1) # length should not cross the DW boundary - umi_mem_agent limitation length = np.random.randint(0, 256) - wordindexer = np.random.choice([0,1,2]) + wordindexer = np.random.choice([0, 1, 2]) maxrange = 2**(8*(2**wordindexer)) data = np.random.randint(0, maxrange, size=(length+1), dtype=avail_datatype[wordindexer]) addr = addr*(2**wordindexer) & 0x1FF @@ -128,7 +125,7 @@ def main(vldmode="2", rdymode="2", n=100, host2dut="host2dut_0.q", dut2host="dut print(f"umi writing {length+1} words of type {avail_datatype[wordindexer]} to addr 0x{addr:08x}") host.write(addr, data) atomicopcode = np.random.randint(0, 9) - atomicdata = np.random.randint(0,256,dtype=avail_datatype[wordindexer]) + atomicdata = np.random.randint(0, 256, dtype=avail_datatype[wordindexer]) print(f"umi atomic opcode: {atomicopcode} of type {avail_datatype[wordindexer]} to addr 0x{addr:08x}") atomicval = host.atomic(addr, atomicdata, atomicopcode) if not (atomicval == data[0]): @@ -144,12 +141,15 @@ def main(vldmode="2", rdymode="2", n=100, host2dut="host2dut_0.q", dut2host="dut print("### TEST PASS ###") + if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('--vldmode', default='2') parser.add_argument('--rdymode', default='2') - parser.add_argument('-n', type=int, default=10, help='Number of' - ' transactions to send during the test.') + parser.add_argument('-n', type=int, default=10, + help='Number of transactions to send during the test.') args = parser.parse_args() - main(vldmode=args.vldmode,rdymode=args.rdymode, n=args.n) + main(vldmode=args.vldmode, + rdymode=args.rdymode, + n=args.n) diff --git a/umi/testbench/test_regif.py b/umi/testbench/test_regif.py index dcf0dc3..21ef88c 100755 --- a/umi/testbench/test_regif.py +++ b/umi/testbench/test_regif.py @@ -62,21 +62,21 @@ def apply_atomic(origdata, atomicdata, operation, maxrange): elif (operation == 3): tempval = origdata ^ atomicdata elif (operation == 4): - if (origdata & (maxrange>>1)): + if (origdata & (maxrange >> 1)): origdata = int(origdata) - int(maxrange) else: origdata = int(origdata) - if (atomicdata & (maxrange>>1)): + if (atomicdata & (maxrange >> 1)): atomicdata = int(atomicdata) - int(maxrange) else: atomicdata = int(atomicdata) tempval = origdata if (origdata > atomicdata) else atomicdata elif (operation == 5): - if (origdata & (maxrange>>1)): + if (origdata & (maxrange >> 1)): origdata = int(origdata) - int(maxrange) else: origdata = int(origdata) - if (atomicdata & (maxrange>>1)): + if (atomicdata & (maxrange >> 1)): atomicdata = int(atomicdata) - int(maxrange) else: atomicdata = int(atomicdata) @@ -101,7 +101,6 @@ def main(vldmode="2", rdymode="2", n=100, host2dut="host2dut_0.q", dut2host="dut verilator_bin = build_testbench() # launch the simulation - #verilator_run(verilator_bin, plusargs=['trace']) verilator_run(verilator_bin, plusargs=['trace', ('valid_mode', vldmode), ('ready_mode', rdymode)]) # instantiate TX and RX queues. note that these can be instantiated without @@ -113,9 +112,8 @@ def main(vldmode="2", rdymode="2", n=100, host2dut="host2dut_0.q", dut2host="dut print("### Starting test ###") # regif accesses are all 32b wide and aligned - for count in range (n): + for _ in range(n): addr = np.random.randint(0, 512) * 4 - src_addr = random.randrange(2**64-1) # length should not cross the DW boundary - umi_mem_agent limitation data = np.uint32(random.randrange(2**32-1)) @@ -138,12 +136,15 @@ def main(vldmode="2", rdymode="2", n=100, host2dut="host2dut_0.q", dut2host="dut print("### TEST PASS ###") + if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('--vldmode', default='2') parser.add_argument('--rdymode', default='2') - parser.add_argument('-n', type=int, default=10, help='Number of' - ' transactions to send during the test.') + parser.add_argument('-n', type=int, default=10, + help='Number of transactions to send during the test.') args = parser.parse_args() - main(vldmode=args.vldmode,rdymode=args.rdymode, n=args.n) + main(vldmode=args.vldmode, + rdymode=args.rdymode, + n=args.n) diff --git a/umi/testbench/umi_testbench.py b/umi/testbench/umi_testbench.py index d9dc99b..bda9086 100644 --- a/umi/testbench/umi_testbench.py +++ b/umi/testbench/umi_testbench.py @@ -6,6 +6,7 @@ import pytest from siliconcompiler.core import SiliconCompilerError + def setup(chip): '''Adds sources/build configuration for the UMI testbench. @@ -30,7 +31,7 @@ def setup(chip): chip.add('option', 'define', 'TRACE') # Configure tools for verification flow - cflags =['-Wno-unknown-warning-option', f'-I{sbdir}/cpp'] + cflags = ['-Wno-unknown-warning-option', f'-I{sbdir}/cpp'] if trace: cflags += ['-DTRACE'] chip.set('tool', 'za_verilator', 'var', 'compile', '0', 'cflags', cflags) @@ -47,6 +48,7 @@ def setup(chip): # Make Verilator allow warnings - missing connections in current testbench chip.set('option', 'relax', True) + def compile_tb(chip, module): '''Sets up and compiles a testbench from a Chip object.''' setup(chip) @@ -65,6 +67,7 @@ def compile_tb(chip, module): return chip + def run_tb(chip, job): '''Runs the execute step of the verification flow. diff --git a/utils/testbench/test_umi2tl_np.py b/utils/testbench/test_umi2tl_np.py index bc7cb03..eae3866 100755 --- a/utils/testbench/test_umi2tl_np.py +++ b/utils/testbench/test_umi2tl_np.py @@ -17,7 +17,7 @@ def build_testbench(topo="2d"): EX_DIR = EX_DIR.resolve() # Set up inputs - if topo=='2d': + if topo == '2d': dut.input('testbench_umi2tl_np.v') print("### Running 2D topology ###") # elif topo=='3d': @@ -77,37 +77,25 @@ def main(topo="2d", vldmode="2", n=100, client2rtl="client2rtl_0.q", rtl2client= n_sent = 0 - # while (n_sent < n): - # txp = random_umi_packet(dstaddr=random.randint(0, 0x1FFFFFFF), size=0, len=0x7) - # if umi.send(txp, blocking=False): - # print('* TX *', n_sent) - # print(str(txp)) - # n_sent += 1 - while (n_sent < n): print(f"Transaction {n_sent}:") addr = random.randrange(511) length = random.choice([1, 2, 4, 8]) - addr = addr & (0xFFFFFFF8 | (8-length)) # FIXME: Align address. Limitation of umi2tl converter. Will be fixed in the next release + + # FIXME: Align address. Limitation of umi2tl converter. Will be fixed in the next release + addr = addr & (0xFFFFFFF8 | (8-length)) + data8 = np.random.randint(0, 255, size=length, dtype=np.uint8) print(f"umi writing {length} bytes:: data: {data8} to addr: 0x{addr:08x}") umi.write(addr, data8, srcaddr=0x0000110000000000) print(f"umi reading {length} bytes:: from addr 0x{addr:08x}") val8 = umi.read(addr, length, np.uint8, srcaddr=0x0000110000000000) print(f"umi Read: {val8}") - if ~((val8 == data8).all()) : + if not (val8 == data8).all(): print(f"ERROR core read from addr 0x{addr:08x} expected {data8} actual {val8}") assert (val8 == data8).all() n_sent = n_sent + 1 - # addr = random.randrange(511) - # data8 = np.uint8(random.randrange(2**32-1)) - # umi.write(addr, data8, srcaddr=0x0000110000000000) - # umi.write(addr, data8, srcaddr=0x0000110000000000) - # umi.write(addr, data8, srcaddr=0x0000110000000000) - # umi.write(addr, data8, srcaddr=0x0000110000000000) - # umi.write(addr, data8, srcaddr=0x0000110000000000) - ret_val.wait() @@ -115,8 +103,8 @@ def main(topo="2d", vldmode="2", n=100, client2rtl="client2rtl_0.q", rtl2client= parser = ArgumentParser() parser.add_argument('--topo', default='2d') parser.add_argument('--vldmode', default='2') - parser.add_argument('-n', type=int, default=10, help='Number of' - ' transactions to send during the test.') + parser.add_argument('-n', type=int, default=10, + help='Number of transactions to send during the test.') args = parser.parse_args() main(topo=args.topo, vldmode=args.vldmode, n=args.n) diff --git a/utils/testbench/test_umi_address_remap.py b/utils/testbench/test_umi_address_remap.py index b91275a..01d74c1 100755 --- a/utils/testbench/test_umi_address_remap.py +++ b/utils/testbench/test_umi_address_remap.py @@ -3,8 +3,6 @@ # Copyright (C) 2023 Zero ASIC import random -import time -import numpy as np from pathlib import Path from argparse import ArgumentParser from switchboard import SbDut, UmiTxRx, delete_queue, verilator_run, random_umi_packet @@ -17,7 +15,7 @@ def build_testbench(topo="2d"): EX_DIR = Path('../..') # Set up inputs - if topo=='2d': + if topo == '2d': dut.input('testbench_umi_address_remap.v') print("### Running 2D topology ###") # elif topo=='3d': @@ -76,9 +74,7 @@ def main(topo="2d", rdymode="2", vldmode="2", n=100, client2rtl="client2rtl_0.q" while (n_sent < n) or (n_recv < n): addr = random.randrange(0x0000_0000_0000_0000, 0x0000_07FF_FFFF_FFFF) - addr = addr & 0xFFFF_FF00_0000_FFF0 # Allow different devices but reduce address space per device - length = random.choice([1, 2, 4, 8]) - data8 = np.random.randint(0, 255, size=length, dtype=np.uint8) + addr = addr & 0xFFFF_FF00_0000_FFF0 # Allow different devices but reduce address space per device txp = random_umi_packet(dstaddr=addr, srcaddr=0x0000110000000000) if n_sent < n: @@ -87,8 +83,8 @@ def main(topo="2d", rdymode="2", vldmode="2", n=100, client2rtl="client2rtl_0.q" print(str(txp)) txq.append(txp) # Offset - if ((addr >= 0x0000_0600_0000_0080) & \ - (addr <= 0x0000_06FF_FFFF_FFFF)): + if ((addr >= 0x0000_0600_0000_0080) and + (addr <= 0x0000_06FF_FFFF_FFFF)): addr = addr - 0x0000_0000_0000_0080 txq[-1].dstaddr = addr # Remap @@ -116,8 +112,8 @@ def main(topo="2d", rdymode="2", vldmode="2", n=100, client2rtl="client2rtl_0.q" parser.add_argument('--topo', default='2d') parser.add_argument('--rdymode', default='2') parser.add_argument('--vldmode', default='2') - parser.add_argument('-n', type=int, default=10, help='Number of' - ' transactions to send during the test.') + parser.add_argument('-n', type=int, default=10, + help='Number of transactions to send during the test.') args = parser.parse_args() main(topo=args.topo, rdymode=args.rdymode, vldmode=args.vldmode, n=args.n) diff --git a/utils/testbench/test_umi_packet_merge_greedy.py b/utils/testbench/test_umi_packet_merge_greedy.py index 6cc7a51..d894d4e 100755 --- a/utils/testbench/test_umi_packet_merge_greedy.py +++ b/utils/testbench/test_umi_packet_merge_greedy.py @@ -14,7 +14,7 @@ def build_testbench(topo="2d"): EX_DIR = Path('../..') # Set up inputs - if topo=='2d': + if topo == '2d': dut.input('testbench_umi_packet_merge_greedy.v') print("### Running 2D topology ###") # elif topo=='3d': @@ -85,8 +85,8 @@ def main(topo="2d", vldmode="2", n=100, client2rtl="client2rtl_0.q", rtl2client= parser = ArgumentParser() parser.add_argument('--topo', default='2d') parser.add_argument('--vldmode', default='2') - parser.add_argument('-n', type=int, default=10, help='Number of' - ' transactions to send during the test.') + parser.add_argument('-n', type=int, default=10, + help='Number of transactions to send during the test.') args = parser.parse_args() main(topo=args.topo, vldmode=args.vldmode, n=args.n)