diff --git a/interfaces/BBUS_IF.sv b/include/interfaces/BBUS_IF.sv similarity index 100% rename from interfaces/BBUS_IF.sv rename to include/interfaces/BBUS_IF.sv diff --git a/interfaces/DBG_IF.sv b/include/interfaces/DBG_IF.sv similarity index 100% rename from interfaces/DBG_IF.sv rename to include/interfaces/DBG_IF.sv diff --git a/interfaces/WISHBONE_IF.sv b/include/interfaces/WISHBONE_IF.sv similarity index 98% rename from interfaces/WISHBONE_IF.sv rename to include/interfaces/WISHBONE_IF.sv index 9f14cc3..c985e9f 100644 --- a/interfaces/WISHBONE_IF.sv +++ b/include/interfaces/WISHBONE_IF.sv @@ -1,12 +1,12 @@ /** * @file WISHBONE_IF.sv * @author Jacob Chisholm (https://Jchisholm204.github.io) - * @brief + * @brief * @version 0.1 * @date Created: 2025-05-31 * @modified Last Modified: 2025-05-31 * - * + * * All wishbone signals must be active high * Port sizes must be 8, 16, 32, or 64 bit * Default port size is 32 bit diff --git a/processor/types/debug_types.svh b/include/types/debug_types.svh similarity index 100% rename from processor/types/debug_types.svh rename to include/types/debug_types.svh diff --git a/processor/types/pipeline_types.svh b/include/types/pipeline_types.svh similarity index 100% rename from processor/types/pipeline_types.svh rename to include/types/pipeline_types.svh diff --git a/processor/types/reg_transport.svh b/include/types/reg_transport.svh similarity index 100% rename from processor/types/reg_transport.svh rename to include/types/reg_transport.svh diff --git a/processor/Processor.sv b/processor/Processor.sv index 425fc64..2d0a2ea 100644 --- a/processor/Processor.sv +++ b/processor/Processor.sv @@ -10,9 +10,9 @@ */ `timescale 1ns/100ps -`include "pipeline_types.svh" -`include "reg_transport.svh" -`include "rv32_isa.svh" +// `include "pipeline_types.svh" +// `include "reg_transport.svh" +// `include "rv32_isa.svh" import pipeline_types::*; import reg_transport::reg_transport_t; import rv32_isa::*; diff --git a/program/.gitignore b/processor/firmware/.gitignore similarity index 100% rename from program/.gitignore rename to processor/firmware/.gitignore diff --git a/program/CMakeLists.txt b/processor/firmware/CMakeLists.txt similarity index 100% rename from program/CMakeLists.txt rename to processor/firmware/CMakeLists.txt diff --git a/processor/asm/.gitignore b/processor/firmware/asm/.gitignore similarity index 100% rename from processor/asm/.gitignore rename to processor/firmware/asm/.gitignore diff --git a/processor/asm/Makefile b/processor/firmware/asm/Makefile similarity index 100% rename from processor/asm/Makefile rename to processor/firmware/asm/Makefile diff --git a/processor/asm/test.hex b/processor/firmware/asm/test.hex similarity index 100% rename from processor/asm/test.hex rename to processor/firmware/asm/test.hex diff --git a/processor/asm/test.s b/processor/firmware/asm/test.s similarity index 100% rename from processor/asm/test.s rename to processor/firmware/asm/test.s diff --git a/program/gcc-riscv-none.cmake b/processor/firmware/gcc-riscv-none.cmake similarity index 100% rename from program/gcc-riscv-none.cmake rename to processor/firmware/gcc-riscv-none.cmake diff --git a/program/pantheon.ld b/processor/firmware/pantheon.ld similarity index 100% rename from program/pantheon.ld rename to processor/firmware/pantheon.ld diff --git a/program/src/start.c b/processor/firmware/src/start.c similarity index 100% rename from program/src/start.c rename to processor/firmware/src/start.c diff --git a/program/start/STM32F446RETX_FLASH.ld b/processor/firmware/start/STM32F446RETX_FLASH.ld similarity index 100% rename from program/start/STM32F446RETX_FLASH.ld rename to processor/firmware/start/STM32F446RETX_FLASH.ld diff --git a/program/start/startup_stm32f446retx.s b/processor/firmware/start/startup_stm32f446retx.s similarity index 100% rename from program/start/startup_stm32f446retx.s rename to processor/firmware/start/startup_stm32f446retx.s diff --git a/processor/memory/RegisterFile.sv b/processor/memory/RegisterFile.sv index 68bde04..33f6139 100644 --- a/processor/memory/RegisterFile.sv +++ b/processor/memory/RegisterFile.sv @@ -25,9 +25,9 @@ module RegisterFile #( input logic [addr_width-1:0] iAddrRs1, input logic [addr_width-1:0] iAddrRs2, output logic [reg_width-1:0] oRs1, - output logic [reg_width-1:0] oRs2, + output logic [reg_width-1:0] oRs2 `ifndef RF_TOP - BBUS_IF.slave dbg_acc + ,BBUS_IF.slave dbg_acc `endif ); diff --git a/processor/sim/Makefile b/processor/sim/Makefile deleted file mode 100644 index d1296ce..0000000 --- a/processor/sim/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# Cocotb + Icarus Verilog -TOPLEVEL_LANG = verilog -# VERILOG_SOURCES = $(filter-out %cocotb_iverilog_dump.v, \ - $(shell find ../ -name '*.v' -o -name '*.sv')) -# TOPLEVEL = DIV32 -# MODULE = divisor # Name of the Python test without .py - -# WAVES=3 # This tells cocotb to dump VCD automatically -SIM=icarus -# -# IVERILOG_FLAGS += -D ICARUS_TRACE_ARRAYS - -# VERILOG_SOURCES ?= -# TOPLEVEL ?= -# MODULE ?= - -include $(shell cocotb-config --makefiles)/Makefile.sim - diff --git a/processor/sim/sources.py b/processor/sim/sources.py deleted file mode 100644 index 14eb3ce..0000000 --- a/processor/sim/sources.py +++ /dev/null @@ -1,52 +0,0 @@ - -ISA_SOURCES = [ - "rv32_isa.svh" -] - -TYPES_SOURCES = [ - "types/reg_transport.svh", - "types/pipeline_types.svh", - "types/debug_types.svh" -] - -ALU_SOURCES = [ - "ALU/CLA.sv", - "ALU/BitWise.sv", - "ALU/DIV32.sv", - "ALU/MUL32.sv", - "ALU/SHIFT.sv", - "ALU/ALU.sv" -] - -MEM_SOURCES = [ - "memory/DMEM.sv", - "memory/IMEM.sv", - "memory/RAMBlock.sv", - "memory/ROMBlock.sv", - "memory/Register.sv", - "memory/RegisterFile.sv" -] - -WISHBONE_SOURCES = [ - "../interfaces/WISHBONE_IF.sv" -] - -PIPE_SOURCES = [ - "datapipe/IF.sv", - "datapipe/ID.sv", - "datapipe/EX.sv", - "datapipe/ME.sv" -] - -CTRL_SOURCES = [ - "control/BranchOutcome.sv", - "control/HazardUnit.sv", - "control/PC.sv", - "control/decoder.sv", -] - -INTERFACE_SOURCES = [ - "../interfaces/WISHBONE_IF.sv", - "../interfaces/DBG_IF.sv", - "../interfaces/BBUS_IF.sv" -] diff --git a/processor/sim/test_mem_onchip.py b/processor/sim/test_mem_onchip.py deleted file mode 100644 index 6de5722..0000000 --- a/processor/sim/test_mem_onchip.py +++ /dev/null @@ -1,59 +0,0 @@ -import cocotb -import os -import random -from cocotb.triggers import Timer, FallingEdge, RisingEdge -from cocotb.clock import Clock -from cocotb.runner import get_runner -from pathlib import Path -import rv32_isa -from testbench import TB - - -async def onchipMem_setup(dut, iReadnWrite=None, iEn=1): - clock = Clock(dut.iClk, 10, units="ns") - cocotb.start_soon(clock.start()) - await RisingEdge(dut.iClk) - if iReadnWrite is not None: - dut.iReadnWrite.value = iReadnWrite - if iEn is not None: - dut.iEn.value = iEn - - -# @cocotb.test -# async def onchipMem_rw(dut): -# # Setup chip and attempt to write to an address -# await onchipMem_setup(dut, 0, 1) -# dut.iAddr.value = 1 -# randval = random.getrandbits(32) -# dut.iData.value = randval -# # Wait for the data to latch, Check it -# await RisingEdge(dut.iClk) -# read = dut.oData.value.integer -# assert read == randval, \ -# f'Failed RW test, {read} =/= {randval}' -# -# -# async def onchipMem_rwmulti(dut): -# # Setup chip and attempt to write to an address -# await onchipMem_setup(dut, 0, 1) -# for i in range(0, 4096): -# dut.iAddr.value = i -# random.seed(231485261*i) -# randval = random.getrandbits(32) -# dut.iData.value = randval -# # Wait for the data to latch, Check it -# await RisingEdge(dut.iClk) -# read = dut.oData.value.integer -# assert read == randval, \ -# f'Failed RW test, {read} =/= {randval}' - - -# def test_onchipMem_runner(): -# tb = TB("test_mem_onchip", "MEM") -# tb.add_source("rv32_isa.sv") -# tb.add_source("MEM.sv") -# tb.run_tests() -# -# -# if __name__ == "main": -# test_onchipMem_runner() diff --git a/pytest.ini b/pytest.ini index 0ee949b..92d8785 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,2 +1,3 @@ [pytest] python_files = test_*.py +pythonpath="sim" diff --git a/processor/sim/.gitignore b/sim/.gitignore similarity index 55% rename from processor/sim/.gitignore rename to sim/.gitignore index a591db8..a7b1f73 100644 --- a/processor/sim/.gitignore +++ b/sim/.gitignore @@ -1,3 +1,5 @@ results.xml/* sim_build/* __pycache__/* +.pytest_cache/* +*/__pycache__/* diff --git a/sim/__init__.py b/sim/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/processor/sim/SuperStruct.py b/sim/incl/SuperStruct.py similarity index 100% rename from processor/sim/SuperStruct.py rename to sim/incl/SuperStruct.py diff --git a/sim/incl/__init__.py b/sim/incl/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/processor/sim/debug_types.py b/sim/incl/debug_types.py similarity index 99% rename from processor/sim/debug_types.py rename to sim/incl/debug_types.py index 3840aaa..00d21dc 100644 --- a/processor/sim/debug_types.py +++ b/sim/incl/debug_types.py @@ -1,4 +1,4 @@ -from SuperStruct import SuperStruct +from incl.SuperStruct import SuperStruct from cocotb.handle import ModifiableObject diff --git a/processor/sim/pipeline_types.py b/sim/incl/pipeline_types.py similarity index 97% rename from processor/sim/pipeline_types.py rename to sim/incl/pipeline_types.py index 7bc794d..f68d765 100644 --- a/processor/sim/pipeline_types.py +++ b/sim/incl/pipeline_types.py @@ -1,6 +1,6 @@ -from SuperStruct import SuperStruct +from incl.SuperStruct import SuperStruct from cocotb.handle import ModifiableObject -from reg_transport_t import reg_transport_t +from incl.reg_transport_t import reg_transport_t class pipe_control_t(SuperStruct): diff --git a/processor/sim/reg_transport_t.py b/sim/incl/reg_transport_t.py similarity index 92% rename from processor/sim/reg_transport_t.py rename to sim/incl/reg_transport_t.py index 4f5a631..46f15ab 100644 --- a/processor/sim/reg_transport_t.py +++ b/sim/incl/reg_transport_t.py @@ -1,5 +1,5 @@ from cocotb.handle import ModifiableObject -from SuperStruct import SuperStruct +from incl.SuperStruct import SuperStruct class reg_transport_t(SuperStruct): diff --git a/sim/pyproject.toml b/sim/pyproject.toml new file mode 100644 index 0000000..0958717 --- /dev/null +++ b/sim/pyproject.toml @@ -0,0 +1,3 @@ +[tool.pytest.ini_options] +pythonpath = "." + diff --git a/processor/sim/rv32_isa.py b/sim/rv32_isa.py similarity index 100% rename from processor/sim/rv32_isa.py rename to sim/rv32_isa.py diff --git a/processor/sim/test_alu.py b/sim/test_alu.py similarity index 91% rename from processor/sim/test_alu.py rename to sim/test_alu.py index 0d5f628..0873196 100644 --- a/processor/sim/test_alu.py +++ b/sim/test_alu.py @@ -5,9 +5,9 @@ from cocotb.runner import get_runner from pathlib import Path import rv32_isa -import test_shift -import testbench -import sources +import test_alu_shift as test_shift +import util.testbench as testbench +from util.sources import Sources @cocotb.test() @@ -121,10 +121,14 @@ async def alu_rem_test(dut): def test_alu_runner(): tb = testbench.TB("test_alu", "ALU") - tb.add_sources(sources.ISA_SOURCES) - tb.add_sources(sources.ALU_SOURCES) + tb.add_sources(Sources.ISA()) + tb.add_sources(Sources.TYPES()) + tb.add_sources(Sources.INTERFACES()) + tb.add_sources(Sources.PROC()) + tb.add_sources(Sources.ALU()) + print(tb.sources) tb.run_tests() -if __name__ == "main": +if __name__ == "__main__": test_alu_runner() diff --git a/processor/sim/test_bitwise.py b/sim/test_alu_bitwise.py similarity index 78% rename from processor/sim/test_bitwise.py rename to sim/test_alu_bitwise.py index f6bde32..55d6035 100644 --- a/processor/sim/test_bitwise.py +++ b/sim/test_alu_bitwise.py @@ -4,13 +4,8 @@ from cocotb.triggers import Timer from cocotb.runner import get_runner from pathlib import Path - - -def to_signed32(n): - """Convert unsigned 32-bit int to signed 32-bit.""" - n = n & 0xFFFFFFFF - return n if n < 0x80000000 else n - 0x100000000 - +from util.representation import to_signed32 as to_signed32 +import util.testbench as testbench @cocotb.test() async def and_test_specific(dut): @@ -118,33 +113,8 @@ async def xor_test_random(dut): def test_bitwise_runner(): - sim = os.getenv("SIM", "icarus") - - proj_path = Path(__file__).resolve().parent.parent - - sources = [proj_path / "ALU/BitWise.sv"] - - if sim == "icarus": - build_args = ["-DICARUS_TRACE_ARRAYS", "-DICARUS_FST"] - else: - build_args = ["--trace", "-Wno-fatal"] - - runner = get_runner(sim) - runner.build( - verilog_sources=sources, - hdl_toplevel="BitWise", - clean=False, - waves=True, - # build_args=["-DICARUS_TRACE_ARRAYS", "-DICARUS_FST"], - build_args=build_args, - always=True, - ) - runner.test( - hdl_toplevel="BitWise", - test_module="test_bitwise", - plusargs=["-fst"], - waves=True - ) + tb = testbench.TB("test_alu_bitwise", "BitWise") + tb.add_source("processor/ALU/BitWise.sv") if __name__ == "__main__": diff --git a/processor/sim/test_cla.py b/sim/test_alu_cla.py similarity index 70% rename from processor/sim/test_cla.py rename to sim/test_alu_cla.py index 6a338bc..53e26f9 100644 --- a/processor/sim/test_cla.py +++ b/sim/test_alu_cla.py @@ -4,6 +4,7 @@ from cocotb.triggers import Timer from cocotb.runner import get_runner from pathlib import Path +import util.testbench as testbench @cocotb.test() @@ -50,33 +51,8 @@ async def cla_add_tests(dut): def test_cla_runner(): - sim = os.getenv("SIM", "icarus") - - proj_path = Path(__file__).resolve().parent.parent - - sources = [proj_path / "ALU/CLA.sv"] - - if sim == "icarus": - build_args = ["-DICARUS_TRACE_ARRAYS", "-DICARUS_FST"] - else: - build_args = ["--trace", "-Wno-fatal"] - - runner = get_runner(sim) - runner.build( - verilog_sources=sources, - hdl_toplevel="CLA", - clean=False, - waves=True, - # build_args=["-DICARUS_TRACE_ARRAYS", "-DICARUS_FST"], - build_args=build_args, - always=True, - ) - runner.test( - hdl_toplevel="CLA", - test_module="test_cla", - plusargs=["-fst"], - waves=True - ) + tb = testbench.TB("test_alu_cla", "CLA") + tb.add_source("processor/ALU/CLA.sv") if __name__ == "__main__": diff --git a/processor/sim/test_divisor.py b/sim/test_alu_divisor.py similarity index 84% rename from processor/sim/test_divisor.py rename to sim/test_alu_divisor.py index 461a33a..2c46b87 100644 --- a/processor/sim/test_divisor.py +++ b/sim/test_alu_divisor.py @@ -4,6 +4,7 @@ from cocotb.triggers import Timer from cocotb.runner import get_runner from pathlib import Path +import util.testbench as testbench @cocotb.test() @@ -94,32 +95,8 @@ async def div32_small(dut): def test_div32_runner(): - sim = os.getenv("SIM", "icarus") - - proj_path = Path(__file__).resolve().parent.parent - - sources = [proj_path / "ALU/DIV32.sv"] - - if sim == "icarus": - build_args = ["-DICARUS_TRACE_ARRAYS", "-DICARUS_FST"] - else: - build_args = ["--trace", "-Wno-fatal"] - - runner = get_runner(sim) - runner.build( - verilog_sources=sources, - hdl_toplevel="DIV32", - clean=False, - waves=True, - build_args=build_args, - always=True, - ) - runner.test( - hdl_toplevel="DIV32", - test_module="test_divisor", - plusargs=["-fst"], - waves=True - ) + tb = testbench.TB("test_alu_divisor", "DIV32") + tb.add_source("processor/ALU/DIV32.sv") if __name__ == "__main__": diff --git a/processor/sim/test_shift.py b/sim/test_alu_shift.py similarity index 95% rename from processor/sim/test_shift.py rename to sim/test_alu_shift.py index 1fa1848..8b4caff 100644 --- a/processor/sim/test_shift.py +++ b/sim/test_alu_shift.py @@ -1,7 +1,7 @@ import cocotb import random from cocotb.triggers import Timer -import testbench +import util.testbench as testbench def to_signed32(n): @@ -94,8 +94,8 @@ async def left_logic_test(dut): def test_shift_runner(): - tb = testbench.TB("test_shift", "SHIFT") - tb.add_source("ALU/SHIFT.sv") + tb = testbench.TB("test_alu_shift", "SHIFT") + tb.add_source("processor/ALU/SHIFT.sv") tb.run_tests() diff --git a/processor/sim/test_debugmodule.py b/sim/test_debugmodule.py similarity index 81% rename from processor/sim/test_debugmodule.py rename to sim/test_debugmodule.py index 0b5dd9c..6d8714c 100644 --- a/processor/sim/test_debugmodule.py +++ b/sim/test_debugmodule.py @@ -2,11 +2,11 @@ from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotb.clock import Clock from cocotb.handle import ModifiableObject -import testbench -from hex_creator import HexCreator +import util.testbench as testbench +from util.hex_creator import HexCreator from rv32_isa import * -from pipeline_types import if_id_t, id_ex_t, ex_mem_t, mem_wb_t -from sources import TYPES_SOURCES, ISA_SOURCES, INTERFACE_SOURCES, MEM_SOURCES +from incl.pipeline_types import if_id_t, id_ex_t, ex_mem_t, mem_wb_t +from util.sources import Sources class DebugModule(): @@ -57,12 +57,12 @@ async def dbg_mod_scratch(dut): def test_debugmodule_runner(): tb = testbench.TB("test_debugmodule", "DebugModuleTest") - tb.add_sources(ISA_SOURCES) - tb.add_sources(TYPES_SOURCES) - tb.add_sources(INTERFACE_SOURCES) - tb.add_sources(MEM_SOURCES) - tb.add_source("control/DebugModule.sv") - tb.add_source("sim/DebugModuleTest.sv") + tb.add_sources(Sources.ISA()) + tb.add_sources(Sources.TYPES()) + tb.add_sources(Sources.INTERFACES()) + tb.add_sources(Sources.MEM()) + tb.add_source("processor/control/DebugModule.sv") + tb.add_source("sim/wrappers/DebugModuleTest.sv") tb.run_tests() diff --git a/processor/sim/test_hazard_unit.py b/sim/test_hazard_unit.py similarity index 97% rename from processor/sim/test_hazard_unit.py rename to sim/test_hazard_unit.py index 1be4db3..37caf96 100644 --- a/processor/sim/test_hazard_unit.py +++ b/sim/test_hazard_unit.py @@ -2,11 +2,11 @@ from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotb.clock import Clock from cocotb.handle import ModifiableObject -import testbench -from hex_creator import HexCreator +import util.testbench as testbench +from util.hex_creator import HexCreator from rv32_isa import * -from pipeline_types import if_id_t, id_ex_t, ex_mem_t, mem_wb_t -from sources import TYPES_SOURCES, ISA_SOURCES +from incl.pipeline_types import if_id_t, id_ex_t, ex_mem_t, mem_wb_t +from util.sources import Sources class HazardUnit(): @@ -312,9 +312,9 @@ async def check_forward_me(dut): def test_hazard_unit_runner(): tb = testbench.TB("test_hazard_unit", "HazardUnit") - tb.add_sources(ISA_SOURCES) - tb.add_sources(TYPES_SOURCES) - tb.add_source("control/HazardUnit.sv") + tb.add_sources(Sources.ISA()) + tb.add_sources(Sources.TYPES()) + tb.add_source("processor/control/HazardUnit.sv") tb.run_tests() diff --git a/processor/sim/test_pc.py b/sim/test_if_pc.py similarity index 87% rename from processor/sim/test_pc.py rename to sim/test_if_pc.py index 1c7ad15..8f60965 100644 --- a/processor/sim/test_pc.py +++ b/sim/test_if_pc.py @@ -1,8 +1,9 @@ import cocotb from cocotb.triggers import RisingEdge, FallingEdge from cocotb.clock import Clock -import testbench -from sources import ISA_SOURCES +import sys +import util.testbench as testbench +from util.sources import Sources async def setup_pc(dut): @@ -64,11 +65,12 @@ async def pc_adder_out(dut): def test_pc_runner(): - tb = testbench.TB("test_pc", "PC") - tb.add_sources(ISA_SOURCES) - tb.add_source("control/PC.sv") - tb.add_source("ALU/CLA.sv") + tb = testbench.TB("test_if_pc", "PC") + tb.add_sources(Sources.ISA()) + tb.add_sources(Sources.ALU()) + tb.add_source("processor/control/PC.sv") tb.add_param("START_ADDR", 0) + print(tb.sources) tb.run_tests() diff --git a/processor/sim/test_ex.py b/sim/test_proc_ex.py similarity index 89% rename from processor/sim/test_ex.py rename to sim/test_proc_ex.py index 98d0840..22b9013 100644 --- a/processor/sim/test_ex.py +++ b/sim/test_proc_ex.py @@ -1,12 +1,12 @@ import cocotb from cocotb.triggers import RisingEdge, FallingEdge from cocotb.clock import Clock -import testbench -from pipeline_types import id_ex_t, ex_mem_t -from pipeline_types import pipe_control_t -from sample_mem import mem_sample_add, mem_sample_alu, mem_sample_mem +import util.testbench as testbench +from incl.pipeline_types import id_ex_t, ex_mem_t +from incl.pipeline_types import pipe_control_t +from util.sample_mem import mem_sample_add, mem_sample_alu, mem_sample_mem from rv32_isa import * -from sources import ISA_SOURCES, TYPES_SOURCES, ALU_SOURCES +from util.sources import Sources import random @@ -22,11 +22,11 @@ async def setup_ex(dut): def test_ex_runner(): - tb = testbench.TB("test_ex", "EX") - tb.add_sources(ISA_SOURCES) - tb.add_sources(TYPES_SOURCES) - tb.add_sources(ALU_SOURCES) - tb.add_source("datapipe/EX.sv") + tb = testbench.TB("test_proc_ex", "EX") + tb.add_sources(Sources.ISA()) + tb.add_sources(Sources.TYPES()) + tb.add_sources(Sources.ALU()) + tb.add_source("processor/datapipe/EX.sv") tb.run_tests() diff --git a/processor/sim/test_id.py b/sim/test_proc_id.py similarity index 94% rename from processor/sim/test_id.py rename to sim/test_proc_id.py index 8b7240b..b017ee6 100644 --- a/processor/sim/test_id.py +++ b/sim/test_proc_id.py @@ -1,11 +1,11 @@ import cocotb from cocotb.triggers import RisingEdge, FallingEdge from cocotb.clock import Clock -import testbench -from pipeline_types import if_id_t, id_ex_t -from sample_mem import mem_sample_add, mem_sample_alu, mem_sample_mem +import util.testbench as testbench +from incl.pipeline_types import if_id_t, id_ex_t +from util.sample_mem import mem_sample_add, mem_sample_alu, mem_sample_mem from rv32_isa import * -from sources import TYPES_SOURCES, CTRL_SOURCES, ISA_SOURCES +from util.sources import Sources async def setup_id(dut): clock = Clock(dut.iClk, 10, units='ns') @@ -19,11 +19,11 @@ async def setup_id(dut): def test_id_runner(): - tb = testbench.TB("test_id", "ID") - tb.add_sources(ISA_SOURCES) - tb.add_sources(TYPES_SOURCES) - tb.add_sources(CTRL_SOURCES) - tb.add_source("datapipe/ID.sv") + tb = testbench.TB("test_proc_id", "ID") + tb.add_sources(Sources.ISA()) + tb.add_sources(Sources.TYPES()) + tb.add_sources(Sources.CTRL()) + tb.add_source("processor/datapipe/ID.sv") tb.run_tests() diff --git a/processor/sim/test_if.py b/sim/test_proc_if.py similarity index 71% rename from processor/sim/test_if.py rename to sim/test_proc_if.py index 07b2a2a..93e41dc 100644 --- a/processor/sim/test_if.py +++ b/sim/test_proc_if.py @@ -1,11 +1,11 @@ import cocotb from cocotb.triggers import RisingEdge, FallingEdge from cocotb.clock import Clock -import testbench -from hex_creator import HexCreator +import util.testbench as testbench +from util.hex_creator import HexCreator from rv32_isa import * -from pipeline_types import if_id_t -from sources import INTERFACE_SOURCES, ISA_SOURCES, TYPES_SOURCES +from incl.pipeline_types import if_id_t +from util.sources import Sources def setup_mem(fname="testROM.hex"): @@ -32,16 +32,15 @@ async def setup_if(dut): def test_if_runner(): fname = "testROM.hex" setup_mem(fname).export() - tb = testbench.TB("test_if", "IF") + tb = testbench.TB("test_proc_if", "IF") tb.add_define("ROMFile", f'"../{fname}"') - tb.add_sources(ISA_SOURCES) - tb.add_sources(TYPES_SOURCES) - tb.add_source("control/PC.sv") - tb.add_source("ALU/CLA.sv") - tb.add_sources(INTERFACE_SOURCES) - tb.add_source("memory/ROMBlock.sv") - tb.add_source("memory/IMEM.sv") - tb.add_source("datapipe/IF.sv") + tb.add_sources(Sources.ISA()) + tb.add_sources(Sources.TYPES()) + tb.add_source("processor/control/PC.sv") + tb.add_source("processor/ALU/CLA.sv") + tb.add_sources(Sources.INTERFACES()) + tb.add_sources(Sources.MEM()) + tb.add_source("processor/datapipe/IF.sv") tb.run_tests() diff --git a/processor/sim/test_me.py b/sim/test_proc_me.py similarity index 91% rename from processor/sim/test_me.py rename to sim/test_proc_me.py index 958839c..6573874 100644 --- a/processor/sim/test_me.py +++ b/sim/test_proc_me.py @@ -1,14 +1,13 @@ import cocotb from cocotb.triggers import RisingEdge, FallingEdge from cocotb.clock import Clock -import testbench -from pipeline_types import ex_mem_t, mem_wb_t -from pipeline_types import pipe_control_t -from sample_mem import mem_sample_add, mem_sample_alu, mem_sample_mem +import util.testbench as testbench +from incl.pipeline_types import ex_mem_t, mem_wb_t +from incl.pipeline_types import pipe_control_t +from util.sample_mem import mem_sample_add, mem_sample_alu, mem_sample_mem from rv32_isa import * -from sources import ISA_SOURCES, TYPES_SOURCES, WISHBONE_SOURCES, MEM_SOURCES -import random -from test_bitwise import to_signed32 +from util.sources import Sources +from util.representation import to_signed32 N_TEST = 10 @@ -24,12 +23,12 @@ async def setup_me(dut): def test_me_runner(): - tb = testbench.TB("test_me", "ME") - tb.add_sources(ISA_SOURCES) - tb.add_sources(TYPES_SOURCES) - tb.add_sources(WISHBONE_SOURCES) - tb.add_sources(MEM_SOURCES) - tb.add_source("datapipe/ME.sv") + tb = testbench.TB("test_proc_me", "ME") + tb.add_sources(Sources.ISA()) + tb.add_sources(Sources.TYPES()) + tb.add_sources(Sources.WISHBONE()) + tb.add_sources(Sources.MEM()) + tb.add_source("processor/datapipe/ME.sv") tb.run_tests() diff --git a/processor/sim/test_processor.py b/sim/test_processor.py similarity index 88% rename from processor/sim/test_processor.py rename to sim/test_processor.py index 93346ce..20a3cfe 100644 --- a/processor/sim/test_processor.py +++ b/sim/test_processor.py @@ -1,15 +1,13 @@ import cocotb +import util.testbench as testbench +from util.sources import Sources from cocotb.handle import ModifiableObject, NonHierarchyIndexableObject from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotb.clock import Clock -from reg_transport_t import reg_transport_t -import testbench -from sources import ISA_SOURCES, TYPES_SOURCES, ALU_SOURCES -from sources import MEM_SOURCES, WISHBONE_SOURCES, PIPE_SOURCES -from sources import CTRL_SOURCES -from test_if import setup_mem -from hex_creator import HexCreator -from test_bitwise import to_signed32 +from incl.reg_transport_t import reg_transport_t +from util.hex_creator import HexCreator +from util.representation import to_signed32 +from test_proc_if import setup_mem from rv32_isa import * @@ -67,7 +65,6 @@ async def run_test(self, rom: HexCreator): for _ in range(0, 4): await RisingEdge(self.iClk) - # For debugging purposes only.. not actual testing @cocotb.test async def proc_dbg(dut): @@ -146,15 +143,14 @@ def test_processor_runner(): setup_mem(fname).export() tb.add_define("ROMFile", f'"../{fname}"') tb.add_define("RF_TOP", 1) - tb.add_sources(ISA_SOURCES) - tb.add_sources(TYPES_SOURCES) - tb.add_sources(ALU_SOURCES) - tb.add_sources(MEM_SOURCES) - tb.add_sources(WISHBONE_SOURCES) - tb.add_sources(CTRL_SOURCES) - tb.add_sources(PIPE_SOURCES) - tb.add_source("control/HazardUnit.sv") - tb.add_source("Processor.sv") + # for x in Sources.CTRL: + # print(x) + tb.add_sources(Sources.ISA()) + tb.add_sources(Sources.INTERFACES()) + tb.add_sources(Sources.TYPES()) + tb.add_sources(Sources.PROC()) + for s in tb.sources: + print(s) tb.run_tests() diff --git a/processor/sim/test_register_file.py b/sim/test_register_file.py similarity index 78% rename from processor/sim/test_register_file.py rename to sim/test_register_file.py index 5545b6d..a3f908b 100644 --- a/processor/sim/test_register_file.py +++ b/sim/test_register_file.py @@ -4,9 +4,9 @@ from cocotb.triggers import RisingEdge, FallingEdge from cocotb.runner import get_runner from pathlib import Path -from testbench import TB -from reg_transport_t import reg_transport_t -from sources import TYPES_SOURCES, ISA_SOURCES +from util.testbench import TB +from incl.reg_transport_t import reg_transport_t +from util.sources import Sources async def setup_test(dut): @@ -143,47 +143,15 @@ async def regfile_test_forwarding(dut): # assert dut.oRs3.value == i*22, "DBG Fail" -def old_register_file_runner(): - sim = os.getenv("SIM", "icarus") - - proj_path = Path(__file__).resolve().parent.parent - - sources = [ - proj_path / "rv32_isa.sv", - proj_path / "register_file.sv", - ] - # sources = list((proj_path).glob("*.sv")) - - if sim == "icarus": - build_args = ["-DICARUS_TRACE_ARRAYS", "-DICARUS_FST"] - else: - build_args = ["-Wno-fatal"] - - runner = get_runner(sim) - runner.build( - verilog_sources=sources, - hdl_toplevel="register_file", - clean=False, - waves=False, - always=True, - # build_args=["-DICARUS_TRACE_ARRAYS", "-DICARUS_FST"], - build_args=build_args - ) - runner.test( - hdl_toplevel="register_file", - test_module="test_register_file", - plusargs=["-fst"], - waves=True - ) - - def test_RF_runner(): tb = TB("test_register_file", "RegisterFile") tb.add_define("RF_TOP", 1) - tb.add_sources(ISA_SOURCES) - tb.add_sources(TYPES_SOURCES) - tb.add_source("memory/Register.sv") - tb.add_source("memory/RegisterFile.sv") + tb.add_sources(Sources.ISA()) + tb.add_sources(Sources.TYPES()) + tb.add_source("processor/memory/Register.sv") + tb.add_source("processor/memory/RegisterFile.sv") + for s in tb.sources: + print(s) tb.run_tests() diff --git a/sim/test_sources.py b/sim/test_sources.py new file mode 100644 index 0000000..1cb7b0a --- /dev/null +++ b/sim/test_sources.py @@ -0,0 +1,100 @@ +from util.sources import Sources, SourceFiles +import string + + +def test_sources(): + all_included = SourceFiles() + # Verify Types + ts = Sources.TYPES() + all_included += ts + try: + assert isinstance(ts, SourceFiles), \ + "Sources did not return SourceFiles instance" + except AssertionError: + assert isinstance(ts, list), \ + "Sources did not return SourceFiles or List instance" + # Verify ISA + ts = Sources.ISA() + all_included += ts + try: + assert isinstance(ts, SourceFiles), \ + "Sources did not return SourceFiles instance" + except AssertionError: + assert isinstance(ts, list), \ + "Sources did not return SourceFiles or List instance" + # Verify ALU + ts = Sources.ALU() + all_included += ts + try: + assert isinstance(ts, SourceFiles), \ + "Sources did not return SourceFiles instance" + except AssertionError: + assert isinstance(ts, list), \ + "Sources did not return SourceFiles or List instance" + # Verify MEM + ts = Sources.MEM() + all_included += ts + try: + assert isinstance(ts, SourceFiles), \ + "Sources did not return SourceFiles instance" + except AssertionError: + assert isinstance(ts, list), \ + "Sources did not return SourceFiles or List instance" + # Verify Interfaces + ts = Sources.INTERFACES() + all_included += ts + try: + assert isinstance(ts, SourceFiles), \ + "Sources did not return SourceFiles instance" + except AssertionError: + assert isinstance(ts, list), \ + "Sources did not return SourceFiles or List instance" + # Verify Wishbone + ts = Sources.WISHBONE() + all_included += ts + try: + assert isinstance(ts, SourceFiles), \ + "Sources did not return SourceFiles instance" + except AssertionError: + assert isinstance(ts, list), \ + "Sources did not return SourceFiles or List instance" + # Verify Pipe + ts = Sources.PIPE() + all_included += ts + try: + assert isinstance(ts, SourceFiles), \ + "Sources did not return SourceFiles instance" + except AssertionError: + assert isinstance(ts, list), \ + "Sources did not return SourceFiles or List instance" + # Verify Control + ts = Sources.CTRL() + all_included += ts + try: + assert isinstance(ts, SourceFiles), \ + "Sources did not return SourceFiles instance" + except AssertionError: + assert isinstance(ts, list), \ + "Sources did not return SourceFiles or List instance" + # Verify Processor + proc_sources = Sources.PROC() + try: + assert isinstance(proc_sources, SourceFiles), \ + "Sources did not return SourceFiles instance" + except AssertionError: + assert isinstance(proc_sources, list), \ + "Sources did not return SourceFiles or List instance" + # for psource in proc_sources: + # found = False + # duplicate = False + # for asource in all_included: + # if found is False and psource == asource: + # found = True + # elif found is True and psource == asource: + # duplicate = True + # assert found is True, f"{asource} not found" + # assert duplicate is False, f"{asource} has a duplicate" + + +if __name__ == "__main__": + test_sources() diff --git a/sim/util/__init__.py b/sim/util/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/processor/sim/hex_creator.py b/sim/util/hex_creator.py similarity index 100% rename from processor/sim/hex_creator.py rename to sim/util/hex_creator.py diff --git a/sim/util/representation.py b/sim/util/representation.py new file mode 100644 index 0000000..3e4c942 --- /dev/null +++ b/sim/util/representation.py @@ -0,0 +1,4 @@ +def to_signed32(n): + """Convert unsigned 32-bit int to signed 32-bit.""" + n = n & 0xFFFFFFFF + return n if n < 0x80000000 else n - 0x100000000 diff --git a/processor/sim/sample_mem.py b/sim/util/sample_mem.py similarity index 95% rename from processor/sim/sample_mem.py rename to sim/util/sample_mem.py index 70b2264..e389c8c 100644 --- a/processor/sim/sample_mem.py +++ b/sim/util/sample_mem.py @@ -1,4 +1,4 @@ -from hex_creator import HexCreator +from util.hex_creator import HexCreator from rv32_isa import * diff --git a/sim/util/sources.py b/sim/util/sources.py new file mode 100644 index 0000000..8249d8e --- /dev/null +++ b/sim/util/sources.py @@ -0,0 +1,74 @@ +import os +from pathlib import Path + + +class SourceFiles(list): + pass + + +class Sources: + def get_basepath(): + basepath = Path(__file__).resolve() + # Remove the file name + basepath = basepath.parent + basestring = str(basepath) + while not basestring.endswith("sim") and basestring != "/home": + basepath = basepath.parent + basestring = str(basepath) + if basestring == "/home": + assert "Path Resolution Failure" + return basepath.parent + + def get_path(folder_name: str) -> Path: + base = str(Sources.get_basepath()) + base += f"/{folder_name}" + return Path(base) + + def get_sourceFiles(path: [Path, str], pattern="*") -> SourceFiles: + if isinstance(path, str): + path = Path(path) + path = path.rglob(pattern) + ls = SourceFiles() + for x in path: + ls.append(str(x)) + return ls + + def TYPES() -> SourceFiles: + basepath = Sources.get_path("include/types") + sources = SourceFiles() + sources += [basepath / "reg_transport.svh"] + sources += [basepath / "pipeline_types.svh"] + sources += [basepath / "debug_types.svh"] + return sources + + def ISA() -> list: + return ["processor/rv32_isa.svh"] + + def ALU() -> SourceFiles: + basepath = Sources.get_path("processor/ALU") + return Sources.get_sourceFiles(basepath) + + def MEM() -> SourceFiles: + basepath = Sources.get_path("processor/memory") + return Sources.get_sourceFiles(basepath) + + def INTERFACES() -> SourceFiles: + basepath = Sources.get_path("include/interfaces") + return Sources.get_sourceFiles(basepath) + + def WISHBONE() -> SourceFiles: + return ["include/interfaces/WISHBONE_IF.sv"] + + def PIPE() -> SourceFiles: + basepath = Sources.get_path("processor/datapipe") + return Sources.get_sourceFiles(basepath) + + def CTRL() -> SourceFiles: + basepath = Sources.get_path("processor/control") + return Sources.get_sourceFiles(basepath) + + def PROC() -> SourceFiles: + basepath = Sources.get_path("processor") + sl = Sources.get_sourceFiles(basepath, "*.sv") + sl += Sources.get_sourceFiles(basepath, "*.svh") + return sl diff --git a/processor/sim/testROM.hex b/sim/util/testROM.hex similarity index 100% rename from processor/sim/testROM.hex rename to sim/util/testROM.hex diff --git a/processor/sim/testbench.py b/sim/util/testbench.py similarity index 82% rename from processor/sim/testbench.py rename to sim/util/testbench.py index ff4d2cc..6e4a885 100644 --- a/processor/sim/testbench.py +++ b/sim/util/testbench.py @@ -4,6 +4,7 @@ from pathlib import Path import shutil import inspect +from util.sources import Sources, SourceFiles class TB: @@ -11,7 +12,7 @@ def __init__(self, test_module: str, hdl_toplevel: str, sim="verilator"): self.test_module = test_module self.hdl_toplevel = hdl_toplevel self.sim = os.getenv("SIM", sim) - self.basepath = Path(__file__).resolve().parent.parent + self.basepath = Sources.get_basepath() self.sources = [] self.parameters = {} self.defines = {} @@ -19,7 +20,11 @@ def __init__(self, test_module: str, hdl_toplevel: str, sim="verilator"): def add_source(self, source: str): self.sources += [self.basepath / source] - def add_sources(self, sources): + def add_sources(self, sources: [list, SourceFiles]): + # if isinstance(sources, SourceFiles): + # for source in sources: + # self.sources += [source] + # else: for source in sources: self.add_source(source) @@ -40,9 +45,9 @@ def run_tests(self): "--vpi", # "--output-split", "8", # "--threads", "1" - "-I../processor", - "-I../processor/types", - "-I../interfaces" + "-I../include", + "-I../include/types", + "-I../include/interfaces" ] runner = get_runner(self.sim) print(runner.build( diff --git a/processor/sim/DebugModuleTest.sv b/sim/wrappers/DebugModuleTest.sv similarity index 100% rename from processor/sim/DebugModuleTest.sv rename to sim/wrappers/DebugModuleTest.sv