From 4a38772cfb76ba0f2243f5f8a767a92028b43fd1 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Sat, 16 May 2020 13:07:35 -0400 Subject: [PATCH] Add comments on what CROP (crand, cror) do and how they work --- src/soc/cr/main_stage.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/soc/cr/main_stage.py b/src/soc/cr/main_stage.py index 53004900..e954dd8a 100644 --- a/src/soc/cr/main_stage.py +++ b/src/soc/cr/main_stage.py @@ -33,7 +33,7 @@ class CRMainStage(PipeModBase): return CRInputData(self.pspec) def ospec(self): - return CROutputData(self.pspec) # TODO: ALUIntermediateData + return CROutputData(self.pspec) def elaborate(self, platform): m = Module() @@ -55,24 +55,35 @@ class CRMainStage(PipeModBase): for i in range(32): comb += cr_output[31-i].eq(cr_out_arr[i]) comb += cr_out_arr[i].eq(cr_arr[i]) - + + + # crand/cror and friends get decoded to the same opcode, but + # one of the fields inside the instruction is a 4 bit lookup + # table. This lookup table gets indexed by bits a and b from + # the CR to determine what the resulting bit should be. # Grab the lookup table for cr_op type instructions lut = Signal(4, reset_less=True) # There's no field, just have to grab it directly from the insn comb += lut.eq(self.i.ctx.op.insn[6:10]) - + with m.Switch(op.insn_type): with m.Case(InternalOp.OP_MCRF): + # MCRF copies the 4 bits of crA to crB (for instance + # copying cr2 to cr1) + + # The destination CR bf = Signal(xl_fields['BF'][0:-1].shape()) comb += bf.eq(xl_fields['BF'][0:-1]) + # the source CR bfa = Signal(xl_fields['BFA'][0:-1].shape()) comb += bfa.eq(xl_fields['BFA'][0:-1]) for i in range(4): comb += cr_out_arr[bf*4 + i].eq(cr_arr[bfa*4 + i]) with m.Case(InternalOp.OP_CROP): + # Get the bit selector fields from the instruction bt = Signal(xl_fields['BT'][0:-1].shape()) comb += bt.eq(xl_fields['BT'][0:-1]) ba = Signal(xl_fields['BA'][0:-1].shape()) @@ -80,19 +91,24 @@ class CRMainStage(PipeModBase): bb = Signal(xl_fields['BB'][0:-1].shape()) comb += bb.eq(xl_fields['BB'][0:-1]) + # Extract the two input bits from the CR bit_a = Signal(reset_less=True) bit_b = Signal(reset_less=True) comb += bit_a.eq(cr_arr[ba]) comb += bit_b.eq(cr_arr[bb]) bit_out = Signal(reset_less=True) + + # Use the two input bits to look up the result in the + # lookup table comb += bit_out.eq(Mux(bit_b, Mux(bit_a, lut[3], lut[1]), Mux(bit_a, lut[2], lut[0]))) + # Set the output to the result above comb += cr_out_arr[bt].eq(bit_out) - - + + comb += self.o.cr.eq(cr_output) comb += self.o.ctx.eq(self.i.ctx) -- 2.30.2