Refine memory interface. Change start addr from 10000 to 0.

This commit is contained in:
colin.liang 2023-01-18 21:04:15 +08:00
parent 780c18e008
commit f6b14b047b
5 changed files with 33 additions and 79 deletions

View File

@ -85,6 +85,7 @@ build/dhry.hex: build/dhry.elf
build/dhry.elf: $(DHRY_OBJS) build/dhry.elf: $(DHRY_OBJS)
$(TOOLCHAIN_PREFIX)gcc $(CFLAGS) -Wl,-Bstatic,-T,firmware/riscv.ld,-Map,build/dhry.map,--strip-debug -o $@ $(DHRY_OBJS) -lgcc -lc $(TOOLCHAIN_PREFIX)gcc $(CFLAGS) -Wl,-Bstatic,-T,firmware/riscv.ld,-Map,build/dhry.map,--strip-debug -o $@ $(DHRY_OBJS) -lgcc -lc
$(TOOLCHAIN_PREFIX)objdump -S $@ > build/dhry.dis
chmod -x $@ chmod -x $@
build/dhry_1.o: dhrystone/dhry_1.c build/dhry_1.o: dhrystone/dhry_1.c

View File

@ -10,7 +10,7 @@ OUTPUT_ARCH(riscv)
ENTRY(_start) ENTRY(_start)
SECTIONS SECTIONS
{ {
. = 0x00010000; . = 0x00000000;
.text : .text :
{ {
*(.text) *(.text)

View File

@ -15,7 +15,7 @@ MEMORY {
SECTIONS { SECTIONS {
.memory : { .memory : {
. = 0x10000; . = 0x00000;
start*(.text); start*(.text);
*(.text); *(.text);
*(*); *(*);

View File

@ -39,13 +39,7 @@ module picorv32 #(
input resetn, input resetn,
output reg trap, output reg trap,
output reg mem_valid, input [31:0] mem_la_rdata,
input mem_ready,
output [31:0] mem_addr,
output [31:0] mem_wdata,
output [ 3:0] mem_wstrb,
input [31:0] mem_rdata,
// Look-Ahead Interface // Look-Ahead Interface
output mem_la_read, output mem_la_read,
@ -87,11 +81,11 @@ module picorv32 #(
assign mem_la_addr = (mem_do_prefetch || mem_do_r_inst) ? {next_pc[31:2], 2'b00} : {reg_op1[31:2], 2'b00}; assign mem_la_addr = (mem_do_prefetch || mem_do_r_inst) ? {next_pc[31:2], 2'b00} : {reg_op1[31:2], 2'b00};
wire [31:0] mem_rdata_latched; wire [31:0] mem_rdata_latched;
assign mem_rdata_latched = mem_xfer ? mem_rdata : mem_rdata_q; assign mem_rdata_latched = mem_xfer ? mem_la_rdata : mem_rdata_q;
always @(posedge clk) begin always @(posedge clk) begin
if (mem_xfer) begin if (mem_xfer) begin
mem_rdata_q <= mem_rdata; mem_rdata_q <= mem_la_rdata;
end end
end end
@ -101,24 +95,24 @@ module picorv32 #(
0: begin 0: begin
mem_la_wdata = reg_op2; mem_la_wdata = reg_op2;
mem_la_wstrb = 4'b1111; mem_la_wstrb = 4'b1111;
mem_rdata_word = mem_rdata; mem_rdata_word = mem_la_rdata;
end end
1: begin 1: begin
mem_la_wdata = {2{reg_op2[15:0]}}; mem_la_wdata = {2{reg_op2[15:0]}};
mem_la_wstrb = reg_op1[1] ? 4'b1100 : 4'b0011; mem_la_wstrb = reg_op1[1] ? 4'b1100 : 4'b0011;
case (reg_op1[1]) case (reg_op1[1])
1'b0: mem_rdata_word = {16'b0, mem_rdata[15:0]}; 1'b0: mem_rdata_word = {16'b0, mem_la_rdata[15:0]};
1'b1: mem_rdata_word = {16'b0, mem_rdata[31:16]}; 1'b1: mem_rdata_word = {16'b0, mem_la_rdata[31:16]};
endcase endcase
end end
2: begin 2: begin
mem_la_wdata = {4{reg_op2[7:0]}}; mem_la_wdata = {4{reg_op2[7:0]}};
mem_la_wstrb = 4'b0001 << reg_op1[1:0]; mem_la_wstrb = 4'b0001 << reg_op1[1:0];
case (reg_op1[1:0]) case (reg_op1[1:0])
2'b00: mem_rdata_word = {24'b0, mem_rdata[7:0]}; 2'b00: mem_rdata_word = {24'b0, mem_la_rdata[7:0]};
2'b01: mem_rdata_word = {24'b0, mem_rdata[15:8]}; 2'b01: mem_rdata_word = {24'b0, mem_la_rdata[15:8]};
2'b10: mem_rdata_word = {24'b0, mem_rdata[23:16]}; 2'b10: mem_rdata_word = {24'b0, mem_la_rdata[23:16]};
2'b11: mem_rdata_word = {24'b0, mem_rdata[31:24]}; 2'b11: mem_rdata_word = {24'b0, mem_la_rdata[31:24]};
endcase endcase
end end
endcase endcase
@ -135,14 +129,9 @@ module picorv32 #(
.resetn(resetn), .resetn(resetn),
.trap(trap), .trap(trap),
.mem_valid(mem_valid), .mem_xfer(mem_xfer),
.mem_ready(mem_ready),
.mem_xfer (mem_xfer),
.mem_addr (mem_addr), .mem_la_rdata(mem_la_rdata),
.mem_wdata(mem_wdata),
.mem_wstrb(mem_wstrb),
.mem_rdata(mem_rdata),
.mem_la_read (mem_la_read), .mem_la_read (mem_la_read),
.mem_la_write(mem_la_write), .mem_la_write(mem_la_write),
@ -1077,23 +1066,16 @@ module picorv32_memory (
input resetn, input resetn,
input trap, input trap,
output reg mem_valid,
input mem_ready,
output reg mem_xfer, output reg mem_xfer,
output reg [31:0] mem_addr,
output reg [31:0] mem_wdata,
output reg [ 3:0] mem_wstrb,
input [31:0] mem_rdata,
// Look-Ahead Interface // Look-Ahead Interface
output mem_la_read, output mem_la_read,
output mem_la_write, output mem_la_write,
input [31:0] mem_la_addr, input [31:0] mem_la_addr,
input [31:0] mem_la_wdata, input [31:0] mem_la_wdata,
input [31:0] mem_la_rdata,
input [ 3:0] mem_la_wstrb, input [ 3:0] mem_la_wstrb,
input mem_do_prefetch, input mem_do_prefetch,
input mem_do_r_inst, input mem_do_r_inst,
input mem_do_rdata, input mem_do_rdata,
@ -1110,15 +1092,9 @@ module picorv32_memory (
reg [1:0] mem_state; reg [1:0] mem_state;
reg last_mem_valid; reg last_mem_valid;
reg [15:0] mem_16bit_buffer;
reg mem_instr; reg mem_instr;
assign mem_xfer = mem_valid && mem_ready;
wire mem_busy = |{mem_do_prefetch, mem_do_r_inst, mem_do_rdata, mem_do_wdata};
assign mem_done = resetn && ((mem_xfer && |mem_state && (mem_do_r_inst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_r_inst)); assign mem_done = resetn && ((mem_xfer && |mem_state && (mem_do_r_inst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_r_inst));
assign mem_la_write = resetn && !mem_state && mem_do_wdata; assign mem_la_write = resetn && !mem_state && mem_do_wdata;
assign mem_la_read = resetn && ((!mem_state && (mem_do_r_inst || mem_do_prefetch || mem_do_rdata))); assign mem_la_read = resetn && ((!mem_state && (mem_do_r_inst || mem_do_prefetch || mem_do_rdata)));
@ -1126,7 +1102,7 @@ module picorv32_memory (
if (!resetn) begin if (!resetn) begin
last_mem_valid <= 0; last_mem_valid <= 0;
end else begin end else begin
if (!last_mem_valid) last_mem_valid <= mem_valid && !mem_ready; if (!last_mem_valid) last_mem_valid <= 0;
end end
end end
@ -1145,56 +1121,45 @@ module picorv32_memory (
`assert(!(mem_do_prefetch || mem_do_r_inst || mem_do_rdata)); `assert(!(mem_do_prefetch || mem_do_r_inst || mem_do_rdata));
if (mem_state == 2 || mem_state == 3) if (mem_state == 2 || mem_state == 3)
`assert(mem_valid || mem_do_prefetch); `assert(mem_xfer || mem_do_prefetch);
end end
end end
always @(posedge clk) begin always @(posedge clk) begin
if (!resetn || trap) begin if (!resetn || trap) begin
if (!resetn) mem_state <= 0; if (!resetn) mem_state <= 0;
if (!resetn || mem_ready) mem_valid <= 0; mem_xfer <= 0;
end else begin end else begin
if (mem_la_read || mem_la_write) begin
mem_addr <= mem_la_addr;
mem_wstrb <= mem_la_wstrb & {4{mem_la_write}};
end
if (mem_la_write) begin
mem_wdata <= mem_la_wdata;
end
case (mem_state) case (mem_state)
0: begin 0: begin
if (mem_do_prefetch || mem_do_r_inst || mem_do_rdata) begin if (mem_do_prefetch || mem_do_r_inst || mem_do_rdata) begin
mem_valid <= 1; mem_xfer <= 1;
mem_instr <= mem_do_prefetch || mem_do_r_inst; mem_instr <= mem_do_prefetch || mem_do_r_inst;
mem_wstrb <= 0;
mem_state <= 1; mem_state <= 1;
end end
if (mem_do_wdata) begin if (mem_do_wdata) begin
mem_valid <= 1; mem_xfer <= 1;
mem_instr <= 0; mem_instr <= 0;
mem_state <= 2; mem_state <= 2;
end end
end end
1: begin 1: begin
`assert(mem_wstrb == 0);
`assert(mem_do_prefetch || mem_do_r_inst || mem_do_rdata); `assert(mem_do_prefetch || mem_do_r_inst || mem_do_rdata);
`assert(mem_valid == 1); `assert(mem_xfer == 1);
`assert(mem_instr == (mem_do_prefetch || mem_do_r_inst)); `assert(mem_instr == (mem_do_prefetch || mem_do_r_inst));
if (mem_xfer) begin if (mem_xfer) begin
mem_valid <= 0; mem_xfer <= 0;
mem_state <= mem_do_r_inst || mem_do_rdata ? 0 : 3; mem_state <= mem_do_r_inst || mem_do_rdata ? 0 : 3;
end end
end end
2: begin 2: begin
`assert(mem_wstrb != 0);
`assert(mem_do_wdata); `assert(mem_do_wdata);
if (mem_xfer) begin if (mem_xfer) begin
mem_valid <= 0; mem_xfer <= 0;
mem_state <= 0; mem_state <= 0;
end end
end end
3: begin 3: begin
`assert(mem_wstrb == 0);
`assert(mem_do_prefetch); `assert(mem_do_prefetch);
if (mem_do_r_inst) begin if (mem_do_r_inst) begin
mem_state <= 0; mem_state <= 0;

View File

@ -60,17 +60,13 @@ module picorv32_wb #(
input rst, input rst,
input clk input clk
); );
wire mem_valid;
wire [31:0] mem_addr;
wire [31:0] mem_wdata;
wire [ 3:0] mem_wstrb;
reg mem_ready;
reg [31:0] mem_rdata;
wire mem_la_read; wire mem_la_read;
wire mem_la_write; wire mem_la_write;
wire [31:0] mem_la_addr; wire [31:0] mem_la_addr;
wire [31:0] mem_la_wdata; wire [31:0] mem_la_wdata;
reg [31:0] mem_la_rdata;
wire [ 3:0] mem_la_wstrb; wire [ 3:0] mem_la_wstrb;
wire resetn; wire resetn;
@ -79,32 +75,24 @@ module picorv32_wb #(
assign resetn = ~rst; assign resetn = ~rst;
picorv32 #( picorv32 #(
.PROGADDR_RESET(32'h0001_0000), .PROGADDR_RESET(32'h0000_0000),
.STACKADDR(32'h0001_0000) .STACKADDR(32'h0004_0000)
) picorv32_core ( ) picorv32_core (
.clk (clk), .clk (clk),
.resetn(resetn), .resetn(resetn),
.trap (trap), .trap (trap),
.mem_valid (mem_valid),
.mem_ready (mem_ready),
.mem_addr (mem_addr),
.mem_wdata (mem_wdata),
.mem_wstrb (mem_wstrb),
.mem_rdata (mem_rdata),
.mem_la_read (mem_la_read), .mem_la_read (mem_la_read),
.mem_la_write(mem_la_write), .mem_la_write(mem_la_write),
.mem_la_addr (mem_la_addr), .mem_la_addr (mem_la_addr),
.mem_la_wdata(mem_la_wdata), .mem_la_wdata(mem_la_wdata),
.mem_la_rdata(mem_la_rdata),
.mem_la_wstrb(mem_la_wstrb) .mem_la_wstrb(mem_la_wstrb)
); );
reg [7:0] memory[0:256*1024-1]; reg [7:0] memory[0:256*1024-1];
assign mem_ready = 1;
integer fconsole, fif; integer fconsole, fif;
initial begin initial begin
fconsole = $fopen("console.log", "w"); fconsole = $fopen("console.log", "w");
@ -112,10 +100,10 @@ module picorv32_wb #(
end end
always @(posedge clk) begin always @(posedge clk) begin
mem_rdata[7:0] <= mem_la_read ? memory[mem_la_addr+0] : 'bx; mem_la_rdata[7:0] <= mem_la_read ? memory[mem_la_addr+0] : 'bx;
mem_rdata[15:8] <= mem_la_read ? memory[mem_la_addr+1] : 'bx; mem_la_rdata[15:8] <= mem_la_read ? memory[mem_la_addr+1] : 'bx;
mem_rdata[23:16] <= mem_la_read ? memory[mem_la_addr+2] : 'bx; mem_la_rdata[23:16] <= mem_la_read ? memory[mem_la_addr+2] : 'bx;
mem_rdata[31:24] <= mem_la_read ? memory[mem_la_addr+3] : 'bx; mem_la_rdata[31:24] <= mem_la_read ? memory[mem_la_addr+3] : 'bx;
if (mem_la_write) begin if (mem_la_write) begin
case (mem_la_addr) case (mem_la_addr)
32'h1000_0000: begin 32'h1000_0000: begin