File tree Expand file tree Collapse file tree 8 files changed +538
-448
lines changed
Expand file tree Collapse file tree 8 files changed +538
-448
lines changed Original file line number Diff line number Diff line change @@ -119,10 +119,11 @@ jobs:
119119 - ldrh_strh_imm_offset
120120 - ldr_str_sp_rel
121121 - add_cmp_mov_hi
122+ - add_sub_sp
122123 - b
123124 - bcc
124125 - bx
125- - add_sub_sp
126+ - bl_blx_prefix
126127 # - push_pop
127128
128129 steps :
Original file line number Diff line number Diff line change @@ -1149,10 +1149,12 @@ module GBA_ControlUnit (
11491149 // TODO: Currently this instr lasts an extra cycle. We need to overlap the fetch and cycle 2.
11501150 ARM_INSTR_BRANCH_LINK : begin
11511151 if (cycle == 8'd0 ) begin
1152- // Rd should be R14 (LR)
1152+ // Rd == R14 (LR)
11531153 control_signals.ALU_writeback = ALU_WB_REG_RD ;
11541154
11551155 control_signals.ALU_op = ALU_OP_SUB ;
1156+
1157+ // Rn == R15 (PC)
11561158 control_signals.A_bus_source = A_BUS_SRC_RN ;
11571159
11581160 control_signals.B_bus_source = B_BUS_SRC_IMM ;
@@ -1200,6 +1202,31 @@ module GBA_ControlUnit (
12001202 end
12011203 end
12021204
1205+ ARM_INSTR_THUMB_LONG_BRANCH_LINK_0 : begin
1206+ if (cycle == 8'd0 ) begin
1207+ control_signals.addr_bus_src = ADDR_SRC_INCR ;
1208+ control_signals | = fetch_next_instr ();
1209+ control_signals.pipeline_advance = 1'b1 ;
1210+ control_signals.incrementer_writeback = 1'b1 ;
1211+
1212+ control_signals.ALU_op = ALU_OP_ADD ;
1213+
1214+ // Rn == R15 (PC)
1215+ control_signals.A_bus_source = A_BUS_SRC_RN ;
1216+
1217+ // Rd == R14 (LR)
1218+ control_signals.ALU_writeback = ALU_WB_REG_RD ;
1219+
1220+ control_signals.B_bus_source = B_BUS_SRC_IMM ;
1221+ control_signals.B_bus_imm = decoder_bus.word.arm.branch.imm24;
1222+ control_signals.B_bus_sign_extend = 1'b1 ;
1223+
1224+ control_signals.shift_type = SHIFT_LSL ;
1225+ control_signals.shift_amount = 5'd12 ;
1226+
1227+ end
1228+ end
1229+
12031230 ARM_INSTR_SWI : begin
12041231 if (cycle == 8'd0 ) begin
12051232 // Rd should be R14 (LR)
Original file line number Diff line number Diff line change @@ -37,6 +37,17 @@ module GBA_Decoder (
3737 end
3838 end
3939
40+ logic [10 : 0 ] thumb_bl_imm11;
41+
42+ always_ff @ (posedge clk) begin
43+ if (reset) begin
44+ thumb_bl_imm11 <= 11'b0 ;
45+ end else if (execution_mode == MODE_THUMB && IR_THUMB [15 : 11 ] == 5'b11110 ) begin
46+ thumb_bl_imm11 <= IR_THUMB [10 : 0 ];
47+ $display (" [GBA_Decoder] Latched upper half of BL immediate value 0x%03x " , IR_THUMB [10 : 0 ]);
48+ end
49+ end
50+
4051 always_comb begin
4152 bus.instr_type = ARM_INSTR_UNDEFINED ;
4253 bus.condition_pass = 1'b1 ;
@@ -344,7 +355,20 @@ module GBA_Decoder (
344355
345356 // Long Branch with Link
346357 16'b1111_????_????_???? : begin
347- $display (" [Decoder] Detected THUMB BL instruction with IR=0x%08x " , IR_THUMB );
358+ if (IR_THUMB [11 ] == 1'b0 ) begin
359+ // bus.instr_type = ARM_INSTR_BRANCH_LINK;
360+
361+ bus.instr_type = ARM_INSTR_THUMB_LONG_BRANCH_LINK_0 ;
362+
363+ // Overwrite Rn and Rd
364+ bus.decoded_regs.Rn = 4'd15 ;
365+ bus.decoded_regs.Rd = 4'd14 ;
366+
367+ bus.word.arm.branch.imm24 = {{ 13 { IR_THUMB [10 ]}} , IR_THUMB [10 : 0 ]} ;
368+ $display (" [Decoder] Detected THUMB BL instruction with IR=0x%08x " , IR_THUMB );
369+ end else begin
370+
371+ end
348372 end
349373
350374 // Add Offset to Stack Pointer
Original file line number Diff line number Diff line change 1+ module ExampleModule (
2+ input logic clk,
3+ );
4+
5+ always_ff @ (posedge clk) begin
6+ // do stuff here
7+ end
Original file line number Diff line number Diff line change @@ -295,6 +295,9 @@ package gba_cpu_types_pkg;
295295 // / Branch and exchange (BX)
296296 ARM_INSTR_BRANCH_EX ,
297297
298+ // / Thumb Long Branch with Link (BL) - first instruction
299+ ARM_INSTR_THUMB_LONG_BRANCH_LINK_0 ,
300+
298301 // ======================================================
299302 // Data Processing
300303 // ======================================================
@@ -355,7 +358,11 @@ package gba_cpu_types_pkg;
355358 ARM_INSTR_MRS ,
356359
357360 // / MSR (write CPSR/SPSR)
358- ARM_INSTR_MSR
361+ ARM_INSTR_MSR ,
362+
363+ // / This instruction is for the BL instruction in thumb mode which takes
364+ // / 2 instructions to execute.
365+ ARM_INSTR_THUMB_STALL
359366
360367 } arm_instr_t ;
361368
Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ add_subdirectory(golden/nba/src/nba)
44
55add_subdirectory (cpu )
66add_subdirectory (arm.gba )
7+ add_subdirectory (thumb.gba )
78
89add_executable (test_gba
910 ${CMAKE_CURRENT_SOURCE_DIR} /main.cpp
@@ -22,6 +23,7 @@ target_link_libraries(test_gba
2223 PRIVATE
2324 test_cpu_adv
2425 test_arm_gba
26+ test_thumb_gba
2527 GTest::gtest
2628 libcommon
2729)
Load Diff Large diffs are not rendered by default.
You can’t perform that action at this time.
0 commit comments