mirror of https://github.com/YosysHQ/picorv32.git
Towards compressed ISA support
This commit is contained in:
parent
c59b0043c4
commit
db26b51afe
93
picorv32.v
93
picorv32.v
|
@ -45,6 +45,7 @@ module picorv32 #(
|
||||||
parameter [ 0:0] TWO_STAGE_SHIFT = 1,
|
parameter [ 0:0] TWO_STAGE_SHIFT = 1,
|
||||||
parameter [ 0:0] TWO_CYCLE_COMPARE = 0,
|
parameter [ 0:0] TWO_CYCLE_COMPARE = 0,
|
||||||
parameter [ 0:0] TWO_CYCLE_ALU = 0,
|
parameter [ 0:0] TWO_CYCLE_ALU = 0,
|
||||||
|
parameter [ 0:0] COMPRESSED_ISA = 0,
|
||||||
parameter [ 0:0] CATCH_MISALIGN = 1,
|
parameter [ 0:0] CATCH_MISALIGN = 1,
|
||||||
parameter [ 0:0] CATCH_ILLINSN = 1,
|
parameter [ 0:0] CATCH_ILLINSN = 1,
|
||||||
parameter [ 0:0] ENABLE_PCPI = 0,
|
parameter [ 0:0] ENABLE_PCPI = 0,
|
||||||
|
@ -184,7 +185,7 @@ module picorv32 #(
|
||||||
|
|
||||||
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);
|
||||||
assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? next_pc : {reg_op1[31:2], 2'b00};
|
assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? {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_valid && mem_ready) || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q;
|
assign mem_rdata_latched = ((mem_valid && mem_ready) || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q;
|
||||||
|
@ -219,8 +220,33 @@ module picorv32 #(
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (mem_valid && mem_ready)
|
if (mem_valid && mem_ready) begin
|
||||||
mem_rdata_q <= mem_rdata_latched;
|
mem_rdata_q <= mem_rdata_latched;
|
||||||
|
|
||||||
|
if (COMPRESSED_ISA && mem_do_rinst) begin
|
||||||
|
case (mem_rdata_latched[1:0] == 1)
|
||||||
|
2'b00: begin // Quadrant 0
|
||||||
|
end
|
||||||
|
2'b01: begin // Quadrant 1
|
||||||
|
case (mem_rdata_latched[15:13])
|
||||||
|
3'b 000: begin // C.ADDI
|
||||||
|
mem_rdata_q[14:12] <= 3'b000;
|
||||||
|
mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]});
|
||||||
|
end
|
||||||
|
3'b 011: begin
|
||||||
|
if (mem_rdata_latched[11:7] == 2) begin // C.ADDI16SP
|
||||||
|
mem_rdata_q[14:12] <= 3'b000;
|
||||||
|
mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[4:3],
|
||||||
|
mem_rdata_latched[5], mem_rdata_latched[2], mem_rdata_latched[6], 4'b 0000});
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
2'b10: begin // Quadrant 2
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
|
@ -281,6 +307,7 @@ module picorv32 #(
|
||||||
reg decoder_trigger;
|
reg decoder_trigger;
|
||||||
reg decoder_trigger_q;
|
reg decoder_trigger_q;
|
||||||
reg decoder_pseudo_trigger;
|
reg decoder_pseudo_trigger;
|
||||||
|
reg compressed_instr;
|
||||||
|
|
||||||
reg is_lui_auipc_jal;
|
reg is_lui_auipc_jal;
|
||||||
reg is_lb_lh_lw_lbu_lhu;
|
reg is_lb_lh_lw_lbu_lhu;
|
||||||
|
@ -404,6 +431,47 @@ module picorv32 #(
|
||||||
|
|
||||||
if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ)
|
if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ)
|
||||||
decoded_rs1 <= ENABLE_IRQ_QREGS ? irqregs_offset : 3; // instr_retirq
|
decoded_rs1 <= ENABLE_IRQ_QREGS ? irqregs_offset : 3; // instr_retirq
|
||||||
|
|
||||||
|
compressed_instr <= 0;
|
||||||
|
if (COMPRESSED_ISA && mem_rdata_latched[1:0] != 2'b11) begin
|
||||||
|
compressed_instr <= 1;
|
||||||
|
decoded_rd <= 0;
|
||||||
|
|
||||||
|
{ decoded_imm_uj[31:11], decoded_imm_uj[4], decoded_imm_uj[9:8], decoded_imm_uj[10], decoded_imm_uj[6],
|
||||||
|
decoded_imm_uj[7], decoded_imm_uj[3:1], decoded_imm_uj[5], decoded_imm_uj[0] } <= $signed({mem_rdata_latched[12:2], 1'b0});
|
||||||
|
|
||||||
|
case (mem_rdata_latched[1:0])
|
||||||
|
2'b00: begin // Quadrant 0
|
||||||
|
decoded_rs1 <= 8 + mem_rdata_latched[9:7];
|
||||||
|
decoded_rd <= 8 + mem_rdata_latched[4:2];
|
||||||
|
end
|
||||||
|
2'b01: begin // Quadrant 1
|
||||||
|
case (mem_rdata_latched[15:13])
|
||||||
|
3'b000: begin // C.NOP / C.ADDI
|
||||||
|
is_alu_reg_imm <= 1;
|
||||||
|
decoded_rd <= mem_rdata_latched[11:7];
|
||||||
|
decoded_rs1 <= mem_rdata_latched[11:7];
|
||||||
|
end
|
||||||
|
3'b001: begin // C.JAL
|
||||||
|
instr_jal <= 1;
|
||||||
|
decoded_rd <= 1;
|
||||||
|
end
|
||||||
|
3'b 011: begin
|
||||||
|
if (mem_rdata_latched[11:7] == 2) begin // C.ADDI16SP
|
||||||
|
is_alu_reg_imm <= 1;
|
||||||
|
decoded_rd <= mem_rdata_latched[11:7];
|
||||||
|
decoded_rs1 <= mem_rdata_latched[11:7];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
3'b101: begin // C.J
|
||||||
|
instr_jal <= 1;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
2'b10: begin // Quadrant 2
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (decoder_trigger && !decoder_pseudo_trigger) begin
|
if (decoder_trigger && !decoder_pseudo_trigger) begin
|
||||||
|
@ -535,6 +603,7 @@ module picorv32 #(
|
||||||
reg latched_store;
|
reg latched_store;
|
||||||
reg latched_stalu;
|
reg latched_stalu;
|
||||||
reg latched_branch;
|
reg latched_branch;
|
||||||
|
reg latched_compr;
|
||||||
reg latched_is_lu;
|
reg latched_is_lu;
|
||||||
reg latched_is_lh;
|
reg latched_is_lh;
|
||||||
reg latched_is_lb;
|
reg latched_is_lb;
|
||||||
|
@ -685,8 +754,8 @@ module picorv32 #(
|
||||||
case (1'b1)
|
case (1'b1)
|
||||||
latched_branch: begin
|
latched_branch: begin
|
||||||
current_pc = latched_store ? (latched_stalu ? alu_out_q : reg_out) : reg_next_pc;
|
current_pc = latched_store ? (latched_stalu ? alu_out_q : reg_out) : reg_next_pc;
|
||||||
`debug($display("ST_RD: %2d 0x%08x, BRANCH 0x%08x", latched_rd, reg_pc + 4, current_pc);)
|
`debug($display("ST_RD: %2d 0x%08x, BRANCH 0x%08x", latched_rd, reg_pc + (latched_compr ? 2 : 4), current_pc);)
|
||||||
cpuregs[latched_rd] <= reg_pc + 4;
|
cpuregs[latched_rd] <= reg_pc + (latched_compr ? 2 : 4);
|
||||||
end
|
end
|
||||||
latched_store && !latched_branch: begin
|
latched_store && !latched_branch: begin
|
||||||
`debug($display("ST_RD: %2d 0x%08x", latched_rd, latched_stalu ? alu_out_q : reg_out);)
|
`debug($display("ST_RD: %2d 0x%08x", latched_rd, latched_stalu ? alu_out_q : reg_out);)
|
||||||
|
@ -715,6 +784,7 @@ module picorv32 #(
|
||||||
latched_is_lh <= 0;
|
latched_is_lh <= 0;
|
||||||
latched_is_lb <= 0;
|
latched_is_lb <= 0;
|
||||||
latched_rd <= decoded_rd;
|
latched_rd <= decoded_rd;
|
||||||
|
latched_compr <= compressed_instr;
|
||||||
|
|
||||||
if (ENABLE_IRQ && ((decoder_trigger && !irq_active && |(irq_pending & ~irq_mask)) || irq_state)) begin
|
if (ENABLE_IRQ && ((decoder_trigger && !irq_active && |(irq_pending & ~irq_mask)) || irq_state)) begin
|
||||||
irq_state <=
|
irq_state <=
|
||||||
|
@ -729,14 +799,14 @@ module picorv32 #(
|
||||||
if (irq_pending) begin
|
if (irq_pending) begin
|
||||||
latched_store <= 1;
|
latched_store <= 1;
|
||||||
reg_out <= irq_pending;
|
reg_out <= irq_pending;
|
||||||
reg_next_pc <= current_pc + 4;
|
reg_next_pc <= current_pc + (compressed_instr ? 2 : 4);
|
||||||
mem_do_rinst <= 1;
|
mem_do_rinst <= 1;
|
||||||
end else
|
end else
|
||||||
do_waitirq <= 1;
|
do_waitirq <= 1;
|
||||||
end else
|
end else
|
||||||
if (decoder_trigger) begin
|
if (decoder_trigger) begin
|
||||||
`debug($display("-- %-0t", $time);)
|
`debug($display("-- %-0t", $time);)
|
||||||
reg_next_pc <= current_pc + 4;
|
reg_next_pc <= current_pc + (compressed_instr ? 2 : 4);
|
||||||
if (ENABLE_COUNTERS)
|
if (ENABLE_COUNTERS)
|
||||||
count_instr <= count_instr + 1;
|
count_instr <= count_instr + 1;
|
||||||
if (instr_jal) begin
|
if (instr_jal) begin
|
||||||
|
@ -1067,7 +1137,7 @@ module picorv32 #(
|
||||||
cpu_state <= cpu_state_trap;
|
cpu_state <= cpu_state_trap;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if (CATCH_MISALIGN && resetn && mem_do_rinst && reg_pc[1:0] != 0) begin
|
if (CATCH_MISALIGN && resetn && mem_do_rinst && (COMPRESSED_ISA ? reg_pc[0] : |reg_pc[1:0])) begin
|
||||||
`debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);)
|
`debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);)
|
||||||
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
||||||
next_irq_pending[irq_buserror] = 1;
|
next_irq_pending[irq_buserror] = 1;
|
||||||
|
@ -1091,8 +1161,13 @@ module picorv32 #(
|
||||||
|
|
||||||
irq_pending <= next_irq_pending & ~MASKED_IRQ;
|
irq_pending <= next_irq_pending & ~MASKED_IRQ;
|
||||||
|
|
||||||
reg_pc[1:0] <= 0;
|
if (COMPRESSED_ISA) begin
|
||||||
reg_next_pc[1:0] <= 0;
|
reg_pc[0] <= 0;
|
||||||
|
reg_next_pc[0] <= 0;
|
||||||
|
end else begin
|
||||||
|
reg_pc[1:0] <= 0;
|
||||||
|
reg_next_pc[1:0] <= 0;
|
||||||
|
end
|
||||||
current_pc = 'bx;
|
current_pc = 'bx;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue