summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-12-18 00:22:13 -0600
committerAlejandro Soto <alejandro@34project.org>2022-12-18 00:22:23 -0600
commit6d458ad9629268ecfc69881b4fb10dca0498fbd0 (patch)
treeea149276a31f518788c758899ab5ced8a8a8b74c
parentca8b6e6696e279f56faacad39501019c3762a1b7 (diff)
Fix datapath of shifter carry-out during adc/sbc/rsc
-rw-r--r--rtl/core/alu/alu.sv3
-rw-r--r--rtl/core/arm810.sv13
-rw-r--r--rtl/core/control/control.sv2
-rw-r--r--rtl/core/control/data.sv8
-rw-r--r--tb/sim/shifts.S3
-rw-r--r--tb/sim/shifts.py1
6 files changed, 18 insertions, 12 deletions
diff --git a/rtl/core/alu/alu.sv b/rtl/core/alu/alu.sv
index 2f71d6a..c0ccd32 100644
--- a/rtl/core/alu/alu.sv
+++ b/rtl/core/alu/alu.sv
@@ -8,6 +8,7 @@ module core_alu
input logic[W - 1:0] a,
b,
input logic c_in,
+ c_logic,
output logic[W - 1:0] q,
output psr_flags nzcv,
@@ -106,7 +107,7 @@ module core_alu
v = 1'bx;
unique case(op)
`ALU_AND, `ALU_EOR, `ALU_TST, `ALU_TEQ, `ALU_ORR, `ALU_MOV, `ALU_BIC, `ALU_MVN:
- c = c_in;
+ c = c_logic;
`ALU_ADD, `ALU_ADC, `ALU_CMN: begin
c = c_add;
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv
index 4b08a2c..8ebabc1 100644
--- a/rtl/core/arm810.sv
+++ b/rtl/core/arm810.sv
@@ -64,18 +64,17 @@ module arm810
);
reg_num rd, ra, rb;
- logic explicit_branch, writeback, c_in;
+ logic explicit_branch, writeback;
ptr branch_target, pc_visible;
psr_mode reg_mode;
- alu_op alu_ctrl;
shifter_control shifter_ctrl;
- word alu_a, alu_b, wr_value;
+ word wr_value;
logic[7:0] shifter_shift;
core_control control
(
- .branch(explicit_branch),
.alu(alu_ctrl),
+ .branch(explicit_branch),
.shifter(shifter_ctrl),
.mem_addr(data_addr),
.mem_start(data_start),
@@ -121,9 +120,10 @@ module arm810
.*
);
+ word alu_a, alu_b, q_alu;
+ logic c_logic, alu_v_valid;
+ alu_op alu_ctrl;
psr_flags alu_flags;
- logic alu_v_valid;
- word q_alu;
core_alu #(.W(32)) alu
(
@@ -131,6 +131,7 @@ module arm810
.a(alu_a),
.b(alu_b),
.q(q_alu),
+ .c_in(flags.c),
.nzcv(alu_flags),
.v_valid(alu_v_valid),
.*
diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv
index cbc7191..a421572 100644
--- a/rtl/core/control/control.sv
+++ b/rtl/core/control/control.sv
@@ -42,7 +42,7 @@ module core_control
writeback,
breakpoint,
update_flags,
- c_in,
+ c_logic,
output reg_num rd,
ra,
rb,
diff --git a/rtl/core/control/data.sv b/rtl/core/control/data.sv
index 5d34b13..3174ee1 100644
--- a/rtl/core/control/data.sv
+++ b/rtl/core/control/data.sv
@@ -31,7 +31,7 @@ module core_control_data
output shifter_control shifter,
output word shifter_base,
output logic[7:0] shifter_shift,
- output logic c_in,
+ output logic c_logic,
trivial_shift,
data_snd_shift_by_reg
);
@@ -75,7 +75,7 @@ module core_control_data
always_ff @(posedge clk or negedge rst_n)
if(!rst_n) begin
alu <= {$bits(alu){1'b0}};
- c_in <= 0;
+ c_logic <= 0;
shifter <= {$bits(shifter){1'b0}};
data_imm <= {$bits(data_imm){1'b0}};
saved_base <= 0;
@@ -84,7 +84,7 @@ module core_control_data
data_snd_shift_by_reg <= 0;
end else if(next_cycle.issue) begin
alu <= dec.data.op;
- c_in <= flags.c;
+ c_logic <= 0;
data_imm <= dec.snd.imm;
data_shift_imm <= dec.snd.shift_imm;
@@ -99,7 +99,7 @@ module core_control_data
saved_base <= rd_value_b;
data_snd_shift_by_reg <= 0;
end else if(next_cycle.with_shift) begin
- c_in <= c_shifter;
+ c_logic <= c_shifter;
saved_base <= q_shifter;
end else if(next_cycle.transfer) begin
if(ldst_next)
diff --git a/tb/sim/shifts.S b/tb/sim/shifts.S
index 6209157..ba464f7 100644
--- a/tb/sim/shifts.S
+++ b/tb/sim/shifts.S
@@ -17,4 +17,7 @@ reset:
ldr r4, =(512 << 20)
ldr r5, =#60
lsr r4, r4, r5
+ mov r5, #0
+ ldr r12, =-123456
+ adc r5, r5, r12, asr #18
mov pc, lr
diff --git a/tb/sim/shifts.py b/tb/sim/shifts.py
index 9923124..11413e5 100644
--- a/tb/sim/shifts.py
+++ b/tb/sim/shifts.py
@@ -3,3 +3,4 @@ def final():
assert_reg(r2, 0x00015000)
assert_reg(r3, 0xaaa9fd55)
assert_reg(r4, 0)
+ assert_reg(r5, -1)