Towards compressed ISA support
This commit is contained in:
parent
db26b51afe
commit
60b9216856
40
picorv32.v
40
picorv32.v
|
@ -180,15 +180,22 @@ module picorv32 #(
|
||||||
reg mem_do_rdata;
|
reg mem_do_rdata;
|
||||||
reg mem_do_wdata;
|
reg mem_do_wdata;
|
||||||
|
|
||||||
|
reg mem_la_secondword;
|
||||||
|
wire mem_la_firstword = COMPRESSED_ISA && (mem_do_prefetch || mem_do_rinst) && next_pc[1] && !mem_la_secondword;
|
||||||
|
reg [15:0] mem_16bit_buffer;
|
||||||
|
|
||||||
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_ready && |mem_state && (mem_do_rinst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_rinst));
|
wire mem_done = resetn && ((mem_ready && |mem_state && (mem_do_rinst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_rinst)) && !mem_la_firstword;
|
||||||
|
|
||||||
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_state && (mem_do_rinst || mem_do_prefetch || mem_do_rdata)) || (mem_ready && mem_la_firstword && !mem_la_secondword));
|
||||||
assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? {next_pc[31:2], 2'b00} : {reg_op1[31:2], 2'b00};
|
assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? {next_pc[31:2] + (mem_ready && 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;
|
wire [31:0] mem_rdata_latched;
|
||||||
assign mem_rdata_latched = ((mem_valid && mem_ready) || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q;
|
assign mem_rdata_latched = COMPRESSED_ISA && mem_la_secondword ? {mem_rdata_latched_noshuffle[15:0], mem_16bit_buffer} : mem_rdata_latched_noshuffle;
|
||||||
|
|
||||||
always @* begin
|
always @* begin
|
||||||
(* full_case *)
|
(* full_case *)
|
||||||
|
@ -221,7 +228,7 @@ module picorv32 #(
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (mem_valid && mem_ready) begin
|
if (mem_valid && mem_ready) begin
|
||||||
mem_rdata_q <= mem_rdata_latched;
|
mem_rdata_q <= mem_rdata;
|
||||||
|
|
||||||
if (COMPRESSED_ISA && mem_do_rinst) begin
|
if (COMPRESSED_ISA && mem_do_rinst) begin
|
||||||
case (mem_rdata_latched[1:0] == 1)
|
case (mem_rdata_latched[1:0] == 1)
|
||||||
|
@ -253,6 +260,7 @@ module picorv32 #(
|
||||||
if (!resetn) begin
|
if (!resetn) begin
|
||||||
mem_state <= 0;
|
mem_state <= 0;
|
||||||
mem_valid <= 0;
|
mem_valid <= 0;
|
||||||
|
mem_la_secondword <= 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;
|
||||||
|
@ -272,10 +280,17 @@ module picorv32 #(
|
||||||
end
|
end
|
||||||
1: begin
|
1: begin
|
||||||
if (mem_ready) begin
|
if (mem_ready) begin
|
||||||
|
if (COMPRESSED_ISA && mem_la_firstword && !mem_la_secondword) begin
|
||||||
|
mem_addr <= mem_la_addr;
|
||||||
|
mem_la_secondword <= 1;
|
||||||
|
mem_16bit_buffer <= mem_rdata[31:16];
|
||||||
|
end else begin
|
||||||
mem_valid <= 0;
|
mem_valid <= 0;
|
||||||
|
mem_la_secondword <= 0;
|
||||||
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
|
||||||
2: begin
|
2: begin
|
||||||
if (mem_ready) begin
|
if (mem_ready) begin
|
||||||
mem_valid <= 0;
|
mem_valid <= 0;
|
||||||
|
@ -303,7 +318,7 @@ module picorv32 #(
|
||||||
wire instr_trap;
|
wire instr_trap;
|
||||||
|
|
||||||
reg [regindex_bits-1:0] decoded_rd, decoded_rs1, decoded_rs2;
|
reg [regindex_bits-1:0] decoded_rd, decoded_rs1, decoded_rs2;
|
||||||
reg [31:0] decoded_imm, decoded_imm_uj;
|
reg [31:0] decoded_imm, decoded_imm_uj, current_insn;
|
||||||
reg decoder_trigger;
|
reg decoder_trigger;
|
||||||
reg decoder_trigger_q;
|
reg decoder_trigger_q;
|
||||||
reg decoder_pseudo_trigger;
|
reg decoder_pseudo_trigger;
|
||||||
|
@ -340,6 +355,7 @@ module picorv32 #(
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
new_ascii_instr = "";
|
new_ascii_instr = "";
|
||||||
|
|
||||||
if (instr_lui) new_ascii_instr = "lui";
|
if (instr_lui) new_ascii_instr = "lui";
|
||||||
if (instr_auipc) new_ascii_instr = "auipc";
|
if (instr_auipc) new_ascii_instr = "auipc";
|
||||||
if (instr_jal) new_ascii_instr = "jal";
|
if (instr_jal) new_ascii_instr = "jal";
|
||||||
|
@ -394,8 +410,10 @@ module picorv32 #(
|
||||||
if (instr_waitirq) new_ascii_instr = "waitirq";
|
if (instr_waitirq) new_ascii_instr = "waitirq";
|
||||||
if (instr_timer) new_ascii_instr = "timer";
|
if (instr_timer) new_ascii_instr = "timer";
|
||||||
|
|
||||||
if (decoder_trigger_q)
|
if (decoder_trigger_q) begin
|
||||||
ascii_instr <= new_ascii_instr;
|
ascii_instr <= new_ascii_instr;
|
||||||
|
`debug($display("DECODE: 0x%08x 0x%08x %-0s", reg_pc, current_insn, new_ascii_instr ? new_ascii_instr : "UNKNOWN");)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
|
@ -407,6 +425,8 @@ module picorv32 #(
|
||||||
is_compare <= |{is_beq_bne_blt_bge_bltu_bgeu, instr_slti, instr_slt, instr_sltiu, instr_sltu};
|
is_compare <= |{is_beq_bne_blt_bge_bltu_bgeu, instr_slti, instr_slt, instr_sltiu, instr_sltu};
|
||||||
|
|
||||||
if (mem_do_rinst && mem_done) begin
|
if (mem_do_rinst && mem_done) begin
|
||||||
|
current_insn <= mem_rdata_latched;
|
||||||
|
|
||||||
instr_lui <= mem_rdata_latched[6:0] == 7'b0110111;
|
instr_lui <= mem_rdata_latched[6:0] == 7'b0110111;
|
||||||
instr_auipc <= mem_rdata_latched[6:0] == 7'b0010111;
|
instr_auipc <= mem_rdata_latched[6:0] == 7'b0010111;
|
||||||
instr_jal <= mem_rdata_latched[6:0] == 7'b1101111;
|
instr_jal <= mem_rdata_latched[6:0] == 7'b1101111;
|
||||||
|
@ -810,7 +830,6 @@ module picorv32 #(
|
||||||
if (ENABLE_COUNTERS)
|
if (ENABLE_COUNTERS)
|
||||||
count_instr <= count_instr + 1;
|
count_instr <= count_instr + 1;
|
||||||
if (instr_jal) begin
|
if (instr_jal) begin
|
||||||
`debug($display("DECODE: 0x%08x jal", current_pc);)
|
|
||||||
mem_do_rinst <= 1;
|
mem_do_rinst <= 1;
|
||||||
reg_next_pc <= current_pc + decoded_imm_uj;
|
reg_next_pc <= current_pc + decoded_imm_uj;
|
||||||
latched_branch <= 1;
|
latched_branch <= 1;
|
||||||
|
@ -825,7 +844,6 @@ module picorv32 #(
|
||||||
cpu_state_ld_rs1: begin
|
cpu_state_ld_rs1: begin
|
||||||
reg_op1 <= 'bx;
|
reg_op1 <= 'bx;
|
||||||
reg_op2 <= 'bx;
|
reg_op2 <= 'bx;
|
||||||
`debug($display("DECODE: 0x%08x %-0s", reg_pc, ascii_instr ? ascii_instr : "UNKNOWN");)
|
|
||||||
|
|
||||||
(* parallel_case *)
|
(* parallel_case *)
|
||||||
case (1'b1)
|
case (1'b1)
|
||||||
|
@ -1525,6 +1543,7 @@ module picorv32_axi_adapter (
|
||||||
reg ack_awvalid;
|
reg ack_awvalid;
|
||||||
reg ack_arvalid;
|
reg ack_arvalid;
|
||||||
reg ack_wvalid;
|
reg ack_wvalid;
|
||||||
|
reg xfer_done;
|
||||||
|
|
||||||
assign mem_axi_awvalid = mem_valid && |mem_wstrb && !ack_awvalid;
|
assign mem_axi_awvalid = mem_valid && |mem_wstrb && !ack_awvalid;
|
||||||
assign mem_axi_awaddr = mem_addr;
|
assign mem_axi_awaddr = mem_addr;
|
||||||
|
@ -1547,13 +1566,14 @@ module picorv32_axi_adapter (
|
||||||
if (!resetn) begin
|
if (!resetn) begin
|
||||||
ack_awvalid <= 0;
|
ack_awvalid <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
|
xfer_done <= mem_valid && mem_ready;
|
||||||
if (mem_axi_awready && mem_axi_awvalid)
|
if (mem_axi_awready && mem_axi_awvalid)
|
||||||
ack_awvalid <= 1;
|
ack_awvalid <= 1;
|
||||||
if (mem_axi_arready && mem_axi_arvalid)
|
if (mem_axi_arready && mem_axi_arvalid)
|
||||||
ack_arvalid <= 1;
|
ack_arvalid <= 1;
|
||||||
if (mem_axi_wready && mem_axi_wvalid)
|
if (mem_axi_wready && mem_axi_wvalid)
|
||||||
ack_wvalid <= 1;
|
ack_wvalid <= 1;
|
||||||
if (!mem_valid) begin
|
if (xfer_done || !mem_valid) begin
|
||||||
ack_awvalid <= 0;
|
ack_awvalid <= 0;
|
||||||
ack_arvalid <= 0;
|
ack_arvalid <= 0;
|
||||||
ack_wvalid <= 0;
|
ack_wvalid <= 0;
|
||||||
|
|
Loading…
Reference in New Issue