Remote COMPOSE_ISA support.

This commit is contained in:
colin.liang 2023-01-12 15:58:11 +08:00
parent b99c193120
commit d9e14153fc
2 changed files with 17 additions and 330 deletions

View File

@ -16,7 +16,6 @@ FIRMWARE_OBJS = firmware/start.o firmware/irq.o firmware/print.o firmware/hello.
GCC_WARNS = -Werror -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings
GCC_WARNS += -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic # -Wconversion
TOOLCHAIN_PREFIX = $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)/bin/riscv32-unknown-elf-
COMPRESSED_ISA = C
# Add things like "export http_proxy=... https_proxy=..." here
GIT_ENV = true
@ -30,13 +29,9 @@ test_wb_vcd: testbench_wb.vvp firmware/firmware.hex
test_verilator: testbench_verilator firmware/firmware.hex
./testbench_verilator
testbench_wb.vvp: testbench_wb.v picorv32.v
$(IVERILOG) -o $@ $(subst C,-DCOMPRESSED_ISA,$(COMPRESSED_ISA)) $^
chmod -x $@
testbench_verilator: testbench_wb.v picorv32.v testbench.cc
$(VERILATOR) --cc --exe -Wno-lint -trace --top-module picorv32_wrapper testbench_wb.v picorv32.v testbench.cc \
$(subst C,-DCOMPRESSED_ISA,$(COMPRESSED_ISA)) --Mdir testbench_verilator_dir
--Mdir testbench_verilator_dir
$(MAKE) -C testbench_verilator_dir -f Vpicorv32_wrapper.mk
cp testbench_verilator_dir/Vpicorv32_wrapper testbench_verilator
@ -55,16 +50,9 @@ check.smt2: picorv32.v
synth.v: picorv32.v scripts/yosys/synth_sim.ys
yosys -qv3 -l synth.log scripts/yosys/synth_sim.ys
# firmware/firmware.hex: firmware/firmware.bin firmware/makehex.py
# $(PYTHON) firmware/makehex.py $< 32768 > $@
firmware/firmware.hex: firmware/firmware.elf
$(TOOLCHAIN_PREFIX)objcopy -O verilog $< $@
# firmware/firmware.bin: firmware/firmware.elf
# $(TOOLCHAIN_PREFIX)objcopy -O binary $< $@
# chmod -x $@
firmware/firmware.elf: $(FIRMWARE_OBJS) $(TEST_OBJS) firmware/sections.lds
$(TOOLCHAIN_PREFIX)gcc -Os -mabi=ilp32 -march=rv32im -ffreestanding -nostdlib -o $@ \
-Wl,--build-id=none,-Bstatic,-T,firmware/sections.lds,-Map,firmware/firmware.map,--strip-debug \

View File

