Skip to content

Commit c78e7fa

Browse files
committed
fixed LDM fetch
1 parent ca3a184 commit c78e7fa

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

cores/gba/rtl/cpu/ControlUnit.sv

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ module GBA_ControlUnit (
884884

885885
// Latch the last fetched word into the register file and
886886
// increment address for the next memory access
887-
if (cycle < 8'd1 + 8'(regs_count)) begin
887+
if (cycle < 8'(regs_count)) begin
888888
control_signals.Rp_imm =
889889
get_ith_bit(4'(cycle - 8'd2), decoder_bus.word.arm.block.reg_list);
890890

@@ -901,11 +901,38 @@ module GBA_ControlUnit (
901901
control_signals.ALU_op = ALU_OP_MOV;
902902
end else
903903

904+
// Latch the last fetched word into the register file and
905+
// update the address bus back to PC for the next instruction
906+
// So we can fetch next cycle
907+
if (cycle == 8'(regs_count)) begin
908+
control_signals.Rp_imm =
909+
get_ith_bit(4'(cycle - 8'd2), decoder_bus.word.arm.block.reg_list);
910+
911+
control_signals.ALU_writeback = ALU_WB_REG_RP;
912+
913+
control_signals.B_bus_source = B_BUS_SRC_READ_DATA;
914+
915+
control_signals.addr_bus_src = ADDR_SRC_PC;
916+
917+
// Read the next word in the block
918+
control_signals.memory_read_en = 1'b1;
919+
920+
// Let the B_bus word pass through the ALU unmodified for the writeback
921+
control_signals.ALU_op = ALU_OP_MOV;
922+
end else
923+
904924
// Latch the final fetched word into the register file and
905925
// update the address bus back to PC for the next instruction
906926
if (cycle == 8'd1 + 8'(regs_count) && regs_count != 0) begin
907927

908-
control_signals.addr_bus_src = ADDR_SRC_INCR;
928+
// If in the final cycle, r15 is being written too,
929+
// then we need to update the address as well.
930+
931+
if (decoder_bus.word.arm.block.reg_list[15]) begin
932+
control_signals.addr_bus_src = ADDR_SRC_ALU;
933+
end else begin
934+
control_signals.addr_bus_src = ADDR_SRC_INCR;
935+
end
909936

910937
control_signals |= fetch_next_instr();
911938

cores/gba/tests/arm.gba/test_arm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ TEST(ARM_GBA_Tests, CPUInstrsAll) {
375375

376376
instructions_executed++;
377377

378-
ASSERT_GT(max_ticks, 0)
378+
EXPECT_GT(max_ticks, 0)
379379
<< "Timeout in test.";
380380

381381
if (harness.get_top().rootp->GameboyAdvance__DOT__cpu_inst__DOT__flush_req) {

0 commit comments

Comments
 (0)