projects
/
soc.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
fcc9bc0
)
normalise XER regs carry/32 and SO
author
Luke Kenneth Casson Leighton
<lkcl@lkcl.net>
Wed, 20 May 2020 16:47:41 +0000
(17:47 +0100)
committer
Luke Kenneth Casson Leighton
<lkcl@lkcl.net>
Wed, 20 May 2020 16:47:41 +0000
(17:47 +0100)
src/soc/fu/alu/input_stage.py
patch
|
blob
|
history
src/soc/fu/alu/main_stage.py
patch
|
blob
|
history
src/soc/fu/alu/output_stage.py
patch
|
blob
|
history
src/soc/fu/alu/pipe_data.py
patch
|
blob
|
history
src/soc/fu/alu/test/test_pipe_caller.py
patch
|
blob
|
history
src/soc/fu/logical/main_stage.py
patch
|
blob
|
history
src/soc/fu/logical/pipe_data.py
patch
|
blob
|
history
src/soc/fu/logical/test/test_pipe_caller.py
patch
|
blob
|
history
diff --git
a/src/soc/fu/alu/input_stage.py
b/src/soc/fu/alu/input_stage.py
index fd3fd1edd78c097acc7d242781e52ac317fac6dc..426f1248a5fbea6db594df71c2d9464f836c714e 100644
(file)
--- 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
# 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,
# 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):
# 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(0b0
0)
with m.Case(CryIn.ONE):
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):
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) #####
##### 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
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 6eeb2ca388de123e8c8012ef077133c35ed3ae27..2173814465efa1b014248849c4ee1d240e226c30 100644
(file)
--- 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
def elaborate(self, platform):
m = Module()
comb = m.d.comb
- cry_o, o, cr0 = self.o.xer_c
o
, 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_c
a
, 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)
# 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
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)
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 #####
###### 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
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 08946de12cb5e8dc3ab0d0fa67a6d92ec27a7026..8b95334702bcc2d0969a017e1fab312c165c09a0 100644
(file)
--- 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 += target.eq(o)
# Handle carry_out
- comb += self.o.xer_c
o.data.eq(self.i.xer_co
.data)
- comb += self.o.xer_c
o
.ok.eq(op.output_carry)
+ comb += self.o.xer_c
a.data.eq(self.i.xer_ca
.data)
+ comb += self.o.xer_c
a
.ok.eq(op.output_carry)
# create condition register cr0 and sticky-overflow
is_zero = Signal(reset_less=True)
# 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 744db57a6c9e4678ffe689e7149aa1f04d98761b..0d299ef477e987d466d5e5fcda0e3e6cc836b39a 100644
(file)
--- 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
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
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),
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
# 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")
super().__init__(pspec)
self.o = Signal(64, reset_less=True, name="stage_o")
self.cr0 = Data(4, name="cr0")
- self.xer_c
o = Data(2, name="xer_co") # bit0: co, bit1: co
32
+ self.xer_c
a = Data(2, name="xer_co") # bit0: ca, bit1: ca
32
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
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_c
o
+ yield self.xer_c
a
yield self.cr0
yield self.xer_ov
yield self.xer_so
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),
def eq(self, i):
lst = super().eq(i)
return lst + [self.o.eq(i.o),
- self.xer_c
o.eq(i.xer_co
),
+ self.xer_c
a.eq(i.xer_ca
),
self.cr0.eq(i.cr0),
self.xer_ov.eq(i.xer_ov), self.xer_so.eq(i.xer_so)]
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 4f682f6751373ebd1d3dfef00cd4f8ae04a1baa5..875bfab43bcea61ee85e94fe28d7b3b3ee4458cf 100644
(file)
--- 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
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
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
# 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}")
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)
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
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_c
o
.data[0] # XXX CO not CO32
+ real_carry = yield alu.n.data_o.xer_c
a
.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
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_c
o
.data[1] # XXX CO32
+ real_carry32 = yield alu.n.data_o.xer_c
a
.data[1] # XXX CO32
self.assertEqual(expected_carry32, real_carry32, code)
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 9c223ddceaa979363c21341f2d9f721e347da5ea..4885708997b835b62a0be10b25bb2c5ee8cdf7ac 100644
(file)
--- 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 #####
###### 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
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 3b1b13513a4a6b07ea549623f02c42a6c4821335..aed7868977d08e06aaaadf9cca38b19036153d1d 100644
(file)
--- 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
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
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),
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 05e1a816967ac3f019c8a407ce348bb72688a1c8..4a22308c071ef86cde9bfd8f2e3b5a1d4b348f48 100644
(file)
--- 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
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
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
# This test bench is a bit different than is usual. Initially when I