diff --git a/src/add/example_buf_pipe.py b/src/add/example_buf_pipe.py index 2604262..00eecc3 100644 --- a/src/add/example_buf_pipe.py +++ b/src/add/example_buf_pipe.py @@ -203,7 +203,7 @@ class BufferedPipeline: ]   -class BufPipe(BufferedPipeline): +class ExampleBufPipe(BufferedPipeline):  def __init__(self): BufferedPipeline.__init__(self) diff --git a/src/add/nmigen_div_experiment.py b/src/add/nmigen_div_experiment.py index eb0c935..e074c5c 100644 --- a/src/add/nmigen_div_experiment.py +++ b/src/add/nmigen_div_experiment.py @@ -6,7 +6,7 @@ from nmigen import Module, Signal, Const, Cat from nmigen.cli import main, verilog  from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase -from nmigen_add_experiment import FPState +from nmigen_add_experiment import FPState, FPGetOp  class Div: def __init__(self, width): @@ -66,14 +66,26 @@ class FPDIV(FPBase): # ****** # gets operand a  + geta = FPGetOp("get_a", "get_b", self.in_a, self.width) + geta.setup(m, self.in_a) + with m.State("get_a"): - self.get_op(m, self.in_a, a, "get_b") + geta.action(m) + with m.If(geta.out_decode): + m.d.sync += a.decode(self.in_a.v) + #self.get_op(m, self.in_a, a, "get_b")  # ****** # gets operand b  + getb = FPGetOp("get_b", "special_cases", self.in_b, self.width) + getb.setup(m, self.in_b) + with m.State("get_b"): - self.get_op(m, self.in_b, b, "special_cases") + getb.action(m) + with m.If(getb.out_decode): + m.d.sync += b.decode(self.in_b.v) + #self.get_op(m, self.in_b, b, "special_cases")  # ****** # special cases: NaNs, infs, zeros, denormalised diff --git a/src/add/test_buf_pipe.py b/src/add/test_buf_pipe.py index 2a06893..fa23eac 100644 --- a/src/add/test_buf_pipe.py +++ b/src/add/test_buf_pipe.py @@ -1,6 +1,6 @@ from nmigen import Module, Signal from nmigen.compat.sim import run_simulation -from example_buf_pipe import BufPipe +from example_buf_pipe import ExampleBufPipe from random import randint   @@ -171,7 +171,7 @@ def testbench4(dut): break   -class BufPipe2: +class ExampleBufPipe2: """ connect these: ------|---------------| v v @@ -180,8 +180,8 @@ class BufPipe2: stage.i_data >>in pipe1 o_data out>> stage.i_data >>in pipe2 """ def __init__(self): - self.pipe1 = BufPipe() - self.pipe2 = BufPipe() + self.pipe1 = ExampleBufPipe() + self.pipe2 = ExampleBufPipe()  # input self.i_p_valid = Signal() # >>in - comes in from PREVIOUS stage @@ -217,18 +217,18 @@ class BufPipe2:  if __name__ == '__main__': print ("test 1") - dut = BufPipe() + dut = ExampleBufPipe() run_simulation(dut, testbench(dut), vcd_name="test_bufpipe.vcd")  print ("test 2") - dut = BufPipe2() + dut = ExampleBufPipe2() run_simulation(dut, testbench2(dut), vcd_name="test_bufpipe2.vcd")  print ("test 3") - dut = BufPipe() + dut = ExampleBufPipe() test = Test3(dut) run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe3.vcd")  print ("test 4") - dut = BufPipe2() + dut = ExampleBufPipe2() run_simulation(dut, testbench4(dut), vcd_name="test_bufpipe4.vcd") diff --git a/src/add/test_inputgroup.py b/src/add/test_inputgroup.py index ca8523d..bb68861 100644 --- a/src/add/test_inputgroup.py +++ b/src/add/test_inputgroup.py @@ -99,9 +99,81 @@ def testbench(dut): assert out_mid == 3, "out mid %d" % out_mid   +class InputTest: + def __init__(self, dut): + self.dut = dut + self.di = {} + self.do = {} + self.tlen = 10 + for mid in range(dut.num_rows): + self.di[mid] = {} + self.do[mid] = {} + for i in range(self.tlen): + self.di[mid][i] = randint(0, 100) + self.do[mid][i] = self.di[mid][i] + + def send(self, mid): + for i in range(self.tlen): + op2 = self.di[mid][i] + rs = dut.rs[mid] + ack = yield rs.ack + while not ack: + yield + ack = yield rs.ack + yield rs.in_op[0].eq(i) + yield rs.in_op[1].eq(op2) + yield rs.stb.eq(0b11) # strobe indicate 1st op ready + ack = yield rs.ack + while ack: + yield + ack = yield rs.ack + yield rs.stb.eq(0) + + # wait random period of time before queueing another value + for i in range(randint(0, 12)): + yield + + def recv(self): + while True: + stb = yield dut.out_op.stb + yield dut.out_op.ack.eq(0) + while not stb: + yield + stb = yield dut.out_op.stb + + yield dut.out_op.ack.eq(1) + stb = yield dut.out_op.stb + while stb: + yield + stb = yield dut.out_op.stb + mid = yield dut.mid + out_i = yield dut.out_op.v[0] + out_v = yield dut.out_op.v[1] + + # see if this output has occurred already, delete it if it has + assert out_i in self.do[mid] + assert self.do[mid][out_i] == out_v + del self.do[mid][out_i] + + # check if there's any more outputs + zerolen = True + for (k, v) in self.do.items(): + if v: + zerolen = False + if zerolen: + break + if __name__ == '__main__': dut = InputGroup(width=32) vl = rtlil.convert(dut, ports=dut.ports()) with open("test_inputgroup.il", "w") as f: f.write(vl) run_simulation(dut, testbench(dut), vcd_name="test_inputgroup.vcd") + + dut = InputGroup(width=16) + test = InputTest(dut) + run_simulation(dut, [test.send(3), test.send(2), + test.send(1), test.send(0), + diff --git a/src/add/example_buf_pipe.py b/src/add/example_buf_pipe.py index 2604262..00eecc3 100644 --- a/src/add/example_buf_pipe.py +++ b/src/add/example_buf_pipe.py @@ -203,7 +203,7 @@ class BufferedPipeline: ]   -class BufPipe(BufferedPipeline): +class ExampleBufPipe(BufferedPipeline):  def __init__(self): BufferedPipeline.__init__(self) diff --git a/src/add/nmigen_div_experiment.py b/src/add/nmigen_div_experiment.py index eb0c935..e074c5c 100644 --- a/src/add/nmigen_div_experiment.py +++ b/src/add/nmigen_div_experiment.py @@ -6,7 +6,7 @@ from nmigen import Module, Signal, Const, Cat from nmigen.cli import main, verilog  from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase -from nmigen_add_experiment import FPState +from nmigen_add_experiment import FPState, FPGetOp  class Div: def __init__(self, width): @@ -66,14 +66,26 @@ class FPDIV(FPBase): # ****** # gets operand a  + geta = FPGetOp("get_a", "get_b", self.in_a, self.width) + geta.setup(m, self.in_a) + with m.State("get_a"): - self.get_op(m, self.in_a, a, "get_b") + geta.action(m) + with m.If(geta.out_decode): + m.d.sync += a.decode(self.in_a.v) + #self.get_op(m, self.in_a, a, "get_b")  # ****** # gets operand b  + getb = FPGetOp("get_b", "special_cases", self.in_b, self.width) + getb.setup(m, self.in_b) + with m.State("get_b"): - self.get_op(m, self.in_b, b, "special_cases") + getb.action(m) + with m.If(getb.out_decode): + m.d.sync += b.decode(self.in_b.v) + #self.get_op(m, self.in_b, b, "special_cases")  # ****** # special cases: NaNs, infs, zeros, denormalised diff --git a/src/add/test_buf_pipe.py b/src/add/test_buf_pipe.py index 2a06893..fa23eac 100644 --- a/src/add/test_buf_pipe.py +++ b/src/add/test_buf_pipe.py @@ -1,6 +1,6 @@ from nmigen import Module, Signal from nmigen.compat.sim import run_simulation -from example_buf_pipe import BufPipe +from example_buf_pipe import ExampleBufPipe from random import randint   @@ -171,7 +171,7 @@ def testbench4(dut): break   -class BufPipe2: +class ExampleBufPipe2: """ connect these: ------|---------------| v v @@ -180,8 +180,8 @@ class BufPipe2: stage.i_data >>in pipe1 o_data out>> stage.i_data >>in pipe2 """ def __init__(self): - self.pipe1 = BufPipe() - self.pipe2 = BufPipe() + self.pipe1 = ExampleBufPipe() + self.pipe2 = ExampleBufPipe()  # input self.i_p_valid = Signal() # >>in - comes in from PREVIOUS stage @@ -217,18 +217,18 @@ class BufPipe2:  if __name__ == '__main__': print ("test 1") - dut = BufPipe() + dut = ExampleBufPipe() run_simulation(dut, testbench(dut), vcd_name="test_bufpipe.vcd")  print ("test 2") - dut = BufPipe2() + dut = ExampleBufPipe2() run_simulation(dut, testbench2(dut), vcd_name="test_bufpipe2.vcd")  print ("test 3") - dut = BufPipe() + dut = ExampleBufPipe() test = Test3(dut) run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe3.vcd")  print ("test 4") - dut = BufPipe2() + dut = ExampleBufPipe2() run_simulation(dut, testbench4(dut), vcd_name="test_bufpipe4.vcd") diff --git a/src/add/test_inputgroup.py b/src/add/test_inputgroup.py index ca8523d..bb68861 100644 --- a/src/add/test_inputgroup.py +++ b/src/add/test_inputgroup.py @@ -99,9 +99,81 @@ def testbench(dut): assert out_mid == 3, "out mid %d" % out_mid   +class InputTest: + def __init__(self, dut): + self.dut = dut + self.di = {} + self.do = {} + self.tlen = 10 + for mid in range(dut.num_rows): + self.di[mid] = {} + self.do[mid] = {} + for i in range(self.tlen): + self.di[mid][i] = randint(0, 100) + self.do[mid][i] = self.di[mid][i] + + def send(self, mid): + for i in range(self.tlen): + op2 = self.di[mid][i] + rs = dut.rs[mid] + ack = yield rs.ack + while not ack: + yield + ack = yield rs.ack + yield rs.in_op[0].eq(i) + yield rs.in_op[1].eq(op2) + yield rs.stb.eq(0b11) # strobe indicate 1st op ready + ack = yield rs.ack + while ack: + yield + ack = yield rs.ack + yield rs.stb.eq(0) + + # wait random period of time before queueing another value + for i in range(randint(0, 12)): + yield + + def recv(self): + while True: + stb = yield dut.out_op.stb + yield dut.out_op.ack.eq(0) + while not stb: + yield + stb = yield dut.out_op.stb + + yield dut.out_op.ack.eq(1) + stb = yield dut.out_op.stb + while stb: + yield + stb = yield dut.out_op.stb + mid = yield dut.mid + out_i = yield dut.out_op.v[0] + out_v = yield dut.out_op.v[1] + + # see if this output has occurred already, delete it if it has + assert out_i in self.do[mid] + assert self.do[mid][out_i] == out_v + del self.do[mid][out_i] + + # check if there's any more outputs + zerolen = True + for (k, v) in self.do.items(): + if v: + zerolen = False + if zerolen: + break + if __name__ == '__main__': dut = InputGroup(width=32) vl = rtlil.convert(dut, ports=dut.ports()) with open("test_inputgroup.il", "w") as f: f.write(vl) run_simulation(dut, testbench(dut), vcd_name="test_inputgroup.vcd") + + dut = InputGroup(width=16) + test = InputTest(dut) + run_simulation(dut, [test.send(3), test.send(2), + test.send(1), test.send(0), + test.recv()], + vcd_name="test_inputgroup_parallel.vcd") + diff --git a/src/add/example_buf_pipe.py b/src/add/example_buf_pipe.py index 2604262..00eecc3 100644 --- a/src/add/example_buf_pipe.py +++ b/src/add/example_buf_pipe.py @@ -203,7 +203,7 @@ class BufferedPipeline: ]   -class BufPipe(BufferedPipeline): +class ExampleBufPipe(BufferedPipeline):  def __init__(self): BufferedPipeline.__init__(self) diff --git a/src/add/fmul.py b/src/add/fmul.py index 130d49e..5b6da94 100644 --- a/src/add/fmul.py +++ b/src/add/fmul.py @@ -2,7 +2,8 @@ from nmigen import Module, Signal, Cat, Mux, Array, Const from nmigen.cli import main, verilog  from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase -from nmigen_add_experiment import FPState ++from nmigen_add_experiment import FPState, FPGetOp +  class FPMUL(FPBase):  diff --git a/src/add/nmigen_div_experiment.py b/src/add/nmigen_div_experiment.py index eb0c935..e074c5c 100644 --- a/src/add/nmigen_div_experiment.py +++ b/src/add/nmigen_div_experiment.py @@ -6,7 +6,7 @@ from nmigen import Module, Signal, Const, Cat from nmigen.cli import main, verilog  from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase -from nmigen_add_experiment import FPState +from nmigen_add_experiment import FPState, FPGetOp  class Div: def __init__(self, width): @@ -66,14 +66,26 @@ class FPDIV(FPBase): # ****** # gets operand a  + geta = FPGetOp("get_a", "get_b", self.in_a, self.width) + geta.setup(m, self.in_a) + with m.State("get_a"): - self.get_op(m, self.in_a, a, "get_b") + geta.action(m) + with m.If(geta.out_decode): + m.d.sync += a.decode(self.in_a.v) + #self.get_op(m, self.in_a, a, "get_b")  # ****** # gets operand b  + getb = FPGetOp("get_b", "special_cases", self.in_b, self.width) + getb.setup(m, self.in_b) + with m.State("get_b"): - self.get_op(m, self.in_b, b, "special_cases") + getb.action(m) + with m.If(getb.out_decode): + m.d.sync += b.decode(self.in_b.v) + #self.get_op(m, self.in_b, b, "special_cases")  # ****** # special cases: NaNs, infs, zeros, denormalised diff --git a/src/add/test_buf_pipe.py b/src/add/test_buf_pipe.py index 2a06893..fa23eac 100644 --- a/src/add/test_buf_pipe.py +++ b/src/add/test_buf_pipe.py @@ -1,6 +1,6 @@ from nmigen import Module, Signal from nmigen.compat.sim import run_simulation -from example_buf_pipe import BufPipe +from example_buf_pipe import ExampleBufPipe from random import randint   @@ -171,7 +171,7 @@ def testbench4(dut): break   -class BufPipe2: +class ExampleBufPipe2: """ connect these: ------|---------------| v v @@ -180,8 +180,8 @@ class BufPipe2: stage.i_data >>in pipe1 o_data out>> stage.i_data >>in pipe2 """ def __init__(self): - self.pipe1 = BufPipe() - self.pipe2 = BufPipe() + self.pipe1 = ExampleBufPipe() + self.pipe2 = ExampleBufPipe()  # input self.i_p_valid = Signal() # >>in - comes in from PREVIOUS stage @@ -217,18 +217,18 @@ class BufPipe2:  if __name__ == '__main__': print ("test 1") - dut = BufPipe() + dut = ExampleBufPipe() run_simulation(dut, testbench(dut), vcd_name="test_bufpipe.vcd")  print ("test 2") - dut = BufPipe2() + dut = ExampleBufPipe2() run_simulation(dut, testbench2(dut), vcd_name="test_bufpipe2.vcd")  print ("test 3") - dut = BufPipe() + dut = ExampleBufPipe() test = Test3(dut) run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe3.vcd")  print ("test 4") - dut = BufPipe2() + dut = ExampleBufPipe2() run_simulation(dut, testbench4(dut), vcd_name="test_bufpipe4.vcd") diff --git a/src/add/test_inputgroup.py b/src/add/test_inputgroup.py index ca8523d..bb68861 100644 --- a/src/add/test_inputgroup.py +++ b/src/add/test_inputgroup.py @@ -99,9 +99,81 @@ def testbench(dut): assert out_mid == 3, "out mid %d" % out_mid   +class InputTest: + def __init__(self, dut): + self.dut = dut + self.di = {} + self.do = {} + self.tlen = 10 + for mid in range(dut.num_rows): + self.di[mid] = {} + self.do[mid] = {} + for i in range(self.tlen): + self.di[mid][i] = randint(0, 100) + self.do[mid][i] = self.di[mid][i] + + def send(self, mid): + for i in range(self.tlen): + op2 = self.di[mid][i] + rs = dut.rs[mid] + ack = yield rs.ack + while not ack: + yield + ack = yield rs.ack + yield rs.in_op[0].eq(i) + yield rs.in_op[1].eq(op2) + yield rs.stb.eq(0b11) # strobe indicate 1st op ready + ack = yield rs.ack + while ack: + yield + ack = yield rs.ack + yield rs.stb.eq(0) + + # wait random period of time before queueing another value + for i in range(randint(0, 12)): + yield + + def recv(self): + while True: + stb = yield dut.out_op.stb + yield dut.out_op.ack.eq(0) + while not stb: + yield + stb = yield dut.out_op.stb + + yield dut.out_op.ack.eq(1) + stb = yield dut.out_op.stb + while stb: + yield + stb = yield dut.out_op.stb + mid = yield dut.mid + out_i = yield dut.out_op.v[0] + out_v = yield dut.out_op.v[1] + + # see if this output has occurred already, delete it if it has + assert out_i in self.do[mid] + assert self.do[mid][out_i] == out_v + del self.do[mid][out_i] + + # check if there's any more outputs + zerolen = True + for (k, v) in self.do.items(): + if v: + zerolen = False + if zerolen: + break + if __name__ == '__main__': dut = InputGroup(width=32) vl = rtlil.convert(dut, ports=dut.ports()) with open("test_inputgroup.il", "w") as f: f.write(vl) run_simulation(dut, testbench(dut), vcd_name="test_inputgroup.vcd") + + dut = InputGroup(width=16) + test = InputTest(dut) + run_simulation(dut, [test.send(3), test.send(2), + test.send(1), test.send(0), + test.recv()], + vcd_name="test_inputgroup_parallel.vcd") +