aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorJoshua Yun <joshua@joshuayun.com>2025-03-15 23:09:39 -0500
committerJoshua Yun <joshua@joshuayun.com>2025-03-15 23:09:39 -0500
commit6bd9f4f7ab48576d3fda98bef915162a7436866d (patch)
treea0af72467af1020f9e492b177e2d95ed8998d1dc /core
parent59fd8c25ee1452452cb564d6fe4163b7a9394aef (diff)
downloadriscv-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
Diffstat (limited to 'core')
-rw-r--r--core/cpu.core3
-rw-r--r--core/pkg/riscv_types.sv14
-rw-r--r--core/rtl/core.sv13
-rw-r--r--core/rtl/decode.sv34
-rw-r--r--core/rtl/fetch.sv14
-rw-r--r--core/tb/.gitignore3
-rw-r--r--core/tb/core_tb.sv31
-rw-r--r--core/tb/core_tb_imem.sv17
8 files changed, 102 insertions, 27 deletions
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