def mkLed(): m = Module('blinkled') clk = m.Input('CLK') rst = m.Input('RST') datawidth = 32 addrwidth = 10 myaxi = vthread.AXIM(m, 'myaxi', clk, rst, datawidth) ram_a = vthread.RAM(m, 'ram_a', clk, rst, datawidth, addrwidth) ram_b = vthread.RAM(m, 'ram_b', clk, rst, datawidth, addrwidth) strm = vthread.Stream(m, 'mystream', clk, rst) img_width = strm.parameter('img_width') counter = strm.Counter() a = strm.source('a') a_addr = strm.Counter() sp = strm.Scratchpad(a, a_addr, length=128) a_old_addr = strm.Counter() - img_width a_old = sp.read(a_old_addr) b = a + a_old strm.sink(b, 'b', when=counter >= img_width) # add a stall condition count = m.Reg('count', 4, initval=0) seq = Seq(m, 'seq', clk, rst) seq(count.inc()) util.add_disable_cond(strm.oready, 1, count == 0) def comp_stream(size, offset): strm.set_source('a', ram_a, offset, size * 2) strm.set_sink('b', ram_b, offset, size) strm.set_parameter('img_width', size) strm.run() strm.join() def comp_sequential(size, offset): for i in range(size): a_buf = ram_a.read(i + offset) a = ram_a.read(i + offset + size) b = a_buf + a ram_b.write(i + offset, b) def check(size, offset_stream, offset_seq): all_ok = True for i in range(size): st = ram_b.read(i + offset_stream) sq = ram_b.read(i + offset_seq) if vthread.verilog.NotEql(st, sq): all_ok = False if all_ok: print('# verify: PASSED') else: print('# verify: FAILED') def comp(size): # stream offset = 0 myaxi.dma_read(ram_a, offset, 0, size * 2) comp_stream(size, offset) myaxi.dma_write(ram_b, offset, 1024, size) # sequential offset = size * 4 myaxi.dma_read(ram_a, offset, 0, size * 2) comp_sequential(size, offset) myaxi.dma_write(ram_b, offset, 1024 * 2, size) # verification check(size, 0, offset) vthread.finish() th = vthread.Thread(m, 'th_comp', clk, rst, comp) fsm = th.start(32) return m
def mkLed(): m = Module('blinkled') clk = m.Input('CLK') rst = m.Input('RST') datawidth = 32 addrwidth = 10 myaxi = vthread.AXIM(m, 'myaxi', clk, rst, datawidth) ram_a = vthread.RAM(m, 'ram_a', clk, rst, datawidth, addrwidth) ram_b = vthread.RAM(m, 'ram_b', clk, rst, datawidth, addrwidth) ram_c = vthread.RAM(m, 'ram_c', clk, rst, datawidth, addrwidth) patterns = ( ((8, 1), (2, 8)), # pattern 1 ((8, 2), (2, 16))) # pattern 2 sizes = [ functools.reduce(lambda x, y: x * y, [pat[0] for pat in pattern], 1) for pattern in patterns ] strides = [pattern[0][1] for pattern in patterns] offsets = [0] i = 0 for size, stride in zip(sizes[:-1], strides[:-1]): offsets.append(offsets[i] + size * stride) i += 1 dma_size = functools.reduce( lambda x, y: x + y, [size * stride for size, stride in zip(sizes, strides)]) strm = vthread.Stream(m, 'mystream', clk, rst) a = strm.source('a') b = strm.source('b') c = a + b strm.sink(c, 'c') # add a stall condition count = m.Reg('count', 4, initval=0) seq = Seq(m, 'seq', clk, rst) seq(count.inc()) util.add_disable_cond(strm.oready, 1, count == 0) def comp_stream(): strm.set_source_multipattern('a', ram_a, offsets, patterns) strm.set_source_multipattern('b', ram_b, offsets, patterns) strm.set_sink_multipattern('c', ram_c, offsets, patterns) strm.run() strm.join() def comp_sequential(global_offset): addr = 0 for i in range(sizes[0]): a = ram_a.read(addr + offsets[0] + global_offset) b = ram_b.read(addr + offsets[0] + global_offset) sum = a + b ram_c.write(addr + offsets[0] + global_offset, sum) addr += strides[0] addr = 0 for i in range(sizes[1]): a = ram_a.read(addr + offsets[1] + global_offset) b = ram_b.read(addr + offsets[1] + global_offset) sum = a + b ram_c.write(addr + offsets[1] + global_offset, sum) addr += strides[1] def check(offset_stream, offset_seq): all_ok = True addr = 0 for i in range(sizes[0]): st = ram_c.read(addr + offsets[0] + offset_stream) sq = ram_c.read(addr + offsets[0] + offset_seq) addr += strides[0] if vthread.verilog.NotEql(st, sq): all_ok = False addr = 0 for i in range(sizes[1]): st = ram_c.read(addr + offsets[1] + offset_stream) sq = ram_c.read(addr + offsets[1] + offset_seq) addr += strides[1] if vthread.verilog.NotEql(st, sq): all_ok = False if all_ok: print('# verify: PASSED') else: print('# verify: FAILED') def comp(): # stream myaxi.dma_read(ram_a, 0, 0, dma_size) myaxi.dma_read(ram_b, 0, 0, dma_size) comp_stream() myaxi.dma_write(ram_c, 0, 1024 * 8, dma_size) # sequential myaxi.dma_read(ram_a, dma_size, 0, dma_size) myaxi.dma_read(ram_b, dma_size, 0, dma_size) comp_sequential(dma_size) myaxi.dma_write(ram_c, dma_size, 1024 * 12, dma_size) # verification myaxi.dma_read(ram_c, 0, 1024 * 8, dma_size) myaxi.dma_read(ram_c, dma_size, 1024 * 12, dma_size) check(0, dma_size) vthread.finish() th = vthread.Thread(m, 'th_comp', clk, rst, comp) fsm = th.start() return m
def mkLed(): m = Module('blinkled') clk = m.Input('CLK') rst = m.Input('RST') datawidth = 32 addrwidth = 10 myaxi = vthread.AXIM(m, 'myaxi', clk, rst, datawidth) myaxi.disable_write() ram_a = vthread.RAM(m, 'ram_a', clk, rst, datawidth, addrwidth) strm = vthread.Stream(m, 'mystream', clk, rst) a = strm.source('a') i = strm.Counter() term = a == 270 strm.sink(i, 'i') strm.terminate(term) # add a stall condition count = m.Reg('count', 4, initval=0) seq = Seq(m, 'seq', clk, rst) seq(count.inc()) util.add_disable_cond(strm.oready, 1, count == 0) def comp_stream(size, offset): strm.set_source('a', ram_a, offset, size) strm.set_sink_immediate('i', 0) strm.run() strm.join() i = strm.read_sink('i') return i def comp_sequential(size, offset): for i in range(size): a = ram_a.read(i + offset) if a == 270: return i return size - 1 def check(size_stream, size_seq): all_ok = True if vthread.verilog.NotEql(size_stream, size_seq): all_ok = False print(size_stream, size_seq) if all_ok: print('# verify: PASSED') else: print('# verify: FAILED') def comp(size): # stream offset = 0 myaxi.dma_read(ram_a, offset, 1024, size) st_i = comp_stream(size, offset) st_i = comp_stream(size, offset) # sequential offset = size myaxi.dma_read(ram_a, offset, 1024, size) sq_i = comp_sequential(size, offset) # verification check(st_i, sq_i) vthread.finish() th = vthread.Thread(m, 'th_comp', clk, rst, comp) fsm = th.start(32) return m
def mkLed(): m = Module('blinkled') clk = m.Input('CLK') rst = m.Input('RST') datawidth = 32 addrwidth = 10 myaxi = vthread.AXIM(m, 'myaxi', clk, rst, datawidth) saxi_length = 5 saxi = vthread.AXISLiteRegister(m, 'saxi', clk, rst, datawidth=datawidth, length=saxi_length) ram_src = vthread.RAM(m, 'ram_src', clk, rst, datawidth, addrwidth) ram_dummy_src = vthread.RAM(m, 'ram_dummy_src', clk, rst, datawidth, addrwidth) ram_dst = vthread.RAM(m, 'ram_dst', clk, rst, datawidth, addrwidth) strm = vthread.Stream(m, 'mystream', clk, rst) dummy_src = strm.source('dummy_src') c = strm.Counter(initval=0, size=4) x = strm.Counter(initval=0, size=8, enable=(c == 3)) y = strm.Counter(initval=0, size=8, enable=((c == 3) & (x == 7))) shift_cond = (x & 1 == 0) & ((y & 1) == 0) rotate_cond1 = (((((x & 1) == 0) & ((y & 1) == 0)) == 0) & (((x & 1) == 0) == 0)) rotate_cond2 = (((((x & 1) == 0) & ((y & 1) == 0)) == 0) & ((x & 1) == 0)) read_cond = shift_cond addrcounter = strm.Counter(initval=0, enable=read_cond) src = strm.read_RAM('ram_src', addr=addrcounter, when=read_cond, datawidth=datawidth) counter = strm.Counter(initval=0) width = strm.parameter('width') height = strm.parameter('height') linebuf = strm.LineBuffer(shape=(1, 1, 1), memlens=[4, 13], head_initvals=[0, 0], tail_initvals=[3, 12], data=src, shift_cond=shift_cond, rotate_conds=[rotate_cond1, rotate_cond2]) dst = linebuf.get_window(0) strm.sink(dst, 'dst') # add a stall condition count = m.Reg('count', 4, initval=0) seq = Seq(m, 'seq', clk, rst) seq(count.inc()) util.add_disable_cond(strm.oready, 1, count == 0) def comp_stream(channel, width, height, offset): strm.set_source('dummy_src', ram_dummy_src, offset, channel * width * height * 2 * 2) strm.set_read_RAM('ram_src', ram_src) strm.set_sink('dst', ram_dst, offset, channel * width * height * 2 * 2) strm.set_parameter('width', width) strm.set_parameter('height', height) strm.run() strm.join() def comp_sequential(channel, width, height, roffset, woffset): for yy in range(height * 2): for xx in range(width * 2): for c in range(channel): # f(c, x, y) = in(c, x/2, y/2); src_i = (xx // 2) * channel + (yy // 2) * width * channel + c dst_i = xx * channel + yy * width * 2 * channel + c val = ram_src.read(roffset + src_i) ram_dst.write(woffset + dst_i, val) def check(offset_stream, offset_seq, size): all_ok = True for i in range(size): st = ram_dst.read(offset_stream + i) sq = ram_dst.read(offset_seq + i) if vthread.verilog.NotEql(st, sq): all_ok = False if all_ok: print('# verify: PASSED') else: print('# verify: FAILED') def comp(): saxi.write(addr=1, value=0) saxi.wait_flag(0, value=1, resetvalue=0) channel = saxi.read(2) width = saxi.read(3) height = saxi.read(4) insize = channel * width * height outsize = channel * width * 2 * height * 2 roffset = 0 woffset = 0 myaxi.dma_read(ram_src, roffset, 0, insize) comp_stream(channel, width, height, roffset) myaxi.dma_write(ram_dst, woffset, 1024, outsize) roffset = insize woffset = outsize myaxi.dma_read(ram_src, roffset, 0, insize) comp_sequential(channel, width, height, roffset, woffset) myaxi.dma_write(ram_dst, woffset, 2 * 1024, outsize) check(0, woffset, outsize) saxi.write(addr=1, value=1) th = vthread.Thread(m, 'th_comp', clk, rst, comp) fsm = th.start() return m
def mkLed(): m = Module('blinkled') clk = m.Input('CLK') rst = m.Input('RST') datawidth = 32 addrwidth = 10 myaxi = vthread.AXIM(m, 'myaxi', clk, rst, datawidth) ram_a = vthread.RAM(m, 'ram_a', clk, rst, datawidth, addrwidth) ram_b = vthread.RAM(m, 'ram_b', clk, rst, datawidth, addrwidth) ram_c = vthread.RAM(m, 'ram_c', clk, rst, datawidth, addrwidth) mulstrm = vthread.Stream(m, 'mul_stream', clk, rst) mulx = mulstrm.source('x') muly = mulstrm.source('y') mulz = mulx * muly mulstrm.sink(mulz, 'z') # add a stall condition count = m.Reg('count', 4, initval=0) seq = Seq(m, 'seq', clk, rst) seq(count.inc()) util.add_disable_cond(mulstrm.oready, 1, count == 0) macstrm = vthread.Stream(m, 'mac_stream', clk, rst) a = macstrm.source('a') b = macstrm.source('b') a = a + 1 b = b + 1 sub = macstrm.substream(mulstrm) sub.to_source('x', a) sub.to_source('y', b) c = sub.from_sink('z') size = macstrm.parameter('size') sum, sum_valid = macstrm.ReduceAddValid(c, size) macstrm.sink(sum, 'sum', when=sum_valid, when_name='sum_valid') # add a stall condition util.add_disable_cond(macstrm.oready, 1, count == 0) actstrm = vthread.Stream(m, 'act_stream', clk, rst) a = actstrm.source('a') b = actstrm.source('b') a = a + 1 b = b + 1 a = a + 1 b = b + 1 sub = actstrm.substream(mulstrm) sub.to_source('x', a) sub.to_source('y', b) c = sub.from_sink('z') size = actstrm.parameter('size') sum, sum_valid = actstrm.ReduceAddValid(c, size) sum = actstrm.Mux(sum > 0, sum, 0) actstrm.sink(sum, 'sum', when=sum_valid, when_name='sum_valid') # add a stall condition util.add_disable_cond(actstrm.oready, 1, count == 0) all_ok = m.TmpReg(initval=0) def comp_stream_mul(size, offset): mulstrm.set_source('x', ram_a, offset, size) mulstrm.set_source('y', ram_b, offset, size) mulstrm.set_sink('z', ram_c, offset, size) mulstrm.run() mulstrm.join() def comp_stream_mac(size, offset): macstrm.set_source('a', ram_a, offset, size) macstrm.set_source('b', ram_b, offset, size) macstrm.set_parameter('size', size) macstrm.set_sink('sum', ram_c, offset, 1) macstrm.run() macstrm.join() def comp_stream_act(size, offset): actstrm.set_source('a', ram_a, offset, size) actstrm.set_source('b', ram_b, offset, size) actstrm.set_parameter('size', size) actstrm.set_sink('sum', ram_c, offset, 1) actstrm.run() actstrm.join() def comp_sequential_mul(size, offset): sum = 0 for i in range(size): a = ram_a.read(i + offset) b = ram_b.read(i + offset) sum = a * b ram_c.write(i + offset, sum) def comp_sequential_mac(size, offset): sum = 0 for i in range(size): a = ram_a.read(i + offset) + 1 b = ram_b.read(i + offset) + 1 sum += a * b ram_c.write(offset, sum) def comp_sequential_act(size, offset): sum = 0 for i in range(size): a = ram_a.read(i + offset) + 1 + 1 b = ram_b.read(i + offset) + 1 + 1 sum += a * b if sum <= 0: sum = 0 ram_c.write(offset, sum) def check(size, offset_stream, offset_seq): for i in range(size): st = ram_c.read(i + offset_stream) sq = ram_c.read(i + offset_seq) if vthread.verilog.NotEql(st, sq): all_ok.value = False if all_ok: print('# verify: PASSED') else: print('# verify: FAILED') def comp(size): all_ok.value = True # mul # stream offset = 0 myaxi.dma_read(ram_a, offset, 0, size) myaxi.dma_read(ram_b, offset, 512, size) comp_stream_mul(size, offset) myaxi.dma_write(ram_c, offset, 1024, size) # sequential offset = size myaxi.dma_read(ram_a, offset, 0, size) myaxi.dma_read(ram_b, offset, 512, size) comp_sequential_mul(size, offset) myaxi.dma_write(ram_c, offset, 1024 * 2, size) # verification print('# MUL') myaxi.dma_read(ram_c, 0, 1024, size) myaxi.dma_read(ram_c, offset, 1024 * 2, size) check(size, 0, offset) # mac # stream offset = 0 myaxi.dma_read(ram_a, offset, 0, size) myaxi.dma_read(ram_b, offset, 512, size) comp_stream_mac(size, offset) myaxi.dma_write(ram_c, offset, 1024, 1) # sequential offset = size myaxi.dma_read(ram_a, offset, 0, size) myaxi.dma_read(ram_b, offset, 512, size) comp_sequential_mac(size, offset) myaxi.dma_write(ram_c, offset, 1024 * 2, 1) # verification print('# MAC') myaxi.dma_read(ram_c, 0, 1024, size) myaxi.dma_read(ram_c, offset, 1024 * 2, size) check(1, 0, offset) # act # stream offset = 0 myaxi.dma_read(ram_a, offset, 0, size) myaxi.dma_read(ram_b, offset, 512, size) comp_stream_act(size, offset) myaxi.dma_write(ram_c, offset, 1024, 1) # sequential offset = size myaxi.dma_read(ram_a, offset, 0, size) myaxi.dma_read(ram_b, offset, 512, size) comp_sequential_act(size, offset) myaxi.dma_write(ram_c, offset, 1024 * 2, 1) # verification print('# ACT') myaxi.dma_read(ram_c, 0, 1024, size) myaxi.dma_read(ram_c, offset, 1024 * 2, size) check(1, 0, offset) vthread.finish() th = vthread.Thread(m, 'th_comp', clk, rst, comp) fsm = th.start(32) return m
def mkLed(): m = Module('blinkled') clk = m.Input('CLK') rst = m.Input('RST') datawidth = 32 addrwidth = 10 myaxi = vthread.AXIM(m, 'myaxi', clk, rst, datawidth) ram_a = vthread.RAM(m, 'ram_a', clk, rst, datawidth, addrwidth) ram_b = vthread.RAM(m, 'ram_b', clk, rst, datawidth, addrwidth) ram_c = vthread.RAM(m, 'ram_c', clk, rst, datawidth, addrwidth) strm = vthread.Stream(m, 'mystream', clk, rst) a = strm.source('a') b = strm.source('b') c = a + b strm.sink(c, 'c') # add a stall condition count = m.Reg('count', 4, initval=0) seq = Seq(m, 'seq', clk, rst) seq(count.inc()) util.add_disable_cond(strm.oready, 1, count == 0) def comp_stream(size, offset): strm.set_source('a', ram_a, offset, size) strm.set_source('b', ram_b, offset, size) strm.set_sink('c', ram_c, offset, size) strm.run() strm.join() def comp_sequential(size, offset): sum = 0 for i in range(size): a = ram_a.read(i + offset) b = ram_b.read(i + offset) sum = a + b ram_c.write(i + offset, sum) def check(size, offset_stream, offset_seq): all_ok = True for i in range(size): st = ram_c.read(i + offset_stream) sq = ram_c.read(i + offset_seq) if vthread.verilog.NotEql(st, sq): all_ok = False if all_ok: print('# verify: PASSED') else: print('# verify: FAILED') def comp(size): # stream offset = 0 myaxi.dma_read(ram_a, offset, 0, size) myaxi.dma_read(ram_b, offset, 512, size) comp_stream(size, offset) myaxi.dma_write(ram_c, offset, 1024, size) # sequential offset = size myaxi.dma_read(ram_a, offset, 0, size) myaxi.dma_read(ram_b, offset, 512, size) comp_sequential(size, offset) myaxi.dma_write(ram_c, offset, 1024 * 2, size) # verification myaxi.dma_read(ram_c, 0, 1024, size) myaxi.dma_read(ram_c, offset, 1024 * 2, size) check(size, 0, offset) vthread.finish() th = vthread.Thread(m, 'th_comp', clk, rst, comp) fsm = th.start(32) return m
def mkLed(): m = Module('blinkled') clk = m.Input('CLK') rst = m.Input('RST') datawidth = 32 addrwidth = 10 myaxi = vthread.AXIM(m, 'myaxi', clk, rst, datawidth) saxi_length = 4 saxi = vthread.AXISLiteRegister(m, 'saxi', clk, rst, datawidth=datawidth, length=saxi_length) ram_src = vthread.RAM(m, 'ram_src', clk, rst, datawidth, addrwidth) ram_dst = vthread.RAM(m, 'ram_dst', clk, rst, datawidth, addrwidth) strm = vthread.Stream(m, 'mystream', clk, rst) src = strm.source('src') counter = strm.Counter(initval=0) width = strm.parameter('width') height = strm.parameter('height') # shift x20 # rotate x10 # shift, rotate x34 shift_cond = strm.Or((counter < 20), ((counter >= 30) & (counter & 1 == 0))) rotate_cond = strm.Or(((counter >= 20) & (counter < 30)), ((counter >= 30) & (counter & 1 == 1))) linebuf = strm.LineBuffer(shape=(3, 3), memlens=[4], data=src, head_initvals=[0], tail_initvals=[3], shift_cond=shift_cond, rotate_conds=[rotate_cond]) window = [None] * 9 for y in range(3): for x in range(3): window[y * 3 + x] = linebuf.get_window(y * 3 + x) # The window register contains an invalid value in the beginning # because the initial value of shift memory is undefined. # Do not output sum until all the window register have valid value. dst = strm.Mux(counter < 20, window[8], strm.AddN(*window)) strm.sink(dst, 'dst') # add a stall condition count = m.Reg('count', 4, initval=0) seq = Seq(m, 'seq', clk, rst) seq(count.inc()) util.add_disable_cond(strm.oready, 1, count == 0) # for sequential ram_bufs = [ vthread.RAM(m, 'ram_buf' + str(i), clk, rst, datawidth, addrwidth) for i in range(3) ] def comp_stream(width, height, offset): strm.set_source('src', ram_src, offset, width * height) strm.set_sink('dst', ram_dst, offset, width * height) strm.set_parameter('width', width) strm.set_parameter('height', height) strm.run() strm.join() def comp_sequential(width, height, offset): head = 0 tail = 3 window_0 = window_1 = window_2 = 0 window_3 = window_4 = window_5 = 0 window_6 = window_7 = window_8 = 0 for i in range(width * height): src = ram_src.read(offset + i) shift = ((i < 20) or ((i >= 30) and (i & 1 == 0))) rotate = (((i >= 20) and (i < 30)) or ((i >= 30) and (i & 1 == 1))) if shift: ram_bufs[2].write(tail, window_8) window_8 = window_7 window_7 = window_6 window_6 = ram_bufs[1].read(head) ram_bufs[1].write(tail, window_5) window_5 = window_4 window_4 = window_3 window_3 = ram_bufs[0].read(head) ram_bufs[0].write(tail, window_2) window_2 = window_1 window_1 = window_0 window_0 = src head = head + 1 if head < 3 else 0 tail = tail + 1 if tail < 3 else 0 elif rotate: ram_bufs[2].write(tail, window_8) window_8 = window_7 window_7 = window_6 window_6 = ram_bufs[2].read(head) ram_bufs[1].write(tail, window_5) window_5 = window_4 window_4 = window_3 window_3 = ram_bufs[1].read(head) ram_bufs[0].write(tail, window_2) window_2 = window_1 window_1 = window_0 window_0 = ram_bufs[0].read(head) head = head + 1 if head < 3 else 0 tail = tail + 1 if tail < 3 else 0 sum = window_0 + window_1 + window_2 + window_3 + \ window_4 + window_5 + window_6 + window_7 + window_8 if i < 20: ram_dst.write(offset + i, window_0) else: ram_dst.write(offset + i, sum) def check(offset_stream, offset_seq, size): all_ok = True for i in range(size): st = ram_dst.read(offset_stream + i) sq = ram_dst.read(offset_seq + i) if vthread.verilog.NotEql(st, sq): all_ok = False if all_ok: print('# verify: PASSED') else: print('# verify: FAILED') def comp(): saxi.write(addr=1, value=0) saxi.wait_flag(0, value=1, resetvalue=0) width = saxi.read(2) height = saxi.read(3) size = width * height offset = 0 myaxi.dma_read(ram_src, offset, 0, size) comp_stream(width, height, offset) myaxi.dma_write(ram_dst, offset, 1024, size) offset = size myaxi.dma_read(ram_src, offset, 0, size) comp_sequential(width, height, offset) myaxi.dma_write(ram_dst, offset, 2 * 1024, size) check(0, offset, size) saxi.write(addr=1, value=1) th = vthread.Thread(m, 'th_comp', clk, rst, comp) fsm = th.start() return m
def mkLed(): m = Module('blinkled') clk = m.Input('CLK') rst = m.Input('RST') datawidth = 32 addrwidth = 10 myaxi = vthread.AXIM(m, 'myaxi', clk, rst, datawidth) ram_a = vthread.RAM(m, 'ram_a', clk, rst, datawidth, addrwidth) ram_b = vthread.RAM(m, 'ram_b', clk, rst, datawidth, addrwidth, numports=2) strm = vthread.Stream(m, 'mystream', clk, rst) numbins = strm.parameter('numbins') offset = strm.parameter('offset') a = strm.source('a') a = strm.Mux(a < 0, 0, a) a.latency = 0 a = strm.Mux(a >= numbins, numbins - 1, a) a.latency = 0 raddr = a + offset raddrs = (raddr, ) waddr = raddr op = strm.Add op_args = (1, ) strm.read_modify_write_RAM('ext', raddrs, waddr, op, op_args) # add a stall condition count = m.Reg('count', 4, initval=0) seq = Seq(m, 'seq', clk, rst) seq(count.inc()) util.add_disable_cond(strm.oready, 1, count == 0) def comp_stream(numbins, size, offset): for i in range(numbins): ram_b.write(i + offset, 0) strm.set_parameter('numbins', numbins) strm.set_parameter('offset', offset) strm.set_source('a', ram_a, offset, size) strm.set_read_modify_write_RAM('ext', ram_b, read_ports=(0, ), write_port=1) strm.run() strm.join() def comp_sequential(numbins, size, offset): for i in range(numbins): ram_b.write(i + offset, 0) for i in range(size): a = ram_a.read(i + offset) a = 0 if a < 0 else a a = numbins - 1 if a >= numbins else a current = ram_b.read(a + offset) updated = current + 1 ram_b.write(a + offset, updated) def check(size, offset_stream, offset_seq): all_ok = True for i in range(size): st = ram_b.read(i + offset_stream) sq = ram_b.read(i + offset_seq) if vthread.verilog.NotEql(st, sq): all_ok = False if all_ok: print('# verify: PASSED') else: print('# verify: FAILED') def comp(size): numbins = 8 # stream offset = 0 myaxi.dma_read(ram_a, offset, 0, size) comp_stream(numbins, size, offset) myaxi.dma_write(ram_b, offset, 1024, numbins) # sequential offset = size * 4 myaxi.dma_read(ram_a, offset, 0, size * 2) comp_sequential(numbins, size, offset) myaxi.dma_write(ram_b, offset, 1024 * 2, numbins) # verification myaxi.dma_read(ram_b, 0, 1024, numbins) myaxi.dma_read(ram_b, offset, 1024 * 2, numbins) check(numbins, 0, offset) vthread.finish() th = vthread.Thread(m, 'th_comp', clk, rst, comp) fsm = th.start(32) return m