From e8da3c44cf2de617cca77eb280580c99c19157dd Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 20 May 2020 17:47:41 +0100 Subject: [PATCH] normalise XER regs carry/32 and SO --- src/soc/fu/alu/input_stage.py | 10 +++++----- src/soc/fu/alu/main_stage.py | 8 ++++---- src/soc/fu/alu/output_stage.py | 4 ++-- src/soc/fu/alu/pipe_data.py | 18 +++++++++--------- src/soc/fu/alu/test/test_pipe_caller.py | 12 +++++++----- src/soc/fu/logical/main_stage.py | 2 +- src/soc/fu/logical/pipe_data.py | 12 ++++++------ src/soc/fu/logical/test/test_pipe_caller.py | 6 ++++-- 8 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/soc/fu/alu/input_stage.py b/src/soc/fu/alu/input_stage.py index fd3fd1ed..426f1248 100644 --- a/src/soc/fu/alu/input_stage.py +++ b/src/soc/fu/alu/input_stage.py @@ -1,5 +1,5 @@ # This stage is intended to adjust the input data before sending it to -# the acutal ALU. Things like handling inverting the input, carry_in +# the acutal ALU. Things like handling inverting the input, xer_ca # generation for subtraction, and handling of immediates should happen # here from nmigen import (Module, Signal, Cat, Const, Mux, Repl, signed, @@ -43,15 +43,15 @@ class ALUInputStage(PipeModBase): # either copy incoming carry or set to 1/0 as defined by op with m.Switch(ctx.op.input_carry): with m.Case(CryIn.ZERO): - comb += self.o.carry_in.eq(0) + comb += self.o.xer_ca.eq(0b00) with m.Case(CryIn.ONE): - comb += self.o.carry_in.eq(1) + comb += self.o.xer_ca.eq(0b11) # set both CA and CA32 with m.Case(CryIn.CA): - comb += self.o.carry_in.eq(self.i.carry_in) + comb += self.o.xer_ca.eq(self.i.xer_ca) ##### sticky overflow and context (both pass-through) ##### - comb += self.o.so.eq(self.i.so) + comb += self.o.xer_so.eq(self.i.xer_so) comb += self.o.ctx.eq(ctx) return m diff --git a/src/soc/fu/alu/main_stage.py b/src/soc/fu/alu/main_stage.py index 6eeb2ca3..21738144 100644 --- a/src/soc/fu/alu/main_stage.py +++ b/src/soc/fu/alu/main_stage.py @@ -24,8 +24,8 @@ class ALUMainStage(PipeModBase): def elaborate(self, platform): m = Module() comb = m.d.comb - cry_o, o, cr0 = self.o.xer_co, self.o.o, self.o.cr0 - a, b, cry_i, op = self.i.a, self.i.b, self.i.carry_in, self.i.ctx.op + cry_o, o, cr0 = self.o.xer_ca, self.o.o, self.o.cr0 + a, b, cry_i, op = self.i.a, self.i.b, self.i.xer_ca, self.i.ctx.op # check if op is 32-bit, and get sign bit from operand a is_32bit = Signal(reset_less=True) @@ -40,7 +40,7 @@ class ALUMainStage(PipeModBase): with m.If((op.insn_type == InternalOp.OP_ADD) | (op.insn_type == InternalOp.OP_CMP)): # in bit 0, 1+carry_in creates carry into bit 1 and above - comb += add_a.eq(Cat(cry_i, a, Const(0, 1))) + comb += add_a.eq(Cat(cry_i[0], a, Const(0, 1))) comb += add_b.eq(Cat(Const(1, 1), b, Const(0, 1))) comb += add_o.eq(add_a + add_b) @@ -86,7 +86,7 @@ class ALUMainStage(PipeModBase): ###### sticky overflow and context, both pass-through ##### - comb += self.o.xer_so.data.eq(self.i.so) + comb += self.o.xer_so.data.eq(self.i.xer_so) comb += self.o.ctx.eq(self.i.ctx) return m diff --git a/src/soc/fu/alu/output_stage.py b/src/soc/fu/alu/output_stage.py index 08946de1..8b953347 100644 --- a/src/soc/fu/alu/output_stage.py +++ b/src/soc/fu/alu/output_stage.py @@ -38,8 +38,8 @@ class ALUOutputStage(PipeModBase): comb += target.eq(o) # Handle carry_out - comb += self.o.xer_co.data.eq(self.i.xer_co.data) - comb += self.o.xer_co.ok.eq(op.output_carry) + comb += self.o.xer_ca.data.eq(self.i.xer_ca.data) + comb += self.o.xer_ca.ok.eq(op.output_carry) # create condition register cr0 and sticky-overflow is_zero = Signal(reset_less=True) diff --git a/src/soc/fu/alu/pipe_data.py b/src/soc/fu/alu/pipe_data.py index 744db57a..0d299ef4 100644 --- a/src/soc/fu/alu/pipe_data.py +++ b/src/soc/fu/alu/pipe_data.py @@ -25,21 +25,21 @@ class ALUInputData(IntegerData): super().__init__(pspec) self.a = Signal(64, reset_less=True) # RA self.b = Signal(64, reset_less=True) # RB/immediate - self.so = Signal(reset_less=True) - self.carry_in = Signal(reset_less=True) + self.xer_so = Signal(reset_less=True) # XER bit 32: SO + self.xer_ca = Signal(2, reset_less=True) # XER bit 34/45: CA/CA32 def __iter__(self): yield from super().__iter__() yield self.a yield self.b - yield self.carry_in - yield self.so + yield self.xer_ca + yield self.xer_so def eq(self, i): lst = super().eq(i) return lst + [self.a.eq(i.a), self.b.eq(i.b), - self.carry_in.eq(i.carry_in), - self.so.eq(i.so)] + self.xer_ca.eq(i.xer_ca), + self.xer_so.eq(i.xer_so)] # TODO: ALUIntermediateData which does not have # cr0, ov, ov32 in it (because they are generated as outputs by @@ -51,14 +51,14 @@ class ALUOutputData(IntegerData): super().__init__(pspec) self.o = Signal(64, reset_less=True, name="stage_o") self.cr0 = Data(4, name="cr0") - self.xer_co = Data(2, name="xer_co") # bit0: co, bit1: co32 + self.xer_ca = Data(2, name="xer_co") # bit0: ca, bit1: ca32 self.xer_ov = Data(2, name="xer_ov") # bit0: ov, bit1: ov32 self.xer_so = Data(1, name="xer_so") def __iter__(self): yield from super().__iter__() yield self.o - yield self.xer_co + yield self.xer_ca yield self.cr0 yield self.xer_ov yield self.xer_so @@ -66,7 +66,7 @@ class ALUOutputData(IntegerData): def eq(self, i): lst = super().eq(i) return lst + [self.o.eq(i.o), - self.xer_co.eq(i.xer_co), + self.xer_ca.eq(i.xer_ca), self.cr0.eq(i.cr0), self.xer_ov.eq(i.xer_ov), self.xer_so.eq(i.xer_so)] diff --git a/src/soc/fu/alu/test/test_pipe_caller.py b/src/soc/fu/alu/test/test_pipe_caller.py index 4f682f67..875bfab4 100644 --- a/src/soc/fu/alu/test/test_pipe_caller.py +++ b/src/soc/fu/alu/test/test_pipe_caller.py @@ -67,9 +67,11 @@ def set_alu_inputs(alu, dec2, sim): def set_extra_alu_inputs(alu, dec2, sim): carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0 - yield alu.p.data_i.carry_in.eq(carry) + carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0 + yield alu.p.data_i.xer_ca[0].eq(carry) + yield alu.p.data_i.xer_ca[1].eq(carry32) so = 1 if sim.spr['XER'][XER_bits['SO']] else 0 - yield alu.p.data_i.so.eq(so) + yield alu.p.data_i.xer_so.eq(so) # This test bench is a bit different than is usual. Initially when I @@ -236,7 +238,7 @@ class TestRunner(FHDLTestCase): write_reg_idx = yield pdecode2.e.write_reg.data expected = simulator.gpr(write_reg_idx).value print(f"expected {expected:x}, actual: {alu_out:x}") - self.assertEqual(expected, alu_out) + self.assertEqual(expected, alu_out, code) yield from self.check_extra_alu_outputs(alu, pdecode2, simulator, code) @@ -263,10 +265,10 @@ class TestRunner(FHDLTestCase): cry_out = yield dec2.e.output_carry if cry_out: expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0 - real_carry = yield alu.n.data_o.xer_co.data[0] # XXX CO not CO32 + real_carry = yield alu.n.data_o.xer_ca.data[0] # XXX CO not CO32 self.assertEqual(expected_carry, real_carry, code) expected_carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0 - real_carry32 = yield alu.n.data_o.xer_co.data[1] # XXX CO32 + real_carry32 = yield alu.n.data_o.xer_ca.data[1] # XXX CO32 self.assertEqual(expected_carry32, real_carry32, code) diff --git a/src/soc/fu/logical/main_stage.py b/src/soc/fu/logical/main_stage.py index 9c223ddc..48857089 100644 --- a/src/soc/fu/logical/main_stage.py +++ b/src/soc/fu/logical/main_stage.py @@ -132,7 +132,7 @@ class LogicalMainStage(PipeModBase): ###### sticky overflow and context, both pass-through ##### - comb += self.o.xer_so.data.eq(self.i.so) + comb += self.o.xer_so.data.eq(self.i.xer_so) comb += self.o.ctx.eq(self.i.ctx) return m diff --git a/src/soc/fu/logical/pipe_data.py b/src/soc/fu/logical/pipe_data.py index 3b1b1351..aed78689 100644 --- a/src/soc/fu/logical/pipe_data.py +++ b/src/soc/fu/logical/pipe_data.py @@ -8,18 +8,18 @@ class LogicalInputData(IntegerData): super().__init__(pspec) self.a = Signal(64, reset_less=True) # RA self.b = Signal(64, reset_less=True) # RB/immediate - self.so = Signal(reset_less=True) - self.carry_in = Signal(reset_less=True) + self.xer_so = Signal(reset_less=True) # XER bit 32: SO + self.xer_ca = Signal(2, reset_less=True) # XER bit 34/45: CA/CA32 def __iter__(self): yield from super().__iter__() yield self.a yield self.b - yield self.carry_in - yield self.so + yield self.xer_ca + yield self.xer_so def eq(self, i): lst = super().eq(i) return lst + [self.a.eq(i.a), self.b.eq(i.b), - self.carry_in.eq(i.carry_in), - self.so.eq(i.so)] + self.xer_ca.eq(i.xer_ca), + self.xer_so.eq(i.xer_so)] diff --git a/src/soc/fu/logical/test/test_pipe_caller.py b/src/soc/fu/logical/test/test_pipe_caller.py index 05e1a816..4a22308c 100644 --- a/src/soc/fu/logical/test/test_pipe_caller.py +++ b/src/soc/fu/logical/test/test_pipe_caller.py @@ -68,9 +68,11 @@ def set_alu_inputs(alu, dec2, sim): def set_extra_alu_inputs(alu, dec2, sim): carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0 - yield alu.p.data_i.carry_in.eq(carry) + carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0 + yield alu.p.data_i.xer_ca[0].eq(carry) + yield alu.p.data_i.xer_ca[1].eq(carry32) so = 1 if sim.spr['XER'][XER_bits['SO']] else 0 - yield alu.p.data_i.so.eq(so) + yield alu.p.data_i.xer_so.eq(so) # This test bench is a bit different than is usual. Initially when I -- 2.30.2