From 24a5622103308cbbb9466ac91c3db5095f630749 Mon Sep 17 00:00:00 2001 From: Mario Romero Date: Mon, 27 Feb 2023 23:22:34 -0300 Subject: [PATCH] Add 5 stage pipeline test and move timescale to include --- cmake/utils.cmake | 2 +- hwinc/timescale.sv | 2 + rtl/alu.sv | 2 + rtl/alu_decoder.sv | 4 +- rtl/cache_controller.sv | 4 +- rtl/cache_memory.sv | 2 +- rtl/control_unit.sv | 2 +- rtl/data_memory.sv | 2 + rtl/data_memory_if.sv | 19 ++ rtl/five_stage_pipeline_datapath.sv | 267 ++++++++++++++++++++++++++ rtl/hazard_unit.sv | 39 ++-- rtl/imm_extend.sv | 2 +- rtl/instr_memory.sv | 2 + rtl/instr_memory_if.sv | 2 + rtl/jump_control.sv | 2 +- rtl/main_decoder.sv | 3 +- rtl/pipelined_control_unit.sv | 48 ++--- rtl/pipelined_cpu.sv | 237 ----------------------- rtl/priority_encoder.sv | 2 +- rtl/register_file.sv | 2 + rtl/rotate_cru.sv | 4 +- rtl/rv32i_defs.sv | 3 +- rtl/single_cycle_datapath.sv | 2 + rtl/two_way_lru_cache.sv | 4 +- rtl/two_way_lru_cru.sv | 4 +- test/CMakeLists.txt | 86 +++++---- test/test_alu.sv | 2 + test/test_five_stage_pipeline_core.sv | 37 ++++ test/test_single_cycle_core.sv | 26 +-- 29 files changed, 460 insertions(+), 353 deletions(-) create mode 100644 hwinc/timescale.sv create mode 100644 rtl/five_stage_pipeline_datapath.sv delete mode 100644 rtl/pipelined_cpu.sv create mode 100644 test/test_five_stage_pipeline_core.sv diff --git a/cmake/utils.cmake b/cmake/utils.cmake index b6b188c..0e7cba1 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -44,7 +44,7 @@ function(rvscc_add_test) PREFIX verilator_${TEST_TOP} TOP_MODULE ${TEST_TOP} TRACE - VERILATOR_ARGS --timing --assert + VERILATOR_ARGS --timing --assert -I${PROJECT_SOURCE_DIR}/hwinc ) target_compile_definitions(${TEST_TARGET_NAME} PRIVATE TEST_HEADER="verilator_${TEST_TOP}.h" diff --git a/hwinc/timescale.sv b/hwinc/timescale.sv new file mode 100644 index 0000000..b9c3f3d --- /dev/null +++ b/hwinc/timescale.sv @@ -0,0 +1,2 @@ +// Project timescale +`timescale 1ns / 1ps diff --git a/rtl/alu.sv b/rtl/alu.sv index ca50fe2..0201a10 100644 --- a/rtl/alu.sv +++ b/rtl/alu.sv @@ -1,3 +1,5 @@ +`include "timescale.sv" + import rv32i_defs::*; module alu ( diff --git a/rtl/alu_decoder.sv b/rtl/alu_decoder.sv index 8225f1a..d139d3b 100644 --- a/rtl/alu_decoder.sv +++ b/rtl/alu_decoder.sv @@ -1,6 +1,6 @@ -`timescale 1ns / 1ps +`include "timescale.sv" -module alu_decoder( +module alu_decoder ( input logic opcode_5, input logic [2:0] funct_3, input logic funct_7_5, diff --git a/rtl/cache_controller.sv b/rtl/cache_controller.sv index ede8d9c..ec35c73 100644 --- a/rtl/cache_controller.sv +++ b/rtl/cache_controller.sv @@ -1,6 +1,6 @@ -`timescale 1ns / 1ps +`include "timescale.sv" -module CacheController #( +module cache_controller #( parameter int ADDR_SIZE = 32, parameter int NUM_SETS = 16, parameter int NUM_WAYS = 4, diff --git a/rtl/cache_memory.sv b/rtl/cache_memory.sv index b70e35a..aaa9a03 100644 --- a/rtl/cache_memory.sv +++ b/rtl/cache_memory.sv @@ -1,4 +1,4 @@ -`timescale 1ns / 1ps +`include "timescale.sv" module cache_memory #( parameter int ADDR_SIZE = 32, diff --git a/rtl/control_unit.sv b/rtl/control_unit.sv index 7a4b636..9bc1696 100644 --- a/rtl/control_unit.sv +++ b/rtl/control_unit.sv @@ -1,4 +1,4 @@ -`timescale 1ns / 1ps +`include "timescale.sv" import rv32i_defs::*; diff --git a/rtl/data_memory.sv b/rtl/data_memory.sv index c30351f..a933e2e 100644 --- a/rtl/data_memory.sv +++ b/rtl/data_memory.sv @@ -1,3 +1,5 @@ +`include "timescale.sv" + import rv32i_defs::*; module data_memory #( diff --git a/rtl/data_memory_if.sv b/rtl/data_memory_if.sv index ef73d45..bd90530 100644 --- a/rtl/data_memory_if.sv +++ b/rtl/data_memory_if.sv @@ -1,3 +1,5 @@ +`include "timescale.sv" + interface data_memory_if #( parameter int ADDR_SIZE = 32, parameter int DATA_SIZE = 32 @@ -14,5 +16,22 @@ interface data_memory_if #( modport datapath(input read_data, output addr, write_enable, write_data); modport ram(input clk, rst, addr, write_enable, write_data, output read_data); + modport test(input read_data, write_enable, write_data); + + /* + * Test assertion that should be used against test-core.s firmware. + * This function checks if the results in data memory are the expected. + * Must be called each clock cycle. + */ + function static void check_fw_test_core_assertions(); + if (write_enable) begin + if (addr == 'd100 && write_data == 'd25) begin + $finish; + end else + assert (addr == 'd96) + else $error("Unexpected write address in test-core program"); + $finish; + end + endfunction endinterface diff --git a/rtl/five_stage_pipeline_datapath.sv b/rtl/five_stage_pipeline_datapath.sv new file mode 100644 index 0000000..1b1e886 --- /dev/null +++ b/rtl/five_stage_pipeline_datapath.sv @@ -0,0 +1,267 @@ +`include "timescale.sv" + +module five_stage_pipeline_datapath ( + input logic clk, + input logic rst, + instr_memory_if.datapath instr_mem_if, + data_memory_if.datapath data_mem_if +); + logic [31:0] fetch_pc, fetch_pc_next; + + logic [31:0] fetch_pc_plus_4, execute_pc_target; + logic execute_pc_src; + always_comb begin + fetch_pc_plus_4 = fetch_pc + 'd4; + case (execute_pc_src) + 'd0: fetch_pc_next = fetch_pc_plus_4; + 'd1: fetch_pc_next = execute_pc_target; + default: fetch_pc_next = 'dx; + endcase + end + + logic fetch_stall; + always_ff @(posedge clk) begin + if (rst) fetch_pc <= 'b0; + else if (!fetch_stall) fetch_pc <= fetch_pc_next; + end + + logic [31:0] fetch_instr; + assign instr_mem_if.addr = instr_mem_if.AddrSize'(fetch_pc); + assign fetch_instr = instr_mem_if.instr; + + logic decode_stall, decode_flush; + logic [31:0] decode_instr, decode_pc, decode_pc_plus_4; + always_ff @(posedge clk) begin + if (decode_flush) begin + decode_instr <= 'd0; + decode_pc <= 'd0; + decode_pc_plus_4 <= 'd0; + end else if (!decode_stall) begin + decode_instr <= fetch_instr; + decode_pc <= fetch_pc; + decode_pc_plus_4 <= fetch_pc_plus_4; + end + end + + logic [4:0] decode_rs_1, decode_rs_2, decode_rd; + assign decode_rs_1 = decode_instr[19:15]; + assign decode_rs_2 = decode_instr[24:20]; + assign decode_rd = decode_instr[11:7]; + + logic writeback_reg_write; + logic [31:0] decode_read_data_1, decode_read_data_2; + logic [31:0] result, writeback_result; + register_file register_file ( + .clk(!clk), + .rst(rst), + .addr_1(decode_instr[19:15]), + .addr_2(decode_instr[24:20]), + .addr_3(writeback_rd), + .write_enable_3(writeback_reg_write), + .write_data_3(writeback_result), + .read_data_1(decode_read_data_1), + .read_data_2(decode_read_data_2) + ); + + logic [1:0] decode_result_src; + logic [1:0] decode_imm_src; + logic [2:0] decode_alu_ctrl; + logic decode_reg_write; + logic decode_mem_write; + logic decode_jump; + logic decode_branch; + logic decode_alu_src; + logic decode_branch_alu_neg; + control_unit control_unit ( + .opcode(decode_instr[6:0]), + .funct_3(decode_instr[14:12]), + .funct_7(decode_instr[31:25]), + .reg_write(decode_reg_write), + .result_src(decode_result_src), + .mem_write(decode_mem_write), + .jump(decode_jump), + .branch(decode_branch), + .alu_ctrl(decode_alu_ctrl), + .alu_src(decode_alu_src), + .imm_src(decode_imm_src), + .branch_alu_neg(decode_branch_alu_neg) + ); + + logic [31:0] decode_imm_ext; + imm_extend imm_extend ( + .imm_src(decode_imm_src[1:0]), + .instr (decode_instr[31:7]), + .imm_ext(decode_imm_ext[31:0]) + ); + + logic execute_reg_write; + logic execute_mem_write; + logic execute_jump; + logic execute_branch; + logic execute_branch_alu_neg; + logic execute_alu_src; + logic execute_flush; + logic [1:0] execute_result_src; + logic [2:0] execute_alu_ctrl; + logic [4:0] execute_rs_1, execute_rs_2, execute_rd; + logic [31:0] execute_pc; + logic [31:0] execute_pc_plus_4; + logic [31:0] execute_read_data_1; + logic [31:0] execute_read_data_2; + logic [31:0] execute_imm_ext; + always_ff @(posedge clk) begin + if (execute_flush) begin + execute_reg_write <= 'd0; + execute_result_src <= 'd0; + execute_mem_write <= 'd0; + execute_jump <= 'd0; + execute_branch <= 'd0; + execute_alu_ctrl <= 'd0; + execute_alu_src <= 'd0; + execute_read_data_1 <= 'd0; + execute_read_data_2 <= 'd0; + execute_pc <= 'd0; + execute_rs_1 <= 'd0; + execute_rs_2 <= 'd0; + execute_rd <= 'd0; + execute_imm_ext <= 'd0; + execute_pc_plus_4 <= 'd0; + end else if (!decode_stall) begin + execute_reg_write <= decode_reg_write; + execute_result_src <= decode_result_src; + execute_mem_write <= decode_mem_write; + execute_jump <= decode_jump; + execute_branch <= decode_branch; + execute_branch_alu_neg <= decode_branch_alu_neg; + execute_alu_ctrl <= decode_alu_ctrl; + execute_alu_src <= decode_alu_src; + execute_read_data_1 <= decode_read_data_1; + execute_read_data_2 <= decode_read_data_2; + execute_pc <= decode_pc; + execute_rs_1 <= decode_rs_1; + execute_rs_2 <= decode_rs_2; + execute_rd <= decode_rd; + execute_imm_ext <= decode_imm_ext; + execute_pc_plus_4 <= decode_pc_plus_4; + end + end + + logic execute_zero; + jump_control jump_control ( + .jump(execute_jump), + .branch(execute_branch), + .branch_alu_neg(execute_branch_alu_neg), + .zero(execute_zero), + .pc_src(execute_pc_src) + ); + + logic [31:0] execute_src_a, memory_alu_result; + logic [1:0] execute_forward_a; + always_comb begin + case (execute_forward_a) + 'b00: execute_src_a = execute_read_data_1; + 'b01: execute_src_a = writeback_result; + 'b10: execute_src_a = memory_alu_result; + 'b11: execute_src_a = 'dx; + default: execute_src_a = 'dx; + endcase + end + + logic [31:0] execute_write_data; + logic [ 1:0] execute_forward_b; + always_comb begin + case (execute_forward_b) + 'b00: execute_write_data = execute_read_data_2; + 'b01: execute_write_data = writeback_result; + 'b10: execute_write_data = memory_alu_result; + 'b11: execute_write_data = 'dx; + default: execute_write_data = 'dx; + endcase + end + + logic [31:0] execute_src_b; + always_comb begin + case (execute_alu_src) + 'd0: execute_src_b = execute_write_data; + 'd1: execute_src_b = execute_imm_ext; + default: execute_src_b = 'dx; + endcase + end + + logic [31:0] execute_alu_result; + logic [ 3:0] execute_alu_status; + assign execute_zero = execute_alu_status[2]; + alu alu ( + .a(execute_src_a), + .b(execute_src_b), + .operation(execute_alu_ctrl), + .result(execute_alu_result), + .status(execute_alu_status) + ); + + assign execute_pc_target = execute_pc + execute_imm_ext; + + logic memory_reg_write, memory_mem_write; + logic [1:0] memory_result_src; + logic [4:0] memory_rd; + logic [31:0] memory_pc_plus_4, memory_write_data; + always_ff @(posedge clk) begin + memory_reg_write <= execute_reg_write; + memory_result_src <= execute_result_src; + memory_mem_write <= execute_mem_write; + memory_alu_result <= execute_alu_result; + memory_write_data <= execute_write_data; + memory_rd <= execute_rd; + memory_pc_plus_4 <= execute_pc_plus_4; + end + + logic [31:0] memory_read_data; + always_comb begin + data_mem_if.addr = memory_alu_result; + data_mem_if.write_enable = memory_mem_write; + data_mem_if.write_data = memory_write_data; + memory_read_data = data_mem_if.read_data; + end + + logic [1:0] writeback_result_src; + logic [4:0] writeback_rd; + logic [31:0] writeback_pc_plus_4, writeback_alu_result, writeback_read_data; + always_ff @(posedge clk) begin + writeback_reg_write <= memory_reg_write; + writeback_result_src <= memory_result_src; + writeback_alu_result <= memory_alu_result; + writeback_read_data <= memory_read_data; + writeback_rd <= memory_rd; + writeback_pc_plus_4 <= memory_pc_plus_4; + end + + always_comb begin + case (writeback_result_src) + 'b00: writeback_result = writeback_alu_result; + 'b01: writeback_result = writeback_read_data; + 'b10: writeback_result = writeback_pc_plus_4; + default: writeback_result = 'dx; + endcase + end + + hazard_unit hazard_unit ( + .rst(rst), + .execute_pc_src(execute_pc_src), + .execute_result_src_0(execute_result_src[0]), + .memory_reg_write(memory_reg_write), + .writeback_reg_write(writeback_reg_write), + .decode_rs_1(decode_rs_1), + .decode_rs_2(decode_rs_2), + .execute_rs_1(execute_rs_1), + .execute_rs_2(execute_rs_2), + .execute_rd(execute_rd), + .memory_rd(memory_rd), + .writeback_rd(writeback_rd), + .fetch_stall(fetch_stall), + .decode_stall(decode_stall), + .decode_flush(decode_flush), + .execute_flush(execute_flush), + .execute_forward_a(execute_forward_a), + .execute_forward_b(execute_forward_b) + ); +endmodule diff --git a/rtl/hazard_unit.sv b/rtl/hazard_unit.sv index b16526a..d5271c4 100644 --- a/rtl/hazard_unit.sv +++ b/rtl/hazard_unit.sv @@ -1,24 +1,24 @@ -`timescale 1ns / 1ps +`include "timescale.sv" -module HazardUnit ( +module hazard_unit ( input logic rst, - execute_pc_src, - execute_result_src_0, - memory_reg_write, - writeback_reg_write, + input logic execute_pc_src, + input logic execute_result_src_0, + input logic memory_reg_write, + input logic writeback_reg_write, input logic [4:0] decode_rs_1, - decode_rs_2, - execute_rs_1, - execute_rs_2, - execute_rd, - memory_rd, - writeback_rd, + input logic [4:0] decode_rs_2, + input logic [4:0] execute_rs_1, + input logic [4:0] execute_rs_2, + input logic [4:0] execute_rd, + input logic [4:0] memory_rd, + input logic [4:0] writeback_rd, output logic fetch_stall, - decode_stall, - decode_flush, - execute_flush, + output logic decode_stall, + output logic decode_flush, + output logic execute_flush, output logic [1:0] execute_forward_a, - execute_forward_b + output logic [1:0] execute_forward_b ); logic lw_stall; always_comb begin @@ -27,15 +27,18 @@ module HazardUnit ( decode_stall = 0; decode_flush = 1; execute_flush = 1; - execute_forward_a = 0; - execute_forward_b = 0; + execute_forward_a = 2'd0; + execute_forward_b = 2'd0; + lw_stall = 1'dx; end else begin + // set execute_forward_a if (((execute_rs_1 == memory_rd) & memory_reg_write) & (execute_rs_1 != 0)) execute_forward_a = 'b10; else if (((execute_rs_1 == writeback_rd) & writeback_reg_write) & (execute_rs_1 != 0)) execute_forward_a = 'b01; else execute_forward_a = 'b00; + // set execute_forward_b if (((execute_rs_2 == memory_rd) & memory_reg_write) & (execute_rs_2 != 0)) execute_forward_b = 'b10; else if (((execute_rs_2 == writeback_rd) & writeback_reg_write) & (execute_rs_2 != 0)) diff --git a/rtl/imm_extend.sv b/rtl/imm_extend.sv index b2d128c..3861bc5 100644 --- a/rtl/imm_extend.sv +++ b/rtl/imm_extend.sv @@ -1,4 +1,4 @@ -`timescale 1ns / 1ps +`include "timescale.sv" module imm_extend ( input logic [ 1:0] imm_src, diff --git a/rtl/instr_memory.sv b/rtl/instr_memory.sv index e51749b..22cac1d 100644 --- a/rtl/instr_memory.sv +++ b/rtl/instr_memory.sv @@ -1,3 +1,5 @@ +`include "timescale.sv" + import rv32i_defs::*; module instr_memory #( diff --git a/rtl/instr_memory_if.sv b/rtl/instr_memory_if.sv index 0eedb7c..d9ff755 100644 --- a/rtl/instr_memory_if.sv +++ b/rtl/instr_memory_if.sv @@ -1,3 +1,5 @@ +`include "timescale.sv" + import rv32i_defs::*; interface instr_memory_if #( diff --git a/rtl/jump_control.sv b/rtl/jump_control.sv index fe4e3f3..3c5774a 100644 --- a/rtl/jump_control.sv +++ b/rtl/jump_control.sv @@ -1,4 +1,4 @@ -`timescale 1ns / 1ps +`include "timescale.sv" module jump_control ( input logic jump, diff --git a/rtl/main_decoder.sv b/rtl/main_decoder.sv index 192d4b2..85286bf 100644 --- a/rtl/main_decoder.sv +++ b/rtl/main_decoder.sv @@ -1,4 +1,4 @@ -`timescale 1ns / 1ps +`include "timescale.sv" import rv32i_defs::*; @@ -13,7 +13,6 @@ module main_decoder ( output logic reg_write, output logic [1:0] alu_op ); - opcode_fmt_t opcode_enum; assign opcode_enum = opcode_fmt_t'(opcode); always_comb begin diff --git a/rtl/pipelined_control_unit.sv b/rtl/pipelined_control_unit.sv index a02ad69..5c63674 100644 --- a/rtl/pipelined_control_unit.sv +++ b/rtl/pipelined_control_unit.sv @@ -1,6 +1,6 @@ -`timescale 1ns / 1ps +`include "timescale.sv" -module PipelinedControlUnit ( +module pipelined_control_unit ( input logic [6:0] opcode, input logic [2:0] funct_3, input logic [6:0] funct_7, @@ -12,35 +12,25 @@ module PipelinedControlUnit ( output logic alu_src, output logic [1:0] imm_src ); - //logic branch, branch_result, branch_neg, jump; - //assign pc_src = (branch & branch_result) | jump; - /* - always_comb begin - case(branch_neg) - 'd0: branch_result = !zero; - 'd1: branch_result = zero; - endcase - end*/ - logic [1:0] alu_op; - MainDecoder main_decoder ( - opcode, - branch, - jump, - result_src, - mem_write, - alu_src, - imm_src, - reg_write, - alu_op + main_decoder main_decoder ( + .opcode(opcode), + .branch(branch), + .jump(jump), + .result_src(result_src), + .mem_write(mem_write), + .alu_src(alu_src), + .imm_src(imm_src), + .reg_write(reg_write), + .alu_op(alu_op) ); - ALUDecoder alu_decoder ( - opcode[5], - funct_3, - funct_7[5], - alu_op, - alu_ctrl, - branch_neg + alu_decoder alu_decoder ( + .opcode(opcode[5]), + .funct_3(funct_3), + .funct_7_5(funct_7[5]), + .alu_op(alu_op), + .alu_ctrl(alu_ctrl), + .branch_neg(branch_neg) ); endmodule diff --git a/rtl/pipelined_cpu.sv b/rtl/pipelined_cpu.sv deleted file mode 100644 index d1fe674..0000000 --- a/rtl/pipelined_cpu.sv +++ /dev/null @@ -1,237 +0,0 @@ -`timescale 1ns / 1ps - -module PipelinedCPU( - input logic clk, reset -); - logic[31:0] fetch_pc, fetch_pc_next; - - logic[31:0] fetch_pc_plus_4, execute_pc_target; - always_comb begin - fetch_pc_plus_4 = fetch_pc + 'd4; - case(execute_pc_src) - 'd0: fetch_pc_next = fetch_pc_plus_4; - 'd1: fetch_pc_next = execute_pc_target; - endcase - end - - always_ff @(posedge clk) begin - if(reset) - fetch_pc <= 'b0; - else if(!fetch_stall) - fetch_pc <= fetch_pc_next; - end - - logic[31:0] fetch_instr; - InstructionMemory #(.N(32)) instruction_memory(fetch_pc, fetch_instr); - - logic decode_stall, decode_flush; - logic[31:0] decode_instr, decode_pc, decode_pc_plus_4; - always_ff @(posedge clk) begin - if(decode_flush) begin - decode_instr <= 'd0; - decode_pc <= 'd0; - decode_pc_plus_4 <= 'd0; - end else if(!decode_stall) begin - decode_instr <= fetch_instr; - decode_pc <= fetch_pc; - decode_pc_plus_4 <= fetch_pc_plus_4; - end - end - - logic[4:0] decode_rs_1, decode_rs_2, decode_rd; - assign decode_rs_1 = decode_instr[19:15]; - assign decode_rs_2 = decode_instr[24:20]; - assign decode_rd = decode_instr[11:7]; - - logic writeback_reg_write; - logic[31:0] decode_read_data_1, decode_read_data_2; - logic[31:0] result, writeback_result; - RegisterFile #(.N_REG_ADDR(5), .N_DATA(32)) register_file( - ~clk, - reset, - decode_instr[19:15], - decode_instr[24:20], - writeback_rd, - writeback_reg_write, - writeback_result, - decode_read_data_1, - decode_read_data_2 - ); - - logic[1:0] decode_result_src; - logic[1:0] decode_imm_src; - logic[2:0] decode_alu_ctrl; - logic decode_reg_write, decode_branch_alu_neg; - ControlUnit control_unit( - .opcode(decode_instr[6:0]), - .funct_3(decode_instr[14:12]), - .funct_7(decode_instr[31:25]), - .reg_write(decode_reg_write), - .result_src(decode_result_src), - .mem_write(decode_mem_write), - .jump(decode_jump), - .branch(decode_branch), - .alu_ctrl(decode_alu_ctrl), - .alu_src(decode_alu_src), - .imm_src(decode_imm_src), - .branch_alu_neg(decode_branch_alu_neg) - ); - - logic[31:0] decode_imm_ext; - Extend imm_extend( - decode_imm_src[1:0], - decode_instr[31:7], - decode_imm_ext[31:0] - ); - - logic execute_reg_write, execute_mem_write, execute_jump, execute_branch, execute_branch_alu_neg, execute_alu_src; - logic[1:0] execute_result_src; - logic[2:0] execute_alu_ctrl; - logic[4:0] execute_rs_1, execute_rs_2, execute_rd; - logic[31:0] execute_pc, execute_pc_plus_4, execute_read_data_1, execute_read_data_2, execute_imm_ext; - always_ff @(posedge clk) begin - if(execute_flush) begin - execute_reg_write <= 'd0; - execute_result_src <= 'd0; - execute_mem_write <= 'd0; - execute_jump <= 'd0; - execute_branch <= 'd0; - execute_alu_ctrl <= 'd0; - execute_alu_src <= 'd0; - execute_read_data_1 <= 'd0; - execute_read_data_2 <= 'd0; - execute_pc <= 'd0; - execute_rs_1 <= 'd0; - execute_rs_2 <= 'd0; - execute_rd <= 'd0; - execute_imm_ext <= 'd0; - execute_pc_plus_4 <= 'd0; - end else if (!decode_stall) begin - execute_reg_write <= decode_reg_write; - execute_result_src <= decode_result_src; - execute_mem_write <= decode_mem_write; - execute_jump <= decode_jump; - execute_branch <= decode_branch; - execute_branch_alu_neg <= decode_branch_alu_neg; - execute_alu_ctrl <= decode_alu_ctrl; - execute_alu_src <= decode_alu_src; - execute_read_data_1 <= decode_read_data_1; - execute_read_data_2 <= decode_read_data_2; - execute_pc <= decode_pc; - execute_rs_1 <= decode_rs_1; - execute_rs_2 <= decode_rs_2; - execute_rd <= decode_rd; - execute_imm_ext <= decode_imm_ext; - execute_pc_plus_4 <= decode_pc_plus_4; - end - end - - JumpControl jump_control( - execute_jump, - execute_branch, - execute_branch_alu_neg, - execute_zero, - execute_pc_src - ); - - logic[31:0] execute_src_a, memory_alu_result; - logic[1:0] execute_forward_a; - always_comb begin - case(execute_forward_a) - 'b00: execute_src_a = execute_read_data_1; - 'b01: execute_src_a = writeback_result; - 'b10: execute_src_a = memory_alu_result; - 'b11: execute_src_a = 'dx; - endcase - end - - logic[31:0] execute_write_data; - logic[1:0] execute_forward_b; - always_comb begin - case(execute_forward_b) - 'b00: execute_write_data = execute_read_data_2; - 'b01: execute_write_data = writeback_result; - 'b10: execute_write_data = memory_alu_result; - 'b11: execute_write_data = 'dx; - endcase - end - - logic[31:0] execute_src_b; - always_comb begin - case(execute_alu_src) - 'd0: execute_src_b = execute_write_data; - 'd1: execute_src_b = execute_imm_ext; - endcase - end - - logic[31:0] execute_alu_result; - logic[3:0] execute_alu_status; - assign execute_zero = execute_alu_status[2]; - ALU alu( - execute_src_a, - execute_src_b, - execute_alu_ctrl, - execute_alu_result, - execute_alu_status - ); - - assign execute_pc_target = execute_pc + execute_imm_ext; - - logic memory_reg_write, memory_mem_write; - logic[1:0] memory_result_src; - logic[4:0] memory_rd; - logic[31:0] memory_pc_plus_4, memory_write_data; - always_ff @(posedge clk) begin - memory_reg_write <= execute_reg_write; - memory_result_src <= execute_result_src; - memory_mem_write <= execute_mem_write; - memory_alu_result <= execute_alu_result; - memory_write_data <= execute_write_data; - memory_rd <= execute_rd; - memory_pc_plus_4 <= execute_pc_plus_4; - end - - logic[31:0] memory_read_data; - DataMemory data_memory( - clk, - reset, - memory_alu_result, - memory_mem_write, - memory_write_data, - memory_read_data - ); - - logic[1:0] writeback_result_src; - logic[4:0] writeback_rd; - logic[31:0] writeback_pc_plus_4, writeback_alu_result, writeback_read_data; - always_ff @(posedge clk) begin - writeback_reg_write <= memory_reg_write; - writeback_result_src <= memory_result_src; - writeback_alu_result <= memory_alu_result; - writeback_read_data <= memory_read_data; - writeback_rd <= memory_rd; - writeback_pc_plus_4 <= memory_pc_plus_4; - end - - always_comb begin - case(writeback_result_src) - 'b00: writeback_result = writeback_alu_result; - 'b01: writeback_result = writeback_read_data; - 'b10: writeback_result = writeback_pc_plus_4; - 'b11: writeback_result = 'dx; - endcase - end - - HazardUnit hazard_unit( - reset, - execute_pc_src, execute_result_src[0], - memory_reg_write, writeback_reg_write, - decode_rs_1, decode_rs_2, - execute_rs_1, execute_rs_2, - execute_rd, memory_rd, writeback_rd, - fetch_stall, decode_stall, - decode_flush, execute_flush, - execute_forward_a, execute_forward_b - ); - -endmodule diff --git a/rtl/priority_encoder.sv b/rtl/priority_encoder.sv index 06effb6..a7cc16f 100644 --- a/rtl/priority_encoder.sv +++ b/rtl/priority_encoder.sv @@ -1,4 +1,4 @@ -`timescale 1ns / 1ps +`include "timescale.sv" // 2**N to N Priority encoder module priority_encoder #( diff --git a/rtl/register_file.sv b/rtl/register_file.sv index 8fb39c4..dfb35f1 100644 --- a/rtl/register_file.sv +++ b/rtl/register_file.sv @@ -1,3 +1,5 @@ +`include "timescale.sv" + import rv32i_defs::*; module register_file ( diff --git a/rtl/rotate_cru.sv b/rtl/rotate_cru.sv index 1ba67fa..494cb23 100644 --- a/rtl/rotate_cru.sv +++ b/rtl/rotate_cru.sv @@ -1,6 +1,6 @@ -`timescale 1ns / 1ps +`include "timescale.sv" -module RotateCRP #( +module rotate_cru#( parameter ADDR_SIZE = 32, parameter NUM_SETS = 16, parameter NUM_WAYS = 4, diff --git a/rtl/rv32i_defs.sv b/rtl/rv32i_defs.sv index dac7ee4..5592761 100644 --- a/rtl/rv32i_defs.sv +++ b/rtl/rv32i_defs.sv @@ -1,4 +1,4 @@ -`timescale 1ns / 1ps +`include "timescale.sv" package rv32i_defs; // Sizes in bits @@ -27,5 +27,4 @@ package rv32i_defs; LUI = 'b0110111, AUIPC = 'b0010111 } opcode_fmt_t; - endpackage diff --git a/rtl/single_cycle_datapath.sv b/rtl/single_cycle_datapath.sv index 0c9c1ad..aab614f 100644 --- a/rtl/single_cycle_datapath.sv +++ b/rtl/single_cycle_datapath.sv @@ -1,3 +1,5 @@ +`include "timescale.sv" + import rv32i_defs::*; module single_cycle_datapath ( diff --git a/rtl/two_way_lru_cache.sv b/rtl/two_way_lru_cache.sv index db3a440..b388af9 100644 --- a/rtl/two_way_lru_cache.sv +++ b/rtl/two_way_lru_cache.sv @@ -1,6 +1,6 @@ -`timescale 1ns / 1ps +`include "timescale.sv" -module TwoWayLRUCache #( +module two_way_lru_cache #( parameter ADDR_SIZE = 32, parameter NUM_SETS = 16, parameter BLOCK_SIZE = 32 diff --git a/rtl/two_way_lru_cru.sv b/rtl/two_way_lru_cru.sv index b28eba8..79a3d69 100644 --- a/rtl/two_way_lru_cru.sv +++ b/rtl/two_way_lru_cru.sv @@ -1,6 +1,6 @@ -`timescale 1ns / 1ps +`include "timescale.sv" -module TwoWayLRUCRU #( +module two_way_lru_cru #( parameter ADDR_SIZE = 32, parameter NUM_SETS = 16, parameter BLOCK_SIZE = 32 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1e240b3..97cfc15 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,4 @@ -include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/utils.cmake) +include(${PROJECT_SOURCE_DIR}/cmake/utils.cmake) find_package(verilator HINTS $ENV{VERILATOR_ROOT}) if (NOT verilator_FOUND) @@ -13,66 +13,86 @@ find_package(SystemCLanguage QUIET) rvscc_add_test( NAME alu TOP test_alu - SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/rv32i_defs.sv - ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/alu.sv - ${CMAKE_CURRENT_SOURCE_DIR}/test_alu.sv + SOURCES ${PROJECT_SOURCE_DIR}/rtl/rv32i_defs.sv + ${PROJECT_SOURCE_DIR}/rtl/alu.sv + ${PROJECT_SOURCE_DIR}/test/test_alu.sv ) rvscc_add_test( NAME priority-encoder TOP test_priority_encoder - SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/priority_encoder.sv - ${CMAKE_CURRENT_SOURCE_DIR}/test_priority_encoder.sv + SOURCES ${PROJECT_SOURCE_DIR}/rtl/priority_encoder.sv + ${PROJECT_SOURCE_DIR}/test/test_priority_encoder.sv ) rvscc_add_test( NAME data-memory TOP test_data_memory - SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/rv32i_defs.sv - ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/data_memory_if.sv - ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/data_memory.sv - ${CMAKE_CURRENT_SOURCE_DIR}/test_data_memory.sv + SOURCES ${PROJECT_SOURCE_DIR}/rtl/rv32i_defs.sv + ${PROJECT_SOURCE_DIR}/rtl/data_memory_if.sv + ${PROJECT_SOURCE_DIR}/rtl/data_memory.sv + ${PROJECT_SOURCE_DIR}/test/test_data_memory.sv ) rvscc_add_test( NAME imm-extend TOP test_imm_extend - SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/imm_extend.sv - ${CMAKE_CURRENT_SOURCE_DIR}/test_imm_extend.sv + SOURCES ${PROJECT_SOURCE_DIR}/rtl/imm_extend.sv + ${PROJECT_SOURCE_DIR}/test/test_imm_extend.sv ) rvscc_add_test( NAME register-file TOP test_register_file - SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/rv32i_defs.sv - ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/register_file.sv - ${CMAKE_CURRENT_SOURCE_DIR}/test_register_file.sv + SOURCES ${PROJECT_SOURCE_DIR}/rtl/rv32i_defs.sv + ${PROJECT_SOURCE_DIR}/rtl/register_file.sv + ${PROJECT_SOURCE_DIR}/test/test_register_file.sv ) 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 + SOURCES ${PROJECT_SOURCE_DIR}/rtl/rv32i_defs.sv + ${PROJECT_SOURCE_DIR}/rtl/instr_memory_if.sv + ${PROJECT_SOURCE_DIR}/rtl/instr_memory.sv + ${PROJECT_SOURCE_DIR}/test/test_instr_memory.sv ) rvscc_add_test( NAME single-cycle-core TOP test_single_cycle_core - SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/rv32i_defs.sv - ${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 - ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/alu_decoder.sv - ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/main_decoder.sv - ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/register_file.sv - ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/imm_extend.sv - ${CMAKE_CURRENT_SOURCE_DIR}/../rtl/alu.sv - ${CMAKE_CURRENT_SOURCE_DIR}/test_single_cycle_core.sv + SOURCES ${PROJECT_SOURCE_DIR}/rtl/rv32i_defs.sv + ${PROJECT_SOURCE_DIR}/rtl/single_cycle_datapath.sv + ${PROJECT_SOURCE_DIR}/rtl/data_memory_if.sv + ${PROJECT_SOURCE_DIR}/rtl/data_memory.sv + ${PROJECT_SOURCE_DIR}/rtl/instr_memory_if.sv + ${PROJECT_SOURCE_DIR}/rtl/instr_memory.sv + ${PROJECT_SOURCE_DIR}/rtl/jump_control.sv + ${PROJECT_SOURCE_DIR}/rtl/control_unit.sv + ${PROJECT_SOURCE_DIR}/rtl/alu_decoder.sv + ${PROJECT_SOURCE_DIR}/rtl/main_decoder.sv + ${PROJECT_SOURCE_DIR}/rtl/register_file.sv + ${PROJECT_SOURCE_DIR}/rtl/imm_extend.sv + ${PROJECT_SOURCE_DIR}/rtl/alu.sv + ${PROJECT_SOURCE_DIR}/test/test_single_cycle_core.sv +) + +rvscc_add_test( + NAME five-stage-pipeline-core + TOP test_five_stage_pipeline_core + SOURCES ${PROJECT_SOURCE_DIR}/rtl/rv32i_defs.sv + ${PROJECT_SOURCE_DIR}/rtl/five_stage_pipeline_datapath.sv + ${PROJECT_SOURCE_DIR}/rtl/data_memory_if.sv + ${PROJECT_SOURCE_DIR}/rtl/data_memory.sv + ${PROJECT_SOURCE_DIR}/rtl/instr_memory_if.sv + ${PROJECT_SOURCE_DIR}/rtl/instr_memory.sv + ${PROJECT_SOURCE_DIR}/rtl/jump_control.sv + ${PROJECT_SOURCE_DIR}/rtl/control_unit.sv + ${PROJECT_SOURCE_DIR}/rtl/alu_decoder.sv + ${PROJECT_SOURCE_DIR}/rtl/main_decoder.sv + ${PROJECT_SOURCE_DIR}/rtl/register_file.sv + ${PROJECT_SOURCE_DIR}/rtl/imm_extend.sv + ${PROJECT_SOURCE_DIR}/rtl/alu.sv + ${PROJECT_SOURCE_DIR}/rtl/hazard_unit.sv + ${PROJECT_SOURCE_DIR}/test/test_five_stage_pipeline_core.sv ) diff --git a/test/test_alu.sv b/test/test_alu.sv index eb82436..6d0409f 100644 --- a/test/test_alu.sv +++ b/test/test_alu.sv @@ -1,3 +1,5 @@ +`timescale 1ns / 1ps + import rv32i_defs::*; module test_alu (); diff --git a/test/test_five_stage_pipeline_core.sv b/test/test_five_stage_pipeline_core.sv new file mode 100644 index 0000000..5daa5d4 --- /dev/null +++ b/test/test_five_stage_pipeline_core.sv @@ -0,0 +1,37 @@ +`include "timescale.sv" + +module test_five_stage_pipeline_core (); + logic clk, rst; + always #1 clk = ~clk; + + instr_memory_if instr_mem_if (); + instr_memory #( + .FILE_PATH("../fw/test/test-core.mem") + ) instr_mem ( + .instr_mem_if(instr_mem_if.mem) + ); + + data_memory_if data_mem_if ( + .clk(clk), + .rst(rst) + ); + data_memory #(.NUM_BLOCKS(128)) data_mem (.data_mem_if(data_mem_if.ram)); + + five_stage_pipeline_datapath dut ( + .clk(clk), + .rst(rst), + .instr_mem_if(instr_mem_if.datapath), + .data_mem_if(data_mem_if.datapath) + ); + + always @(posedge clk) data_mem_if.check_fw_test_core_assertions(); + + initial begin + clk = 0; + rst = 1; + #4; + rst = 0; + #1000; + $error("Program execution timeout"); + end +endmodule diff --git a/test/test_single_cycle_core.sv b/test/test_single_cycle_core.sv index 5a2a3cf..6022785 100644 --- a/test/test_single_cycle_core.sv +++ b/test/test_single_cycle_core.sv @@ -1,11 +1,15 @@ -`timescale 1ns / 1ps +`include "timescale.sv" module test_single_cycle_core (); logic clk, rst; always #1 clk = ~clk; - instr_memory_if instr_mem_if(); - instr_memory #(.FILE_PATH("test-core.mem")) instr_mem (.instr_mem_if(instr_mem_if.mem)); + instr_memory_if instr_mem_if (); + instr_memory #( + .FILE_PATH("../fw/test/test-core.mem") + ) instr_mem ( + .instr_mem_if(instr_mem_if.mem) + ); data_memory_if data_mem_if ( .clk(clk), @@ -19,25 +23,15 @@ module test_single_cycle_core (); .instr_mem_if(instr_mem_if.datapath), .data_mem_if(data_mem_if.datapath) ); - - always @(posedge clk) begin - if (data_mem_if.write_enable) begin - if(data_mem_if.addr == 'd100 && data_mem_if.write_data == 'd25) begin - $finish; - end else if (data_mem_if.addr != 'd96) // assert - $finish; - end - end + + always @(posedge clk) data_mem_if.check_fw_test_core_assertions(); initial begin - $dumpfile("single_cycle.vcd"); - $dumpvars(1, dut); clk = 0; rst = 1; #4; rst = 0; #1000; - $display("Hello world"); - $finish; + $error("Program execution timeout"); end endmodule