[libre-riscv-dev] [Bug 333] investigate why CR pipeline code took 100% CPU and locked up generating ILANG
bugzilla-daemon at libre-soc.org
bugzilla-daemon at libre-soc.org
Wed May 20 19:16:31 BST 2020
https://bugs.libre-soc.org/show_bug.cgi?id=333
Michael Nolan <mtnolan2640 at gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |mtnolan2640 at gmail.com
--- Comment #1 from Michael Nolan <mtnolan2640 at gmail.com> ---
It seems we both stumbled on this issue at about the same time, and arrived at
similar solutions. I narrowed down the commit that introduced it to this one:
commit 7638005f8577ba6545a65a0c6e31c5419f1f684e
Author: Luke Kenneth Casson Leighton <lkcl at lkcl.net>
Date: Sun May 17 17:15:58 2020 +0100
use slightly more elegant way to access CR lookup table
diff --git a/src/soc/cr/main_stage.py b/src/soc/cr/main_stage.py
index e29d5ee..23eba32 100644
--- a/src/soc/cr/main_stage.py
+++ b/src/soc/cr/main_stage.py
@@ -67,9 +67,10 @@ class CRMainStage(PipeModBase):
# 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)
+ lut = Array([Signal(name=f"lut{i}") for i in range(4)])
# There's no field, just have to grab it directly from the insn
- comb += lut.eq(self.i.ctx.op.insn[6:10])
+ for i in range(4):
+ comb += lut[i].eq(self.i.ctx.op.insn[6+i])
# Generate the mask for mtcrf, mtocrf, and mfocrf
fxm = Signal(xfx_fields['FXM'][0:-1].shape())
@@ -108,28 +109,15 @@ class CRMainStage(PipeModBase):
comb += ba.eq(xl_fields['BA'][0:-1])
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])
-
- # Use the two input bits to look up the result in the
- # lookup table
- bit_out = Signal(reset_less=True)
- 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)
+ # Use the two input bits to look up the result in the LUT
+ comb += cr_out_arr[bt].eq(lut[Cat(cr_arr[bb], cr_arr[ba])])
##### mtcrf #####
with m.Case(InternalOp.OP_MTCRF):
# mtocrf and mtcrf are essentially identical
# put input (RA) - mask-selected - into output CR, leave
# rest of CR alone.
- comb += cr_o.eq((self.i.a[0:32] & mask) |
- (self.i.cr & ~mask))
+ comb += cr_o.eq((self.i.a[0:32] & mask) | (self.i.cr & ~mask))
##### mfcr #####
with m.Case(InternalOp.OP_MFCR):
I think what happens is nmigen generates something really big for arr[index].
Since that gets used to index lut, and then gets assigned to cr_out_arr[idx],
it generates a gigantic expression. By assigning the temporary expressions to
signals, this doesn't happen. Just a guess
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the libre-riscv-dev
mailing list