diff options
author | Joshua Yun <joshua@joshuayun.com> | 2025-03-15 23:09:39 -0500 |
---|---|---|
committer | Joshua Yun <joshua@joshuayun.com> | 2025-03-15 23:09:39 -0500 |
commit | 6bd9f4f7ab48576d3fda98bef915162a7436866d (patch) | |
tree | a0af72467af1020f9e492b177e2d95ed8998d1dc | |
parent | 59fd8c25ee1452452cb564d6fe4163b7a9394aef (diff) | |
download | riscv-processor-6bd9f4f7ab48576d3fda98bef915162a7436866d.tar.gz |
feat: More setting up, got a janky decode stage that prints out the instruction it receives, added dump options to fusesoc, changed instr width back th 32 from 64
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | core/cpu.core | 3 | ||||
-rw-r--r-- | core/pkg/riscv_types.sv | 14 | ||||
-rw-r--r-- | core/rtl/core.sv | 13 | ||||
-rw-r--r-- | core/rtl/decode.sv | 34 | ||||
-rw-r--r-- | core/rtl/fetch.sv | 14 | ||||
-rw-r--r-- | core/tb/.gitignore | 3 | ||||
-rw-r--r-- | core/tb/core_tb.sv | 31 | ||||
-rw-r--r-- | core/tb/core_tb_imem.sv | 17 | ||||
-rw-r--r-- | primitives/rtl/AFFR.sv | 4 |
10 files changed, 107 insertions, 30 deletions
@@ -1,3 +1,5 @@ # RISCV_Linux -Building a project with fusesoc +Running core testbench + + fusesoc run --target sim bingchao:riscv:cpu diff --git a/core/cpu.core b/core/cpu.core index 7f7b499..a4e99b4 100644 --- a/core/cpu.core +++ b/core/cpu.core @@ -5,8 +5,10 @@ description: "RISC-V Core" filesets: rtl: files: + - pkg/riscv_types.sv - rtl/core.sv - rtl/fetch.sv + - rtl/decode.sv file_type: systemVerilogSource depend: - bingchao:riscv:primitives @@ -33,3 +35,4 @@ targets: tools: verilator: mode: binary + verilator_options: [--trace-fst] diff --git a/core/pkg/riscv_types.sv b/core/pkg/riscv_types.sv new file mode 100644 index 0000000..3d68331 --- /dev/null +++ b/core/pkg/riscv_types.sv @@ -0,0 +1,14 @@ +package riscv_types; + typedef enum logic [6:0] { + INSTR_TYPE_LUI = 7'b0110111, // U load upper immediate + INSTR_TYPE_AUIPC = 7'b0010111, // U add upper immediate PC + INSTR_TYPE_JAL = 7'b1101111, // J jump and link + INSTR_TYPE_JALR = 7'b1100111, // I jump and link register + INSTR_TYPE_BR = 7'b1100011, // B branch + INSTR_TYPE_LD = 7'b0000011, // I load + INSTR_TYPE_ST = 7'b0100011, // S store + INSTR_TYPE_IMM = 7'b0010011, // I arith ops with register/immediate operands + INSTR_TYPE_REG = 7'b0110011, // R arith ops with register operands + INSTR_TYPE_CSR = 7'b1110011 // I control and status register + } opcode_t; +endpackage diff --git a/core/rtl/core.sv b/core/rtl/core.sv index 5f64e7a..d9a51dd 100644 --- a/core/rtl/core.sv +++ b/core/rtl/core.sv @@ -1,10 +1,11 @@ module core +import riscv_types::*; ( input logic clk, input logic rst_l, // Instruction mem interface - output logic [63:0] if_imem_addr_IF, - input logic [63:0] imem_id_instr_ID + output logic [31:0] if_imem_addr_IF, + input logic [31:0] imem_id_instr_ID // Data mem interface ); @@ -15,8 +16,10 @@ fetch fetch0 ( .if_imem_addr_IF(if_imem_addr_IF) ); -always @ (posedge clk) begin - $display("Instruction: %x", imem_id_instr_ID); -end +decode decode0 ( + .clk(clk), + .rst_l(rst_l), + .imem_id_instr_ID(imem_id_instr_ID) +); endmodule diff --git a/core/rtl/decode.sv b/core/rtl/decode.sv new file mode 100644 index 0000000..e337e11 --- /dev/null +++ b/core/rtl/decode.sv @@ -0,0 +1,34 @@ +module decode +import riscv_types::*; +#( + ) + ( + input logic clk, + input logic rst_l, + + // I-MEM Interface + input logic [31:0] imem_id_instr_ID + ); + +opcode_t instrOpCode_ID; + +assign instrOpCode_ID = opcode_t'(imem_id_instr_ID[6:0]); + +always_ff @(posedge clk) begin + $display("Instruction: %x", imem_id_instr_ID); + case (instrOpCode_ID) + INSTR_TYPE_LUI: begin $display("Instr type: LUI"); end + INSTR_TYPE_AUIPC: begin $display("Instr type: AUIPC"); end + INSTR_TYPE_JAL: begin $display("Instr type: JAL"); end + INSTR_TYPE_JALR: begin $display("Instr type: JALR"); end + INSTR_TYPE_BR: begin $display("Instr type: BR"); end + INSTR_TYPE_LD: begin $display("Instr type: LD"); end + INSTR_TYPE_ST: begin $display("Instr type: ST"); end + INSTR_TYPE_IMM: begin $display("Instr type: IMM"); end + INSTR_TYPE_REG: begin $display("Instr type: REG"); end + INSTR_TYPE_CSR: begin $display("Instr type: CSR"); end + default: begin $display("Instr type: Unknown"); end + endcase +end + +endmodule diff --git a/core/rtl/fetch.sv b/core/rtl/fetch.sv index 7cbff6a..d2b5ed0 100644 --- a/core/rtl/fetch.sv +++ b/core/rtl/fetch.sv @@ -1,20 +1,22 @@ module fetch +import riscv_types::*; ( input logic clk, input logic rst_l, // IMEM interface - output logic [63:0] if_imem_addr_IF + output logic [31:0] if_imem_addr_IF ); -logic [63:0] pc_IF; -logic [63:0] pcNxt_IF; +logic [31:0] pc_IF; +logic [31:0] pcNxt_IF; -assign if_imem_addr_IF = pc_IF; // Always fetch PC from IMEM, truncate addresses to be 64 bit aligned? +assign if_imem_addr_IF = pc_IF; // Always fetch PC from IMEM, addresses are always 32 bit aligned + // TODO: Find out if 32 is the best fetching width vs 16 // Program Counter (PC) -assign pcNxt_IF = pc_IF + 64'd4; +assign pcNxt_IF = pc_IF + 32'd4; -AFFR #(.WIDTH(64)) ff_IF_pc ( .clk(clk), .rst_l(rst_l), .en(1'b1), .q(pc_IF), .d(pcNxt_IF) ); +AFFR #(.WIDTH(32)) ff_IF_pc ( .clk(clk), .rst_l(rst_l), .en(1'b1), .q(pc_IF), .d(pcNxt_IF) ); endmodule diff --git a/core/tb/.gitignore b/core/tb/.gitignore new file mode 100644 index 0000000..b5295dc --- /dev/null +++ b/core/tb/.gitignore @@ -0,0 +1,3 @@ +**.S +**.bin +**.o diff --git a/core/tb/core_tb.sv b/core/tb/core_tb.sv index 9780df8..3252a13 100644 --- a/core/tb/core_tb.sv +++ b/core/tb/core_tb.sv @@ -1,27 +1,38 @@ -module core_tb (); +module core_tb +#( + parameter TIMEOUT = 10, + parameter ADDR_WIDTH = 16 +); logic clk; logic rst_l; -logic [63:0] if_imem_addr_IF; -logic [63:0] imem_id_instr_ID; +// imem instruction interface +logic [31:0] if_imem_addr_IF; +logic [31:0] imem_id_instr_ID; // Clock Generation -initial begin - repeat(1000) begin - clk = ~clk; - #1; - end - $finish(); +always begin + clk = #1 ~clk; end +// Signal Dump, Test Timeout, and Reset initial begin + // Dump Setup + $dumpfile("dump.fst"); + $dumpvars; + + // Reset Set up rst_l = 1'b0; repeat (5) @(posedge clk); rst_l = 1'b1; + + // Timeout Setup + repeat (TIMEOUT) @(posedge clk); + $finish("Test Timed Out"); // TODO Make error & increase timeout length end -core_tb_imem #( .ADDR_WIDTH(16) ) imem0 ( +core_tb_imem #( .ADDR_WIDTH(ADDR_WIDTH) ) imem0 ( .clk(clk), .if_imem_addr_IF(if_imem_addr_IF), .imem_id_instr_ID(imem_id_instr_ID) diff --git a/core/tb/core_tb_imem.sv b/core/tb/core_tb_imem.sv index e66af29..6d3fa92 100644 --- a/core/tb/core_tb_imem.sv +++ b/core/tb/core_tb_imem.sv @@ -1,15 +1,15 @@ module core_tb_imem #( - parameter ADDR_WIDTH = 64 + parameter ADDR_WIDTH = 32 ) ( input logic clk, // Fetch Interface - input logic [63:0] if_imem_addr_IF, + input logic [31:0] if_imem_addr_IF, // Decode Interface - output logic [63:0] imem_id_instr_ID + output logic [31:0] imem_id_instr_ID ); int assembly_file; @@ -17,10 +17,11 @@ int status_file; int error_file; string error_message_file; -logic [63:0] imem [(1<<(ADDR_WIDTH))-1:0]; +logic [7:0] imem [0:(1<<(ADDR_WIDTH))-1]; +// Fill up memory using the $fopen and $fread syscalls initial begin - assembly_file = $fopen("/home/joshua/Personal/riscv_linux/core/tb/riscv_arithmetic_basic_test_0.bin", "rb"); + assembly_file = $fopen("/home/joshua/Personal/riscv-linux/core/tb/riscv_arithmetic_basic_test_0.bin", "rb"); status_file = $fread( imem, assembly_file ); if (status_file == 0) begin $ferror( assembly_file, error_message_file ); @@ -29,8 +30,12 @@ initial begin $display("Memory Contents Initialized"); end +// Memory reads, TODO: Should we add a RMASK always_ff @ (posedge clk) begin - imem_id_instr_ID <= imem[if_imem_addr_IF[ADDR_WIDTH-1:0]]; + imem_id_instr_ID[7:0] <= imem[if_imem_addr_IF[ADDR_WIDTH-1:0]+0]; // 4 bytes read into a single word in RISC-V + imem_id_instr_ID[15:8] <= imem[if_imem_addr_IF[ADDR_WIDTH-1:0]+1]; // 4 bytes read into a single word in RISC-V + imem_id_instr_ID[23:16] <= imem[if_imem_addr_IF[ADDR_WIDTH-1:0]+2]; // 4 bytes read into a single word in RISC-V + imem_id_instr_ID[31:24] <= imem[if_imem_addr_IF[ADDR_WIDTH-1:0]+3]; // 4 bytes read into a single word in RISC-V end endmodule diff --git a/primitives/rtl/AFFR.sv b/primitives/rtl/AFFR.sv index 012717d..0be8444 100644 --- a/primitives/rtl/AFFR.sv +++ b/primitives/rtl/AFFR.sv @@ -1,8 +1,8 @@ // AFFR # ( .WIDTH/.DTYPE() ) ff_ ( .q(), .d(), .en(), .clk() , .rst_l ); module AFFR #( - parameter WIDTH = 1, - parameter type DTYPE = logic [WIDTH-1:0], + parameter WIDTH = 1, + parameter type DTYPE = logic [WIDTH-1:0], parameter logic [$bits(DTYPE)-1:0] RST_VALUE = '0 ) ( |