Skip to content

Commit

Permalink
WIP ALSRU
Browse files Browse the repository at this point in the history
  • Loading branch information
whitequark committed Aug 24, 2019
1 parent c6f00b2 commit 1f7e2fc
Showing 1 changed file with 67 additions and 68 deletions.
135 changes: 67 additions & 68 deletions boneless/gateware/alsru.py
Expand Up @@ -46,65 +46,64 @@ class ALSRU_4LUT(ALSRU, Elaboratable):

# The block diagram of an unit cell is as follows:
#
# A-|‾\ CO
# |3 |-X-· | O SLn+1
# B-|_/ |_|‾\ | ___ |
# ._|4 |-·-|D Q|-R-·
# B-|‾\ | |_/ |> | |
# SRn+1-|‾\ |2 |-Y-· | ‾‾‾ SRn-1
# |1 |-S-|_/ CI
# SLn-1-|_/
# CO O SLn+1
# | A-|‾\ | ___ |
# A-|‾\ |4 |-·-|D Q|-R-·
# B-|‾\ |3 |-Y-|_/ |> | |
# SRn+1-|‾\ |2 |-X-|_/ ‾‾‾ SRn-1
# |1 |-S-|_/ |
# SLn-1-|_/ CI
#
# LUT 1 computes: R<<1, R>>1
# LUT 2 computes: B, ~B, 0, S
# LUT 3 computes: A&B, A|B, A^B, A
# LUT 4 computes: X+Y, Y
# LUT 2 computes: 0, S, ~B, B
# LUT 3 computes: A+X, X
# LUT 4 computes: A&Y, A|Y, A^Y, Y
#
# To compute:
# A: X=A Y=0 O=X+Y
# B: Y=B O=Y
# ~B: Y=~B O=Y
# A&B: X=A&B Y=0 O=X+Y
# A|B: X=A|B Y=0 O=X+Y
# A^B: X=A^B Y=0 O=X+Y
# A+B: X=A Y=B O=X+Y
# A-B: X=A Y=~B O=X+Y (pre-invert CI)
# R<<1: S=SLn-1 Y=S O=Y (pre-load R)
# R>>1: S=SRn+1 Y=S O=Y (pre-load R)
# A: X=0 Y=A+X O=Y
# B: X=B Y=X O=Y
# ~B: X=~B Y=X O=Y
# A&B: X=B Y=X O=A&Y
# A|B: X=B Y=X O=A|Y
# A^B: X=B Y=X O=A^Y
# A+B: X=B Y=A+X O=Y
# A-B: X=~B Y=A+X O=Y (pre-invert CI)
# R<<1: S=SLn-1 X=S Y=X O=Y (pre-load R)
# R>>1: S=SRn+1 X=S Y=X O=Y (pre-load R)

class MuxS(ControlEnum):
L = 0b0
R = 0b1
x = 0

class MuxX(ControlEnum):
A = 0b00
AaB = 0b01
AoB = 0b10
AxB = 0b11
x = 0

class MuxY(ControlEnum):
Z = 0b00
S = 0b01
B = 0b10
nB = 0b11
B = 0b10

class MuxY(ControlEnum):
ApX = 0b0
X = 0b1

class MuxO(ControlEnum):
XpY = 0b0
Y = 0b1
AaY = 0b00
AoY = 0b01
AxY = 0b10
Y = 0b11
x = 0

class Op(MultiControlEnum, layout={"s":MuxS, "x":MuxX, "y":MuxY, "o":MuxO}):
A = ("x", "A", "Z", "XpY",)
B = ("x", "x", "B", "Y", )
nB = ("x", "x", "nB", "Y", )
AaB = ("x", "AaB", "Z", "XpY",)
AoB = ("x", "AoB", "Z", "XpY",)
AxB = ("x", "AxB", "Z", "XpY",)
ApB = ("x", "A", "B", "XpY",)
AmB = ("x", "A", "nB", "XpY",)
SL = ("L", "x", "S", "Y", )
SR = ("R", "x", "S", "Y", )
A = ("x", "Z", "ApX", "Y", )
B = ("x", "B", "X", "Y", )
nB = ("x", "nB", "X", "Y", )
AaB = ("x", "B", "X", "AaY",)
AoB = ("x", "B", "X", "AoY",)
AxB = ("x", "B", "X", "AxY",)
ApB = ("x", "B", "ApX", "Y", )
AmB = ("x", "nB", "ApX", "Y", )
SL = ("L", "S", "X", "Y", )
SR = ("R", "S", "X", "Y", )

def elaborate(self, platform):
m = Module()
Expand All @@ -122,42 +121,42 @@ def elaborate(self, platform):

x = Signal.like(self.o)
with m.Switch(op.x):
with m.Case(self.MuxX.AaB):
m.d.comb += x.eq(self.a & self.b)
with m.Case(self.MuxX.AoB):
m.d.comb += x.eq(self.a | self.b)
with m.Case(self.MuxX.AxB):
m.d.comb += x.eq(self.a ^ self.b)
with m.Case(self.MuxX.A):
m.d.comb += x.eq(self.a)

y = Signal.like(self.o)
with m.Switch(op.y):
with m.Case(self.MuxY.Z):
m.d.comb += y.eq(0)
with m.Case(self.MuxY.S):
m.d.comb += y.eq(s)
with m.Case(self.MuxY.B):
m.d.comb += y.eq(self.b)
with m.Case(self.MuxY.nB):
m.d.comb += y.eq(~self.b)
with m.Case(self.MuxX.Z):
m.d.comb += x.eq(0)
with m.Case(self.MuxX.S):
m.d.comb += x.eq(s)
with m.Case(self.MuxX.nB):
m.d.comb += x.eq(~self.b)
with m.Case(self.MuxX.B):
m.d.comb += x.eq(self.b)

p = Signal.like(self.o)
m.d.comb += Cat(p, self.co).eq(x + y + self.ci)

with m.Switch(op.o):
with m.Case(self.MuxO.XpY):
m.d.comb += self.o.eq(p)
with m.Case(self.MuxO.Y):
m.d.comb += self.o.eq(y)
m.d.comb += Cat(p, self.co).eq(self.a + x + self.ci)

# http://teaching.idallen.com/cst8214/08w/notes/overflow.txt
with m.Switch(Cat(x[-1], y[-1], self.o[-1])):
with m.Switch(Cat(self.a[-1], x[-1], p[-1])):
with m.Case(0b100):
m.d.comb += self.vo.eq(1)
with m.Case(0b011):
m.d.comb += self.vo.eq(1)

y = Signal.like(self.o)
with m.Switch(op.y):
with m.Case(self.MuxY.ApX):
m.d.comb += y.eq(p)
with m.Case(self.MuxY.X):
m.d.comb += y.eq(x)

with m.Switch(op.o):
with m.Case(self.MuxO.AaY):
m.d.comb += self.o.eq(self.a & y)
with m.Case(self.MuxO.AoY):
m.d.comb += self.o.eq(self.a | y)
with m.Case(self.MuxO.AxY):
m.d.comb += self.o.eq(self.a ^ y)
with m.Case(self.MuxO.Y):
m.d.comb += self.o.eq(y)

m.d.sync += self.r.eq(self.o)

return m
Expand Down

0 comments on commit 1f7e2fc

Please sign in to comment.