aboutsummaryrefslogtreecommitdiffstats
path: root/picorv32.v
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2016-04-11 16:48:57 +0200
committerClifford Wolf <clifford@clifford.at>2016-04-11 16:48:57 +0200
commitb41c0e723ceb18d9e1ddc70e1aeb17d311a6a721 (patch)
tree506e9f1f72b41c9c9d000e5d8d85f8f5afb9710a /picorv32.v
parentb08d9400bddae1f5bb64b0f43a1824f3569f0ecb (diff)
downloadpicorv32-b41c0e723ceb18d9e1ddc70e1aeb17d311a6a721.tar.gz
picorv32-b41c0e723ceb18d9e1ddc70e1aeb17d311a6a721.zip
Do not re-load a word to read the 16 bit opcode in the upper half
Diffstat (limited to 'picorv32.v')
-rw-r--r--picorv32.v58
1 files changed, 44 insertions, 14 deletions
diff --git a/picorv32.v b/picorv32.v
index 005736e..4f70a74 100644
--- a/picorv32.v
+++ b/picorv32.v
@@ -215,22 +215,27 @@ module picorv32 #(
reg mem_la_secondword;
wire mem_la_firstword = COMPRESSED_ISA && (mem_do_prefetch || mem_do_rinst) && next_pc[1] && !mem_la_secondword;
+
+ reg prefetched_high_word;
+ reg clear_prefetched_high_word;
reg [15:0] mem_16bit_buffer;
+ wire mem_la_use_prefetched_high_word = COMPRESSED_ISA && mem_la_firstword && prefetched_high_word && !clear_prefetched_high_word;
+ wire mem_xfer = (mem_valid && mem_ready) || (mem_la_use_prefetched_high_word && mem_do_rinst);
+
wire mem_busy = |{mem_do_prefetch, mem_do_rinst, mem_do_rdata, mem_do_wdata};
- wire mem_done = resetn && ((mem_valid && mem_ready && |mem_state && (mem_do_rinst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_rinst)) &&
- (!mem_la_firstword || (~&mem_rdata[17:16] && mem_valid && mem_ready));
+ wire mem_done = resetn && ((mem_xfer && |mem_state && (mem_do_rinst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_rinst)) &&
+ (!mem_la_firstword || (~&mem_rdata_latched[1:0] && mem_xfer));
assign mem_la_write = resetn && !mem_state && mem_do_wdata;
- assign mem_la_read = resetn && ((!mem_state && (mem_do_rinst || mem_do_prefetch || mem_do_rdata)) ||
- (COMPRESSED_ISA && mem_valid && mem_ready && mem_la_firstword && !mem_la_secondword && &mem_rdata[17:16]));
- assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? {next_pc[31:2] + (mem_valid && mem_ready && mem_la_firstword), 2'b00} : {reg_op1[31:2], 2'b00};
+ assign mem_la_read = resetn && ((!mem_la_use_prefetched_high_word && !mem_state && (mem_do_rinst || mem_do_prefetch || mem_do_rdata)) ||
+ (COMPRESSED_ISA && mem_xfer && mem_la_firstword && !mem_la_secondword && &mem_rdata_latched[1:0]));
+ assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? {next_pc[31:2] + (mem_xfer && mem_la_firstword), 2'b00} : {reg_op1[31:2], 2'b00};
- wire [31:0] mem_rdata_latched_noshuffle;
- assign mem_rdata_latched_noshuffle = ((mem_valid && mem_ready) || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q;
+ wire [31:0] mem_rdata_latched_noshuffle = (mem_xfer || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q;
- wire [31:0] mem_rdata_latched;
- assign mem_rdata_latched = COMPRESSED_ISA && mem_la_secondword ? {mem_rdata_latched_noshuffle[15:0], mem_16bit_buffer} :
+ wire [31:0] mem_rdata_latched = COMPRESSED_ISA && mem_la_use_prefetched_high_word ? {16'bx, mem_16bit_buffer} :
+ COMPRESSED_ISA && mem_la_secondword ? {mem_rdata_latched_noshuffle[15:0], mem_16bit_buffer} :
COMPRESSED_ISA && mem_la_firstword ? {16'bx, mem_rdata_latched_noshuffle[31:16]} : mem_rdata_latched_noshuffle;
always @* begin
@@ -263,7 +268,7 @@ module picorv32 #(
end
always @(posedge clk) begin
- if (mem_valid && mem_ready) begin
+ if (mem_xfer) begin
mem_rdata_q <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata;
end
@@ -382,6 +387,7 @@ module picorv32 #(
mem_state <= 0;
mem_valid <= 0;
mem_la_secondword <= 0;
+ prefetched_high_word <= 0;
end else case (mem_state)
0: begin
mem_addr <= mem_la_addr;
@@ -391,7 +397,7 @@ module picorv32 #(
current_insn_addr <= next_pc;
end
if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) begin
- mem_valid <= 1;
+ mem_valid <= !mem_la_use_prefetched_high_word;
mem_instr <= mem_do_prefetch || mem_do_rinst;
mem_wstrb <= 0;
mem_state <= 1;
@@ -403,20 +409,30 @@ module picorv32 #(
end
end
1: begin
- if (mem_ready) begin
+ if (mem_xfer) begin
if (COMPRESSED_ISA && mem_la_read) begin
+ mem_valid <= 1;
mem_addr <= mem_la_addr;
mem_la_secondword <= 1;
- mem_16bit_buffer <= mem_rdata[31:16];
+ if (!mem_la_use_prefetched_high_word)
+ mem_16bit_buffer <= mem_rdata[31:16];
end else begin
mem_valid <= 0;
mem_la_secondword <= 0;
+ if (!mem_do_rdata) begin
+ if (~&mem_rdata[1:0] || mem_la_secondword) begin
+ mem_16bit_buffer <= mem_rdata[31:16];
+ prefetched_high_word <= 1;
+ end else begin
+ prefetched_high_word <= 0;
+ end
+ end
mem_state <= mem_do_rinst || mem_do_rdata ? 0 : 3;
end
end
end
2: begin
- if (mem_ready) begin
+ if (mem_xfer) begin
mem_valid <= 0;
mem_state <= 0;
end
@@ -427,6 +443,9 @@ module picorv32 #(
end
end
endcase
+
+ if (clear_prefetched_high_word)
+ prefetched_high_word <= 0;
end
@@ -922,6 +941,17 @@ module picorv32 #(
endcase
end
+ reg clear_prefetched_high_word_q;
+ always @(posedge clk) clear_prefetched_high_word_q <= clear_prefetched_high_word;
+
+ always @* begin
+ clear_prefetched_high_word = clear_prefetched_high_word_q;
+ if (!prefetched_high_word)
+ clear_prefetched_high_word = 0;
+ if (latched_branch || irq_state || !resetn)
+ clear_prefetched_high_word = COMPRESSED_ISA;
+ end
+
always @(posedge clk) begin
trap <= 0;
reg_sh <= 'bx;