Add LB, LBU, LH, LHU, SB and SH instructions
This commit is contained in:
parent
e2a533babb
commit
871e1f4a32
5 changed files with 125 additions and 3 deletions
12
rv32.sv
12
rv32.sv
|
|
@ -53,6 +53,8 @@ module rv32 (
|
|||
.alu_src2_out(decode_alu_src2),
|
||||
.mem_read_en_out(decode_mem_read_en),
|
||||
.mem_write_en_out(decode_mem_write_en),
|
||||
.mem_width_out(decode_mem_width),
|
||||
.mem_zero_extend_out(decode_mem_zero_extend),
|
||||
.branch_op_out(decode_branch_op),
|
||||
.branch_pc_src_out(decode_branch_pc_src),
|
||||
.rd_out(decode_rd),
|
||||
|
|
@ -72,6 +74,8 @@ module rv32 (
|
|||
logic decode_alu_src2;
|
||||
logic decode_mem_read_en;
|
||||
logic decode_mem_write_en;
|
||||
logic [1:0] decode_mem_width;
|
||||
logic decode_mem_zero_extend;
|
||||
logic [1:0] decode_branch_op;
|
||||
logic decode_branch_pc_src;
|
||||
logic [4:0] decode_rd;
|
||||
|
|
@ -93,6 +97,8 @@ module rv32 (
|
|||
.alu_src2_in(decode_alu_src2),
|
||||
.mem_read_en_in(decode_mem_read_en),
|
||||
.mem_write_en_in(decode_mem_write_en),
|
||||
.mem_width_in(decode_mem_width),
|
||||
.mem_zero_extend_in(decode_mem_zero_extend),
|
||||
.branch_op_in(decode_branch_op),
|
||||
.branch_pc_src_in(decode_branch_pc_src),
|
||||
.rd_in(decode_rd),
|
||||
|
|
@ -107,6 +113,8 @@ module rv32 (
|
|||
/* control out */
|
||||
.mem_read_en_out(execute_mem_read_en),
|
||||
.mem_write_en_out(execute_mem_write_en),
|
||||
.mem_width_out(execute_mem_width),
|
||||
.mem_zero_extend_out(execute_mem_zero_extend),
|
||||
.branch_op_out(execute_branch_op),
|
||||
.rd_out(execute_rd),
|
||||
.rd_writeback_out(execute_rd_writeback),
|
||||
|
|
@ -120,6 +128,8 @@ module rv32 (
|
|||
/* execute -> mem control */
|
||||
logic execute_mem_read_en;
|
||||
logic execute_mem_write_en;
|
||||
logic [1:0] execute_mem_width;
|
||||
logic execute_mem_zero_extend;
|
||||
logic [1:0] execute_branch_op;
|
||||
logic [4:0] execute_rd;
|
||||
logic execute_rd_writeback;
|
||||
|
|
@ -135,6 +145,8 @@ module rv32 (
|
|||
/* control in */
|
||||
.read_en_in(execute_mem_read_en),
|
||||
.write_en_in(execute_mem_write_en),
|
||||
.width_in(execute_mem_width),
|
||||
.zero_extend_in(execute_mem_zero_extend),
|
||||
.branch_op_in(execute_branch_op),
|
||||
.rd_in(execute_rd),
|
||||
.rd_writeback_in(execute_rd_writeback),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
`include "rv32_alu_ops.sv"
|
||||
`include "rv32_branch_ops.sv"
|
||||
`include "rv32_mem_ops.sv"
|
||||
`include "rv32_opcodes.sv"
|
||||
`include "rv32_regs.sv"
|
||||
|
||||
|
|
@ -26,6 +27,8 @@ module rv32_decode (
|
|||
output alu_src2_out,
|
||||
output mem_read_en_out,
|
||||
output mem_write_en_out,
|
||||
output [1:0] mem_width_out,
|
||||
output mem_zero_extend_out,
|
||||
output [1:0] branch_op_out,
|
||||
output branch_pc_src_out,
|
||||
output [4:0] rd_out,
|
||||
|
|
@ -83,6 +86,8 @@ module rv32_decode (
|
|||
rd_writeback_out <= 0;
|
||||
mem_read_en_out <= 0;
|
||||
mem_write_en_out <= 0;
|
||||
mem_width_out <= 2'bx;
|
||||
mem_zero_extend_out <= 1'bx;
|
||||
branch_op_out <= RV32_BRANCH_OP_NEVER;
|
||||
branch_pc_src_out <= 1'bx;
|
||||
imm_out <= 32'bx;
|
||||
|
|
@ -200,6 +205,8 @@ module rv32_decode (
|
|||
alu_src1_out <= RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= RV32_ALU_SRC2_IMM;
|
||||
mem_read_en_out <= 1;
|
||||
mem_width_out <= RV32_MEM_WIDTH_BYTE;
|
||||
mem_zero_extend_out <= 0;
|
||||
rd_writeback_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
|
|
@ -211,6 +218,8 @@ module rv32_decode (
|
|||
alu_src1_out <= RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= RV32_ALU_SRC2_IMM;
|
||||
mem_read_en_out <= 1;
|
||||
mem_width_out <= RV32_MEM_WIDTH_HALF;
|
||||
mem_zero_extend_out <= 0;
|
||||
rd_writeback_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
|
|
@ -222,6 +231,7 @@ module rv32_decode (
|
|||
alu_src1_out <= RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= RV32_ALU_SRC2_IMM;
|
||||
mem_read_en_out <= 1;
|
||||
mem_width_out <= RV32_MEM_WIDTH_WORD;
|
||||
rd_writeback_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
|
|
@ -233,6 +243,8 @@ module rv32_decode (
|
|||
alu_src1_out <= RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= RV32_ALU_SRC2_IMM;
|
||||
mem_read_en_out <= 1;
|
||||
mem_width_out <= RV32_MEM_WIDTH_BYTE;
|
||||
mem_zero_extend_out <= 1;
|
||||
rd_writeback_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
|
|
@ -244,6 +256,8 @@ module rv32_decode (
|
|||
alu_src1_out <= RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= RV32_ALU_SRC2_IMM;
|
||||
mem_read_en_out <= 1;
|
||||
mem_width_out <= RV32_MEM_WIDTH_HALF;
|
||||
mem_zero_extend_out <= 1;
|
||||
rd_writeback_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
|
|
@ -255,6 +269,7 @@ module rv32_decode (
|
|||
alu_src1_out <= RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= RV32_ALU_SRC2_IMM;
|
||||
mem_write_en_out <= 1;
|
||||
mem_width_out <= RV32_MEM_WIDTH_BYTE;
|
||||
imm_out <= imm_s;
|
||||
end
|
||||
{RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SH, RV32_FUNCT7_ANY}: begin
|
||||
|
|
@ -265,6 +280,7 @@ module rv32_decode (
|
|||
alu_src1_out <= RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= RV32_ALU_SRC2_IMM;
|
||||
mem_write_en_out <= 1;
|
||||
mem_width_out <= RV32_MEM_WIDTH_HALF;
|
||||
imm_out <= imm_s;
|
||||
end
|
||||
{RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SW, RV32_FUNCT7_ANY}: begin
|
||||
|
|
@ -275,6 +291,7 @@ module rv32_decode (
|
|||
alu_src1_out <= RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= RV32_ALU_SRC2_IMM;
|
||||
mem_write_en_out <= 1;
|
||||
mem_width_out <= RV32_MEM_WIDTH_WORD;
|
||||
imm_out <= imm_s;
|
||||
end
|
||||
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_ADD_SUB, RV32_FUNCT7_ANY}: begin
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ module rv32_execute (
|
|||
input alu_src2_in,
|
||||
input mem_read_en_in,
|
||||
input mem_write_en_in,
|
||||
input [1:0] mem_width_in,
|
||||
input mem_zero_extend_in,
|
||||
input [1:0] branch_op_in,
|
||||
input branch_pc_src_in,
|
||||
input [4:0] rd_in,
|
||||
|
|
@ -28,6 +30,8 @@ module rv32_execute (
|
|||
/* control out */
|
||||
output mem_read_en_out,
|
||||
output mem_write_en_out,
|
||||
output [1:0] mem_width_out,
|
||||
output mem_zero_extend_out,
|
||||
output [1:0] branch_op_out,
|
||||
output [4:0] rd_out,
|
||||
output rd_writeback_out,
|
||||
|
|
@ -74,6 +78,8 @@ module rv32_execute (
|
|||
always_ff @(posedge clk) begin
|
||||
mem_read_en_out <= mem_read_en_in;
|
||||
mem_write_en_out <= mem_write_en_in;
|
||||
mem_width_out <= mem_width_in;
|
||||
mem_zero_extend_out <= mem_zero_extend_in;
|
||||
branch_op_out <= branch_op_in;
|
||||
rd_out <= rd_in;
|
||||
rd_writeback_out <= rd_writeback_in;
|
||||
|
|
|
|||
85
rv32_mem.sv
85
rv32_mem.sv
|
|
@ -2,6 +2,7 @@
|
|||
`define RV32_MEM
|
||||
|
||||
`include "rv32_branch.sv"
|
||||
`include "rv32_mem_ops.sv"
|
||||
|
||||
module rv32_mem (
|
||||
input clk,
|
||||
|
|
@ -9,6 +10,8 @@ module rv32_mem (
|
|||
/* control in */
|
||||
input read_en_in,
|
||||
input write_en_in,
|
||||
input [1:0] width_in,
|
||||
input zero_extend_in,
|
||||
input [1:0] branch_op_in,
|
||||
input [4:0] rd_in,
|
||||
input rd_writeback_in,
|
||||
|
|
@ -45,12 +48,67 @@ module rv32_mem (
|
|||
assign branch_pc_out = branch_pc_in;
|
||||
|
||||
logic [31:0] read_value;
|
||||
logic [31:0] write_value;
|
||||
logic [3:0] write_mask;
|
||||
|
||||
always_comb begin
|
||||
case (width_in)
|
||||
RV32_MEM_WIDTH_WORD: begin
|
||||
write_value = rs2_value_in;
|
||||
write_mask = 4'b1111;
|
||||
end
|
||||
RV32_MEM_WIDTH_HALF: begin
|
||||
case (result_in[0])
|
||||
2'b0: begin
|
||||
write_value = {rs2_value_in[15:0], 16'bx};
|
||||
write_mask = 4'b1100;
|
||||
end
|
||||
2'b1: begin
|
||||
write_value = {16'bx, rs2_value_in[15:0]};
|
||||
write_mask = 4'b0011;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
RV32_MEM_WIDTH_BYTE: begin
|
||||
case (result_in[1:0])
|
||||
2'b00: begin
|
||||
write_value = {rs2_value_in[7:0], 24'bx};
|
||||
write_mask = 4'b1000;
|
||||
end
|
||||
2'b01: begin
|
||||
write_value = {8'bx, rs2_value_in[7:0], 16'bx};
|
||||
write_mask = 4'b0100;
|
||||
end
|
||||
2'b10: begin
|
||||
write_value = {16'bx, rs2_value_in[7:0], 8'bx};
|
||||
write_mask = 4'b0010;
|
||||
end
|
||||
2'b11: begin
|
||||
write_value = {24'bx, rs2_value_in[7:0]};
|
||||
write_mask = 4'b0001;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
default: begin
|
||||
write_value = 32'bx;
|
||||
write_mask = 4'bx;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(negedge clk) begin
|
||||
read_value <= data_mem[result_in[31:2]];
|
||||
|
||||
if (write_en_in)
|
||||
data_mem[result_in[31:2]] <= rs2_value_in;
|
||||
if (write_en_in) begin
|
||||
if (write_mask[3])
|
||||
data_mem[result_in[31:2]][31:24] <= write_value[31:24];
|
||||
if (write_mask[2])
|
||||
data_mem[result_in[31:2]][23:16] <= write_value[23:16];
|
||||
if (write_mask[1])
|
||||
data_mem[result_in[31:2]][15:8] <= write_value[15:8];
|
||||
if (write_mask[0])
|
||||
data_mem[result_in[31:2]][7:0] <= write_value[7:0];
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
|
|
@ -59,7 +117,28 @@ module rv32_mem (
|
|||
rd_writeback_out <= rd_writeback_in;
|
||||
result_out <= result_in;
|
||||
|
||||
read_value_out <= read_value;
|
||||
case (width_in)
|
||||
RV32_MEM_WIDTH_WORD: begin
|
||||
read_value_out <= read_value;
|
||||
end
|
||||
RV32_MEM_WIDTH_HALF: begin
|
||||
case (result_in[0])
|
||||
1'b0: read_value_out <= {{16{zero_extend_in ? 1'b0 : read_value[31]}}, read_value[31:16]};
|
||||
1'b1: read_value_out <= {{16{zero_extend_in ? 1'b0 : read_value[15]}}, read_value[15:0]};
|
||||
endcase
|
||||
end
|
||||
RV32_MEM_WIDTH_BYTE: begin
|
||||
case (result_in[1:0])
|
||||
2'b00: read_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[31]}}, read_value[31:24]};
|
||||
2'b01: read_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[23]}}, read_value[23:16]};
|
||||
2'b10: read_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[15]}}, read_value[15:8]};
|
||||
2'b11: read_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[7]}}, read_value[7:0]};
|
||||
endcase
|
||||
end
|
||||
default: begin
|
||||
read_value_out <= 32'bx;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
|
|
|||
8
rv32_mem_ops.sv
Normal file
8
rv32_mem_ops.sv
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
`ifndef RV32_MEM_OPS
|
||||
`define RV32_MEM_OPS
|
||||
|
||||
localparam RV32_MEM_WIDTH_WORD = 2'b00;
|
||||
localparam RV32_MEM_WIDTH_HALF = 2'b01;
|
||||
localparam RV32_MEM_WIDTH_BYTE = 2'b10;
|
||||
|
||||
`endif
|
||||
Loading…
Reference in a new issue