@ -60,7 +60,6 @@ module picorv32 #(
parameter [ 0:0] BARREL_SHIFTER = 0,
parameter [ 0:0] TWO_CYCLE_COMPARE = 0,
parameter [ 0:0] TWO_CYCLE_ALU = 0,
parameter [ 0:0] COMPRESSED_ISA = 0,
parameter [ 0:0] CATCH_MISALIGN = 1,
parameter [ 0:0] CATCH_ILLINSN = 1,
parameter [ 0:0] ENABLE_PCPI = 0,
@ -280,42 +279,31 @@ module picorv32 #(
reg mem_do_wdata;
wire mem_xfer;
reg mem_la_secondword, mem_la_firstword_reg, last_mem_valid;
wire mem_la_firstword = COMPRESSED_ISA && (mem_do_prefetch || mem_do_rinst) && next_pc[1] && !mem_la_secondword;
wire mem_la_firstword_xfer = COMPRESSED_ISA && mem_xfer && (!last_mem_valid ? mem_la_firstword : mem_la_firstword_reg);
reg last_mem_valid;
reg prefetched_high_word;
reg clear_prefetched_high_word;
reg [15:0] mem_16bit_buffer;
wire [31:0] mem_rdata_latched_noshuffle;
wire [31:0] mem_rdata_latched;
wire mem_la_use_prefetched_high_word = COMPRESSED_ISA && mem_la_firstword && prefetched_high_word && !clear_prefetched_high_word;
assign mem_xfer = (mem_valid && mem_ready) || (mem_la_use_prefetched_high_word && mem_do_rinst);
assign mem_xfer = mem_valid && mem_ready;
wire mem_busy = |{mem_do_prefetch, mem_do_rinst, mem_do_rdata, mem_do_wdata};
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));
wire mem_done = resetn && ((mem_xfer && |mem_state && (mem_do_rinst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_rinst));
assign mem_la_write = resetn && !mem_state && mem_do_wdata;
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 && (!last_mem_valid ? mem_la_firstword : mem_la_firstword_reg) && !mem_la_secondword && &mem_rdata_latched[1:0]));
assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? {next_pc[31:2] + mem_la_firstword_xfer, 2'b00} : {reg_op1[31:2], 2'b00};
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[31:2], 2'b00} : {reg_op1[31:2], 2'b00};
assign mem_rdata_latched_noshuffle = (mem_xfer || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q;
assign 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;
assign mem_rdata_latched = mem_rdata_latched_noshuffle;
always @(posedge clk) begin
if (!resetn) begin
mem_la_firstword_reg <= 0;
last_mem_valid <= 0;
end else begin
if (!last_mem_valid)
mem_la_firstword_reg <= mem_la_firstword;
last_mem_valid <= mem_valid && !mem_ready;
end
end
@ -351,117 +339,8 @@ module picorv32 #(
always @(posedge clk) begin
if (mem_xfer) begin
mem_rdata_q <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata;
next_insn_opcode <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata;
end
if (COMPRESSED_ISA && mem_done && (mem_do_prefetch || mem_do_rinst)) begin
case (mem_rdata_latched[1:0])
2'b00: begin // Quadrant 0
case (mem_rdata_latched[15:13])
3'b000: begin // C.ADDI4SPN
mem_rdata_q[14:12] <= 3'b000;
mem_rdata_q[31:20] <= {2'b0, mem_rdata_latched[10:7], mem_rdata_latched[12:11], mem_rdata_latched[5], mem_rdata_latched[6], 2'b00};
end
3'b010: begin // C.LW
mem_rdata_q[31:20] <= {5'b0, mem_rdata_latched[5], mem_rdata_latched[12:10], mem_rdata_latched[6], 2'b00};
mem_rdata_q[14:12] <= 3'b 010;
end
3'b 110: begin // C.SW
{mem_rdata_q[31:25], mem_rdata_q[11:7]} <= {5'b0, mem_rdata_latched[5], mem_rdata_latched[12:10], mem_rdata_latched[6], 2'b00};
mem_rdata_q[14:12] <= 3'b 010;
end
endcase
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 010: begin // C.LI
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 else begin // C.LUI
mem_rdata_q[31:12] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]});
end
end
3'b100: begin
if (mem_rdata_latched[11:10] == 2'b00) begin // C.SRLI
mem_rdata_q[31:25] <= 7'b0000000;
mem_rdata_q[14:12] <= 3'b 101;
end
if (mem_rdata_latched[11:10] == 2'b01) begin // C.SRAI
mem_rdata_q[31:25] <= 7'b0100000;
mem_rdata_q[14:12] <= 3'b 101;
end
if (mem_rdata_latched[11:10] == 2'b10) begin // C.ANDI
mem_rdata_q[14:12] <= 3'b111;
mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]});
end
if (mem_rdata_latched[12:10] == 3'b011) begin // C.SUB, C.XOR, C.OR, C.AND
if (mem_rdata_latched[6:5] == 2'b00) mem_rdata_q[14:12] <= 3'b000;
if (mem_rdata_latched[6:5] == 2'b01) mem_rdata_q[14:12] <= 3'b100;
if (mem_rdata_latched[6:5] == 2'b10) mem_rdata_q[14:12] <= 3'b110;
if (mem_rdata_latched[6:5] == 2'b11) mem_rdata_q[14:12] <= 3'b111;
mem_rdata_q[31:25] <= mem_rdata_latched[6:5] == 2'b00 ? 7'b0100000 : 7'b0000000;
end
end
3'b 110: begin // C.BEQZ
mem_rdata_q[14:12] <= 3'b000;
{ mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8] } <=
$signed({mem_rdata_latched[12], mem_rdata_latched[6:5], mem_rdata_latched[2],
mem_rdata_latched[11:10], mem_rdata_latched[4:3]});
end
3'b 111: begin // C.BNEZ
mem_rdata_q[14:12] <= 3'b001;
{ mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8] } <=
$signed({mem_rdata_latched[12], mem_rdata_latched[6:5], mem_rdata_latched[2],
mem_rdata_latched[11:10], mem_rdata_latched[4:3]});
end
endcase
end
2'b10: begin // Quadrant 2
case (mem_rdata_latched[15:13])
3'b000: begin // C.SLLI
mem_rdata_q[31:25] <= 7'b0000000;
mem_rdata_q[14:12] <= 3'b 001;
end
3'b010: begin // C.LWSP
mem_rdata_q[31:20] <= {4'b0, mem_rdata_latched[3:2], mem_rdata_latched[12], mem_rdata_latched[6:4], 2'b00};
mem_rdata_q[14:12] <= 3'b 010;
end
3'b100: begin
if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] == 0) begin // C.JR
mem_rdata_q[14:12] <= 3'b000;
mem_rdata_q[31:20] <= 12'b0;
end
if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] != 0) begin // C.MV
mem_rdata_q[14:12] <= 3'b000;
mem_rdata_q[31:25] <= 7'b0000000;
end
if (mem_rdata_latched[12] != 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JALR
mem_rdata_q[14:12] <= 3'b000;
mem_rdata_q[31:20] <= 12'b0;
end
if (mem_rdata_latched[12] != 0 && mem_rdata_latched[6:2] != 0) begin // C.ADD
mem_rdata_q[14:12] <= 3'b000;
mem_rdata_q[31:25] <= 7'b0000000;
end
end
3'b110: begin // C.SWSP
{mem_rdata_q[31:25], mem_rdata_q[11:7]} <= {4'b0, mem_rdata_latched[8:7], mem_rdata_latched[12:9], 2'b00};
mem_rdata_q[14:12] <= 3'b 010;
end
endcase
end
endcase
mem_rdata_q <= mem_rdata;
next_insn_opcode <= mem_rdata;
end
end
@ -490,8 +369,6 @@ module picorv32 #(
mem_state <= 0;
if (!resetn || mem_ready)
mem_valid <= 0;
mem_la_secondword <= 0;
prefetched_high_word <= 0;
end else begin
if (mem_la_read || mem_la_write) begin
mem_addr <= mem_la_addr;
@ -503,7 +380,7 @@ module picorv32 #(
case (mem_state)
0: begin
if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) begin
mem_valid <= !mem_la_use_prefetched_high_word;
mem_valid <= 1;
mem_instr <= mem_do_prefetch || mem_do_rinst;
mem_wstrb <= 0;
mem_state <= 1;
@ -517,29 +394,13 @@ module picorv32 #(
1: begin
`assert(mem_wstrb == 0);
`assert(mem_do_prefetch || mem_do_rinst || mem_do_rdata);
`assert(mem_valid == !mem_la_use_prefetched_high_word);
`assert(mem_valid == 1);
`assert(mem_instr == (mem_do_prefetch || mem_do_rinst));
if (mem_xfer) begin
if (COMPRESSED_ISA && mem_la_read) begin
mem_valid <= 1;
mem_la_secondword <= 1;
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 (COMPRESSED_ISA && !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
`assert(mem_wstrb != 0);
`assert(mem_do_wdata);
@ -557,9 +418,6 @@ module picorv32 #(
end
endcase
end
if (clear_prefetched_high_word)
prefetched_high_word <= 0;
end
@ -812,148 +670,6 @@ module picorv32 #(
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_rs1 <= 0;
decoded_rs2 <= 0;
{ decoded_imm_j[31:11], decoded_imm_j[4], decoded_imm_j[9:8], decoded_imm_j[10], decoded_imm_j[6],
decoded_imm_j[7], decoded_imm_j[3:1], decoded_imm_j[5], decoded_imm_j[0] } <= $signed({mem_rdata_latched[12:2], 1'b0});
case (mem_rdata_latched[1:0])
2'b00: begin // Quadrant 0
case (mem_rdata_latched[15:13])
3'b000: begin // C.ADDI4SPN
is_alu_reg_imm <= |mem_rdata_latched[12:5];
decoded_rs1 <= 2;
decoded_rd <= 8 + mem_rdata_latched[4:2];
end
3'b010: begin // C.LW
is_lb_lh_lw_lbu_lhu <= 1;
decoded_rs1 <= 8 + mem_rdata_latched[9:7];
decoded_rd <= 8 + mem_rdata_latched[4:2];
end
3'b110: begin // C.SW
is_sb_sh_sw <= 1;
decoded_rs1 <= 8 + mem_rdata_latched[9:7];
decoded_rs2 <= 8 + mem_rdata_latched[4:2];
end
endcase
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 010: begin // C.LI
is_alu_reg_imm <= 1;
decoded_rd <= mem_rdata_latched[11:7];
decoded_rs1 <= 0;
end
3'b 011: begin
if (mem_rdata_latched[12] || mem_rdata_latched[6:2]) 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 else begin // C.LUI
instr_lui <= 1;
decoded_rd <= mem_rdata_latched[11:7];
decoded_rs1 <= 0;
end
end
end
3'b100: begin
if (!mem_rdata_latched[11] && !mem_rdata_latched[12]) begin // C.SRLI, C.SRAI
is_alu_reg_imm <= 1;
decoded_rd <= 8 + mem_rdata_latched[9:7];
decoded_rs1 <= 8 + mem_rdata_latched[9:7];
decoded_rs2 <= {mem_rdata_latched[12], mem_rdata_latched[6:2]};
end
if (mem_rdata_latched[11:10] == 2'b10) begin // C.ANDI
is_alu_reg_imm <= 1;
decoded_rd <= 8 + mem_rdata_latched[9:7];
decoded_rs1 <= 8 + mem_rdata_latched[9:7];
end
if (mem_rdata_latched[12:10] == 3'b011) begin // C.SUB, C.XOR, C.OR, C.AND
is_alu_reg_reg <= 1;
decoded_rd <= 8 + mem_rdata_latched[9:7];
decoded_rs1 <= 8 + mem_rdata_latched[9:7];
decoded_rs2 <= 8 + mem_rdata_latched[4:2];
end
end
3'b101: begin // C.J
instr_jal <= 1;
end
3'b110: begin // C.BEQZ
is_beq_bne_blt_bge_bltu_bgeu <= 1;
decoded_rs1 <= 8 + mem_rdata_latched[9:7];
decoded_rs2 <= 0;
end
3'b111: begin // C.BNEZ
is_beq_bne_blt_bge_bltu_bgeu <= 1;
decoded_rs1 <= 8 + mem_rdata_latched[9:7];
decoded_rs2 <= 0;
end
endcase
end
2'b10: begin // Quadrant 2
case (mem_rdata_latched[15:13])
3'b000: begin // C.SLLI
if (!mem_rdata_latched[12]) begin
is_alu_reg_imm <= 1;
decoded_rd <= mem_rdata_latched[11:7];
decoded_rs1 <= mem_rdata_latched[11:7];
decoded_rs2 <= {mem_rdata_latched[12], mem_rdata_latched[6:2]};
end
end
3'b010: begin // C.LWSP
if (mem_rdata_latched[11:7]) begin
is_lb_lh_lw_lbu_lhu <= 1;
decoded_rd <= mem_rdata_latched[11:7];
decoded_rs1 <= 2;
end
end
3'b100: begin
if (mem_rdata_latched[12] == 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JR
instr_jalr <= 1;
decoded_rd <= 0;
decoded_rs1 <= mem_rdata_latched[11:7];
end
if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] != 0) begin // C.MV
is_alu_reg_reg <= 1;
decoded_rd <= mem_rdata_latched[11:7];
decoded_rs1 <= 0;
decoded_rs2 <= mem_rdata_latched[6:2];
end
if (mem_rdata_latched[12] != 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JALR
instr_jalr <= 1;
decoded_rd <= 1;
decoded_rs1 <= mem_rdata_latched[11:7];
end
if (mem_rdata_latched[12] != 0 && mem_rdata_latched[6:2] != 0) begin // C.ADD
is_alu_reg_reg <= 1;
decoded_rd <= mem_rdata_latched[11:7];
decoded_rs1 <= mem_rdata_latched[11:7];
decoded_rs2 <= mem_rdata_latched[6:2];
end
end
3'b110: begin // C.SWSP
is_sb_sh_sw <= 1;
decoded_rs1 <= 2;
decoded_rs2 <= mem_rdata_latched[6:2];
end
endcase
end
endcase
end
end
if (decoder_trigger && !decoder_pseudo_trigger) begin
@ -1005,8 +721,7 @@ module picorv32 #(
instr_rdinstr <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000001000000010);
instr_rdinstrh <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000001000000010);
instr_ecall_ebreak <= ((mem_rdata_q[6:0] == 7'b1110011 && !mem_rdata_q[31:21] && !mem_rdata_q[19:7]) ||
(COMPRESSED_ISA && mem_rdata_q[15:0] == 16'h9002));
instr_ecall_ebreak <= (mem_rdata_q[6:0] == 7'b1110011 && !mem_rdata_q[31:21] && !mem_rdata_q[19:7]);
instr_getq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS;
instr_setq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000001 && ENABLE_IRQ && ENABLE_IRQ_QREGS;
@ -1206,17 +921,6 @@ module picorv32 #(
`endif
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
reg cpuregs_write;
reg [31:0] cpuregs_wrdata;
reg [31:0] cpuregs_rs1;
@ -1840,7 +1544,7 @@ module picorv32 #(
cpu_state <= cpu_state_trap;
end
end
if (CATCH_MISALIGN && resetn && mem_do_rinst && (COMPRESSED_ISA ? reg_pc[0] : |reg_pc[1:0])) begin
if (CATCH_MISALIGN && resetn && mem_do_rinst && (|reg_pc[1:0])) begin
`debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);)
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
next_irq_pending[irq_buserror] = 1;
@ -1868,14 +1572,9 @@ module picorv32 #(
irq_pending <= next_irq_pending & ~MASKED_IRQ;
if (!CATCH_MISALIGN) begin
if (COMPRESSED_ISA) begin
reg_pc[0] <= 0;
reg_next_pc[0] <= 0;
end else begin
reg_pc[1:0] <= 0;
reg_next_pc[1:0] <= 0;
end
end
current_pc = 'bx;
end
endmodule