TTTT.
This commit is contained in:
parent
b99c193120
commit
8196dedc35
20
Makefile
20
Makefile
|
@ -16,27 +16,16 @@ 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 = -Werror -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings
|
||||||
GCC_WARNS += -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic # -Wconversion
|
GCC_WARNS += -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic # -Wconversion
|
||||||
TOOLCHAIN_PREFIX = $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)/bin/riscv32-unknown-elf-
|
TOOLCHAIN_PREFIX = $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)/bin/riscv32-unknown-elf-
|
||||||
COMPRESSED_ISA = C
|
|
||||||
|
|
||||||
# Add things like "export http_proxy=... https_proxy=..." here
|
# Add things like "export http_proxy=... https_proxy=..." here
|
||||||
GIT_ENV = true
|
GIT_ENV = true
|
||||||
|
|
||||||
test_wb: testbench_wb.vvp firmware/firmware.hex
|
|
||||||
$(VVP) -N $<
|
|
||||||
|
|
||||||
test_wb_vcd: testbench_wb.vvp firmware/firmware.hex
|
|
||||||
$(VVP) -N $< +vcd +trace +noerror
|
|
||||||
|
|
||||||
test_verilator: testbench_verilator firmware/firmware.hex
|
test_verilator: testbench_verilator firmware/firmware.hex
|
||||||
./testbench_verilator
|
./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
|
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 \
|
$(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
|
$(MAKE) -C testbench_verilator_dir -f Vpicorv32_wrapper.mk
|
||||||
cp testbench_verilator_dir/Vpicorv32_wrapper testbench_verilator
|
cp testbench_verilator_dir/Vpicorv32_wrapper testbench_verilator
|
||||||
|
|
||||||
|
@ -55,16 +44,9 @@ check.smt2: picorv32.v
|
||||||
synth.v: picorv32.v scripts/yosys/synth_sim.ys
|
synth.v: picorv32.v scripts/yosys/synth_sim.ys
|
||||||
yosys -qv3 -l synth.log 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
|
firmware/firmware.hex: firmware/firmware.elf
|
||||||
$(TOOLCHAIN_PREFIX)objcopy -O verilog $< $@
|
$(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
|
firmware/firmware.elf: $(FIRMWARE_OBJS) $(TEST_OBJS) firmware/sections.lds
|
||||||
$(TOOLCHAIN_PREFIX)gcc -Os -mabi=ilp32 -march=rv32im -ffreestanding -nostdlib -o $@ \
|
$(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 \
|
-Wl,--build-id=none,-Bstatic,-T,firmware/sections.lds,-Map,firmware/firmware.map,--strip-debug \
|
||||||
|
|
349
picorv32.v
349
picorv32.v
|
@ -60,7 +60,6 @@ module picorv32 #(
|
||||||
parameter [ 0:0] BARREL_SHIFTER = 0,
|
parameter [ 0:0] BARREL_SHIFTER = 0,
|
||||||
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,
|
||||||
|
@ -281,8 +280,6 @@ module picorv32 #(
|
||||||
|
|
||||||
wire mem_xfer;
|
wire mem_xfer;
|
||||||
reg mem_la_secondword, mem_la_firstword_reg, last_mem_valid;
|
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 prefetched_high_word;
|
reg prefetched_high_word;
|
||||||
reg clear_prefetched_high_word;
|
reg clear_prefetched_high_word;
|
||||||
|
@ -291,31 +288,25 @@ module picorv32 #(
|
||||||
wire [31:0] mem_rdata_latched_noshuffle;
|
wire [31:0] mem_rdata_latched_noshuffle;
|
||||||
wire [31:0] mem_rdata_latched;
|
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);
|
||||||
assign 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_xfer && |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_latched[1:0] && mem_xfer));
|
((~&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_la_use_prefetched_high_word && !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)));
|
||||||
(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], 2'b00} : {reg_op1[31:2], 2'b00};
|
||||||
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_rdata_latched_noshuffle = (mem_xfer || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q;
|
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;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (!resetn) begin
|
if (!resetn) begin
|
||||||
mem_la_firstword_reg <= 0;
|
mem_la_firstword_reg <= 0;
|
||||||
last_mem_valid <= 0;
|
last_mem_valid <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
if (!last_mem_valid)
|
if (!last_mem_valid)
|
||||||
mem_la_firstword_reg <= mem_la_firstword;
|
mem_la_firstword_reg <= 0;
|
||||||
last_mem_valid <= mem_valid && !mem_ready;
|
last_mem_valid <= mem_valid && !mem_ready;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -351,117 +342,8 @@ module picorv32 #(
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (mem_xfer) begin
|
if (mem_xfer) begin
|
||||||
mem_rdata_q <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata;
|
mem_rdata_q <= mem_rdata;
|
||||||
next_insn_opcode <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata;
|
next_insn_opcode <= 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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -503,7 +385,7 @@ module picorv32 #(
|
||||||
case (mem_state)
|
case (mem_state)
|
||||||
0: begin
|
0: begin
|
||||||
if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) 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_instr <= mem_do_prefetch || mem_do_rinst;
|
||||||
mem_wstrb <= 0;
|
mem_wstrb <= 0;
|
||||||
mem_state <= 1;
|
mem_state <= 1;
|
||||||
|
@ -517,27 +399,12 @@ module picorv32 #(
|
||||||
1: begin
|
1: begin
|
||||||
`assert(mem_wstrb == 0);
|
`assert(mem_wstrb == 0);
|
||||||
`assert(mem_do_prefetch || mem_do_rinst || mem_do_rdata);
|
`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));
|
`assert(mem_instr == (mem_do_prefetch || mem_do_rinst));
|
||||||
if (mem_xfer) begin
|
if (mem_xfer) begin
|
||||||
if (COMPRESSED_ISA && mem_la_read) begin
|
mem_valid <= 0;
|
||||||
mem_valid <= 1;
|
mem_la_secondword <= 0;
|
||||||
mem_la_secondword <= 1;
|
mem_state <= mem_do_rinst || mem_do_rdata ? 0 : 3;
|
||||||
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
|
||||||
end
|
end
|
||||||
2: begin
|
2: begin
|
||||||
|
@ -786,174 +653,26 @@ 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
|
||||||
instr_lui <= mem_rdata_latched[6:0] == 7'b0110111;
|
instr_lui <= 0;
|
||||||
instr_auipc <= mem_rdata_latched[6:0] == 7'b0010111;
|
instr_auipc <= 0;
|
||||||
instr_jal <= mem_rdata_latched[6:0] == 7'b1101111;
|
instr_jal <= 0;
|
||||||
instr_jalr <= mem_rdata_latched[6:0] == 7'b1100111 && mem_rdata_latched[14:12] == 3'b000;
|
instr_jalr <= 0;
|
||||||
instr_retirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ;
|
instr_retirq <= 0;
|
||||||
instr_waitirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000100 && ENABLE_IRQ;
|
instr_waitirq <= 0;
|
||||||
|
|
||||||
is_beq_bne_blt_bge_bltu_bgeu <= mem_rdata_latched[6:0] == 7'b1100011;
|
is_beq_bne_blt_bge_bltu_bgeu <= 0;
|
||||||
is_lb_lh_lw_lbu_lhu <= mem_rdata_latched[6:0] == 7'b0000011;
|
is_lb_lh_lw_lbu_lhu <= 0;
|
||||||
is_sb_sh_sw <= mem_rdata_latched[6:0] == 7'b0100011;
|
is_sb_sh_sw <= 0;
|
||||||
is_alu_reg_imm <= mem_rdata_latched[6:0] == 7'b0010011;
|
is_alu_reg_imm <= 0;
|
||||||
is_alu_reg_reg <= mem_rdata_latched[6:0] == 7'b0110011;
|
is_alu_reg_reg <= 0;
|
||||||
|
|
||||||
{ decoded_imm_j[31:20], decoded_imm_j[10:1], decoded_imm_j[11], decoded_imm_j[19:12], decoded_imm_j[0] } <= $signed({mem_rdata_latched[31:12], 1'b0});
|
{ decoded_imm_j[31:20], decoded_imm_j[10:1], decoded_imm_j[11], decoded_imm_j[19:12], decoded_imm_j[0] } <= $signed({mem_rdata_latched[31:12], 1'b0});
|
||||||
|
|
||||||
decoded_rd <= mem_rdata_latched[11:7];
|
decoded_rd <= 0;
|
||||||
decoded_rs1 <= mem_rdata_latched[19:15];
|
decoded_rs1 <= 0;
|
||||||
decoded_rs2 <= mem_rdata_latched[24:20];
|
decoded_rs2 <= 0;
|
||||||
|
|
||||||
if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS)
|
|
||||||
decoded_rs1[regindex_bits-1] <= 1; // instr_getq
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
compressed_instr <= 0;
|
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
|
end
|
||||||
|
|
||||||
if (decoder_trigger && !decoder_pseudo_trigger) begin
|
if (decoder_trigger && !decoder_pseudo_trigger) begin
|
||||||
|
@ -1005,8 +724,7 @@ module picorv32 #(
|
||||||
instr_rdinstr <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000001000000010);
|
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_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]) ||
|
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_getq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS;
|
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;
|
instr_setq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000001 && ENABLE_IRQ && ENABLE_IRQ_QREGS;
|
||||||
|
@ -1214,7 +932,7 @@ module picorv32 #(
|
||||||
if (!prefetched_high_word)
|
if (!prefetched_high_word)
|
||||||
clear_prefetched_high_word = 0;
|
clear_prefetched_high_word = 0;
|
||||||
if (latched_branch || irq_state || !resetn)
|
if (latched_branch || irq_state || !resetn)
|
||||||
clear_prefetched_high_word = COMPRESSED_ISA;
|
clear_prefetched_high_word = 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
reg cpuregs_write;
|
reg cpuregs_write;
|
||||||
|
@ -1840,7 +1558,7 @@ module picorv32 #(
|
||||||
cpu_state <= cpu_state_trap;
|
cpu_state <= cpu_state_trap;
|
||||||
end
|
end
|
||||||
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);)
|
`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;
|
||||||
|
@ -1868,13 +1586,8 @@ module picorv32 #(
|
||||||
irq_pending <= next_irq_pending & ~MASKED_IRQ;
|
irq_pending <= next_irq_pending & ~MASKED_IRQ;
|
||||||
|
|
||||||
if (!CATCH_MISALIGN) begin
|
if (!CATCH_MISALIGN) begin
|
||||||
if (COMPRESSED_ISA) begin
|
reg_pc[1:0] <= 0;
|
||||||
reg_pc[0] <= 0;
|
reg_next_pc[1:0] <= 0;
|
||||||
reg_next_pc[0] <= 0;
|
|
||||||
end else begin
|
|
||||||
reg_pc[1:0] <= 0;
|
|
||||||
reg_next_pc[1:0] <= 0;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
current_pc = 'bx;
|
current_pc = 'bx;
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue