mirror of https://github.com/YosysHQ/picorv32.git
Do not re-load a word to read the 16 bit opcode in the upper half
This commit is contained in:
parent
b08d9400bd
commit
b41c0e723c
58
picorv32.v
58
picorv32.v
|
@ -215,22 +215,27 @@ module picorv32 #(
|
||||||
|
|
||||||
reg mem_la_secondword;
|
reg mem_la_secondword;
|
||||||
wire mem_la_firstword = COMPRESSED_ISA && (mem_do_prefetch || mem_do_rinst) && next_pc[1] && !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;
|
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_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)) &&
|
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[17:16] && mem_valid && mem_ready));
|
(!mem_la_firstword || (~&mem_rdata_latched[1:0] && mem_xfer));
|
||||||
|
|
||||||
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_rinst || mem_do_prefetch || mem_do_rdata)) ||
|
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_valid && mem_ready && mem_la_firstword && !mem_la_secondword && &mem_rdata[17:16]));
|
(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_valid && mem_ready && mem_la_firstword), 2'b00} : {reg_op1[31:2], 2'b00};
|
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;
|
wire [31:0] mem_rdata_latched_noshuffle = (mem_xfer || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q;
|
||||||
assign mem_rdata_latched_noshuffle = ((mem_valid && mem_ready) || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q;
|
|
||||||
|
|
||||||
wire [31:0] mem_rdata_latched;
|
wire [31:0] mem_rdata_latched = COMPRESSED_ISA && mem_la_use_prefetched_high_word ? {16'bx, mem_16bit_buffer} :
|
||||||
assign mem_rdata_latched = COMPRESSED_ISA && mem_la_secondword ? {mem_rdata_latched_noshuffle[15:0], 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;
|
COMPRESSED_ISA && mem_la_firstword ? {16'bx, mem_rdata_latched_noshuffle[31:16]} : mem_rdata_latched_noshuffle;
|
||||||
|
|
||||||
always @* begin
|
always @* begin
|
||||||
|
@ -263,7 +268,7 @@ module picorv32 #(
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (mem_valid && mem_ready) begin
|
if (mem_xfer) begin
|
||||||
mem_rdata_q <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata;
|
mem_rdata_q <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -382,6 +387,7 @@ module picorv32 #(
|
||||||
mem_state <= 0;
|
mem_state <= 0;
|
||||||
mem_valid <= 0;
|
mem_valid <= 0;
|
||||||
mem_la_secondword <= 0;
|
mem_la_secondword <= 0;
|
||||||
|
prefetched_high_word <= 0;
|
||||||
end else case (mem_state)
|
end else case (mem_state)
|
||||||
0: begin
|
0: begin
|
||||||
mem_addr <= mem_la_addr;
|
mem_addr <= mem_la_addr;
|
||||||
|
@ -391,7 +397,7 @@ module picorv32 #(
|
||||||
current_insn_addr <= next_pc;
|
current_insn_addr <= next_pc;
|
||||||
end
|
end
|
||||||
if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) begin
|
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_instr <= mem_do_prefetch || mem_do_rinst;
|
||||||
mem_wstrb <= 0;
|
mem_wstrb <= 0;
|
||||||
mem_state <= 1;
|
mem_state <= 1;
|
||||||
|
@ -403,20 +409,30 @@ module picorv32 #(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
1: begin
|
1: begin
|
||||||
if (mem_ready) begin
|
if (mem_xfer) begin
|
||||||
if (COMPRESSED_ISA && mem_la_read) begin
|
if (COMPRESSED_ISA && mem_la_read) begin
|
||||||
|
mem_valid <= 1;
|
||||||
mem_addr <= mem_la_addr;
|
mem_addr <= mem_la_addr;
|
||||||
mem_la_secondword <= 1;
|
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
|
end else begin
|
||||||
mem_valid <= 0;
|
mem_valid <= 0;
|
||||||
mem_la_secondword <= 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;
|
mem_state <= mem_do_rinst || mem_do_rdata ? 0 : 3;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
2: begin
|
2: begin
|
||||||
if (mem_ready) begin
|
if (mem_xfer) begin
|
||||||
mem_valid <= 0;
|
mem_valid <= 0;
|
||||||
mem_state <= 0;
|
mem_state <= 0;
|
||||||
end
|
end
|
||||||
|
@ -427,6 +443,9 @@ module picorv32 #(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
if (clear_prefetched_high_word)
|
||||||
|
prefetched_high_word <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -922,6 +941,17 @@ module picorv32 #(
|
||||||
endcase
|
endcase
|
||||||
end
|
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
|
always @(posedge clk) begin
|
||||||
trap <= 0;
|
trap <= 0;
|
||||||
reg_sh <= 'bx;
|
reg_sh <= 'bx;
|
||||||
|
|
Loading…
Reference in New Issue