diff --git a/Bender.yml b/Bender.yml index 72e8658..63ceda0 100644 --- a/Bender.yml +++ b/Bender.yml @@ -54,6 +54,7 @@ sources: # Level 0 - rtl/item_memory/fixed_ca90_unit.sv - rtl/item_memory/cim_bit_flip.sv + - rtl/item_memory/rom_item_memory.sv # Level 1 - rtl/item_memory/ca90_hier_base.sv - rtl/item_memory/cim.sv diff --git a/rtl/hypercorex_top.sv b/rtl/hypercorex_top.sv index b3cf2fd..e4fa8ab 100644 --- a/rtl/hypercorex_top.sv +++ b/rtl/hypercorex_top.sv @@ -30,6 +30,7 @@ module hypercorex_top # ( parameter int unsigned ImAddrWidth = $clog2(NumTotIm), parameter int unsigned SeedWidth = CsrDataWidth, parameter int unsigned HoldFifoDepth = 2, + parameter bit EnableRomIM = 1'b0, //--------------------------- // Instruction Memory Parameters //--------------------------- @@ -418,7 +419,8 @@ module hypercorex_top # ( .NumTotIm ( NumTotIm ), .NumPerImBank ( NumPerImBank ), .SeedWidth ( SeedWidth ), - .HoldFifoDepth ( HoldFifoDepth ) + .HoldFifoDepth ( HoldFifoDepth ), + .EnableRomIM ( EnableRomIM ) ) i_item_memory_top ( //--------------------------- // Clock and resets diff --git a/rtl/item_memory/item_memory.sv b/rtl/item_memory/item_memory.sv index 88570b6..6918143 100644 --- a/rtl/item_memory/item_memory.sv +++ b/rtl/item_memory/item_memory.sv @@ -16,6 +16,7 @@ module item_memory #( parameter int unsigned NumTotIm = 1024, parameter int unsigned NumPerImBank= 128, parameter int unsigned SeedWidth = 32, + parameter bit EnableRomIM = 1'b0, // Don't touch! parameter int unsigned ImAddrWidth = $clog2(NumTotIm), parameter int unsigned NumImSets = NumTotIm/NumPerImBank @@ -96,7 +97,19 @@ module item_memory #( //--------------------------- // CA90 iM Module //--------------------------- - ca90_item_memory #( + if (EnableRomIM) begin: gen_use_rom_im + rom_item_memory #( + .HVDimension ( HVDimension ), + .NumTotIm ( NumTotIm ), + .SeedWidth ( SeedWidth ) + ) i_rom_item_memory ( + .im_sel_a_i ( mux_im_addr_out ), + .im_sel_b_i ( im_b_addr_i ), + .im_a_o ( im_a ), + .im_b_o ( im_b_o ) + ); + end else begin: gen_use_ca90_im + ca90_item_memory #( .HVDimension ( HVDimension ), .NumTotIm ( NumTotIm ), .NumPerImBank ( NumPerImBank ), @@ -108,6 +121,7 @@ module item_memory #( .im_a_o ( im_a ), .im_b_o ( im_b_o ) ); + end //--------------------------- // Output MUX diff --git a/rtl/item_memory/item_memory_top.sv b/rtl/item_memory/item_memory_top.sv index 7b0e0e5..934737d 100644 --- a/rtl/item_memory/item_memory_top.sv +++ b/rtl/item_memory/item_memory_top.sv @@ -15,6 +15,7 @@ module item_memory_top #( parameter int unsigned NumPerImBank = 128, parameter int unsigned SeedWidth = 32, parameter int unsigned HoldFifoDepth = 2, + parameter bit EnableRomIM = 1'b0, // Don't touch! parameter int unsigned ImAddrWidth = $clog2(NumTotIm), parameter int unsigned NumImSets = NumTotIm/NumPerImBank @@ -90,7 +91,8 @@ module item_memory_top #( .HVDimension ( HVDimension ), .NumTotIm ( NumTotIm ), .NumPerImBank ( NumPerImBank ), - .SeedWidth ( SeedWidth ) + .SeedWidth ( SeedWidth ), + .EnableRomIM ( EnableRomIM ) ) i_item_memory ( .port_a_cim_i ( port_a_cim_i[0] ), .cim_seed_hv_i ( cim_seed_hv_i ), diff --git a/tests/test_rom_item_memory.py b/tests/test_rom_item_memory.py new file mode 100644 index 0000000..40daa79 --- /dev/null +++ b/tests/test_rom_item_memory.py @@ -0,0 +1,104 @@ +""" + Copyright 2024 KU Leuven + Ryan Antonio + + Description: + This tests the ROM implemented iM + it was built from the CA90 but + the implementation is a decoder +""" + +import set_parameters +import cocotb +from cocotb.triggers import Timer +import pytest +import sys + +from util import get_root, setup_and_run, check_result_array, numbin2list + +# Add hdc utility functions +hdc_util_path = get_root() + "/hdc_exp/" +sys.path.append(hdc_util_path) + +# Grab the CA90 generation from the +# cellular automata experiment set +from cellular_automata import gen_ca90_im_set # noqa: E402 + +# Temporary parameters +HV_DIM = 512 +NUM_TOT_IM = 1024 +NUM_PER_IM_BANK = int(HV_DIM // 4) + + +@cocotb.test() +async def rom_item_memory_dut(dut): + cocotb.log.info(" ------------------------------------------ ") + cocotb.log.info(" Testing ROM Item Memory ") + cocotb.log.info(" ------------------------------------------ ") + + # Generate seed list and golden IM + seed_list, golden_im, conf_mat = gen_ca90_im_set( + seed_size=set_parameters.REG_FILE_WIDTH, + hv_dim=HV_DIM, + num_total_im=NUM_TOT_IM, + num_per_im_bank=NUM_PER_IM_BANK, + base_seeds=set_parameters.ORTHO_IM_SEEDS, + gen_seed=True, + ca90_mode=set_parameters.CA90_MODE, + ) + + # Propagate time for logic + await Timer(1, units="ps") + + # Load request, propagate, check result + for i in range(set_parameters.NUM_TOT_IM): + dut.im_sel_a_i.value = i + dut.im_sel_b_i.value = i + await Timer(1, units="ps") + + actual_val_a = dut.im_a_o.value.integer + actual_val_b = dut.im_b_o.value.integer + + # Convert actual values to binary list + actual_val_a = numbin2list(actual_val_a, HV_DIM) + actual_val_b = numbin2list(actual_val_b, HV_DIM) + + # Check arrays if they are equal + # Unfortunately, this is needed because there are + # bit-width limitations for integer conversions + check_result_array(actual_val_a, golden_im[i]) + check_result_array(actual_val_b, golden_im[i]) + + # This is for waveform checking later + for i in range(set_parameters.TEST_RUNS): + # Propagate time for logic + await Timer(1, units="ps") + + +# Actual test run +@pytest.mark.parametrize( + "parameters", + [ + { + "HVDimension": str(HV_DIM), + "NumTotIm": str(NUM_TOT_IM), + } + ], +) +def test_rom_item_memory(simulator, parameters, waves): + verilog_sources = [ + "/rtl/item_memory/rom_item_memory.sv", + ] + + toplevel = "rom_item_memory" + + module = "test_rom_item_memory" + + setup_and_run( + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + simulator=simulator, + parameters=parameters, + waves=waves, + )