aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavian Kaufmann <flavian@flaviankaufmann.ch>2024-05-23 08:20:16 +0200
committerFlavian Kaufmann <flavian@flaviankaufmann.ch>2024-05-23 08:20:16 +0200
commit6a9573628b3c7e537bd273a483be9abcfa2ee429 (patch)
treeacc804258af80527e3f606b709cb2fe8e36593a9
parentc6e342f93d1a7fe92d2a7e1b4e488f328e1f4469 (diff)
downloadriscv_cpu-6a9573628b3c7e537bd273a483be9abcfa2ee429.tar.gz
riscv_cpu-6a9573628b3c7e537bd273a483be9abcfa2ee429.zip
mem size
-rw-r--r--rtl/src/control_unit.v4
-rw-r--r--rtl/src/cpu.v3
-rw-r--r--rtl/src/io.v1
-rw-r--r--rtl/src/memory_interface.v4
-rw-r--r--rtl/src/ram.v39
-rw-r--r--rtl/src/rom.v17
6 files changed, 63 insertions, 5 deletions
diff --git a/rtl/src/control_unit.v b/rtl/src/control_unit.v
index 6849214..608f6b1 100644
--- a/rtl/src/control_unit.v
+++ b/rtl/src/control_unit.v
@@ -14,6 +14,7 @@ module control_unit (
output reg mem_addr_src,
output reg mem_we,
+ output reg [2:0] mem_size,
output reg instr_we,
@@ -132,6 +133,7 @@ always @ (*) begin
instr_we = INSTR_WE_DISABLE;
pc_update = PC_UPDATE_DISABLE;
branch = BRANCH_DISABLE;
+ mem_size = FUNCT3_LS_W;
case(state)
STATE_FETCH: begin
mem_addr_src = MEM_ADDR_SRC_PC;
@@ -155,6 +157,7 @@ always @ (*) begin
STATE_MEM_LOAD: begin
mem_addr_src = MEM_ADDR_SRC_RESULT;
result_src = RESULT_SRC_ALU_RESULT_BUF;
+ mem_size = funct3;
end
STATE_MEM_WB: begin
result_src = RESULT_SRC_DATA_BUF;
@@ -164,6 +167,7 @@ always @ (*) begin
mem_addr_src = MEM_ADDR_SRC_RESULT;
result_src = RESULT_SRC_ALU_RESULT_BUF;
mem_we = MEM_WE_ENABLE;
+ mem_size = funct3;
end
STATE_EXECUTE_R: begin
alu_a_src = ALU_A_SRC_RD1_BUF;
diff --git a/rtl/src/cpu.v b/rtl/src/cpu.v
index 5e454fb..a1ccf78 100644
--- a/rtl/src/cpu.v
+++ b/rtl/src/cpu.v
@@ -15,6 +15,7 @@ wire [31:0] mem_addr;
wire mem_addr_src;
wire [31:0] mem_rd;
wire mem_we;
+wire [2:0] mem_size;
wire instr_we;
wire [31:0] instr;
@@ -50,6 +51,7 @@ control_unit control_unit (
.pc_we(pc_we),
.mem_addr_src(mem_addr_src),
.mem_we(mem_we),
+ .mem_size(mem_size),
.instr_we(instr_we),
.result_src(result_src),
.alu_op(alu_op),
@@ -82,6 +84,7 @@ memory_interface memory_interface (
.rstn(rstn),
.we(mem_we),
.addr(mem_addr),
+ .size(mem_size),
.rd(mem_rd),
.wd(rd2_buf),
.io_in(io_in),
diff --git a/rtl/src/io.v b/rtl/src/io.v
index f872b83..90db1ad 100644
--- a/rtl/src/io.v
+++ b/rtl/src/io.v
@@ -7,6 +7,7 @@ module io (
input we,
input [31:0] addr,
+ input [2:0] size,
input [31:0] wd,
output reg [31:0] rd,
diff --git a/rtl/src/memory_interface.v b/rtl/src/memory_interface.v
index 055016e..ebe2f22 100644
--- a/rtl/src/memory_interface.v
+++ b/rtl/src/memory_interface.v
@@ -8,6 +8,7 @@ module memory_interface (
input we,
input [31:0] addr,
input [31:0] wd,
+ input [2:0] size,
output reg [31:0] rd,
@@ -27,6 +28,7 @@ ram #(.SIZE(1024)) ram (
.rstn(rstn),
.we(ram_we),
.addr(rel_addr),
+ .size(size),
.rd(ram_rd),
.wd(wd)
);
@@ -34,6 +36,7 @@ ram #(.SIZE(1024)) ram (
rom #(.SIZE(1024)) rom (
.clk(clk),
.addr(rel_addr),
+ .size(size),
.rd(rom_rd)
);
@@ -42,6 +45,7 @@ io io (
.rstn(rstn),
.we(io_we),
.addr(rel_addr),
+ .size(size),
.rd(io_rd),
.wd(wd),
.io_in(io_in),
diff --git a/rtl/src/ram.v b/rtl/src/ram.v
index c0ec231..323bbdd 100644
--- a/rtl/src/ram.v
+++ b/rtl/src/ram.v
@@ -8,18 +8,49 @@ module ram #(
input rstn,
input we,
input [31:0] addr,
+ input [2:0] size,
input [31:0] wd,
output reg [31:0] rd
);
-`include "include/log2.vh"
+`include "include/consts.vh"
//(* RAM_STYLE="BLOCK" *)
reg [31:0] mem [0:SIZE-1];
-always @(posedge clk) begin
- if (we) mem[addr >> 2] <= wd;
- rd <= mem[addr >> 2];
+wire [31:0] rd_w;
+wire [15:0] rd_h;
+wire [7:0] rd_b;
+assign rd_w = mem[addr >> 2];
+assign rd_h = (mem[addr >> 2] >> (addr[1] * 16)) & 32'hFFFF;
+assign rd_b = (mem[addr >> 2] >> (addr[1:0] * 8)) & 32'hFF;
+
+always @(negedge clk) begin
+ if (we) begin
+ case (size)
+ FUNCT3_LS_W: mem[addr >> 2] <= wd;
+ FUNCT3_LS_H:
+ case (addr[1])
+ 1'b0: mem[addr >> 2][15:0] <= wd[15:0];
+ 1'b1: mem[addr >> 2][31:16] <= wd[15:0];
+ endcase
+ FUNCT3_LS_B:
+ case (addr[1:0])
+ 2'b00: mem[addr >> 2][7:0] <= wd[7:0];
+ 2'b01: mem[addr >> 2][15:8] <= wd[7:0];
+ 2'b10: mem[addr >> 2][23:16] <= wd[7:0];
+ 2'b11: mem[addr >> 2][32:24] <= wd[7:0];
+ endcase
+ endcase
+ end
+ case (size)
+ FUNCT3_LS_W: rd <= rd_w;
+ FUNCT3_LS_H: rd <= { {16{rd_h[15]}}, rd_h };
+ FUNCT3_LS_B: rd <= { {24{rd_b[7]}}, rd_b };
+ FUNCT3_LS_HU: rd <= rd_b;
+ FUNCT3_LS_BU: rd <= rd_h;
+ default: rd <= rd_w;
+ endcase
end
endmodule
diff --git a/rtl/src/rom.v b/rtl/src/rom.v
index 60ca6e1..6cb9a92 100644
--- a/rtl/src/rom.v
+++ b/rtl/src/rom.v
@@ -7,6 +7,7 @@ module rom #(
)(
input clk,
input [31:0] addr,
+ input [2:0] size,
output reg [31:0] rd
);
@@ -21,8 +22,22 @@ initial begin
$readmemh(ROM_FILE, mem, 0, SIZE-1);
end
+wire [31:0] rd_w;
+wire [15:0] rd_h;
+wire [7:0] rd_b;
+assign rd_w = mem[addr >> 2];
+assign rd_h = (mem[addr >> 2] >> (addr[1] * 16)) & 32'hFFFF;
+assign rd_b = (mem[addr >> 2] >> (addr[1:0] * 8)) & 32'hFF;
+
always @ (negedge clk) begin
- rd <= mem[addr >> 2];
+ case (size)
+ FUNCT3_LS_W: rd <= rd_w;
+ FUNCT3_LS_H: rd <= { {16{rd_h[15]}}, rd_h };
+ FUNCT3_LS_B: rd <= { {24{rd_b[7]}}, rd_b };
+ FUNCT3_LS_HU: rd <= rd_b;
+ FUNCT3_LS_BU: rd <= rd_h;
+ default: rd <= rd_w;
+ endcase
end
endmodule