summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
8d0c40f)
fix Logical test_pipe_caller.py to use new regspeckls style
def elaborate(self, platform):
m = Module()
perm = Signal(self.width, reset_less=True)
def elaborate(self, platform):
m = Module()
perm = Signal(self.width, reset_less=True)
- rb64 = [Signal(1, reset_less=True, name=f"rb64_{i}") for i in range(64)]
- for i in range(64):
- m.d.comb += rb64[i].eq(self.rb[63-i])
+ rb64 = [Signal(1, reset_less=True, name=f"rb64_{i}")
+ for i in range(self.width)]
+ for i in range(self.width):
+ m.d.comb += rb64[i].eq(self.rb[self.width-1-i])
+ for i in range(self.width//8):
index = self.rs[8*i:8*i+8]
idx = Signal(8, name=f"idx_{i}", reset_less=True)
m.d.comb += idx.eq(index)
index = self.rs[8*i:8*i+8]
idx = Signal(8, name=f"idx_{i}", reset_less=True)
m.d.comb += idx.eq(index)
+ with m.If(idx < self.width):
m.d.comb += perm[i].eq(rb64[idx])
m.d.comb += self.ra[0:8].eq(perm)
return m
m.d.comb += perm[i].eq(rb64[idx])
m.d.comb += self.ra[0:8].eq(perm)
return m
# to the output stage
# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
# to the output stage
# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
+# Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+
from nmigen import (Module, Signal, Cat, Repl, Mux, Const, Array)
from nmutil.pipemodbase import PipeModBase
from nmutil.clz import CLZ
from nmigen import (Module, Signal, Cat, Repl, Mux, Const, Array)
from nmutil.pipemodbase import PipeModBase
from nmutil.clz import CLZ
return LogicalOutputData(self.pspec)
def elaborate(self, platform):
return LogicalOutputData(self.pspec)
def elaborate(self, platform):
m = Module()
comb = m.d.comb
op, a, b, o = self.i.ctx.op, self.i.a, self.i.b, self.o.o
comb += o.ok.eq(1) # overridden if no op activates
m = Module()
comb = m.d.comb
op, a, b, o = self.i.ctx.op, self.i.a, self.i.b, self.o.o
comb += o.ok.eq(1) # overridden if no op activates
- m.submodules.bpermd = bpermd = Bpermd(64)
- m.submodules.popcount = popcount = Popcount()
+ m.submodules.bpermd = bpermd = Bpermd(XLEN)
+ m.submodules.popcount = popcount = Popcount(XLEN)
##########################
# main switch for logic ops AND, OR and XOR, cmpb, parity, and popcount
##########################
# main switch for logic ops AND, OR and XOR, cmpb, parity, and popcount
par0 = Signal(reset_less=True)
par1 = Signal(reset_less=True)
comb += par0.eq(Cat(a[0], a[8], a[16], a[24]).xor())
par0 = Signal(reset_less=True)
par1 = Signal(reset_less=True)
comb += par0.eq(Cat(a[0], a[8], a[16], a[24]).xor())
- comb += par1.eq(Cat(a[32], a[40], a[48], a[56]).xor())
+ if XLEN == 64:
+ comb += par1.eq(Cat(a[32], a[40], a[48], a[56]).xor())
with m.If(op.data_len[3] == 1):
comb += o.data.eq(par0 ^ par1)
with m.Else():
comb += o[0].eq(par0)
with m.If(op.data_len[3] == 1):
comb += o.data.eq(par0 ^ par1)
with m.Else():
comb += o[0].eq(par0)
+ if XLEN == 64:
+ comb += o[32].eq(par1)
###################
###### cntlz v3.0B p99
###################
###### cntlz v3.0B p99
count_right = Signal(reset_less=True)
comb += count_right.eq(XO[-1])
count_right = Signal(reset_less=True)
comb += count_right.eq(XO[-1])
- cntz_i = Signal(64, reset_less=True)
+ cntz_i = Signal(XLEN, reset_less=True)
a32 = Signal(32, reset_less=True)
comb += a32.eq(a[0:32])
a32 = Signal(32, reset_less=True)
comb += a32.eq(a[0:32])
with m.Else():
comb += cntz_i.eq(Mux(count_right, a[::-1], a))
with m.Else():
comb += cntz_i.eq(Mux(count_right, a[::-1], a))
- m.submodules.clz = clz = CLZ(64)
+ m.submodules.clz = clz = CLZ(XLEN)
comb += clz.sig_in.eq(cntz_i)
comb += o.data.eq(Mux(op.is_32bit, clz.lz-32, clz.lz))
comb += clz.sig_in.eq(cntz_i)
comb += o.data.eq(Mux(op.is_32bit, clz.lz-32, clz.lz))
# input (and output) for logical initial stage (common input)
class LogicalInputData(FUBaseData):
# input (and output) for logical initial stage (common input)
class LogicalInputData(FUBaseData):
- regspec = [('INT', 'ra', '0:63'), # RA
- ('INT', 'rb', '0:63'), # RB/immediate
- ('XER', 'xer_so', '32'), # bit0: so
- ]
def __init__(self, pspec):
super().__init__(pspec, False)
# convenience
self.a, self.b = self.ra, self.rb
def __init__(self, pspec):
super().__init__(pspec, False)
# convenience
self.a, self.b = self.ra, self.rb
+ @property
+ def regspec(self):
+ return [('INT', 'ra', self.intrange), # RA
+ ('INT', 'rb', self.intrange), # RB/immediate
+ ('XER', 'xer_so', '32'), # bit0: so
+ ]
# input to logical final stage (common output)
class LogicalOutputData(FUBaseData):
# input to logical final stage (common output)
class LogicalOutputData(FUBaseData):
- regspec = [('INT', 'o', '0:63'), # RT
- ('CR', 'cr_a', '0:3'),
- ('XER', 'xer_so', '32'), # bit0: so
- ]
def __init__(self, pspec):
super().__init__(pspec, True)
# convenience
self.cr0 = self.cr_a
def __init__(self, pspec):
super().__init__(pspec, True)
# convenience
self.cr0 = self.cr_a
+ @property
+ def regspec(self):
+ return [('INT', 'o', self.intrange),
+ ('CR', 'cr_a', '0:3'),
+ ('XER', 'xer_so', '32'), # bit0: so
+ ]
+
# output from logical final stage (common output) - note that XER.so
# is *not* included (the only reason it's in the input is because of CR0)
class LogicalOutputDataFinal(FUBaseData):
# output from logical final stage (common output) - note that XER.so
# is *not* included (the only reason it's in the input is because of CR0)
class LogicalOutputDataFinal(FUBaseData):
- regspec = [('INT', 'o', '0:63'), # RT
- ('CR', 'cr_a', '0:3'),
- ]
def __init__(self, pspec):
super().__init__(pspec, True)
# convenience
self.cr0 = self.cr_a
def __init__(self, pspec):
super().__init__(pspec, True)
# convenience
self.cr0 = self.cr_a
+ @property
+ def regspec(self):
+ return [('INT', 'o', self.intrange),
+ ('CR', 'cr_a', '0:3'),
+ ]
class LogicalPipeSpec(CommonPipeSpec):
class LogicalPipeSpec(CommonPipeSpec):
class Popcount(Elaboratable):
class Popcount(Elaboratable):
- def __init__(self):
- self.a = Signal(64, reset_less=True)
- self.b = Signal(64, reset_less=True)
+ def __init__(self, width=64):
+ self.width = width
+ self.a = Signal(width, reset_less=True)
+ self.b = Signal(width, reset_less=True)
self.data_len = Signal(4, reset_less=True) # data len up to... err.. 8?
self.data_len = Signal(4, reset_less=True) # data len up to... err.. 8?
- self.o = Signal(64, reset_less=True)
+ self.o = Signal(width, reset_less=True)
+ assert width in [32, 64], "only 32 or 64 bit supported for now"
def elaborate(self, platform):
m = Module()
def elaborate(self, platform):
m = Module()
# creating arrays big enough to store the sum, each time
pc = [a]
# QTY32 2-bit (to take 2x 1-bit sums) etc.
# creating arrays big enough to store the sum, each time
pc = [a]
# QTY32 2-bit (to take 2x 1-bit sums) etc.
- work = [(32, 2), (16, 3), (8, 4), (4, 5), (2, 6), (1, 7)]
+ work = [(16, 3), (8, 4), (4, 5), (2, 6), (1, 7)]
+ if self.width == 64:
+ work = [(32, 2)] + work
for l, bw in work: # l=number of add-reductions, bw=bitwidth
pc.append(array_of(l, bw))
for l, bw in work: # l=number of add-reductions, bw=bitwidth
pc.append(array_of(l, bw))
- pc8 = pc[3] # array of 8 8-bit counts (popcntb)
- pc32 = pc[5] # array of 2 32-bit counts (popcntw)
+ pc8 = pc[-4] # array of 8 8-bit counts (popcntb)
+ pc32 = pc[-2] # array of 2 32-bit counts (popcntw)
popcnt = pc[-1] # array of 1 64-bit count (popcntd)
# cascade-tree of adds
for idx, (l, bw) in enumerate(work):
popcnt = pc[-1] # array of 1 64-bit count (popcntd)
# cascade-tree of adds
for idx, (l, bw) in enumerate(work):
# decode operation length (1-hot)
with m.If(data_len == 1):
# popcntb - pack 8x 4-bit answers into 8x 8-bit output fields
# decode operation length (1-hot)
with m.If(data_len == 1):
# popcntb - pack 8x 4-bit answers into 8x 8-bit output fields
+ for i in range(self.width//8):
comb += o[i*8:(i+1)*8].eq(pc8[i])
with m.Elif(data_len == 4):
comb += o[i*8:(i+1)*8].eq(pc8[i])
with m.Elif(data_len == 4):
- # popcntw - pack 2x 5-bit answers into 2x 32-bit output fields
- for i in range(2):
- comb += o[i*32:(i+1)*32].eq(pc32[i])
+ if self.width == 64:
+ # popcntw - pack 2x 5-bit answers into 2x 32-bit output fields
+ for i in range(2):
+ comb += o[i*32:(i+1)*32].eq(pc32[i])
+ else:
+ comb += o.eq(popcnt[0])
with m.Else():
# popcntd - put 1x 6-bit answer into 64-bit output
comb += o.eq(popcnt[0])
with m.Else():
# popcntd - put 1x 6-bit answer into 64-bit output
comb += o.eq(popcnt[0])
class LogicalIlangCase(TestAccumulatorBase):
def case_ilang(self):
class LogicalIlangCase(TestAccumulatorBase):
def case_ilang(self):
- pspec = LogicalPipeSpec(id_wid=2, parent_pspec=None)
+ class PPspec:
+ XLEN = 64
+ pps = PPspec()
+ pspec = LogicalPipeSpec(id_wid=2, parent_pspec=pps)
alu = LogicalBasePipe(pspec)
vl = rtlil.convert(alu, ports=alu.ports())
with open("logical_pipeline.il", "w") as f:
f.write(vl)
alu = LogicalBasePipe(pspec)
vl = rtlil.convert(alu, ports=alu.ports())
with open("logical_pipeline.il", "w") as f:
f.write(vl)
-class TestRunner(FHDLTestCase):
- def __init__(self, test_data):
- super().__init__("run_all")
- self.test_data = test_data
+class TestRunner(unittest.TestCase):
def execute(self, alu, instruction, pdecode2, test):
print(test.name)
def execute(self, alu, instruction, pdecode2, test):
print(test.name)
simulator, code)
yield Settle()
simulator, code)
yield Settle()
+ def test_it(self):
+ test_data = LogicalIlangCase().test_data + \
+ LogicalTestCase().test_data
m = Module()
comb = m.d.comb
instruction = Signal(32)
m = Module()
comb = m.d.comb
instruction = Signal(32)
m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
- pspec = LogicalPipeSpec(id_wid=2, parent_pspec=None)
+ class PPspec:
+ XLEN = 64
+ pps = PPspec()
+ pspec = LogicalPipeSpec(id_wid=2, parent_pspec=pps)
m.submodules.alu = alu = LogicalBasePipe(pspec)
comb += alu.p.i_data.ctx.op.eq_from_execute1(pdecode2.do)
m.submodules.alu = alu = LogicalBasePipe(pspec)
comb += alu.p.i_data.ctx.op.eq_from_execute1(pdecode2.do)
sim.add_clock(1e-6)
def process():
sim.add_clock(1e-6)
def process():
- for test in self.test_data:
print(test.name)
program = test.program
with self.subTest(test.name):
print(test.name)
program = test.program
with self.subTest(test.name):
if __name__ == "__main__":
if __name__ == "__main__":
- unittest.main(exit=False)
- suite = unittest.TestSuite()
- suite.addTest(TestRunner(LogicalIlangCase().test_data))
- suite.addTest(TestRunner(LogicalTestCase().test_data))
-
- runner = unittest.TextTestRunner()
- runner.run(suite)