Skip to content

Commit 93daddf

Browse files
committed
abstracted some control unit LS logic
1 parent 51c9400 commit 93daddf

File tree

2 files changed

+72
-82
lines changed

2 files changed

+72
-82
lines changed

cores/gba/rtl/cpu/ControlUnit.sv

Lines changed: 14 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -423,43 +423,17 @@ module GBA_ControlUnit (
423423
// the memory access is complete.
424424
control_signals.incrementer_writeback = 1'b1;
425425

426-
// Update the address bus to use the output of the ALU, which
427-
// will is the effective address for the memory access
428-
control_signals.addr_bus_src = ADDR_SRC_ALU;
429-
430-
// Subtract (0) or add (1) the offset to the base register depending
431-
// on the U bit in the instruction.
432-
control_signals.ALU_op = decoder_bus.word.arm.ls.U ? ALU_OP_ADD : ALU_OP_SUB;
433-
434-
// If its pre offset we add/subtract the offset to the base register before the memory access
435-
if (decoder_bus.word.arm.ls.P == ARM_LDR_STR_PRE_OFFSET) begin
436-
if (decoder_bus.word.arm.ls.wt == 1'b1) begin
437-
// Updating the base register with the offset is enabled so we
438-
// latch operand b for the writeback in the next cycle
439-
control_signals.ALU_latch_op_b = 1'b1;
440-
end
441-
end else begin
442-
// Post offset, so we don't add/subtract operand b
443-
// before its used to update the address bus
444-
control_signals.ALU_disable_op_b = 1'b1;
445-
446-
// We also make sure to latch operand b so that we can
447-
// use it for the writeback in the next cycle
448-
control_signals.ALU_latch_op_b = 1'b1;
449-
end
426+
control_signals |= calc_ls_address(
427+
decoder_bus.word.arm.ls.U,
428+
decoder_bus.word.arm.ls.P,
429+
decoder_bus.word.arm.ls.wt,
430+
decoder_bus.word.arm.ls.I,
431+
decoder_bus.word.arm.ls.offset.imm12
432+
);
450433

451434
// Depending on the instruction, operand b can either be an immediate or
452435
// a register with optional shift
453436
if (decoder_bus.word.arm.ls.I == ARM_LDR_STR_IMMEDIATE) begin
454-
// Immediate offset with an optional rotation/shift
455-
456-
control_signals.B_bus_source = B_BUS_SRC_IMM;
457-
control_signals.B_bus_imm = 24'(decoder_bus.word.arm.ls.offset.imm12);
458-
459-
// No shift
460-
control_signals.shift_type = SHIFT_LSL;
461-
control_signals.shift_amount = 5'd0;
462-
463437
end else begin
464438
// We are using a register offset with an optional shift
465439

@@ -575,55 +549,13 @@ module GBA_ControlUnit (
575549
// the memory access is complete.
576550
control_signals.incrementer_writeback = 1'b1;
577551

578-
// Update the address bus to use the output of the ALU, which
579-
// will is the effective address for the memory access
580-
control_signals.addr_bus_src = ADDR_SRC_ALU;
581-
582-
// Subtract (0) or add (1) the offset to the base register depending
583-
// on the U bit in the instruction.
584-
control_signals.ALU_op = decoder_bus.word.arm.ls_half.U ? ALU_OP_ADD : ALU_OP_SUB;
585-
586-
$display("[ControlUnit] ALU operation for address calculation is %s",
587-
control_signals.ALU_op == ALU_OP_ADD ? "ADD" : "SUB");
588-
589-
// If its pre offset we add/subtract the offset to the base register before the memory access
590-
if (decoder_bus.word.arm.ls_half.P == ARM_LDR_STR_PRE_OFFSET) begin
591-
if (decoder_bus.word.arm.ls_half.W == 1'b1) begin
592-
// Updating the base register with the offset is enabled so we
593-
// latch operand b for the writeback in the next cycle
594-
control_signals.ALU_latch_op_b = 1'b1;
595-
end
596-
end else begin
597-
// Post offset, so we don't add/subtract operand b
598-
// before its used to update the address bus
599-
control_signals.ALU_disable_op_b = 1'b1;
600-
601-
// We also make sure to latch operand b so that we can
602-
// use it for the writeback in the next cycle
603-
control_signals.ALU_latch_op_b = 1'b1;
604-
end
605-
606-
// Depending on the instruction, operand b can either be an immediate or
607-
// a register with optional shift
608-
if (decoder_bus.word.arm.ls_half.I) begin
609-
// Immediate offset with an optional rotation/shift
610-
611-
control_signals.B_bus_source = B_BUS_SRC_IMM;
612-
control_signals.B_bus_imm = 24'(decoder_bus.word.arm.ls_half.imm_offset);
613-
614-
// No shift
615-
control_signals.shift_type = SHIFT_LSL;
616-
control_signals.shift_amount = 5'd0;
617-
618-
end else begin
619-
// We are using a register offset
620-
621-
control_signals.B_bus_source = B_BUS_SRC_REG_RM;
622-
623-
// No shift
624-
control_signals.shift_type = SHIFT_LSL;
625-
control_signals.shift_amount = 5'd0;
626-
end
552+
control_signals |= calc_ls_address(
553+
decoder_bus.word.arm.ls_half.U,
554+
decoder_bus.word.arm.ls_half.P,
555+
decoder_bus.word.arm.ls_half.W,
556+
decoder_bus.word.arm.ls_half.I,
557+
12'(decoder_bus.word.arm.ls_half.imm_offset)
558+
);
627559
end
628560

629561
if (decoder_bus.instr_type == ARM_INSTR_LDR_HALF) begin

cores/gba/rtl/cpu/control_util.sv

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import gba_control_types_pkg::*;
2+
import gba_cpu_types_pkg::*;
3+
import gba_cpu_decoder_types_pkg::*;
24

35
package control_util_pkg;
46

@@ -14,4 +16,60 @@ package control_util_pkg;
1416
return s;
1517
endfunction : fetch_next_instr
1618

19+
function automatic control_t calc_ls_address(logic U, logic P, logic W, logic is_imm,
20+
logic [11:0] imm);
21+
22+
control_t s = '0;
23+
24+
// Update the address bus to use the output of the ALU, which
25+
// will is the effective address for the memory access
26+
s.addr_bus_src = ADDR_SRC_ALU;
27+
28+
// Subtract (0) or add (1) the offset to the base register depending
29+
// on the U bit in the instruction.
30+
s.ALU_op = U ? ALU_OP_ADD : ALU_OP_SUB;
31+
32+
$display("[ControlUnit] ALU operation for address calculation is %s",
33+
s.ALU_op == ALU_OP_ADD ? "ADD" : "SUB");
34+
35+
// If its pre offset we add/subtract the offset to the base register before the memory access
36+
if (P == ARM_LDR_STR_PRE_OFFSET) begin
37+
if (W == 1'b1) begin
38+
// Updating the base register with the offset is enabled so we
39+
// latch operand b for the writeback in the next cycle
40+
s.ALU_latch_op_b = 1'b1;
41+
end
42+
end else begin
43+
// Post offset, so we don't add/subtract operand b
44+
// before its used to update the address bus
45+
s.ALU_disable_op_b = 1'b1;
46+
47+
// We also make sure to latch operand b so that we can
48+
// use it for the writeback in the next cycle
49+
s.ALU_latch_op_b = 1'b1;
50+
end
51+
52+
// Depending on the instruction, operand b can either be an immediate or
53+
// a register with optional shift
54+
if (is_imm) begin
55+
// Immediate offset with an optional rotation/shift
56+
57+
s.B_bus_source = B_BUS_SRC_IMM;
58+
s.B_bus_imm = 24'(imm);
59+
60+
// No shift
61+
s.shift_type = SHIFT_LSL;
62+
s.shift_amount = 5'd0;
63+
64+
end else begin
65+
// We are using a register offset
66+
67+
s.B_bus_source = B_BUS_SRC_REG_RM;
68+
69+
// No shift
70+
s.shift_type = SHIFT_LSL;
71+
s.shift_amount = 5'd0;
72+
end
73+
endfunction : calc_ls_address
74+
1775
endpackage : control_util_pkg

0 commit comments

Comments
 (0)