Add memory bus and move data memory to a separate module
This commit is contained in:
parent
03ecd3a97d
commit
018faac560
4 changed files with 156 additions and 71 deletions
36
ram.sv
Normal file
36
ram.sv
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
`ifndef RAM
|
||||
`define RAM
|
||||
|
||||
module ram (
|
||||
input clk,
|
||||
|
||||
/* control in */
|
||||
input [3:0] write_mask_in,
|
||||
|
||||
/* data in */
|
||||
input [31:0] address_in,
|
||||
input [31:0] write_value_in,
|
||||
|
||||
/* data out */
|
||||
output [31:0] read_value_out
|
||||
);
|
||||
logic [31:0] mem [255:0];
|
||||
|
||||
always_ff @(negedge clk) begin
|
||||
read_value_out <= mem[address_in[31:2]];
|
||||
|
||||
if (write_mask_in[3])
|
||||
mem[address_in[31:2]][31:24] <= write_value_in[31:24];
|
||||
|
||||
if (write_mask_in[2])
|
||||
mem[address_in[31:2]][23:16] <= write_value_in[23:16];
|
||||
|
||||
if (write_mask_in[1])
|
||||
mem[address_in[31:2]][15:8] <= write_value_in[15:8];
|
||||
|
||||
if (write_mask_in[0])
|
||||
mem[address_in[31:2]][7:0] <= write_value_in[7:0];
|
||||
end
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
24
rv32.sv
24
rv32.sv
|
|
@ -9,7 +9,17 @@
|
|||
|
||||
module rv32 (
|
||||
input clk,
|
||||
output [7:0] leds
|
||||
output [7:0] leds,
|
||||
|
||||
/* control out (memory bus) */
|
||||
output [3:0] write_mask_out,
|
||||
|
||||
/* data in (memory bus) */
|
||||
input [31:0] read_value_in,
|
||||
|
||||
/* data out (memory bus) */
|
||||
output [31:0] address_out,
|
||||
output [31:0] write_value_out
|
||||
);
|
||||
always_ff @(posedge clk) begin
|
||||
if (mem_rd_writeback && mem_rd == 31)
|
||||
|
|
@ -236,14 +246,24 @@ module rv32 (
|
|||
.rs2_value_in(execute_rs2_value),
|
||||
.branch_pc_in(execute_branch_pc),
|
||||
|
||||
/* data in (from memory bus) */
|
||||
.read_value_in(read_value_in),
|
||||
|
||||
/* control out */
|
||||
.branch_taken_out(mem_branch_taken),
|
||||
.rd_out(mem_rd),
|
||||
.rd_writeback_out(mem_rd_writeback),
|
||||
|
||||
/* control out (to memory bus) */
|
||||
.write_mask_out(write_mask_out),
|
||||
|
||||
/* data out */
|
||||
.rd_value_out(mem_rd_value),
|
||||
.branch_pc_out(mem_branch_pc)
|
||||
.branch_pc_out(mem_branch_pc),
|
||||
|
||||
/* data out (to memory bus) */
|
||||
.address_out(address_out),
|
||||
.write_value_out(write_value_out)
|
||||
);
|
||||
|
||||
/* mem -> writeback control */
|
||||
|
|
|
|||
132
rv32_mem.sv
132
rv32_mem.sv
|
|
@ -28,17 +28,25 @@ module rv32_mem (
|
|||
input [31:0] rs2_value_in,
|
||||
input [31:0] branch_pc_in,
|
||||
|
||||
/* data in (from memory bus) */
|
||||
input [31:0] read_value_in,
|
||||
|
||||
/* control out */
|
||||
output branch_taken_out,
|
||||
output [4:0] rd_out,
|
||||
output rd_writeback_out,
|
||||
|
||||
/* control out (to memory bus) */
|
||||
output [3:0] write_mask_out,
|
||||
|
||||
/* data out */
|
||||
output [31:0] rd_value_out,
|
||||
output [31:0] branch_pc_out
|
||||
);
|
||||
logic [31:0] data_mem [255:0];
|
||||
output [31:0] branch_pc_out,
|
||||
|
||||
/* data out (to memory bus) */
|
||||
output [31:0] address_out,
|
||||
output [31:0] write_value_out
|
||||
);
|
||||
rv32_branch branch (
|
||||
/* control in */
|
||||
.op_in(branch_op_in),
|
||||
|
|
@ -52,67 +60,55 @@ 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;
|
||||
assign address_out = result_in;
|
||||
|
||||
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) 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];
|
||||
case (width_in)
|
||||
RV32_MEM_WIDTH_WORD: begin
|
||||
write_value_out = rs2_value_in;
|
||||
write_mask_out = 4'b1111;
|
||||
end
|
||||
RV32_MEM_WIDTH_HALF: begin
|
||||
case (result_in[0])
|
||||
2'b0: begin
|
||||
write_value_out = {rs2_value_in[15:0], 16'bx};
|
||||
write_mask_out = 4'b1100;
|
||||
end
|
||||
2'b1: begin
|
||||
write_value_out = {16'bx, rs2_value_in[15:0]};
|
||||
write_mask_out = 4'b0011;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
RV32_MEM_WIDTH_BYTE: begin
|
||||
case (result_in[1:0])
|
||||
2'b00: begin
|
||||
write_value_out = {rs2_value_in[7:0], 24'bx};
|
||||
write_mask_out = 4'b1000;
|
||||
end
|
||||
2'b01: begin
|
||||
write_value_out = {8'bx, rs2_value_in[7:0], 16'bx};
|
||||
write_mask_out = 4'b0100;
|
||||
end
|
||||
2'b10: begin
|
||||
write_value_out = {16'bx, rs2_value_in[7:0], 8'bx};
|
||||
write_mask_out = 4'b0010;
|
||||
end
|
||||
2'b11: begin
|
||||
write_value_out = {24'bx, rs2_value_in[7:0]};
|
||||
write_mask_out = 4'b0001;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
default: begin
|
||||
write_value_out = 32'bx;
|
||||
write_mask_out = 4'bx;
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
write_value_out = 32'bx;
|
||||
write_mask_out = 4'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -124,20 +120,20 @@ module rv32_mem (
|
|||
if (read_en_in) begin
|
||||
case (width_in)
|
||||
RV32_MEM_WIDTH_WORD: begin
|
||||
rd_value_out <= read_value;
|
||||
rd_value_out <= read_value_in;
|
||||
end
|
||||
RV32_MEM_WIDTH_HALF: begin
|
||||
case (result_in[0])
|
||||
1'b0: rd_value_out <= {{16{zero_extend_in ? 1'b0 : read_value[31]}}, read_value[31:16]};
|
||||
1'b1: rd_value_out <= {{16{zero_extend_in ? 1'b0 : read_value[15]}}, read_value[15:0]};
|
||||
1'b0: rd_value_out <= {{16{zero_extend_in ? 1'b0 : read_value_in[31]}}, read_value_in[31:16]};
|
||||
1'b1: rd_value_out <= {{16{zero_extend_in ? 1'b0 : read_value_in[15]}}, read_value_in[15:0]};
|
||||
endcase
|
||||
end
|
||||
RV32_MEM_WIDTH_BYTE: begin
|
||||
case (result_in[1:0])
|
||||
2'b00: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[31]}}, read_value[31:24]};
|
||||
2'b01: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[23]}}, read_value[23:16]};
|
||||
2'b10: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[15]}}, read_value[15:8]};
|
||||
2'b11: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[7]}}, read_value[7:0]};
|
||||
2'b00: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value_in[31]}}, read_value_in[31:24]};
|
||||
2'b01: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value_in[23]}}, read_value_in[23:16]};
|
||||
2'b10: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value_in[15]}}, read_value_in[15:8]};
|
||||
2'b11: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value_in[7]}}, read_value_in[7:0]};
|
||||
endcase
|
||||
end
|
||||
default: begin
|
||||
|
|
|
|||
35
top.sv
35
top.sv
|
|
@ -1,4 +1,5 @@
|
|||
`include "clk_div.sv"
|
||||
`include "ram.sv"
|
||||
`include "rv32.sv"
|
||||
|
||||
module top (
|
||||
|
|
@ -45,6 +46,38 @@ module top (
|
|||
|
||||
rv32 rv32 (
|
||||
.clk(clk_slow),
|
||||
.leds(leds)
|
||||
.leds(leds),
|
||||
|
||||
/* control out */
|
||||
.write_mask_out(mem_write_mask),
|
||||
|
||||
/* data in */
|
||||
.read_value_in(mem_read_value),
|
||||
|
||||
/* data out */
|
||||
.address_out(mem_address),
|
||||
.write_value_out(mem_write_value)
|
||||
);
|
||||
|
||||
/* memory bus control */
|
||||
logic [3:0] mem_write_mask;
|
||||
|
||||
/* memory bus data */
|
||||
logic [31:0] mem_address;
|
||||
logic [31:0] mem_read_value;
|
||||
logic [31:0] mem_write_value;
|
||||
|
||||
ram ram (
|
||||
.clk(clk_slow),
|
||||
|
||||
/* control in */
|
||||
.write_mask_in(mem_write_mask),
|
||||
|
||||
/* data in */
|
||||
.address_in(mem_address),
|
||||
.write_value_in(mem_write_value),
|
||||
|
||||
/* data out */
|
||||
.read_value_out(mem_read_value)
|
||||
);
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in a new issue