diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 24a7a7e..b6b188c 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -39,7 +39,6 @@ function(rvscc_add_test) ) set(TEST_TARGET_NAME test-${TEST_NAME}) add_executable(${TEST_TARGET_NAME} sim_main.cpp) - message(${TEST_TOP}) verilate(${TEST_TARGET_NAME} SOURCES ${TEST_SOURCES} PREFIX verilator_${TEST_TOP} diff --git a/rtl/data_memory.sv b/rtl/data_memory.sv index 65ad6e1..c30351f 100644 --- a/rtl/data_memory.sv +++ b/rtl/data_memory.sv @@ -4,19 +4,23 @@ module data_memory #( parameter int BLOCK_SIZE = 8, parameter int NUM_BLOCKS = 32 ) ( - data_memory_if.ram mem_if + data_memory_if.ram data_mem_if ); logic [NUM_BLOCKS-1:0][BLOCK_SIZE-1:0] mem; - assign mem_if.read_data = { - mem[mem_if.addr+'d3], mem[mem_if.addr+'d2], mem[mem_if.addr+'d1], mem[mem_if.addr+'d0] + assign data_mem_if.read_data = { + mem[data_mem_if.addr+'d3], + mem[data_mem_if.addr+'d2], + mem[data_mem_if.addr+'d1], + mem[data_mem_if.addr+'d0] }; - always_ff @(posedge mem_if.clk) begin - if (mem_if.rst) mem <= '{default: '0}; - else if (mem_if.write_enable) - {mem[mem_if.addr+'d3], - mem[mem_if.addr+'d2], - mem[mem_if.addr+'d1], - mem[mem_if.addr+'d0]} <= mem_if.write_data; + + always_ff @(posedge data_mem_if.clk) begin + if (data_mem_if.rst) mem <= '{default: '0}; + else if (data_mem_if.write_enable) + {mem[data_mem_if.addr+'d3], + mem[data_mem_if.addr+'d2], + mem[data_mem_if.addr+'d1], + mem[data_mem_if.addr+'d0]} <= data_mem_if.write_data; end endmodule diff --git a/rtl/instr_memory.sv b/rtl/instr_memory.sv index 35a8e5c..e51749b 100644 --- a/rtl/instr_memory.sv +++ b/rtl/instr_memory.sv @@ -1,18 +1,22 @@ import rv32i_defs::*; module instr_memory #( - parameter int N_INSTR = 32, - parameter string FILE_PATH = "" + parameter string FILE_PATH = "", + parameter int NUM_INSTR = 32 ) ( - input logic [$clog2(N_INSTR * 4)-1:0] addr, - output logic [InstructionSize-1:0] instr + instr_memory_if.mem instr_mem_if ); // Number of bits referenced with one address localparam int BlockSize = 8; - localparam int NumBlocks = N_INSTR * 4; + localparam int NumBlocks = NUM_INSTR * 4; logic [BlockSize-1:0] mem[NumBlocks]; - assign instr = {mem[addr+'d0], mem[addr+'d1], mem[addr+'d2], mem[addr+'d3]}; + assign instr_mem_if.instr = { + mem[instr_mem_if.addr+'d0], + mem[instr_mem_if.addr+'d1], + mem[instr_mem_if.addr+'d2], + mem[instr_mem_if.addr+'d3] + }; initial $readmemh(FILE_PATH, mem); endmodule diff --git a/rtl/instr_memory_if.sv b/rtl/instr_memory_if.sv new file mode 100644 index 0000000..0eedb7c --- /dev/null +++ b/rtl/instr_memory_if.sv @@ -0,0 +1,16 @@ +import rv32i_defs::*; + +interface instr_memory_if #( + parameter int NUM_INSTR = 32 +); + localparam int AddrSize = $clog2(NUM_INSTR) * 4; + logic [AddrSize-1:0] addr; + logic [InstructionSize-1:0] instr; + + modport mem(input addr, output instr); + modport datapath(input instr, output addr); + + function static void next_instr(); + addr = addr + 'd4; + endfunction +endinterface diff --git a/rtl/single_cycle_datapath.sv b/rtl/single_cycle_datapath.sv index 33268d2..18a53c3 100644 --- a/rtl/single_cycle_datapath.sv +++ b/rtl/single_cycle_datapath.sv @@ -1,11 +1,10 @@ -`timescale 1ns / 1ps - import rv32i_defs::*; module single_cycle_datapath ( input logic clk, input logic rst, - data_memory_if.datapath mem_if + instr_memory_if.datapath instr_mem_if, + data_memory_if.datapath data_mem_if ); logic [InstructionSize-1:0] pc, pc_next; logic [OperandSize-1:0] imm_ext; @@ -26,13 +25,7 @@ module single_cycle_datapath ( else pc <= pc_next; end - logic [InstructionSize-1:0] instr; - instr_memory #( - .N_INSTR(32) - ) instr_memory ( - .addr (7'(pc)), - .instr(instr) - ); + assign instr_mem_if.addr = instr_mem_if.AddrSize'(pc); logic reg_write; logic [OperandSize-1:0] read_data_1, read_data_2; @@ -40,9 +33,9 @@ module single_cycle_datapath ( register_file register_file ( .clk(clk), .rst(rst), - .addr_1(instr[19:15]), - .addr_2(instr[24:20]), - .addr_3(instr[11:7]), + .addr_1(instr_mem_if.instr[19:15]), + .addr_2(instr_mem_if.instr[24:20]), + .addr_3(instr_mem_if.instr[11:7]), .write_enable_3(reg_write), .write_data_3(result), .read_data_1(read_data_1), @@ -58,11 +51,11 @@ module single_cycle_datapath ( logic branch; logic branch_alu_neg; control_unit control_unit ( - .opcode(instr[6:0]), - .funct_3(instr[14:12]), - .funct_7(instr[31:25]), + .opcode(instr_mem_if.instr[6:0]), + .funct_3(instr_mem_if.instr[14:12]), + .funct_7(instr_mem_if.instr[31:25]), .result_src(result_src), - .mem_write(mem_if.write_enable), + .mem_write(data_mem_if.write_enable), .alu_ctrl(alu_ctrl), .alu_src(alu_src), .imm_src(imm_src), @@ -82,7 +75,7 @@ module single_cycle_datapath ( imm_extend imm_extend ( .imm_src(imm_src[1:0]), - .instr (instr[31:7]), + .instr (instr_mem_if.instr[31:7]), .imm_ext(imm_ext[31:0]) ); @@ -106,13 +99,13 @@ module single_cycle_datapath ( .status(alu_status) ); - assign mem_if.write_data = read_data_2; - assign mem_if.addr = alu_result; + assign data_mem_if.write_data = read_data_2; + assign data_mem_if.addr = alu_result; always_comb begin case (result_src) 'b00: result = alu_result; - 'b01: result = mem_if.read_data; + 'b01: result = data_mem_if.read_data; 'b10: result = pc + 'd4; 'b11: result = 'dx; default: result = 'dx; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8257935..1e240b3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -53,6 +53,7 @@ rvscc_add_test( NAME instruction_memory TOP test_instr_memory SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/rv32i_defs.sv + ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/instr_memory_if.sv ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/instr_memory.sv ${CMAKE_CURRENT_SOURCE_DIR}/test_instr_memory.sv ) @@ -64,6 +65,7 @@ rvscc_add_test( ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/single_cycle_datapath.sv ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/data_memory_if.sv ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/data_memory.sv + ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/instr_memory_if.sv ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/instr_memory.sv ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/jump_control.sv ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/control_unit.sv diff --git a/test/test_data_memory.sv b/test/test_data_memory.sv index 98de58d..c4026a1 100644 --- a/test/test_data_memory.sv +++ b/test/test_data_memory.sv @@ -23,7 +23,7 @@ module test_data_memory (); .BLOCK_SIZE(MemoryBlockSize), .NUM_BLOCKS(NumMemoryBlocks) ) dut ( - .mem_if(mem_if) + .data_mem_if(mem_if) ); always #1 clk = ~clk; diff --git a/test/test_instr_memory.sv b/test/test_instr_memory.sv index be9a523..cd46c71 100644 --- a/test/test_instr_memory.sv +++ b/test/test_instr_memory.sv @@ -11,12 +11,13 @@ module test_instr_memory (); logic [AddrSize-1:0] addr; logic [InstructionSize-1:0] instr; + instr_memory_if #(.NUM_INSTR(NumInstr)) dut_if; + instr_memory #( - .N_INSTR (NumInstr), - .FILE_PATH(Path) - ) instruction_memory ( - .addr (addr), - .instr(instr) + .FILE_PATH(Path), + .NUM_INSTR(NumInstr) + ) dut ( + .instr_mem_if(dut_if.mem) ); const @@ -46,23 +47,22 @@ module test_instr_memory (); }; initial begin - addr = 'd0; + dut_if.addr = 'd0; #1 - assert (!$isunknown(instr)) + assert (!$isunknown(dut_if.instr)) else $error("Instruction memory not loaded"); #1; foreach (assert_instr_mem[i]) begin - $display(i); - addr = AddrSize'(i * 4); #1 - assert (instr == assert_instr_mem[i]) + assert (dut_if.instr == assert_instr_mem[i]) else $error( "Instruction %h at address %h does not match the expected intruction %h", - instr, - addr, + dut_if.instr, + dut_if.addr, assert_instr_mem[i] ); + dut_if.next_instr(); end $finish; end diff --git a/test/test_single_cycle_core.sv b/test/test_single_cycle_core.sv index f3f9ebe..d321f23 100644 --- a/test/test_single_cycle_core.sv +++ b/test/test_single_cycle_core.sv @@ -4,18 +4,21 @@ module test_single_cycle_core (); logic clk, rst; always #1 clk = ~clk; - single_cycle_datapath dut ( - .clk(clk), - .rst(rst), - .mem_if(mem_if.datapath) - ); + instr_memory_if instr_mem_if; + instr_memory #(.FILE_PATH("../fw/test/test-core.mem")) instr_mem (instr_mem_if.mem); - data_memory_if mem_if ( + data_memory_if data_mem_if ( .clk(clk), .rst(rst) ); + data_memory data_mem (.data_mem_if(data_mem_if.ram)); - data_memory mem (.mem_if(mem_if.ram)); + single_cycle_datapath dut ( + .clk(clk), + .rst(rst), + .instr_mem_if(instr_mem_if.datapath), + .data_mem_if(data_mem_if.datapath) + ); initial begin $dumpfile("single_cycle.vcd");