From: Luke Kenneth Casson Leighton Date: Sat, 23 May 2020 10:35:24 +0000 (+0100) Subject: add CR_ISEL (and unit test) to CR pipeline X-Git-Tag: div_pipeline~920 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ffb669b0d69e1e68e6e1c5a26a7baea4a07c9994;p=soc.git add CR_ISEL (and unit test) to CR pipeline --- diff --git a/src/soc/fu/cr/main_stage.py b/src/soc/fu/cr/main_stage.py index efb821e5..41a0acd0 100644 --- a/src/soc/fu/cr/main_stage.py +++ b/src/soc/fu/cr/main_stage.py @@ -1,4 +1,4 @@ -# This stage is intended to do Condition Register instructions +# This stage is intended to do Condition Register instructions (and ISEL) # and output, as well as carry and overflow generation. # NOTE: with the exception of mtcrf and mfcr, we really should be doing # the field decoding which @@ -34,7 +34,7 @@ class CRMainStage(PipeModBase): m = Module() comb = m.d.comb op = self.i.ctx.op - a, full_cr = self.i.a, self.i.full_cr + a, b, full_cr = self.i.a, self.i.b, self.i.full_cr cr_a, cr_b, cr_c = self.i.cr_a, self.i.cr_b, self.i.cr_c cr_o, full_cr_o, rt_o = self.o.cr_o, self.o.full_cr, self.o.o @@ -133,6 +133,21 @@ class CRMainStage(PipeModBase): # output register RT comb += rt_o.eq(full_cr) + # ##### isel ##### + with m.Case(InternalOp.OP_ISEL): + # just like in branch, CR0-7 is incoming into cr_a, we + # need to select from the last 2 bits of BC + a_fields = self.fields.FormA + BC = a_fields.BC[0:-1][0:2] + cr_bits = Array([cr_a[3-i] for i in range(4)]) + + # The bit of (cr_a=CR0-7) selected by BC + cr_bit = Signal(reset_less=True) + comb += cr_bit.eq(cr_bits[BC]) + + # select a or b as output + comb += rt_o.eq(Mux(cr_bit, a, b)) + comb += self.o.ctx.eq(self.i.ctx) return m diff --git a/src/soc/fu/cr/test/test_pipe_caller.py b/src/soc/fu/cr/test/test_pipe_caller.py index 67b67b6e..1f2a183e 100644 --- a/src/soc/fu/cr/test/test_pipe_caller.py +++ b/src/soc/fu/cr/test/test_pipe_caller.py @@ -58,6 +58,18 @@ class CRTestCase(FHDLTestCase): self.test_name) test_data.append(tc) + def test_isel(self): + for i in range(40): + bi = random.randint(0, 31) + lst = [f"isel 3, 1, 2, {bi}"] + cr = random.randint(0, (1<<32)-1) + initial_regs = [0] * 32 + initial_regs[1] = random.randint(0, (1<<32)-1) + initial_regs[2] = random.randint(0, (1<<32)-1) + initial_regs[3] = random.randint(0, (1<<32)-1) + self.run_tst_program(Program(lst), initial_regs=initial_regs, + initial_cr=cr) + def test_crop(self): insns = ["crand", "cror", "crnand", "crnor", "crxor", "creqv", "crandc", "crorc"] @@ -112,7 +124,6 @@ class CRTestCase(FHDLTestCase): lst = [f"mfocrf 2, {mask}"] cr = random.randint(0, (1<<32)-1) self.run_tst_program(Program(lst), initial_cr=cr) - def test_ilang(self): pspec = CRPipeSpec(id_wid=2) @@ -168,7 +179,6 @@ class TestRunner(FHDLTestCase): expected_cr = simulator.crl[cr_sel].get_range().value real_cr = yield alu.n.data_o.cr_o.data self.assertEqual(expected_cr, real_cr) - def run_all(self): m = Module() @@ -212,7 +222,7 @@ class TestRunner(FHDLTestCase): yield alu.p.valid_i.eq(1) fn_unit = yield pdecode2.e.fn_unit self.assertEqual(fn_unit, Function.CR.value, code) - yield + yield opname = code.split(' ')[0] yield from simulator.call(opname) index = simulator.pc.CIA.value//4 @@ -228,6 +238,7 @@ class TestRunner(FHDLTestCase): with sim.write_vcd("simulator.vcd", "simulator.gtkw", traces=[]): sim.run() + def check_extra_alu_outputs(self, alu, dec2, sim): rc = yield dec2.e.rc.data if rc: