M programs/start.S => programs/start.S +2 -1
@@ 2,7 2,8 @@
.text
_start:
- addi sp, x0, 127
+ addi sp, x0, 124
call main
_loop:
+ ebreak
j _loop
M src/cpu.sv => src/cpu.sv +19 -3
@@ 12,7 12,7 @@ module cpu(
output [31:0] memory_address,
input [31:0] memory_out,
output reg [31:0] memory_write,
- output memory_mask_t memory_mask,
+ output [3:0] memory_byte_enable,
output reg memory_we
);
parameter WIDTH = 32;
@@ 41,6 41,8 @@ module cpu(
wire memory_sign_extension;
+ memory_mask_t memory_mask;
+
function bit[31:0] mem_sext_maybe;
input [31:0] num;
input memory_mask_t mask;
@@ 55,7 57,20 @@ module cpu(
end
endfunction
- assign memory_write = mem_sext_maybe(.num(reg_rd2), .mask(memory_mask), .sext(memory_sign_extension));
+ function bit[3:0] mask_to_mask_bytes;
+ input memory_mask_t mask;
+ begin
+ case(mask)
+ MEM_BYTE: return 4'b0001;
+ MEM_HALFWORD: return 4'b0011;
+ MEM_WORD: return 4'b1111;
+ default: return 0;
+ endcase
+ end
+ endfunction
+
+ assign memory_byte_enable = mask_to_mask_bytes(.mask(memory_mask)) << memory_address[1:0];
+ assign memory_write = reg_rd2 << (8*memory_address[1:0]);
assign memory_address = alu_out;
// alu source 1
@@ 89,11 104,12 @@ module cpu(
end
// register file write source
+ // TODO forwarding pipelined, split to two instead
always_comb begin
case (reg_write_src)
RD_ALU : reg_write = alu_out;
RD_PC_PLUS : reg_write = pc + 4;
- RD_MEMORY : reg_write = mem_sext_maybe(.num(memory_out), .mask(memory_mask), .sext(memory_sign_extension));
+ RD_MEMORY : reg_write = mem_sext_maybe(.num(memory_out >> (8*memory_address[1:0])), .mask(memory_mask), .sext(memory_sign_extension));
default : ;
endcase
end
M src/ram.sv => src/ram.sv +16 -12
@@ 3,21 3,25 @@ import cpu_types::*;
module ram (
input clk, we,
input [31:0] a, wd,
- input memory_mask_t mask,
+ input [3:0] write_byte_enable,
output [31:0] rd);
- reg [4095:0] RAM;
+ reg [31:0] mask;
+ reg [31:0] memory[128];
- assign rd = RAM[(a[11:0] * 8) +:32]; // word aligned
+ assign rd = memory[a[8:2]]; // word aligned
- always @(posedge clk)
- if(we) begin
- case(mask)
- MEM_BYTE: RAM[(a[11:0] * 8) +:8] <= wd[7:0];
- MEM_HALFWORD: RAM[(a[11:0] * 8) +:16] <= wd[15:0];
- MEM_WORD: RAM[(a[11:0] * 8) +:32] <= wd[31:0];
- default: ;
- endcase
- end
+ always_comb begin
+ mask = {
+ {8{write_byte_enable[3]}},
+ {8{write_byte_enable[2]}},
+ {8{write_byte_enable[1]}},
+ {8{write_byte_enable[0]}}
+ };
+ end
+
+ always_ff @ (posedge clk)
+ if(we)
+ memory[a[8:2]] = (rd & ~mask) | (wd & mask);
endmodule
M testbench/tb_cpu_add.sv => testbench/tb_cpu_add.sv +3 -4
@@ 5,10 5,9 @@ module tb_cpu_add();
reg clk, rst_n;
wire [31:0] memory_address, memory_write, memory_out;
+ wire [3:0] memory_write_byte_enable;
wire memory_we;
- memory_mask_t memory_mask;
-
wire [31:0] pc;
reg [31:0] instruction;
@@ 22,14 21,14 @@ module tb_cpu_add();
.memory_address(memory_address),
.memory_out(memory_out),
.memory_write(memory_write),
- .memory_mask(memory_mask),
+ .memory_byte_enable(memory_write_byte_enable),
.memory_we(memory_we)
);
ram memory_inst(
.clk(clk),
.a(memory_address),
- .mask(memory_mask),
+ .write_byte_enable(memory_write_byte_enable),
.we(memory_we),
.wd(memory_write),
.rd(memory_out)
M testbench/tb_cpu_branches.sv => testbench/tb_cpu_branches.sv +3 -4
@@ 4,10 4,9 @@ module tb_cpu_branches();
reg clk, rst_n;
wire [31:0] memory_address, memory_write, memory_out;
+ wire [3:0] memory_write_byte_enable;
wire memory_we;
- memory_mask_t memory_mask;
-
wire [31:0] pc;
reg [31:0] instruction;
@@ 21,14 20,14 @@ module tb_cpu_branches();
.memory_address(memory_address),
.memory_out(memory_out),
.memory_write(memory_write),
- .memory_mask(memory_mask),
+ .memory_byte_enable(memory_write_byte_enable),
.memory_we(memory_we)
);
ram memory_inst(
.clk(clk),
.a(memory_address),
- .mask(memory_mask),
+ .write_byte_enable(memory_write_byte_enable),
.we(memory_we),
.wd(memory_write),
.rd(memory_out)
M testbench/tb_cpu_gcd.sv => testbench/tb_cpu_gcd.sv +3 -4
@@ 4,10 4,9 @@ module tb_cpu_gcd();
reg clk, rst_n;
wire [31:0] memory_address, memory_write, memory_out;
+ wire [3:0] memory_write_byte_enable;
wire memory_we;
- memory_mask_t memory_mask;
-
wire [31:0] pc;
reg [31:0] instruction;
@@ 21,14 20,14 @@ module tb_cpu_gcd();
.memory_address(memory_address),
.memory_out(memory_out),
.memory_write(memory_write),
- .memory_mask(memory_mask),
+ .memory_byte_enable(memory_write_byte_enable),
.memory_we(memory_we)
);
ram memory_inst(
.clk(clk),
.a(memory_address),
- .mask(memory_mask),
+ .write_byte_enable(memory_write_byte_enable),
.we(memory_we),
.wd(memory_write),
.rd(memory_out)
M testbench/tb_cpu_simple.sv => testbench/tb_cpu_simple.sv +3 -4
@@ 5,10 5,9 @@ module tb_cpu_simple();
reg clk, rst_n;
wire [31:0] memory_address, memory_write, memory_out;
+ wire [3:0] memory_write_byte_enable;
wire memory_we;
- memory_mask_t memory_mask;
-
wire [31:0] pc;
reg [31:0] instruction;
@@ 22,14 21,14 @@ module tb_cpu_simple();
.memory_address(memory_address),
.memory_out(memory_out),
.memory_write(memory_write),
- .memory_mask(memory_mask),
+ .memory_byte_enable(memory_write_byte_enable),
.memory_we(memory_we)
);
ram memory_inst(
.clk(clk),
.a(memory_address),
- .mask(memory_mask),
+ .write_byte_enable(memory_write_byte_enable),
.we(memory_we),
.wd(memory_write),
.rd(memory_out)
M testbench/tb_cpu_tests.sv => testbench/tb_cpu_tests.sv +3 -4
@@ 4,10 4,9 @@ module tb_cpu_tests();
reg clk, rst_n;
wire [31:0] memory_address, memory_write, memory_out;
+ wire [3:0] memory_write_byte_enable;
wire memory_we;
- memory_mask_t memory_mask;
-
wire [31:0] pc;
reg [31:0] instruction;
@@ 21,14 20,14 @@ module tb_cpu_tests();
.memory_address(memory_address),
.memory_out(memory_out),
.memory_write(memory_write),
- .memory_mask(memory_mask),
+ .memory_byte_enable(memory_write_byte_enable),
.memory_we(memory_we)
);
ram memory_inst(
.clk(clk),
.a(memory_address),
- .mask(memory_mask),
+ .write_byte_enable(memory_write_byte_enable),
.we(memory_we),
.wd(memory_write),
.rd(memory_out)