1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-30 08:32:52 +08:00

merged changes in pcie

This commit is contained in:
Alex Forencich 2022-04-20 00:44:33 -07:00
commit aaadae3809
49 changed files with 2129 additions and 406 deletions

View File

@ -234,6 +234,132 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# disable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0)
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
await dev_pf0_bar0.write_dword(0x0010c4, 0)
# RAM offset address
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
await dev_pf0_bar0.write_dword(0x0011c4, 0)
# RAM offset address
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -277,6 +277,8 @@ async def run_test(dut):
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# enable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0x3)
# write pcie read descriptor
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
@ -310,10 +312,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -322,16 +352,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -340,36 +370,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -378,23 +412,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -279,6 +279,8 @@ async def run_test(dut):
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# enable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0x3)
# write pcie read descriptor
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
@ -312,10 +314,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -324,16 +354,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -342,36 +372,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -380,23 +414,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -279,6 +279,8 @@ async def run_test(dut):
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# enable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0x3)
# write pcie read descriptor
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
@ -312,10 +314,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -324,16 +354,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -342,36 +372,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -380,23 +414,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -277,6 +277,8 @@ async def run_test(dut):
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# enable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0x3)
# write pcie read descriptor
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
@ -310,10 +312,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -322,16 +352,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -340,36 +370,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -378,23 +412,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -277,6 +277,8 @@ async def run_test(dut):
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# enable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0x3)
# write pcie read descriptor
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
@ -310,10 +312,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -322,16 +352,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -340,36 +370,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -378,23 +412,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -306,10 +306,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -318,16 +346,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -336,36 +364,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -374,23 +406,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -277,6 +277,8 @@ async def run_test(dut):
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# enable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0x3)
# write pcie read descriptor
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
@ -310,10 +312,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -322,16 +352,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -340,36 +370,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -378,23 +412,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -234,6 +234,132 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# disable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0)
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
await dev_pf0_bar0.write_dword(0x0010c4, 0)
# RAM offset address
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
await dev_pf0_bar0.write_dword(0x0011c4, 0)
# RAM offset address
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -278,6 +278,8 @@ async def run_test(dut):
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# enable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0x3)
# write pcie read descriptor
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
@ -311,10 +313,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -323,16 +353,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -341,36 +371,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -379,23 +413,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -284,6 +284,8 @@ async def run_test(dut):
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# enable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0x3)
# write pcie read descriptor
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
@ -317,10 +319,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -329,16 +359,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -347,36 +377,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -385,23 +419,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -279,6 +279,8 @@ async def run_test(dut):
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# enable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0x3)
# write pcie read descriptor
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
@ -312,10 +314,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -324,16 +354,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -342,36 +372,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -380,23 +414,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -284,6 +284,8 @@ async def run_test(dut):
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
# enable interrupts
await dev_pf0_bar0.write_dword(0x000008, 0x3)
# write pcie read descriptor
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
@ -317,10 +319,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -329,16 +359,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -347,36 +377,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -385,23 +419,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -234,6 +234,23 @@ static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1,
edev->dma_region + 0x0200, 256, true);
dev_info(dev, "start immediate write to host");
iowrite32((edev->dma_region_addr + 0x0200) & 0xffffffff, edev->bar[0] + 0x000200);
iowrite32(((edev->dma_region_addr + 0x0200) >> 32) & 0xffffffff, edev->bar[0] + 0x000204);
iowrite32(0x44332211, edev->bar[0] + 0x000208);
iowrite32(0, edev->bar[0] + 0x00020C);
iowrite32(0x4, edev->bar[0] + 0x000210);
iowrite32(0x800000AA, edev->bar[0] + 0x000214);
msleep(1);
dev_info(dev, "Read status");
dev_info(dev, "%08x", ioread32(edev->bar[0] + 0x000218));
dev_info(dev, "read data");
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1,
edev->dma_region + 0x0200, 4, true);
// probe complete
return 0;

View File

@ -41,6 +41,10 @@ module example_core #
parameter AXIL_STRB_WIDTH = (AXIL_DATA_WIDTH/8),
// DMA address width
parameter DMA_ADDR_WIDTH = 64,
// DMA immediate enable
parameter DMA_IMM_ENABLE = 0,
// DMA immediate width
parameter DMA_IMM_WIDTH = 32,
// DMA Length field width
parameter DMA_LEN_WIDTH = 16,
// DMA Tag field width
@ -109,6 +113,8 @@ module example_core #
output wire [DMA_ADDR_WIDTH-1:0] m_axis_dma_write_desc_dma_addr,
output wire [RAM_SEL_WIDTH-1:0] m_axis_dma_write_desc_ram_sel,
output wire [RAM_ADDR_WIDTH-1:0] m_axis_dma_write_desc_ram_addr,
output wire [DMA_IMM_WIDTH-1:0] m_axis_dma_write_desc_imm,
output wire m_axis_dma_write_desc_imm_en,
output wire [DMA_LEN_WIDTH-1:0] m_axis_dma_write_desc_len,
output wire [DMA_TAG_WIDTH-1:0] m_axis_dma_write_desc_tag,
output wire m_axis_dma_write_desc_valid,
@ -145,6 +151,8 @@ module example_core #
output wire [31:0] msi_irq
);
localparam RAM_ADDR_IMM_WIDTH = (DMA_IMM_ENABLE && (DMA_IMM_WIDTH > RAM_ADDR_WIDTH)) ? DMA_IMM_WIDTH : RAM_ADDR_WIDTH;
dma_psdpram #(
.SIZE(16384),
.SEG_COUNT(RAM_SEG_COUNT),
@ -203,7 +211,8 @@ reg [3:0] dma_read_desc_status_error_reg = 0, dma_read_desc_status_error_next;
reg dma_read_desc_status_valid_reg = 0, dma_read_desc_status_valid_next;
reg [DMA_ADDR_WIDTH-1:0] dma_write_desc_dma_addr_reg = 0, dma_write_desc_dma_addr_next;
reg [RAM_ADDR_WIDTH-1:0] dma_write_desc_ram_addr_reg = 0, dma_write_desc_ram_addr_next;
reg [RAM_ADDR_IMM_WIDTH-1:0] dma_write_desc_ram_addr_imm_reg = 0, dma_write_desc_ram_addr_imm_next;
reg dma_write_desc_imm_en_reg = 0, dma_write_desc_imm_en_next;
reg [DMA_LEN_WIDTH-1:0] dma_write_desc_len_reg = 0, dma_write_desc_len_next;
reg [DMA_TAG_WIDTH-1:0] dma_write_desc_tag_reg = 0, dma_write_desc_tag_next;
reg dma_write_desc_valid_reg = 0, dma_write_desc_valid_next;
@ -260,7 +269,9 @@ assign m_axis_dma_read_desc_valid = dma_read_desc_valid_reg;
assign m_axis_dma_write_desc_dma_addr = dma_write_desc_dma_addr_reg;
assign m_axis_dma_write_desc_ram_sel = 0;
assign m_axis_dma_write_desc_ram_addr = dma_write_desc_ram_addr_reg;
assign m_axis_dma_write_desc_ram_addr = dma_write_desc_ram_addr_imm_reg;
assign m_axis_dma_write_desc_imm = dma_write_desc_ram_addr_imm_reg;
assign m_axis_dma_write_desc_imm_en = dma_write_desc_imm_en_reg;
assign m_axis_dma_write_desc_len = dma_write_desc_len_reg;
assign m_axis_dma_write_desc_tag = dma_write_desc_tag_reg;
assign m_axis_dma_write_desc_valid = dma_write_desc_valid_reg;
@ -289,7 +300,8 @@ always @* begin
dma_read_desc_status_valid_next = dma_read_desc_status_valid_reg;
dma_write_desc_dma_addr_next = dma_write_desc_dma_addr_reg;
dma_write_desc_ram_addr_next = dma_write_desc_ram_addr_reg;
dma_write_desc_ram_addr_imm_next = dma_write_desc_ram_addr_imm_reg;
dma_write_desc_imm_en_next = dma_write_desc_imm_en_reg;
dma_write_desc_len_next = dma_write_desc_len_reg;
dma_write_desc_tag_next = dma_write_desc_tag_reg;
dma_write_desc_valid_next = dma_write_desc_valid_reg && !m_axis_dma_write_desc_ready;
@ -357,10 +369,11 @@ always @* begin
// single write
16'h0200: dma_write_desc_dma_addr_next[31:0] = s_axil_ctrl_wdata;
16'h0204: dma_write_desc_dma_addr_next[63:32] = s_axil_ctrl_wdata;
16'h0208: dma_write_desc_ram_addr_next = s_axil_ctrl_wdata;
16'h0208: dma_write_desc_ram_addr_imm_next = s_axil_ctrl_wdata;
16'h0210: dma_write_desc_len_next = s_axil_ctrl_wdata;
16'h0214: begin
dma_write_desc_tag_next = s_axil_ctrl_wdata;
dma_write_desc_tag_next = s_axil_ctrl_wdata[23:0];
dma_write_desc_imm_en_next = s_axil_ctrl_wdata[31];
dma_write_desc_valid_next = 1'b1;
end
// block read
@ -411,6 +424,7 @@ always @* begin
axil_ctrl_arready_next = 1'b1;
axil_ctrl_rresp_next = 2'b00;
axil_ctrl_rvalid_next = 1'b1;
axil_ctrl_rdata_next = 32'd0;
case ({s_axil_ctrl_araddr[15:2], 2'b00})
// control
@ -441,10 +455,13 @@ always @* begin
// single write
16'h0200: axil_ctrl_rdata_next = dma_write_desc_dma_addr_reg;
16'h0204: axil_ctrl_rdata_next = dma_write_desc_dma_addr_reg >> 32;
16'h0208: axil_ctrl_rdata_next = dma_write_desc_ram_addr_reg;
16'h020c: axil_ctrl_rdata_next = dma_write_desc_ram_addr_reg >> 32;
16'h0208: axil_ctrl_rdata_next = dma_write_desc_ram_addr_imm_reg;
16'h020c: axil_ctrl_rdata_next = dma_write_desc_ram_addr_imm_reg >> 32;
16'h0210: axil_ctrl_rdata_next = dma_write_desc_len_reg;
16'h0214: axil_ctrl_rdata_next = dma_write_desc_tag_reg;
16'h0214: begin
axil_ctrl_rdata_next[23:0] = dma_write_desc_tag_reg;
axil_ctrl_rdata_next[31] = dma_write_desc_imm_en_reg;
end
16'h0218: begin
axil_ctrl_rdata_next[15:0] = dma_write_desc_status_tag_reg;
axil_ctrl_rdata_next[27:24] = dma_write_desc_status_error_reg;
@ -553,7 +570,8 @@ always @* begin
dma_write_block_dma_offset_next = dma_write_block_dma_offset_reg + dma_write_block_dma_stride_reg;
dma_write_desc_dma_addr_next = dma_write_block_dma_base_addr_reg + (dma_write_block_dma_offset_reg & dma_write_block_dma_offset_mask_reg);
dma_write_block_ram_offset_next = dma_write_block_ram_offset_reg + dma_write_block_ram_stride_reg;
dma_write_desc_ram_addr_next = dma_write_block_ram_base_addr_reg + (dma_write_block_ram_offset_reg & dma_write_block_ram_offset_mask_reg);
dma_write_desc_ram_addr_imm_next = dma_write_block_ram_base_addr_reg + (dma_write_block_ram_offset_reg & dma_write_block_ram_offset_mask_reg);
dma_write_desc_imm_en_next = 1'b0;
dma_write_desc_len_next = dma_write_block_len_reg;
dma_write_block_count_next = dma_write_block_count_reg - 1;
dma_write_desc_tag_next = dma_write_block_count_reg;
@ -593,7 +611,8 @@ always @(posedge clk) begin
dma_read_desc_status_valid_reg <= dma_read_desc_status_valid_next;
dma_write_desc_dma_addr_reg <= dma_write_desc_dma_addr_next;
dma_write_desc_ram_addr_reg <= dma_write_desc_ram_addr_next;
dma_write_desc_ram_addr_imm_reg <= dma_write_desc_ram_addr_imm_next;
dma_write_desc_imm_en_reg <= dma_write_desc_imm_en_next;
dma_write_desc_len_reg <= dma_write_desc_len_next;
dma_write_desc_tag_reg <= dma_write_desc_tag_next;
dma_write_desc_valid_reg <= dma_write_desc_valid_next;

View File

@ -47,6 +47,10 @@ module example_core_pcie #
parameter TX_SEQ_NUM_WIDTH = 5,
// TX sequence number tracking enable
parameter TX_SEQ_NUM_ENABLE = 1,
// Immediate enable
parameter IMM_ENABLE = 1,
// Immediate width
parameter IMM_WIDTH = 32,
// PCIe tag count
parameter PCIE_TAG_COUNT = 256,
// Operation table size (read)
@ -220,6 +224,8 @@ wire axis_dma_read_desc_status_valid;
wire [PCIE_ADDR_WIDTH-1:0] axis_dma_write_desc_dma_addr;
wire [RAM_SEL_WIDTH-1:0] axis_dma_write_desc_ram_sel;
wire [RAM_ADDR_WIDTH-1:0] axis_dma_write_desc_ram_addr;
wire [IMM_WIDTH-1:0] axis_dma_write_desc_imm;
wire axis_dma_write_desc_imm_en;
wire [DMA_LEN_WIDTH-1:0] axis_dma_write_desc_len;
wire [DMA_TAG_WIDTH-1:0] axis_dma_write_desc_tag;
wire axis_dma_write_desc_valid;
@ -629,6 +635,8 @@ dma_if_pcie #(
.RAM_SEG_ADDR_WIDTH(RAM_SEG_ADDR_WIDTH),
.PCIE_ADDR_WIDTH(PCIE_ADDR_WIDTH),
.PCIE_TAG_COUNT(PCIE_TAG_COUNT),
.IMM_ENABLE(IMM_ENABLE),
.IMM_WIDTH(IMM_WIDTH),
.LEN_WIDTH(DMA_LEN_WIDTH),
.TAG_WIDTH(DMA_TAG_WIDTH),
.READ_OP_TABLE_SIZE(READ_OP_TABLE_SIZE),
@ -716,6 +724,8 @@ dma_if_pcie_inst (
.s_axis_write_desc_pcie_addr(axis_dma_write_desc_dma_addr),
.s_axis_write_desc_ram_sel(axis_dma_write_desc_ram_sel),
.s_axis_write_desc_ram_addr(axis_dma_write_desc_ram_addr),
.s_axis_write_desc_imm(axis_dma_write_desc_imm),
.s_axis_write_desc_imm_en(axis_dma_write_desc_imm_en),
.s_axis_write_desc_len(axis_dma_write_desc_len),
.s_axis_write_desc_tag(axis_dma_write_desc_tag),
.s_axis_write_desc_valid(axis_dma_write_desc_valid),
@ -794,6 +804,8 @@ example_core #(
.AXIL_ADDR_WIDTH(AXIL_ADDR_WIDTH),
.AXIL_STRB_WIDTH(AXIL_STRB_WIDTH),
.DMA_ADDR_WIDTH(PCIE_ADDR_WIDTH),
.DMA_IMM_ENABLE(IMM_ENABLE),
.DMA_IMM_WIDTH(IMM_WIDTH),
.DMA_LEN_WIDTH(DMA_LEN_WIDTH),
.DMA_TAG_WIDTH(DMA_TAG_WIDTH),
.RAM_SEL_WIDTH(RAM_SEL_WIDTH),
@ -854,6 +866,8 @@ core_inst (
.m_axis_dma_write_desc_dma_addr(axis_dma_write_desc_dma_addr),
.m_axis_dma_write_desc_ram_sel(axis_dma_write_desc_ram_sel),
.m_axis_dma_write_desc_ram_addr(axis_dma_write_desc_ram_addr),
.m_axis_dma_write_desc_imm(axis_dma_write_desc_imm),
.m_axis_dma_write_desc_imm_en(axis_dma_write_desc_imm_en),
.m_axis_dma_write_desc_len(axis_dma_write_desc_len),
.m_axis_dma_write_desc_tag(axis_dma_write_desc_tag),
.m_axis_dma_write_desc_valid(axis_dma_write_desc_valid),

View File

@ -39,6 +39,10 @@ module example_core_pcie_s10 #
parameter SEG_DATA_WIDTH = 256,
// H-Tile/L-Tile AVST segment empty signal width
parameter SEG_EMPTY_WIDTH = $clog2(SEG_DATA_WIDTH/32),
// Immediate enable
parameter IMM_ENABLE = 1,
// Immediate width
parameter IMM_WIDTH = 32,
// TX sequence number width
parameter TX_SEQ_NUM_WIDTH = 6,
// TX sequence number tracking enable
@ -366,6 +370,8 @@ example_core_pcie #(
.TX_SEQ_NUM_COUNT(TX_SEQ_NUM_COUNT),
.TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH),
.TX_SEQ_NUM_ENABLE(TX_SEQ_NUM_ENABLE),
.IMM_ENABLE(IMM_ENABLE),
.IMM_WIDTH(IMM_WIDTH),
.PCIE_TAG_COUNT(PCIE_TAG_COUNT),
.READ_OP_TABLE_SIZE(READ_OP_TABLE_SIZE),
.READ_TX_LIMIT(READ_TX_LIMIT),

View File

@ -49,6 +49,10 @@ module example_core_pcie_us #
parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6,
// RQ sequence number tracking enable
parameter RQ_SEQ_NUM_ENABLE = 1,
// Immediate enable
parameter IMM_ENABLE = 1,
// Immediate width
parameter IMM_WIDTH = 32,
// PCIe tag count
parameter PCIE_TAG_COUNT = 256,
// Operation table size (read)
@ -461,6 +465,8 @@ example_core_pcie #(
.TX_SEQ_NUM_COUNT(TX_SEQ_NUM_COUNT),
.TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH),
.TX_SEQ_NUM_ENABLE(TX_SEQ_NUM_ENABLE),
.IMM_ENABLE(IMM_ENABLE),
.IMM_WIDTH(IMM_WIDTH),
.PCIE_TAG_COUNT(PCIE_TAG_COUNT),
.READ_OP_TABLE_SIZE(READ_OP_TABLE_SIZE),
.READ_TX_LIMIT(READ_TX_LIMIT),

View File

@ -56,6 +56,8 @@ export PARAM_TX_SEQ_NUM_COUNT ?= 1
export PARAM_TX_SEQ_NUM_WIDTH ?= 6
export PARAM_TX_SEQ_NUM_ENABLE ?= 1
export PARAM_PCIE_TAG_COUNT ?= 256
export PARAM_IMM_ENABLE ?= 1
export PARAM_IMM_WIDTH ?= 32
export PARAM_READ_OP_TABLE_SIZE ?= $(PARAM_PCIE_TAG_COUNT)
export PARAM_READ_TX_LIMIT ?= $(shell echo "$$(( 1 << $(PARAM_TX_SEQ_NUM_WIDTH) ))" )
export PARAM_READ_TX_FC_ENABLE ?= 1
@ -78,6 +80,8 @@ ifeq ($(SIM), icarus)
COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_ENABLE=$(PARAM_TX_SEQ_NUM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
COMPILE_ARGS += -P $(TOPLEVEL).IMM_ENABLE=$(PARAM_IMM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).IMM_WIDTH=$(PARAM_IMM_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).READ_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_LIMIT=$(PARAM_READ_TX_LIMIT)
COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE)
@ -104,6 +108,8 @@ else ifeq ($(SIM), verilator)
COMPILE_ARGS += -GTX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH)
COMPILE_ARGS += -GTX_SEQ_NUM_ENABLE=$(PARAM_TX_SEQ_NUM_ENABLE)
COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
COMPILE_ARGS += -GIMM_ENABLE=$(PARAM_IMM_ENABLE)
COMPILE_ARGS += -GIMM_WIDTH=$(PARAM_IMM_WIDTH)
COMPILE_ARGS += -GREAD_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE)
COMPILE_ARGS += -GREAD_TX_LIMIT=$(PARAM_READ_TX_LIMIT)
COMPILE_ARGS += -GREAD_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE)

View File

@ -199,10 +199,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -211,16 +239,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -229,36 +257,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -267,23 +299,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
@ -337,6 +377,8 @@ def test_example_core_pcie(request, pcie_data_width):
parameters['TX_SEQ_NUM_WIDTH'] = 6
parameters['TX_SEQ_NUM_ENABLE'] = 1
parameters['PCIE_TAG_COUNT'] = 256
parameters['IMM_ENABLE'] = 1
parameters['IMM_WIDTH'] = 32
parameters['READ_OP_TABLE_SIZE'] = parameters['PCIE_TAG_COUNT']
parameters['READ_TX_LIMIT'] = 2**parameters['TX_SEQ_NUM_WIDTH']
parameters['READ_TX_FC_ENABLE'] = 1

View File

@ -61,6 +61,8 @@ export PARAM_TX_SEQ_NUM_WIDTH ?= 6
export PARAM_TX_SEQ_NUM_ENABLE ?= 1
export PARAM_L_TILE ?= 0
export PARAM_PCIE_TAG_COUNT ?= 256
export PARAM_IMM_ENABLE ?= 1
export PARAM_IMM_WIDTH ?= 32
export PARAM_READ_OP_TABLE_SIZE ?= $(PARAM_PCIE_TAG_COUNT)
export PARAM_READ_TX_LIMIT ?= $(shell echo "$$(( 1 << $(PARAM_TX_SEQ_NUM_WIDTH) ))" )
export PARAM_READ_TX_FC_ENABLE ?= 1
@ -80,6 +82,8 @@ ifeq ($(SIM), icarus)
COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_ENABLE=$(PARAM_TX_SEQ_NUM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).L_TILE=$(PARAM_L_TILE)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
COMPILE_ARGS += -P $(TOPLEVEL).IMM_ENABLE=$(PARAM_IMM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).IMM_WIDTH=$(PARAM_IMM_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).READ_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_LIMIT=$(PARAM_READ_TX_LIMIT)
COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE)
@ -103,6 +107,8 @@ else ifeq ($(SIM), verilator)
COMPILE_ARGS += -GTX_SEQ_NUM_ENABLE=$(PARAM_TX_SEQ_NUM_ENABLE)
COMPILE_ARGS += -GL_TILE=$(PARAM_L_TILE)
COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
COMPILE_ARGS += -GIMM_ENABLE=$(PARAM_IMM_ENABLE)
COMPILE_ARGS += -GIMM_WIDTH=$(PARAM_IMM_WIDTH)
COMPILE_ARGS += -GREAD_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE)
COMPILE_ARGS += -GREAD_TX_LIMIT=$(PARAM_READ_TX_LIMIT)
COMPILE_ARGS += -GREAD_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE)

View File

@ -237,10 +237,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -249,16 +277,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -267,36 +295,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -305,23 +337,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
@ -376,6 +416,8 @@ def test_example_core_pcie_s10(request, data_width, l_tile):
parameters['TX_SEQ_NUM_ENABLE'] = 1
parameters['L_TILE'] = l_tile
parameters['PCIE_TAG_COUNT'] = 256
parameters['IMM_ENABLE'] = 1
parameters['IMM_WIDTH'] = 32
parameters['READ_OP_TABLE_SIZE'] = parameters['PCIE_TAG_COUNT']
parameters['READ_TX_LIMIT'] = 2**parameters['TX_SEQ_NUM_WIDTH']
parameters['READ_TX_FC_ENABLE'] = 1

View File

@ -65,6 +65,8 @@ export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_
export PARAM_RQ_SEQ_NUM_WIDTH ?= $(if $(filter-out 60,$(PARAM_AXIS_PCIE_RQ_USER_WIDTH)),6,4)
export PARAM_RQ_SEQ_NUM_ENABLE ?= 1
export PARAM_PCIE_TAG_COUNT ?= 256
export PARAM_IMM_ENABLE ?= 1
export PARAM_IMM_WIDTH ?= 32
export PARAM_READ_OP_TABLE_SIZE ?= $(PARAM_PCIE_TAG_COUNT)
export PARAM_READ_TX_LIMIT ?= $(shell echo "$$(( 1 << ($(PARAM_RQ_SEQ_NUM_WIDTH)-1) ))" )
export PARAM_READ_TX_FC_ENABLE ?= 1
@ -86,6 +88,8 @@ ifeq ($(SIM), icarus)
COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_ENABLE=$(PARAM_RQ_SEQ_NUM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
COMPILE_ARGS += -P $(TOPLEVEL).IMM_ENABLE=$(PARAM_IMM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).IMM_WIDTH=$(PARAM_IMM_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).READ_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_LIMIT=$(PARAM_READ_TX_LIMIT)
COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE)
@ -111,6 +115,8 @@ else ifeq ($(SIM), verilator)
COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH)
COMPILE_ARGS += -GRQ_SEQ_NUM_ENABLE=$(PARAM_RQ_SEQ_NUM_ENABLE)
COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
COMPILE_ARGS += -GIMM_ENABLE=$(PARAM_IMM_ENABLE)
COMPILE_ARGS += -GIMM_WIDTH=$(PARAM_IMM_WIDTH)
COMPILE_ARGS += -GREAD_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE)
COMPILE_ARGS += -GREAD_TX_LIMIT=$(PARAM_READ_TX_LIMIT)
COMPILE_ARGS += -GREAD_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE)

View File

@ -331,10 +331,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -343,16 +371,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -361,36 +389,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -399,23 +431,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
@ -473,6 +513,8 @@ def test_example_core_pcie_us(request, axis_pcie_data_width):
parameters['RQ_SEQ_NUM_WIDTH'] = 4 if parameters['AXIS_PCIE_RQ_USER_WIDTH'] == 60 else 6
parameters['RQ_SEQ_NUM_ENABLE'] = 1
parameters['PCIE_TAG_COUNT'] = 256
parameters['IMM_ENABLE'] = 1
parameters['IMM_WIDTH'] = 32
parameters['READ_OP_TABLE_SIZE'] = parameters['PCIE_TAG_COUNT']
parameters['READ_TX_LIMIT'] = 2**(parameters['RQ_SEQ_NUM_WIDTH']-1)
parameters['READ_TX_FC_ENABLE'] = 1

View File

@ -312,10 +312,38 @@ async def run_test(dut):
assert mem[0:1024] == mem[0x1000:0x1000+1024]
tb.log.info("Test immediate write")
# write pcie write descriptor
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x000208, 0x44332211)
await dev_pf0_bar0.write_dword(0x000210, 0x4)
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
await Timer(2000, 'ns')
# read status
val = await dev_pf0_bar0.read_dword(0x000218)
tb.log.info("Status: 0x%x", val)
assert val == 0x800000AA
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
tb.log.info("Test DMA block operations")
region_len = 0x2000
src_offset = 0x0000
dest_offset = 0x4000
block_size = 256
block_stride = block_size
block_count = 32
# write packet data
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
# enable DMA
await dev_pf0_bar0.write_dword(0x000000, 1)
@ -324,16 +352,16 @@ async def run_test(dut):
# configure operation (read)
# DMA base address
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001080, (mem_base+src_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001088, 0)
await dev_pf0_bar0.write_dword(0x00108c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001090, region_len-1)
await dev_pf0_bar0.write_dword(0x001094, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001098, 256)
await dev_pf0_bar0.write_dword(0x001098, block_stride)
await dev_pf0_bar0.write_dword(0x00109c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0010c0, 0)
@ -342,36 +370,40 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0010c8, 0)
await dev_pf0_bar0.write_dword(0x0010cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0010d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0010d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0010d8, 256)
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
await dev_pf0_bar0.write_dword(0x0010dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001008, 0)
await dev_pf0_bar0.write_dword(0x00100c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001010, 256)
await dev_pf0_bar0.write_dword(0x001010, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001018, 32)
await dev_pf0_bar0.write_dword(0x001018, block_count)
await dev_pf0_bar0.write_dword(0x00101c, 0)
# start
await dev_pf0_bar0.write_dword(0x001000, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001018)
await Timer(1000, 'ns')
if cnt == 0:
break
# configure operation (write)
# DMA base address
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 32) & 0xffffffff)
# DMA offset address
await dev_pf0_bar0.write_dword(0x001188, 0)
await dev_pf0_bar0.write_dword(0x00118c, 0)
# DMA offset mask
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
await dev_pf0_bar0.write_dword(0x001190, region_len-1)
await dev_pf0_bar0.write_dword(0x001194, 0)
# DMA stride
await dev_pf0_bar0.write_dword(0x001198, 256)
await dev_pf0_bar0.write_dword(0x001198, block_stride)
await dev_pf0_bar0.write_dword(0x00119c, 0)
# RAM base address
await dev_pf0_bar0.write_dword(0x0011c0, 0)
@ -380,23 +412,31 @@ async def run_test(dut):
await dev_pf0_bar0.write_dword(0x0011c8, 0)
await dev_pf0_bar0.write_dword(0x0011cc, 0)
# RAM offset mask
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
await dev_pf0_bar0.write_dword(0x0011d0, region_len-1)
await dev_pf0_bar0.write_dword(0x0011d4, 0)
# RAM stride
await dev_pf0_bar0.write_dword(0x0011d8, 256)
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
await dev_pf0_bar0.write_dword(0x0011dc, 0)
# clear cycle count
await dev_pf0_bar0.write_dword(0x001108, 0)
await dev_pf0_bar0.write_dword(0x00110c, 0)
# block length
await dev_pf0_bar0.write_dword(0x001110, 256)
await dev_pf0_bar0.write_dword(0x001110, block_size)
# block count
await dev_pf0_bar0.write_dword(0x001118, 32)
await dev_pf0_bar0.write_dword(0x001118, block_count)
await dev_pf0_bar0.write_dword(0x00111c, 0)
# start
await dev_pf0_bar0.write_dword(0x001100, 1)
await Timer(2000, 'ns')
for k in range(10):
cnt = await dev_pf0_bar0.read_dword(0x001118)
await Timer(1000, 'ns')
if cnt == 0:
break
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)

View File

@ -55,6 +55,10 @@ module dma_if_axi #
parameter RAM_SEG_BE_WIDTH = RAM_SEG_DATA_WIDTH/8,
// RAM segment address width
parameter RAM_SEG_ADDR_WIDTH = RAM_ADDR_WIDTH-$clog2(RAM_SEG_COUNT*RAM_SEG_BE_WIDTH),
// Immediate enable
parameter IMM_ENABLE = 0,
// Immediate width
parameter IMM_WIDTH = 32,
// Length field width
parameter LEN_WIDTH = 16,
// Tag field width
@ -135,6 +139,8 @@ module dma_if_axi #
input wire [AXI_ADDR_WIDTH-1:0] s_axis_write_desc_axi_addr,
input wire [RAM_SEL_WIDTH-1:0] s_axis_write_desc_ram_sel,
input wire [RAM_ADDR_WIDTH-1:0] s_axis_write_desc_ram_addr,
input wire [IMM_WIDTH-1:0] s_axis_write_desc_imm,
input wire s_axis_write_desc_imm_en,
input wire [LEN_WIDTH-1:0] s_axis_write_desc_len,
input wire [TAG_WIDTH-1:0] s_axis_write_desc_tag,
input wire s_axis_write_desc_valid,
@ -169,7 +175,39 @@ module dma_if_axi #
* Configuration
*/
input wire read_enable,
input wire write_enable
input wire write_enable,
/*
* Statistics
*/
output wire [$clog2(READ_OP_TABLE_SIZE)-1:0] stat_rd_op_start_tag,
output wire [LEN_WIDTH-1:0] stat_rd_op_start_len,
output wire stat_rd_op_start_valid,
output wire [$clog2(READ_OP_TABLE_SIZE)-1:0] stat_rd_op_finish_tag,
output wire [3:0] stat_rd_op_finish_status,
output wire stat_rd_op_finish_valid,
output wire [$clog2(READ_OP_TABLE_SIZE)-1:0] stat_rd_req_start_tag,
output wire [12:0] stat_rd_req_start_len,
output wire stat_rd_req_start_valid,
output wire [$clog2(READ_OP_TABLE_SIZE)-1:0] stat_rd_req_finish_tag,
output wire [3:0] stat_rd_req_finish_status,
output wire stat_rd_req_finish_valid,
output wire stat_rd_op_table_full,
output wire stat_rd_tx_stall,
output wire [$clog2(WRITE_OP_TABLE_SIZE)-1:0] stat_wr_op_start_tag,
output wire [LEN_WIDTH-1:0] stat_wr_op_start_len,
output wire stat_wr_op_start_valid,
output wire [$clog2(WRITE_OP_TABLE_SIZE)-1:0] stat_wr_op_finish_tag,
output wire [3:0] stat_wr_op_finish_status,
output wire stat_wr_op_finish_valid,
output wire [$clog2(WRITE_OP_TABLE_SIZE)-1:0] stat_wr_req_start_tag,
output wire [12:0] stat_wr_req_start_len,
output wire stat_wr_req_start_valid,
output wire [$clog2(WRITE_OP_TABLE_SIZE)-1:0] stat_wr_req_finish_tag,
output wire [3:0] stat_wr_req_finish_status,
output wire stat_wr_req_finish_valid,
output wire stat_wr_op_table_full,
output wire stat_wr_tx_stall
);
dma_if_axi_rd #(
@ -245,7 +283,25 @@ dma_if_axi_rd_inst (
/*
* Configuration
*/
.enable(read_enable)
.enable(read_enable),
/*
* Statistics
*/
.stat_rd_op_start_tag(stat_rd_op_start_tag),
.stat_rd_op_start_len(stat_rd_op_start_len),
.stat_rd_op_start_valid(stat_rd_op_start_valid),
.stat_rd_op_finish_tag(stat_rd_op_finish_tag),
.stat_rd_op_finish_status(stat_rd_op_finish_status),
.stat_rd_op_finish_valid(stat_rd_op_finish_valid),
.stat_rd_req_start_tag(stat_rd_req_start_tag),
.stat_rd_req_start_len(stat_rd_req_start_len),
.stat_rd_req_start_valid(stat_rd_req_start_valid),
.stat_rd_req_finish_tag(stat_rd_req_finish_tag),
.stat_rd_req_finish_status(stat_rd_req_finish_status),
.stat_rd_req_finish_valid(stat_rd_req_finish_valid),
.stat_rd_op_table_full(stat_rd_op_table_full),
.stat_rd_tx_stall(stat_rd_tx_stall)
);
dma_if_axi_wr #(
@ -260,6 +316,8 @@ dma_if_axi_wr #(
.RAM_SEG_DATA_WIDTH(RAM_SEG_DATA_WIDTH),
.RAM_SEG_BE_WIDTH(RAM_SEG_BE_WIDTH),
.RAM_SEG_ADDR_WIDTH(RAM_SEG_ADDR_WIDTH),
.IMM_ENABLE(IMM_ENABLE),
.IMM_WIDTH(IMM_WIDTH),
.LEN_WIDTH(LEN_WIDTH),
.TAG_WIDTH(TAG_WIDTH),
.OP_TABLE_SIZE(WRITE_OP_TABLE_SIZE),
@ -298,6 +356,8 @@ dma_if_axi_wr_inst (
.s_axis_write_desc_axi_addr(s_axis_write_desc_axi_addr),
.s_axis_write_desc_ram_sel(s_axis_write_desc_ram_sel),
.s_axis_write_desc_ram_addr(s_axis_write_desc_ram_addr),
.s_axis_write_desc_imm(s_axis_write_desc_imm),
.s_axis_write_desc_imm_en(s_axis_write_desc_imm_en),
.s_axis_write_desc_len(s_axis_write_desc_len),
.s_axis_write_desc_tag(s_axis_write_desc_tag),
.s_axis_write_desc_valid(s_axis_write_desc_valid),
@ -324,7 +384,25 @@ dma_if_axi_wr_inst (
/*
* Configuration
*/
.enable(write_enable)
.enable(write_enable),
/*
* Statistics
*/
.stat_wr_op_start_tag(stat_wr_op_start_tag),
.stat_wr_op_start_len(stat_wr_op_start_len),
.stat_wr_op_start_valid(stat_wr_op_start_valid),
.stat_wr_op_finish_tag(stat_wr_op_finish_tag),
.stat_wr_op_finish_status(stat_wr_op_finish_status),
.stat_wr_op_finish_valid(stat_wr_op_finish_valid),
.stat_wr_req_start_tag(stat_wr_req_start_tag),
.stat_wr_req_start_len(stat_wr_req_start_len),
.stat_wr_req_start_valid(stat_wr_req_start_valid),
.stat_wr_req_finish_tag(stat_wr_req_finish_tag),
.stat_wr_req_finish_status(stat_wr_req_finish_status),
.stat_wr_req_finish_valid(stat_wr_req_finish_valid),
.stat_wr_op_table_full(stat_wr_op_table_full),
.stat_wr_tx_stall(stat_wr_tx_stall)
);
endmodule

View File

@ -120,9 +120,28 @@ module dma_if_axi_rd #
/*
* Configuration
*/
input wire enable
input wire enable,
/*
* Statistics
*/
output wire [$clog2(OP_TABLE_SIZE)-1:0] stat_rd_op_start_tag,
output wire [LEN_WIDTH-1:0] stat_rd_op_start_len,
output wire stat_rd_op_start_valid,
output wire [$clog2(OP_TABLE_SIZE)-1:0] stat_rd_op_finish_tag,
output wire [3:0] stat_rd_op_finish_status,
output wire stat_rd_op_finish_valid,
output wire [$clog2(OP_TABLE_SIZE)-1:0] stat_rd_req_start_tag,
output wire [12:0] stat_rd_req_start_len,
output wire stat_rd_req_start_valid,
output wire [$clog2(OP_TABLE_SIZE)-1:0] stat_rd_req_finish_tag,
output wire [3:0] stat_rd_req_finish_status,
output wire stat_rd_req_finish_valid,
output wire stat_rd_op_table_full,
output wire stat_rd_tx_stall
);
parameter RAM_DATA_WIDTH = RAM_SEG_COUNT*RAM_SEG_DATA_WIDTH;
parameter RAM_WORD_WIDTH = RAM_SEG_BE_WIDTH;
parameter RAM_WORD_SIZE = RAM_SEG_DATA_WIDTH/RAM_WORD_WIDTH;
@ -171,7 +190,7 @@ initial begin
$finish;
end
if (RAM_SEG_COUNT*RAM_SEG_DATA_WIDTH != AXI_DATA_WIDTH*2) begin
if (RAM_DATA_WIDTH != AXI_DATA_WIDTH*2) begin
$error("Error: RAM interface width must be double the AXI interface width (instance %m)");
$finish;
end
@ -185,6 +204,11 @@ initial begin
$error("Error: RAM_ADDR_WIDTH does not match RAM configuration (instance %m)");
$finish;
end
if (OP_TABLE_SIZE > 2**AXI_ID_WIDTH) begin
$error("Error: AXI_ID_WIDTH insufficient for requested OP_TABLE_SIZE (instance %m)");
$finish;
end
end
localparam [1:0]
@ -223,12 +247,14 @@ reg [RAM_SEL_WIDTH-1:0] req_ram_sel_reg = {RAM_SEL_WIDTH{1'b0}}, req_ram_sel_nex
reg [RAM_ADDR_WIDTH-1:0] req_ram_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, req_ram_addr_next;
reg [LEN_WIDTH-1:0] req_op_count_reg = {LEN_WIDTH{1'b0}}, req_op_count_next;
reg [LEN_WIDTH-1:0] req_tr_count_reg = {LEN_WIDTH{1'b0}}, req_tr_count_next;
reg req_zero_len_reg = 1'b0, req_zero_len_next;
reg [TAG_WIDTH-1:0] req_tag_reg = {TAG_WIDTH{1'b0}}, req_tag_next;
reg [RAM_SEL_WIDTH-1:0] ram_sel_reg = {RAM_SEL_WIDTH{1'b0}}, ram_sel_next;
reg [RAM_ADDR_WIDTH-1:0] addr_reg = {RAM_ADDR_WIDTH{1'b0}}, addr_next;
reg [RAM_ADDR_WIDTH-1:0] addr_delay_reg = {RAM_ADDR_WIDTH{1'b0}}, addr_delay_next;
reg [12:0] op_count_reg = 13'd0, op_count_next;
reg zero_len_reg = 1'b0, zero_len_next;
reg [RAM_SEG_COUNT-1:0] ram_mask_reg = {RAM_SEG_COUNT{1'b0}}, ram_mask_next;
reg [RAM_SEG_COUNT-1:0] ram_mask_0_reg = {RAM_SEG_COUNT{1'b0}}, ram_mask_0_next;
reg [RAM_SEG_COUNT-1:0] ram_mask_1_reg = {RAM_SEG_COUNT{1'b0}}, ram_mask_1_next;
@ -247,16 +273,22 @@ reg [OP_TAG_WIDTH-1:0] status_fifo_op_tag[(2**STATUS_FIFO_ADDR_WIDTH)-1:0];
reg [RAM_SEG_COUNT-1:0] status_fifo_mask[(2**STATUS_FIFO_ADDR_WIDTH)-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg status_fifo_finish[(2**STATUS_FIFO_ADDR_WIDTH)-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [3:0] status_fifo_error[(2**STATUS_FIFO_ADDR_WIDTH)-1:0];
reg [OP_TAG_WIDTH-1:0] status_fifo_wr_op_tag;
reg [RAM_SEG_COUNT-1:0] status_fifo_wr_mask;
reg status_fifo_wr_finish;
reg [3:0] status_fifo_wr_error;
reg status_fifo_we;
reg status_fifo_mask_reg = 1'b0, status_fifo_mask_next;
reg status_fifo_finish_reg = 1'b0, status_fifo_finish_next;
reg [3:0] status_fifo_error_reg = 4'd0, status_fifo_error_next;
reg status_fifo_we_reg = 1'b0, status_fifo_we_next;
reg status_fifo_half_full_reg = 1'b0;
reg [OP_TAG_WIDTH-1:0] status_fifo_rd_op_tag_reg = 0, status_fifo_rd_op_tag_next;
reg [RAM_SEG_COUNT-1:0] status_fifo_rd_mask_reg = 0, status_fifo_rd_mask_next;
reg status_fifo_rd_finish_reg = 1'b0, status_fifo_rd_finish_next;
reg [3:0] status_fifo_rd_error_reg = 4'd0, status_fifo_rd_error_next;
reg status_fifo_rd_valid_reg = 1'b0, status_fifo_rd_valid_next;
reg [AXI_DATA_WIDTH-1:0] m_axi_rdata_int_reg = {AXI_DATA_WIDTH{1'b0}}, m_axi_rdata_int_next;
@ -274,6 +306,21 @@ reg [TAG_WIDTH-1:0] m_axis_read_desc_status_tag_reg = {TAG_WIDTH{1'b0}}, m_axis_
reg [3:0] m_axis_read_desc_status_error_reg = 4'd0, m_axis_read_desc_status_error_next;
reg m_axis_read_desc_status_valid_reg = 1'b0, m_axis_read_desc_status_valid_next;
reg [OP_TAG_WIDTH-1:0] stat_rd_op_start_tag_reg = 0, stat_rd_op_start_tag_next;
reg [LEN_WIDTH-1:0] stat_rd_op_start_len_reg = 0, stat_rd_op_start_len_next;
reg stat_rd_op_start_valid_reg = 1'b0, stat_rd_op_start_valid_next;
reg [OP_TAG_WIDTH-1:0] stat_rd_op_finish_tag_reg = 0, stat_rd_op_finish_tag_next;
reg [3:0] stat_rd_op_finish_status_reg = 4'd0, stat_rd_op_finish_status_next;
reg stat_rd_op_finish_valid_reg = 1'b0, stat_rd_op_finish_valid_next;
reg [OP_TAG_WIDTH-1:0] stat_rd_req_start_tag_reg = 0, stat_rd_req_start_tag_next;
reg [12:0] stat_rd_req_start_len_reg = 13'd0, stat_rd_req_start_len_next;
reg stat_rd_req_start_valid_reg = 1'b0, stat_rd_req_start_valid_next;
reg [OP_TAG_WIDTH-1:0] stat_rd_req_finish_tag_reg = 0, stat_rd_req_finish_tag_next;
reg [3:0] stat_rd_req_finish_status_reg = 4'd0, stat_rd_req_finish_status_next;
reg stat_rd_req_finish_valid_reg = 1'b0, stat_rd_req_finish_valid_next;
reg stat_rd_op_table_full_reg = 1'b0, stat_rd_op_table_full_next;
reg stat_rd_tx_stall_reg = 1'b0, stat_rd_tx_stall_next;
// internal datapath
reg [RAM_SEG_COUNT*RAM_SEL_WIDTH-1:0] ram_wr_cmd_sel_int;
reg [RAM_SEG_COUNT*RAM_SEG_BE_WIDTH-1:0] ram_wr_cmd_be_int;
@ -302,20 +349,39 @@ assign m_axis_read_desc_status_tag = m_axis_read_desc_status_tag_reg;
assign m_axis_read_desc_status_error = m_axis_read_desc_status_error_reg;
assign m_axis_read_desc_status_valid = m_axis_read_desc_status_valid_reg;
assign stat_rd_op_start_tag = stat_rd_op_start_tag_reg;
assign stat_rd_op_start_len = stat_rd_op_start_len_reg;
assign stat_rd_op_start_valid = stat_rd_op_start_valid_reg;
assign stat_rd_op_finish_tag = stat_rd_op_finish_tag_reg;
assign stat_rd_op_finish_status = stat_rd_op_finish_status_reg;
assign stat_rd_op_finish_valid = stat_rd_op_finish_valid_reg;
assign stat_rd_req_start_tag = stat_rd_req_start_tag_reg;
assign stat_rd_req_start_len = stat_rd_req_start_len_reg;
assign stat_rd_req_start_valid = stat_rd_req_start_valid_reg;
assign stat_rd_req_finish_tag = stat_rd_req_finish_tag_reg;
assign stat_rd_req_finish_status = stat_rd_req_finish_status_reg;
assign stat_rd_req_finish_valid = stat_rd_req_finish_valid_reg;
assign stat_rd_op_table_full = stat_rd_op_table_full_reg;
assign stat_rd_tx_stall = stat_rd_tx_stall_reg;
// operation tag management
reg [OP_TAG_WIDTH+1-1:0] op_table_start_ptr_reg = 0;
reg [AXI_ADDR_WIDTH-1:0] op_table_start_axi_addr;
reg [RAM_SEL_WIDTH-1:0] op_table_start_ram_sel;
reg [RAM_ADDR_WIDTH-1:0] op_table_start_ram_addr;
reg [11:0] op_table_start_len;
reg op_table_start_zero_len;
reg [CYCLE_COUNT_WIDTH-1:0] op_table_start_cycle_count;
reg [TAG_WIDTH-1:0] op_table_start_tag;
reg op_table_start_last;
reg op_table_start_en;
reg op_table_read_complete_en;
reg [OP_TAG_WIDTH+1-1:0] op_table_read_complete_ptr_reg = 0;
reg op_table_write_complete_en;
reg op_table_read_complete_en;
reg [OP_TAG_WIDTH-1:0] op_table_update_status_ptr;
reg [3:0] op_table_update_status_error;
reg op_table_update_status_en;
reg [OP_TAG_WIDTH-1:0] op_table_write_complete_ptr;
reg op_table_write_complete_en;
reg [OP_TAG_WIDTH+1-1:0] op_table_finish_ptr_reg = 0;
reg op_table_finish_en;
@ -329,6 +395,8 @@ reg [RAM_ADDR_WIDTH-1:0] op_table_ram_addr [2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [11:0] op_table_len[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg op_table_zero_len[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [CYCLE_COUNT_WIDTH-1:0] op_table_cycle_count[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [TAG_WIDTH-1:0] op_table_tag[2**OP_TAG_WIDTH-1:0];
@ -336,6 +404,12 @@ reg [TAG_WIDTH-1:0] op_table_tag[2**OP_TAG_WIDTH-1:0];
reg op_table_last[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg op_table_write_complete[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg op_table_error_a [2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg op_table_error_b [2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [3:0] op_table_error_code [2**OP_TAG_WIDTH-1:0];
integer i;
@ -345,10 +419,14 @@ initial begin
op_table_ram_sel[i] = 0;
op_table_ram_addr[i] = 0;
op_table_len[i] = 0;
op_table_zero_len[i] = 1'b0;
op_table_cycle_count[i] = 0;
op_table_tag[i] = 0;
op_table_last[i] = 0;
op_table_write_complete[i] = 0;
op_table_error_a[i] = 0;
op_table_error_b[i] = 0;
op_table_error_code[i] = 0;
end
end
@ -357,11 +435,21 @@ always @* begin
s_axis_read_desc_ready_next = 1'b0;
stat_rd_op_start_tag_next = stat_rd_op_start_tag_reg;
stat_rd_op_start_len_next = stat_rd_op_start_len_reg;
stat_rd_op_start_valid_next = 1'b0;
stat_rd_req_start_tag_next = stat_rd_req_start_tag_reg;
stat_rd_req_start_len_next = stat_rd_req_start_len_reg;
stat_rd_req_start_valid_next = 1'b0;
stat_rd_op_table_full_next = !(!op_table_active[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] && ($unsigned(op_table_start_ptr_reg - op_table_finish_ptr_reg) < 2**OP_TAG_WIDTH));
stat_rd_tx_stall_next = m_axi_arvalid_reg && !m_axi_arready;
req_axi_addr_next = req_axi_addr_reg;
req_ram_sel_next = req_ram_sel_reg;
req_ram_addr_next = req_ram_addr_reg;
req_op_count_next = req_op_count_reg;
req_tr_count_next = req_tr_count_reg;
req_zero_len_next = req_zero_len_reg;
req_tag_next = req_tag_reg;
m_axi_arid_next = m_axi_arid_reg;
@ -373,6 +461,7 @@ always @* begin
op_table_start_ram_sel = req_ram_sel_reg;
op_table_start_ram_addr = req_ram_addr_reg;
op_table_start_len = 0;
op_table_start_zero_len = req_zero_len_reg;
op_table_start_tag = req_tag_reg;
op_table_start_cycle_count = 0;
op_table_start_last = 0;
@ -386,7 +475,14 @@ always @* begin
req_axi_addr_next = s_axis_read_desc_axi_addr;
req_ram_sel_next = s_axis_read_desc_ram_sel;
req_ram_addr_next = s_axis_read_desc_ram_addr;
req_op_count_next = s_axis_read_desc_len;
if (s_axis_read_desc_len == 0) begin
// zero-length operation
req_op_count_next = 1;
req_zero_len_next = 1'b1;
end else begin
req_op_count_next = s_axis_read_desc_len;
req_zero_len_next = 1'b0;
end
req_tag_next = s_axis_read_desc_tag;
if (req_op_count_next <= AXI_MAX_BURST_SIZE - (req_axi_addr_next & OFFSET_MASK) || AXI_MAX_BURST_SIZE >= 4096) begin
@ -411,6 +507,11 @@ always @* begin
if (s_axis_read_desc_ready && s_axis_read_desc_valid) begin
s_axis_read_desc_ready_next = 1'b0;
stat_rd_op_start_tag_next = stat_rd_op_start_tag_reg+1;
stat_rd_op_start_len_next = s_axis_read_desc_len;
stat_rd_op_start_valid_next = 1'b1;
req_state_next = REQ_STATE_START;
end else begin
req_state_next = REQ_STATE_IDLE;
@ -426,11 +527,16 @@ always @* begin
op_table_start_ram_sel = req_ram_sel_reg;
op_table_start_ram_addr = req_ram_addr_reg;
op_table_start_len = req_tr_count_next;
op_table_start_zero_len = req_zero_len_reg;
op_table_start_tag = req_tag_reg;
op_table_start_cycle_count = (req_tr_count_next + (req_axi_addr_reg & OFFSET_MASK) - 1) >> AXI_BURST_SIZE;
op_table_start_last = req_op_count_reg == req_tr_count_next;
op_table_start_en = 1'b1;
stat_rd_req_start_tag_next = op_table_start_ptr_reg[OP_TAG_WIDTH-1:0];
stat_rd_req_start_len_next = req_zero_len_reg ? 0 : req_tr_count_reg;
stat_rd_req_start_valid_next = 1'b1;
m_axi_arid_next = op_table_start_ptr_reg[OP_TAG_WIDTH-1:0];
m_axi_araddr_next = req_axi_addr_reg;
m_axi_arlen_next = op_table_start_cycle_count;
@ -474,10 +580,18 @@ always @* begin
m_axi_rready_next = 1'b0;
stat_rd_op_finish_tag_next = stat_rd_op_finish_tag_reg;
stat_rd_op_finish_status_next = stat_rd_op_finish_status_reg;
stat_rd_op_finish_valid_next = 1'b0;
stat_rd_req_finish_tag_next = stat_rd_req_finish_tag_reg;
stat_rd_req_finish_status_next = stat_rd_req_finish_status_reg;
stat_rd_req_finish_valid_next = 1'b0;
ram_sel_next = ram_sel_reg;
addr_next = addr_reg;
addr_delay_next = addr_delay_reg;
op_count_next = op_count_reg;
zero_len_next = zero_len_reg;
ram_mask_next = ram_mask_reg;
ram_mask_0_next = ram_mask_0_reg;
ram_mask_1_next = ram_mask_1_reg;
@ -489,13 +603,13 @@ always @* begin
op_tag_next = op_tag_reg;
op_table_read_complete_en = 1'b0;
op_table_write_complete_en = 1'b0;
op_table_write_complete_ptr = m_axi_rid;
m_axi_rdata_int_next = m_axi_rdata_int_reg;
m_axi_rvalid_int_next = 1'b0;
status_fifo_mask_next = 1'b1;
status_fifo_finish_next = 1'b0;
status_fifo_error_next = DMA_ERROR_NONE;
status_fifo_we_next = 1'b0;
out_done_ack = {RAM_SEG_COUNT{1'b0}};
@ -534,6 +648,7 @@ always @* begin
ram_sel_next = op_table_ram_sel[op_tag_next];
addr_next = op_table_ram_addr[op_tag_next];
op_count_next = op_table_len[op_tag_next];
zero_len_next = op_table_zero_len[op_tag_next];
offset_next = op_table_ram_addr[op_tag_next][RAM_OFFSET_WIDTH-1:0]-(op_table_axi_addr[op_tag_next] & OFFSET_MASK);
if (m_axi_rready && m_axi_rvalid) begin
@ -563,15 +678,37 @@ always @* begin
m_axi_rdata_int_next = m_axi_rdata;
m_axi_rvalid_int_next = 1'b1;
status_fifo_mask_next = 1'b1;
status_fifo_finish_next = 1'b0;
status_fifo_error_next = DMA_ERROR_NONE;
status_fifo_we_next = 1'b1;
if (zero_len_next) begin
m_axi_rvalid_int_next = 1'b0;
status_fifo_mask_next = 1'b0;
end
if (m_axi_rresp == AXI_RESP_SLVERR) begin
m_axi_rvalid_int_next = 1'b0;
status_fifo_mask_next = 1'b0;
status_fifo_error_next = DMA_ERROR_AXI_RD_SLVERR;
end else if (m_axi_rresp == AXI_RESP_DECERR) begin
m_axi_rvalid_int_next = 1'b0;
status_fifo_mask_next = 1'b0;
status_fifo_error_next = DMA_ERROR_AXI_RD_DECERR;
end
stat_rd_req_finish_tag_next = op_tag_next;
stat_rd_req_finish_status_next = status_fifo_error_next;
stat_rd_req_finish_valid_next = 1'b0;
if (!USE_AXI_ID) begin
op_table_read_complete_en = 1'b1;
end
if (m_axi_rlast) begin
status_fifo_finish_next = 1'b1;
stat_rd_req_finish_valid_next = 1'b1;
axi_state_next = AXI_STATE_IDLE;
end else begin
axi_state_next = AXI_STATE_WRITE;
@ -612,11 +749,28 @@ always @* begin
m_axi_rdata_int_next = m_axi_rdata;
m_axi_rvalid_int_next = 1'b1;
status_fifo_mask_next = 1'b1;
status_fifo_finish_next = 1'b0;
status_fifo_error_next = DMA_ERROR_NONE;
status_fifo_we_next = 1'b1;
if (m_axi_rresp == AXI_RESP_SLVERR) begin
m_axi_rvalid_int_next = 1'b0;
status_fifo_mask_next = 1'b0;
status_fifo_error_next = DMA_ERROR_AXI_RD_SLVERR;
end else if (m_axi_rresp == AXI_RESP_DECERR) begin
m_axi_rvalid_int_next = 1'b0;
status_fifo_mask_next = 1'b0;
status_fifo_error_next = DMA_ERROR_AXI_RD_DECERR;
end
stat_rd_req_finish_tag_next = op_tag_next;
stat_rd_req_finish_status_next = status_fifo_error_next;
stat_rd_req_finish_valid_next = 1'b0;
if (m_axi_rlast) begin
status_fifo_finish_next = 1'b1;
stat_rd_req_finish_valid_next = 1'b1;
axi_state_next = AXI_STATE_IDLE;
end else begin
axi_state_next = AXI_STATE_WRITE;
@ -630,14 +784,16 @@ always @* begin
status_fifo_rd_ptr_next = status_fifo_rd_ptr_reg;
status_fifo_wr_op_tag = op_tag_reg;
status_fifo_wr_mask = ram_mask_reg;
status_fifo_wr_mask = status_fifo_mask_reg ? ram_mask_reg : 0;
status_fifo_wr_finish = status_fifo_finish_reg;
status_fifo_wr_error = status_fifo_error_reg;
status_fifo_we = 1'b0;
if (status_fifo_we_reg) begin
status_fifo_wr_op_tag = op_tag_reg;
status_fifo_wr_mask = ram_mask_reg;
status_fifo_wr_mask = status_fifo_mask_reg ? ram_mask_reg : 0;
status_fifo_wr_finish = status_fifo_finish_reg;
status_fifo_wr_error = status_fifo_error_reg;
status_fifo_we = 1'b1;
end
@ -645,6 +801,11 @@ always @* begin
status_fifo_rd_mask_next = status_fifo_rd_mask_reg;
status_fifo_rd_finish_next = status_fifo_rd_finish_reg;
status_fifo_rd_valid_next = status_fifo_rd_valid_reg;
status_fifo_rd_error_next = status_fifo_rd_error_reg;
op_table_update_status_ptr = status_fifo_rd_op_tag_reg;
op_table_update_status_error = status_fifo_rd_error_reg;
op_table_update_status_en = 1'b0;
op_table_write_complete_ptr = status_fifo_rd_op_tag_reg;
op_table_write_complete_en = 1'b0;
@ -652,6 +813,7 @@ always @* begin
if (status_fifo_rd_valid_reg && (status_fifo_rd_mask_reg & ~out_done) == 0) begin
// got write completion, pop and return status
status_fifo_rd_valid_next = 1'b0;
op_table_update_status_en = 1'b1;
out_done_ack = status_fifo_rd_mask_reg;
@ -667,6 +829,7 @@ always @* begin
status_fifo_rd_op_tag_next = status_fifo_op_tag[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]];
status_fifo_rd_mask_next = status_fifo_mask[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]];
status_fifo_rd_finish_next = status_fifo_finish[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]];
status_fifo_rd_error_next = status_fifo_error[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]];
status_fifo_rd_valid_next = 1'b1;
status_fifo_rd_ptr_next = status_fifo_rd_ptr_reg + 1;
end
@ -674,17 +837,33 @@ always @* begin
// commit operations in-order
op_table_finish_en = 1'b0;
if (m_axis_read_desc_status_valid_reg) begin
m_axis_read_desc_status_error_next = DMA_ERROR_NONE;
end else begin
m_axis_read_desc_status_error_next = m_axis_read_desc_status_error_reg;
end
m_axis_read_desc_status_tag_next = op_table_tag[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]];
m_axis_read_desc_status_error_next = 0;
m_axis_read_desc_status_valid_next = 1'b0;
stat_rd_op_finish_tag_next = stat_rd_op_finish_tag_reg;
stat_rd_op_finish_status_next = m_axis_read_desc_status_error_next;
stat_rd_op_finish_valid_next = 1'b0;
if (op_table_active[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]] && op_table_write_complete[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]] && op_table_finish_ptr_reg != op_table_start_ptr_reg) begin
op_table_finish_en = 1'b1;
if (op_table_error_a[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]] != op_table_error_b[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]]) begin
m_axis_read_desc_status_error_next = op_table_error_code[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]];
end
stat_rd_op_finish_status_next = m_axis_read_desc_status_error_next;
if (op_table_last[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]]) begin
m_axis_read_desc_status_tag_next = op_table_tag[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]];
m_axis_read_desc_status_error_next = 0;
m_axis_read_desc_status_valid_next = 1'b1;
stat_rd_op_finish_tag_next = stat_rd_op_finish_tag_reg + 1;
stat_rd_op_finish_valid_next = 1'b1;
end
end
end
@ -698,12 +877,14 @@ always @(posedge clk) begin
req_ram_addr_reg <= req_ram_addr_next;
req_op_count_reg <= req_op_count_next;
req_tr_count_reg <= req_tr_count_next;
req_zero_len_reg <= req_zero_len_next;
req_tag_reg <= req_tag_next;
ram_sel_reg <= ram_sel_next;
addr_reg <= addr_next;
addr_delay_reg <= addr_delay_next;
op_count_reg <= op_count_next;
zero_len_reg <= zero_len_next;
ram_mask_reg <= ram_mask_next;
ram_mask_0_reg <= ram_mask_0_next;
ram_mask_1_reg <= ram_mask_1_next;
@ -729,20 +910,39 @@ always @(posedge clk) begin
m_axis_read_desc_status_error_reg <= m_axis_read_desc_status_error_next;
m_axis_read_desc_status_valid_reg <= m_axis_read_desc_status_valid_next;
stat_rd_op_start_tag_reg <= stat_rd_op_start_tag_next;
stat_rd_op_start_len_reg <= stat_rd_op_start_len_next;
stat_rd_op_start_valid_reg <= stat_rd_op_start_valid_next;
stat_rd_op_finish_tag_reg <= stat_rd_op_finish_tag_next;
stat_rd_op_finish_status_reg <= stat_rd_op_finish_status_next;
stat_rd_op_finish_valid_reg <= stat_rd_op_finish_valid_next;
stat_rd_req_start_tag_reg <= stat_rd_req_start_tag_next;
stat_rd_req_start_len_reg <= stat_rd_req_start_len_next;
stat_rd_req_start_valid_reg <= stat_rd_req_start_valid_next;
stat_rd_req_finish_tag_reg <= stat_rd_req_finish_tag_next;
stat_rd_req_finish_status_reg <= stat_rd_req_finish_status_next;
stat_rd_req_finish_valid_reg <= stat_rd_req_finish_valid_next;
stat_rd_op_table_full_reg <= stat_rd_op_table_full_next;
stat_rd_tx_stall_reg <= stat_rd_tx_stall_next;
if (status_fifo_we) begin
status_fifo_op_tag[status_fifo_wr_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]] <= status_fifo_wr_op_tag;
status_fifo_mask[status_fifo_wr_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]] <= status_fifo_wr_mask;
status_fifo_finish[status_fifo_wr_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]] <= status_fifo_wr_finish;
status_fifo_error[status_fifo_wr_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]] <= status_fifo_wr_error;
status_fifo_wr_ptr_reg <= status_fifo_wr_ptr_reg + 1;
end
status_fifo_rd_ptr_reg <= status_fifo_rd_ptr_next;
status_fifo_mask_reg <= status_fifo_mask_next;
status_fifo_finish_reg <= status_fifo_finish_next;
status_fifo_error_reg <= status_fifo_error_next;
status_fifo_we_reg <= status_fifo_we_next;
status_fifo_rd_op_tag_reg <= status_fifo_rd_op_tag_next;
status_fifo_rd_mask_reg <= status_fifo_rd_mask_next;
status_fifo_rd_finish_reg <= status_fifo_rd_finish_next;
status_fifo_rd_error_reg <= status_fifo_rd_error_next;
status_fifo_rd_valid_reg <= status_fifo_rd_valid_next;
status_fifo_half_full_reg <= $unsigned(status_fifo_wr_ptr_reg - status_fifo_rd_ptr_reg) >= 2**(STATUS_FIFO_ADDR_WIDTH-1);
@ -754,16 +954,25 @@ always @(posedge clk) begin
op_table_ram_sel[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_ram_sel;
op_table_ram_addr[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_ram_addr;
op_table_len[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_len;
op_table_zero_len[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_zero_len;
op_table_cycle_count[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_cycle_count;
op_table_tag[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_tag;
op_table_last[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_last;
op_table_write_complete[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= 1'b0;
op_table_error_a[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_error_b[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]];
end
if (!USE_AXI_ID && op_table_read_complete_en) begin
op_table_read_complete_ptr_reg <= op_table_read_complete_ptr_reg + 1;
end
if (op_table_update_status_en) begin
if (op_table_update_status_error != 0) begin
op_table_error_code[op_table_update_status_ptr] <= op_table_update_status_error;
op_table_error_b[op_table_update_status_ptr] <= !op_table_error_a[op_table_update_status_ptr];
end
end
if (op_table_write_complete_en) begin
op_table_write_complete[op_table_write_complete_ptr] <= 1'b1;
end
@ -783,8 +992,18 @@ always @(posedge clk) begin
m_axi_rready_reg <= 1'b0;
s_axis_read_desc_ready_reg <= 1'b0;
m_axis_read_desc_status_error_reg = 4'd0;
m_axis_read_desc_status_valid_reg <= 1'b0;
stat_rd_op_start_tag_reg <= 0;
stat_rd_op_start_valid_reg <= 1'b0;
stat_rd_op_finish_tag_reg <= 0;
stat_rd_op_finish_valid_reg <= 1'b0;
stat_rd_req_start_valid_reg <= 1'b0;
stat_rd_req_finish_valid_reg <= 1'b0;
stat_rd_op_table_full_reg <= 1'b0;
stat_rd_tx_stall_reg <= 1'b0;
status_fifo_wr_ptr_reg <= 0;
status_fifo_rd_ptr_reg <= 0;
status_fifo_we_reg <= 1'b0;

View File

@ -55,6 +55,10 @@ module dma_if_axi_wr #
parameter RAM_SEG_BE_WIDTH = RAM_SEG_DATA_WIDTH/8,
// RAM segment address width
parameter RAM_SEG_ADDR_WIDTH = RAM_ADDR_WIDTH-$clog2(RAM_SEG_COUNT*RAM_SEG_BE_WIDTH),
// Immediate enable
parameter IMM_ENABLE = 0,
// Immediate width
parameter IMM_WIDTH = 32,
// Length field width
parameter LEN_WIDTH = 16,
// Tag field width
@ -97,6 +101,8 @@ module dma_if_axi_wr #
input wire [AXI_ADDR_WIDTH-1:0] s_axis_write_desc_axi_addr,
input wire [RAM_SEL_WIDTH-1:0] s_axis_write_desc_ram_sel,
input wire [RAM_ADDR_WIDTH-1:0] s_axis_write_desc_ram_addr,
input wire [IMM_WIDTH-1:0] s_axis_write_desc_imm,
input wire s_axis_write_desc_imm_en,
input wire [LEN_WIDTH-1:0] s_axis_write_desc_len,
input wire [TAG_WIDTH-1:0] s_axis_write_desc_tag,
input wire s_axis_write_desc_valid,
@ -123,9 +129,28 @@ module dma_if_axi_wr #
/*
* Configuration
*/
input wire enable
input wire enable,
/*
* Statistics
*/
output wire [$clog2(OP_TABLE_SIZE)-1:0] stat_wr_op_start_tag,
output wire [LEN_WIDTH-1:0] stat_wr_op_start_len,
output wire stat_wr_op_start_valid,
output wire [$clog2(OP_TABLE_SIZE)-1:0] stat_wr_op_finish_tag,
output wire [3:0] stat_wr_op_finish_status,
output wire stat_wr_op_finish_valid,
output wire [$clog2(OP_TABLE_SIZE)-1:0] stat_wr_req_start_tag,
output wire [12:0] stat_wr_req_start_len,
output wire stat_wr_req_start_valid,
output wire [$clog2(OP_TABLE_SIZE)-1:0] stat_wr_req_finish_tag,
output wire [3:0] stat_wr_req_finish_status,
output wire stat_wr_req_finish_valid,
output wire stat_wr_op_table_full,
output wire stat_wr_tx_stall
);
parameter RAM_DATA_WIDTH = RAM_SEG_COUNT*RAM_SEG_DATA_WIDTH;
parameter RAM_WORD_WIDTH = RAM_SEG_BE_WIDTH;
parameter RAM_WORD_SIZE = RAM_SEG_DATA_WIDTH/RAM_WORD_WIDTH;
@ -173,7 +198,7 @@ initial begin
$finish;
end
if (RAM_SEG_COUNT*RAM_SEG_DATA_WIDTH != AXI_DATA_WIDTH*2) begin
if (RAM_DATA_WIDTH != AXI_DATA_WIDTH*2) begin
$error("Error: RAM interface width must be double the AXI interface width (instance %m)");
$finish;
end
@ -187,6 +212,16 @@ initial begin
$error("Error: RAM_ADDR_WIDTH does not match RAM configuration (instance %m)");
$finish;
end
if (OP_TABLE_SIZE > 2**AXI_ID_WIDTH) begin
$error("Error: AXI_ID_WIDTH insufficient for requested OP_TABLE_SIZE (instance %m)");
$finish;
end
if (IMM_ENABLE && IMM_WIDTH > AXI_DATA_WIDTH) begin
$error("Error: IMM_WIDTH must not be larger than the AXI interface width (instance %m)");
$finish;
end
end
localparam [1:0]
@ -234,7 +269,10 @@ reg read_cmd_ready;
reg [AXI_ADDR_WIDTH-1:0] req_axi_addr_reg = {AXI_ADDR_WIDTH{1'b0}}, req_axi_addr_next;
reg [RAM_SEL_WIDTH-1:0] ram_sel_reg = {RAM_SEL_WIDTH{1'b0}}, ram_sel_next;
reg [RAM_ADDR_WIDTH-1:0] ram_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, ram_addr_next;
reg [IMM_WIDTH-1:0] imm_reg = {IMM_WIDTH{1'b0}}, imm_next;
reg imm_en_reg = 1'b0, imm_en_next;
reg [LEN_WIDTH-1:0] op_count_reg = {LEN_WIDTH{1'b0}}, op_count_next;
reg zero_len_reg = 1'b0, zero_len_next;
reg [LEN_WIDTH-1:0] tr_count_reg = {LEN_WIDTH{1'b0}}, tr_count_next;
reg [12:0] tr_word_count_reg = 13'd0, tr_word_count_next;
reg [TAG_WIDTH-1:0] tag_reg = {TAG_WIDTH{1'b0}}, tag_next;
@ -242,6 +280,7 @@ reg [TAG_WIDTH-1:0] tag_reg = {TAG_WIDTH{1'b0}}, tag_next;
reg [AXI_ADDR_WIDTH-1:0] read_axi_addr_reg = {AXI_ADDR_WIDTH{1'b0}}, read_axi_addr_next;
reg [RAM_SEL_WIDTH-1:0] read_ram_sel_reg = {RAM_SEL_WIDTH{1'b0}}, read_ram_sel_next;
reg [RAM_ADDR_WIDTH-1:0] read_ram_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, read_ram_addr_next;
reg read_imm_en_reg = 1'b0, read_imm_en_next;
reg [LEN_WIDTH-1:0] read_len_reg = {LEN_WIDTH{1'b0}}, read_len_next;
reg [RAM_SEG_COUNT-1:0] read_ram_mask_reg = {RAM_SEG_COUNT{1'b0}}, read_ram_mask_next;
reg [RAM_SEG_COUNT-1:0] read_ram_mask_0_reg = {RAM_SEG_COUNT{1'b0}}, read_ram_mask_0_next;
@ -254,7 +293,10 @@ reg [RAM_OFFSET_WIDTH-1:0] start_offset_reg = {RAM_OFFSET_WIDTH{1'b0}}, start_of
reg [RAM_OFFSET_WIDTH-1:0] end_offset_reg = {RAM_OFFSET_WIDTH{1'b0}}, end_offset_next;
reg [AXI_ADDR_WIDTH-1:0] axi_addr_reg = {AXI_ADDR_WIDTH{1'b0}}, axi_addr_next;
reg [IMM_WIDTH-1:0] axi_imm_reg = {IMM_WIDTH{1'b0}}, axi_imm_next;
reg axi_imm_en_reg = 1'b0, axi_imm_en_next;
reg [12:0] axi_len_reg = 13'd0, axi_len_next;
reg axi_zero_len_reg = 1'b0, axi_zero_len_next;
reg [RAM_OFFSET_WIDTH-1:0] offset_reg = {RAM_OFFSET_WIDTH{1'b0}}, offset_next;
reg [AXI_STRB_WIDTH-1:0] strb_offset_mask_reg = {AXI_STRB_WIDTH{1'b1}}, strb_offset_mask_next;
reg [OFFSET_WIDTH-1:0] last_cycle_offset_reg = {OFFSET_WIDTH{1'b0}}, last_cycle_offset_next;
@ -266,6 +308,7 @@ reg last_cycle_reg = 1'b0, last_cycle_next;
reg [AXI_ADDR_WIDTH-1:0] read_cmd_axi_addr_reg = {AXI_ADDR_WIDTH{1'b0}}, read_cmd_axi_addr_next;
reg [RAM_SEL_WIDTH-1:0] read_cmd_ram_sel_reg = {RAM_SEL_WIDTH{1'b0}}, read_cmd_ram_sel_next;
reg [RAM_ADDR_WIDTH-1:0] read_cmd_ram_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, read_cmd_ram_addr_next;
reg read_cmd_imm_en_reg = 1'b0, read_cmd_imm_en_next;
reg [12:0] read_cmd_len_reg = 13'd0, read_cmd_len_next;
reg [CYCLE_COUNT_WIDTH-1:0] read_cmd_cycle_count_reg = {CYCLE_COUNT_WIDTH{1'b0}}, read_cmd_cycle_count_next;
reg read_cmd_last_cycle_reg = 1'b0, read_cmd_last_cycle_next;
@ -297,6 +340,21 @@ reg [RAM_SEG_COUNT*RAM_SEG_ADDR_WIDTH-1:0] ram_rd_cmd_addr_reg = 0, ram_rd_cmd_a
reg [RAM_SEG_COUNT-1:0] ram_rd_cmd_valid_reg = 0, ram_rd_cmd_valid_next;
reg [RAM_SEG_COUNT-1:0] ram_rd_resp_ready_cmb;
reg [OP_TAG_WIDTH-1:0] stat_wr_op_start_tag_reg = 0, stat_wr_op_start_tag_next;
reg [LEN_WIDTH-1:0] stat_wr_op_start_len_reg = 0, stat_wr_op_start_len_next;
reg stat_wr_op_start_valid_reg = 1'b0, stat_wr_op_start_valid_next;
reg [OP_TAG_WIDTH-1:0] stat_wr_op_finish_tag_reg = 0, stat_wr_op_finish_tag_next;
reg [3:0] stat_wr_op_finish_status_reg = 0, stat_wr_op_finish_status_next;
reg stat_wr_op_finish_valid_reg = 1'b0, stat_wr_op_finish_valid_next;
reg [OP_TAG_WIDTH-1:0] stat_wr_req_start_tag_reg = 0, stat_wr_req_start_tag_next;
reg [12:0] stat_wr_req_start_len_reg = 13'd0, stat_wr_req_start_len_next;
reg stat_wr_req_start_valid_reg = 1'b0, stat_wr_req_start_valid_next;
reg [OP_TAG_WIDTH-1:0] stat_wr_req_finish_tag_reg = 0, stat_wr_req_finish_tag_next;
reg [3:0] stat_wr_req_finish_status_reg = 0, stat_wr_req_finish_status_next;
reg stat_wr_req_finish_valid_reg = 1'b0, stat_wr_req_finish_valid_next;
reg stat_wr_op_table_full_reg = 1'b0, stat_wr_op_table_full_next;
reg stat_wr_tx_stall_reg = 1'b0, stat_wr_tx_stall_next;
// internal datapath
reg [AXI_DATA_WIDTH-1:0] m_axi_wdata_int;
reg [AXI_STRB_WIDTH-1:0] m_axi_wstrb_int;
@ -326,10 +384,28 @@ assign ram_rd_cmd_addr = ram_rd_cmd_addr_reg;
assign ram_rd_cmd_valid = ram_rd_cmd_valid_reg;
assign ram_rd_resp_ready = ram_rd_resp_ready_cmb;
assign stat_wr_op_start_tag = stat_wr_op_start_tag_reg;
assign stat_wr_op_start_len = stat_wr_op_start_len_reg;
assign stat_wr_op_start_valid = stat_wr_op_start_valid_reg;
assign stat_wr_op_finish_tag = stat_wr_op_finish_tag_reg;
assign stat_wr_op_finish_status = stat_wr_op_finish_status_reg;
assign stat_wr_op_finish_valid = stat_wr_op_finish_valid_reg;
assign stat_wr_req_start_tag = stat_wr_req_start_tag_reg;
assign stat_wr_req_start_len = stat_wr_req_start_len_reg;
assign stat_wr_req_start_valid = stat_wr_req_start_valid_reg;
assign stat_wr_req_finish_tag = stat_wr_req_finish_tag_reg;
assign stat_wr_req_finish_status = stat_wr_req_finish_status_reg;
assign stat_wr_req_finish_valid = stat_wr_req_finish_valid_reg;
assign stat_wr_op_table_full = stat_wr_op_table_full_reg;
assign stat_wr_tx_stall = stat_wr_tx_stall_reg;
// operation tag management
reg [OP_TAG_WIDTH+1-1:0] op_table_start_ptr_reg = 0;
reg [AXI_ADDR_WIDTH-1:0] op_table_start_axi_addr;
reg [IMM_WIDTH-1:0] op_table_start_imm;
reg op_table_start_imm_en;
reg [11:0] op_table_start_len;
reg op_table_start_zero_len;
reg [CYCLE_COUNT_WIDTH-1:0] op_table_start_cycle_count;
reg [RAM_OFFSET_WIDTH-1:0] op_table_start_offset;
reg [TAG_WIDTH-1:0] op_table_start_tag;
@ -339,8 +415,9 @@ reg [OP_TAG_WIDTH+1-1:0] op_table_tx_start_ptr_reg = 0;
reg op_table_tx_start_en;
reg [OP_TAG_WIDTH+1-1:0] op_table_tx_finish_ptr_reg = 0;
reg op_table_tx_finish_en;
reg op_table_write_complete_en;
reg [OP_TAG_WIDTH-1:0] op_table_write_complete_ptr;
reg [3:0] op_table_write_complete_error;
reg op_table_write_complete_en;
reg [OP_TAG_WIDTH+1-1:0] op_table_finish_ptr_reg = 0;
reg op_table_finish_en;
@ -349,8 +426,14 @@ reg [2**OP_TAG_WIDTH-1:0] op_table_write_complete = 0;
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [AXI_ADDR_WIDTH-1:0] op_table_axi_addr[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [IMM_WIDTH-1:0] op_table_imm[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg op_table_imm_en[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [11:0] op_table_len[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg op_table_zero_len[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [CYCLE_COUNT_WIDTH-1:0] op_table_cycle_count[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [RAM_OFFSET_WIDTH-1:0] op_table_offset[2**OP_TAG_WIDTH-1:0];
@ -358,17 +441,23 @@ reg [RAM_OFFSET_WIDTH-1:0] op_table_offset[2**OP_TAG_WIDTH-1:0];
reg [TAG_WIDTH-1:0] op_table_tag[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg op_table_last[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [3:0] op_table_error_code [2**OP_TAG_WIDTH-1:0];
integer i;
initial begin
for (i = 0; i < 2**OP_TAG_WIDTH; i = i + 1) begin
op_table_axi_addr[i] = 0;
op_table_imm[i] = 0;
op_table_imm_en[i] = 0;
op_table_len[i] = 0;
op_table_zero_len[i] = 1'b0;
op_table_cycle_count[i] = 0;
op_table_offset[i] = 0;
op_table_tag[i] = 0;
op_table_last[i] = 0;
op_table_error_code[i] = 0;
end
end
@ -377,24 +466,40 @@ always @* begin
s_axis_write_desc_ready_next = 1'b0;
stat_wr_op_start_tag_next = stat_wr_op_start_tag_reg;
stat_wr_op_start_len_next = stat_wr_op_start_len_reg;
stat_wr_op_start_valid_next = 1'b0;
stat_wr_req_start_tag_next = stat_wr_req_start_tag_reg;
stat_wr_req_start_len_next = stat_wr_req_start_len_reg;
stat_wr_req_start_valid_next = 1'b0;
stat_wr_op_table_full_next = !(!op_table_active[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] && ($unsigned(op_table_start_ptr_reg - op_table_finish_ptr_reg) < 2**OP_TAG_WIDTH));
stat_wr_tx_stall_next = (m_axi_awvalid && !m_axi_awready) || (m_axi_wvalid && !m_axi_wready);
tag_next = tag_reg;
req_axi_addr_next = req_axi_addr_reg;
ram_sel_next = ram_sel_reg;
ram_addr_next = ram_addr_reg;
imm_next = imm_reg;
imm_en_next = imm_en_reg;
op_count_next = op_count_reg;
zero_len_next = zero_len_reg;
tr_count_next = tr_count_reg;
tr_word_count_next = tr_word_count_reg;
read_cmd_axi_addr_next = read_cmd_axi_addr_reg;
read_cmd_ram_sel_next = read_cmd_ram_sel_reg;
read_cmd_ram_addr_next = read_cmd_ram_addr_reg;
read_cmd_imm_en_next = read_cmd_imm_en_reg;
read_cmd_len_next = read_cmd_len_reg;
read_cmd_cycle_count_next = read_cmd_cycle_count_reg;
read_cmd_last_cycle_next = read_cmd_last_cycle_reg;
read_cmd_valid_next = read_cmd_valid_reg && !read_cmd_ready;
op_table_start_axi_addr = req_axi_addr_reg;
op_table_start_imm = imm_reg;
op_table_start_imm_en = imm_en_reg;
op_table_start_len = 0;
op_table_start_zero_len = zero_len_reg;
op_table_start_cycle_count = 0;
op_table_start_offset = (req_axi_addr_reg & OFFSET_MASK)-ram_addr_reg[RAM_OFFSET_WIDTH-1:0];
op_table_start_tag = tag_reg;
@ -408,9 +513,23 @@ always @* begin
s_axis_write_desc_ready_next = !op_table_active[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] && ($unsigned(op_table_start_ptr_reg - op_table_finish_ptr_reg) < 2**OP_TAG_WIDTH) && enable;
req_axi_addr_next = s_axis_write_desc_axi_addr;
ram_sel_next = s_axis_write_desc_ram_sel;
ram_addr_next = s_axis_write_desc_ram_addr;
op_count_next = s_axis_write_desc_len;
if (IMM_ENABLE && s_axis_write_desc_imm_en) begin
ram_sel_next = 0;
ram_addr_next = 0;
end else begin
ram_sel_next = s_axis_write_desc_ram_sel;
ram_addr_next = s_axis_write_desc_ram_addr;
end
imm_next = s_axis_write_desc_imm;
imm_en_next = IMM_ENABLE && s_axis_write_desc_imm_en;
if (s_axis_write_desc_len == 0) begin
// zero-length operation
op_count_next = 1;
zero_len_next = 1'b1;
end else begin
op_count_next = s_axis_write_desc_len;
zero_len_next = 1'b0;
end
tag_next = s_axis_write_desc_tag;
if (op_count_next <= AXI_MAX_BURST_SIZE - (req_axi_addr_next & OFFSET_MASK) || AXI_MAX_BURST_SIZE >= 4096) begin
@ -435,6 +554,11 @@ always @* begin
if (s_axis_write_desc_ready & s_axis_write_desc_valid) begin
s_axis_write_desc_ready_next = 1'b0;
stat_wr_op_start_tag_next = stat_wr_op_start_tag_reg+1;
stat_wr_op_start_len_next = s_axis_write_desc_len;
stat_wr_op_start_valid_next = 1'b1;
req_state_next = REQ_STATE_START;
end else begin
req_state_next = REQ_STATE_IDLE;
@ -446,6 +570,7 @@ always @* begin
read_cmd_axi_addr_next = req_axi_addr_reg;
read_cmd_ram_sel_next = ram_sel_reg;
read_cmd_ram_addr_next = ram_addr_reg;
read_cmd_imm_en_next = imm_en_reg;
read_cmd_len_next = tr_word_count_next;
read_cmd_cycle_count_next = (tr_word_count_next + (req_axi_addr_reg & OFFSET_MASK) - 1) >> AXI_BURST_SIZE;
op_table_start_cycle_count = read_cmd_cycle_count_next;
@ -457,12 +582,19 @@ always @* begin
op_count_next = op_count_reg - tr_word_count_next;
op_table_start_axi_addr = req_axi_addr_reg;
op_table_start_imm = imm_reg;
op_table_start_imm_en = imm_en_reg;
op_table_start_len = tr_word_count_next;
op_table_start_zero_len = zero_len_reg;
op_table_start_offset = (req_axi_addr_reg & OFFSET_MASK)-ram_addr_reg[RAM_OFFSET_WIDTH-1:0];
op_table_start_tag = tag_reg;
op_table_start_last = op_count_reg == tr_word_count_next;
op_table_start_en = 1'b1;
stat_wr_req_start_tag_next = op_table_start_ptr_reg[OP_TAG_WIDTH-1:0];
stat_wr_req_start_len_next = zero_len_reg ? 0 : tr_word_count_next;
stat_wr_req_start_valid_next = 1'b1;
if (op_count_next <= AXI_MAX_BURST_SIZE - (req_axi_addr_next & OFFSET_MASK) || AXI_MAX_BURST_SIZE >= 4096) begin
// packet smaller than max burst size
if (((req_axi_addr_next & 12'hfff) + (op_count_next & 12'hfff)) >> 12 != 0 || op_count_next >> 12 != 0) begin
@ -508,6 +640,7 @@ always @* begin
read_axi_addr_next = read_axi_addr_reg;
read_ram_sel_next = read_ram_sel_reg;
read_ram_addr_next = read_ram_addr_reg;
read_imm_en_next = read_imm_en_reg;
read_len_next = read_len_reg;
read_ram_mask_next = read_ram_mask_reg;
read_ram_mask_0_next = read_ram_mask_0_reg;
@ -530,6 +663,7 @@ always @* begin
read_axi_addr_next = read_cmd_axi_addr_reg;
read_ram_sel_next = read_cmd_ram_sel_reg;
read_ram_addr_next = read_cmd_ram_addr_reg;
read_imm_en_next = read_cmd_imm_en_reg;
read_len_next = read_cmd_len_reg;
read_cycle_count_next = read_cmd_cycle_count_reg;
read_last_cycle_next = read_cmd_last_cycle_reg;
@ -572,19 +706,17 @@ always @* begin
read_last_cycle_next = read_cycle_count_next == 0;
for (i = 0; i < RAM_SEG_COUNT; i = i + 1) begin
if (read_ram_mask_0_reg[i]) begin
if (read_ram_mask_reg[i]) begin
ram_rd_cmd_sel_next[i*RAM_SEL_WIDTH +: RAM_SEL_WIDTH] = read_ram_sel_reg;
ram_rd_cmd_addr_next[i*RAM_SEG_ADDR_WIDTH +: RAM_SEG_ADDR_WIDTH] = read_ram_addr_reg[RAM_ADDR_WIDTH-1:RAM_ADDR_WIDTH-RAM_SEG_ADDR_WIDTH];
ram_rd_cmd_valid_next[i] = 1'b1;
ram_rd_cmd_valid_next[i] = !(IMM_ENABLE && read_imm_en_reg);
end
if (read_ram_mask_1_reg[i]) begin
ram_rd_cmd_sel_next[i*RAM_SEL_WIDTH +: RAM_SEL_WIDTH] = read_ram_sel_reg;
ram_rd_cmd_addr_next[i*RAM_SEG_ADDR_WIDTH +: RAM_SEG_ADDR_WIDTH] = read_ram_addr_reg[RAM_ADDR_WIDTH-1:RAM_ADDR_WIDTH-RAM_SEG_ADDR_WIDTH]+1;
ram_rd_cmd_valid_next[i] = 1'b1;
end
end
mask_fifo_wr_mask = read_ram_mask_reg;
mask_fifo_wr_mask = (IMM_ENABLE && read_imm_en_reg) ? 0 : read_ram_mask_reg;
mask_fifo_we = 1'b1;
if (read_len_next > AXI_STRB_WIDTH) begin
@ -613,6 +745,7 @@ always @* begin
read_axi_addr_next = read_cmd_axi_addr_reg;
read_ram_sel_next = read_cmd_ram_sel_reg;
read_ram_addr_next = read_cmd_ram_addr_reg;
read_imm_en_next = read_cmd_imm_en_reg;
read_len_next = read_cmd_len_reg;
read_cycle_count_next = read_cmd_cycle_count_reg;
read_last_cycle_next = read_cmd_last_cycle_reg;
@ -654,8 +787,18 @@ always @* begin
ram_rd_resp_ready_cmb = {RAM_SEG_COUNT{1'b0}};
stat_wr_op_finish_tag_next = stat_wr_op_finish_tag_reg;
stat_wr_op_finish_status_next = stat_wr_op_finish_status_reg;
stat_wr_op_finish_valid_next = 1'b0;
stat_wr_req_finish_tag_next = stat_wr_req_finish_tag_reg;
stat_wr_req_finish_status_next = stat_wr_req_finish_status_reg;
stat_wr_req_finish_valid_next = 1'b0;
axi_addr_next = axi_addr_reg;
axi_imm_next = axi_imm_reg;
axi_imm_en_next = axi_imm_en_reg;
axi_len_next = axi_len_reg;
axi_zero_len_next = axi_zero_len_reg;
offset_next = offset_reg;
strb_offset_mask_next = strb_offset_mask_reg;
last_cycle_offset_next = last_cycle_offset_reg;
@ -669,17 +812,14 @@ always @* begin
op_table_tx_start_en = 1'b0;
op_table_tx_finish_en = 1'b0;
op_table_write_complete_en = 1'b0;
op_table_write_complete_ptr = m_axi_bid;
m_axi_awid_next = m_axi_awid_reg;
m_axi_awaddr_next = m_axi_awaddr_reg;
m_axi_awlen_next = m_axi_awlen_reg;
m_axi_awvalid_next = m_axi_awvalid_reg && !m_axi_awready;
m_axi_bready_next = 1'b0;
m_axi_wdata_int = 0;
m_axi_wstrb_int = 0;
m_axi_wdata_int = ((IMM_ENABLE && axi_imm_en_reg) ? {2{{RAM_DATA_WIDTH{1'b0}} | axi_imm_reg}} : {2{ram_rd_resp_data}}) >> (RAM_DATA_WIDTH-offset_reg*AXI_WORD_SIZE);
m_axi_wstrb_int = strb_offset_mask_reg;
m_axi_wlast_int = 1'b0;
m_axi_wvalid_int = 1'b0;
@ -690,9 +830,12 @@ always @* begin
ram_rd_resp_ready_cmb = {RAM_SEG_COUNT{1'b0}};
axi_addr_next = op_table_axi_addr[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
axi_imm_next = op_table_imm[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
axi_imm_en_next = op_table_imm_en[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
axi_len_next = op_table_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
axi_zero_len_next = op_table_zero_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
offset_next = op_table_offset[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
strb_offset_mask_next = {AXI_STRB_WIDTH{1'b1}} << (axi_addr_next & OFFSET_MASK);
strb_offset_mask_next = axi_zero_len_next ? {AXI_STRB_WIDTH{1'b0}} : ({AXI_STRB_WIDTH{1'b1}} << (axi_addr_next & OFFSET_MASK));
last_cycle_offset_next = axi_addr_next + (axi_len_next & OFFSET_MASK);
cycle_count_next = op_table_cycle_count[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
last_cycle_next = op_table_cycle_count[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]] == 0;
@ -723,8 +866,9 @@ always @* begin
offset_next = offset_reg + AXI_STRB_WIDTH;
strb_offset_mask_next = {AXI_STRB_WIDTH{1'b1}};
m_axi_wdata_int = {2{ram_rd_resp_data}} >> (RAM_SEG_COUNT*RAM_SEG_DATA_WIDTH-offset_reg*AXI_WORD_SIZE);
m_axi_wdata_int = ((IMM_ENABLE && axi_imm_en_reg) ? {2{{RAM_DATA_WIDTH{1'b0}} | axi_imm_reg}} : {2{ram_rd_resp_data}}) >> (RAM_DATA_WIDTH-offset_reg*AXI_WORD_SIZE);
m_axi_wstrb_int = strb_offset_mask_reg;
m_axi_wlast_int = 1'b0;
m_axi_wvalid_int = 1'b1;
if (last_cycle_reg) begin
@ -738,9 +882,12 @@ always @* begin
// skip idle state if possible
axi_addr_next = op_table_axi_addr[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
axi_imm_next = op_table_imm[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
axi_imm_en_next = op_table_imm_en[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
axi_len_next = op_table_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
axi_zero_len_next = op_table_zero_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
offset_next = op_table_offset[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
strb_offset_mask_next = {AXI_STRB_WIDTH{1'b1}} << (axi_addr_next & OFFSET_MASK);
strb_offset_mask_next = axi_zero_len_next ? {AXI_STRB_WIDTH{1'b0}} : ({AXI_STRB_WIDTH{1'b1}} << (axi_addr_next & OFFSET_MASK));
last_cycle_offset_next = axi_addr_next + (axi_len_next & OFFSET_MASK);
cycle_count_next = op_table_cycle_count[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
last_cycle_next = op_table_cycle_count[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]] == 0;
@ -770,46 +917,85 @@ always @* begin
mask_fifo_rd_ptr_next = mask_fifo_rd_ptr_reg+1;
end
op_table_write_complete_ptr = m_axi_bid;
if (m_axi_bresp == AXI_RESP_SLVERR) begin
op_table_write_complete_error = DMA_ERROR_AXI_WR_SLVERR;
end else if (m_axi_bresp == AXI_RESP_DECERR) begin
op_table_write_complete_error = DMA_ERROR_AXI_WR_DECERR;
end else begin
op_table_write_complete_error = DMA_ERROR_NONE;
end
op_table_write_complete_en = 1'b0;
m_axis_write_desc_status_tag_next = op_table_tag[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]];
if (m_axis_write_desc_status_valid_reg) begin
m_axis_write_desc_status_error_next = DMA_ERROR_NONE;
end else begin
m_axis_write_desc_status_error_next = m_axis_write_desc_status_error_reg;
end
m_axis_write_desc_status_valid_next = 1'b0;
stat_wr_req_finish_status_next = op_table_write_complete_error;
stat_wr_req_finish_valid_next = 1'b0;
stat_wr_op_finish_tag_next = stat_wr_op_finish_tag_reg;
stat_wr_op_finish_status_next = m_axis_write_desc_status_error_next;
stat_wr_op_finish_valid_next = 1'b0;
if (USE_AXI_ID) begin
// accept write completions
stat_wr_req_finish_tag_next = m_axi_bid;
m_axi_bready_next = 1'b1;
if (m_axi_bready && m_axi_bvalid) begin
op_table_write_complete_en = 1'b1;
op_table_write_complete_ptr = m_axi_bid;
op_table_write_complete_en = 1'b1;
stat_wr_req_finish_valid_next = 1'b1;
end
// commit operations in-order
op_table_finish_en = 1'b0;
m_axis_write_desc_status_tag_next = op_table_tag[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]];
m_axis_write_desc_status_error_next = 0;
m_axis_write_desc_status_valid_next = 1'b0;
if (op_table_active[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]] && op_table_write_complete[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]] && op_table_finish_ptr_reg != op_table_tx_finish_ptr_reg) begin
op_table_finish_en = 1'b1;
if (op_table_error_code[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]] != DMA_ERROR_NONE) begin
m_axis_write_desc_status_error_next = op_table_error_code[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]];
end
stat_wr_op_finish_status_next = m_axis_write_desc_status_error_next;
if (op_table_last[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]]) begin
m_axis_write_desc_status_tag_next = op_table_tag[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]];
m_axis_write_desc_status_error_next = 0;
m_axis_write_desc_status_valid_next = 1'b1;
stat_wr_op_finish_tag_next = stat_wr_op_finish_tag_reg + 1;
stat_wr_op_finish_valid_next = 1'b1;
end
end
end else begin
// accept write completions
op_table_finish_en = 1'b0;
m_axis_write_desc_status_tag_next = op_table_tag[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]];
m_axis_write_desc_status_error_next = 0;
m_axis_write_desc_status_valid_next = 1'b0;
stat_wr_req_finish_tag_next = op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0];
m_axi_bready_next = 1'b1;
if (m_axi_bready && m_axi_bvalid) begin
op_table_finish_en = 1'b1;
stat_wr_req_finish_valid_next = 1'b1;
if (m_axi_bresp == AXI_RESP_SLVERR) begin
m_axis_write_desc_status_error_next = DMA_ERROR_AXI_WR_SLVERR;
end else if (m_axi_bresp == AXI_RESP_DECERR) begin
m_axis_write_desc_status_error_next = DMA_ERROR_AXI_WR_DECERR;
end
stat_wr_op_finish_status_next = m_axis_write_desc_status_error_next;
if (op_table_last[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]]) begin
m_axis_write_desc_status_tag_next = op_table_tag[op_table_finish_ptr_reg[OP_TAG_WIDTH-1:0]];
m_axis_write_desc_status_error_next = 0;
m_axis_write_desc_status_valid_next = 1'b1;
stat_wr_op_finish_tag_next = stat_wr_op_finish_tag_reg + 1;
stat_wr_op_finish_valid_next = 1'b1;
end
end
end
@ -823,7 +1009,10 @@ always @(posedge clk) begin
req_axi_addr_reg <= req_axi_addr_next;
ram_sel_reg <= ram_sel_next;
ram_addr_reg <= ram_addr_next;
imm_reg <= imm_next;
imm_en_reg <= imm_en_next;
op_count_reg <= op_count_next;
zero_len_reg <= zero_len_next;
tr_count_reg <= tr_count_next;
tr_word_count_reg <= tr_word_count_next;
tag_reg <= tag_next;
@ -831,6 +1020,7 @@ always @(posedge clk) begin
read_axi_addr_reg <= read_axi_addr_next;
read_ram_sel_reg <= read_ram_sel_next;
read_ram_addr_reg <= read_ram_addr_next;
read_imm_en_reg <= read_imm_en_next;
read_len_reg <= read_len_next;
read_ram_mask_reg <= read_ram_mask_next;
read_ram_mask_0_reg <= read_ram_mask_0_next;
@ -843,7 +1033,10 @@ always @(posedge clk) begin
end_offset_reg <= end_offset_next;
axi_addr_reg <= axi_addr_next;
axi_imm_reg <= axi_imm_next;
axi_imm_en_reg <= axi_imm_en_next;
axi_len_reg <= axi_len_next;
axi_zero_len_reg <= axi_zero_len_next;
offset_reg <= offset_next;
strb_offset_mask_reg <= strb_offset_mask_next;
last_cycle_offset_reg <= last_cycle_offset_next;
@ -855,6 +1048,7 @@ always @(posedge clk) begin
read_cmd_axi_addr_reg <= read_cmd_axi_addr_next;
read_cmd_ram_sel_reg <= read_cmd_ram_sel_next;
read_cmd_ram_addr_reg <= read_cmd_ram_addr_next;
read_cmd_imm_en_reg <= read_cmd_imm_en_next;
read_cmd_len_reg <= read_cmd_len_next;
read_cmd_cycle_count_reg <= read_cmd_cycle_count_next;
read_cmd_last_cycle_reg <= read_cmd_last_cycle_next;
@ -872,6 +1066,21 @@ always @(posedge clk) begin
m_axis_write_desc_status_error_reg <= m_axis_write_desc_status_error_next;
m_axis_write_desc_status_valid_reg <= m_axis_write_desc_status_valid_next;
stat_wr_op_start_tag_reg <= stat_wr_op_start_tag_next;
stat_wr_op_start_len_reg <= stat_wr_op_start_len_next;
stat_wr_op_start_valid_reg <= stat_wr_op_start_valid_next;
stat_wr_op_finish_tag_reg <= stat_wr_op_finish_tag_next;
stat_wr_op_finish_status_reg <= stat_wr_op_finish_status_next;
stat_wr_op_finish_valid_reg <= stat_wr_op_finish_valid_next;
stat_wr_req_start_tag_reg <= stat_wr_req_start_tag_next;
stat_wr_req_start_len_reg <= stat_wr_req_start_len_next;
stat_wr_req_start_valid_reg <= stat_wr_req_start_valid_next;
stat_wr_req_finish_tag_reg <= stat_wr_req_finish_tag_next;
stat_wr_req_finish_status_reg <= stat_wr_req_finish_status_next;
stat_wr_req_finish_valid_reg <= stat_wr_req_finish_valid_next;
stat_wr_op_table_full_reg <= stat_wr_op_table_full_next;
stat_wr_tx_stall_reg <= stat_wr_tx_stall_next;
ram_rd_cmd_sel_reg <= ram_rd_cmd_sel_next;
ram_rd_cmd_addr_reg <= ram_rd_cmd_addr_next;
ram_rd_cmd_valid_reg <= ram_rd_cmd_valid_next;
@ -887,7 +1096,10 @@ always @(posedge clk) begin
op_table_active[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= 1'b1;
op_table_write_complete[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= 1'b0;
op_table_axi_addr[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_axi_addr;
op_table_imm[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_imm;
op_table_imm_en[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_imm_en;
op_table_len[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_len;
op_table_zero_len[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_zero_len;
op_table_cycle_count[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_cycle_count;
op_table_offset[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_offset;
op_table_tag[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_tag;
@ -904,6 +1116,7 @@ always @(posedge clk) begin
if (USE_AXI_ID && op_table_write_complete_en) begin
op_table_write_complete[op_table_write_complete_ptr] <= 1'b1;
op_table_error_code[op_table_write_complete_ptr] <= op_table_write_complete_error;
end
if (op_table_finish_en) begin
@ -924,8 +1137,18 @@ always @(posedge clk) begin
m_axi_bready_reg <= 1'b0;
s_axis_write_desc_ready_reg <= 1'b0;
m_axis_write_desc_status_error_reg <= 4'd0;
m_axis_write_desc_status_valid_reg <= 1'b0;
stat_wr_op_start_tag_reg <= 0;
stat_wr_op_start_valid_reg <= 1'b0;
stat_wr_op_finish_tag_reg <= 0;
stat_wr_op_finish_valid_reg <= 1'b0;
stat_wr_req_start_valid_reg <= 1'b0;
stat_wr_req_finish_valid_reg <= 1'b0;
stat_wr_op_table_full_reg <= 1'b0;
stat_wr_tx_stall_reg <= 1'b0;
ram_rd_cmd_valid_reg <= {RAM_SEG_COUNT{1'b0}};
mask_fifo_wr_ptr_reg <= 0;

View File

@ -46,6 +46,10 @@ module dma_if_desc_mux #
parameter RAM_ADDR_WIDTH = 16,
// DMA address width
parameter DMA_ADDR_WIDTH = 64,
// Immediate enable
parameter IMM_ENABLE = 0,
// Immediate width
parameter IMM_WIDTH = 32,
// Length field width
parameter LEN_WIDTH = 16,
// Input tag field width
@ -68,6 +72,8 @@ module dma_if_desc_mux #
output wire [DMA_ADDR_WIDTH-1:0] m_axis_desc_dma_addr,
output wire [M_RAM_SEL_WIDTH-1:0] m_axis_desc_ram_sel,
output wire [RAM_ADDR_WIDTH-1:0] m_axis_desc_ram_addr,
output wire [IMM_WIDTH-1:0] m_axis_desc_imm,
output wire m_axis_desc_imm_en,
output wire [LEN_WIDTH-1:0] m_axis_desc_len,
output wire [M_TAG_WIDTH-1:0] m_axis_desc_tag,
output wire m_axis_desc_valid,
@ -86,6 +92,8 @@ module dma_if_desc_mux #
input wire [PORTS*DMA_ADDR_WIDTH-1:0] s_axis_desc_dma_addr,
input wire [PORTS*S_RAM_SEL_WIDTH-1:0] s_axis_desc_ram_sel,
input wire [PORTS*RAM_ADDR_WIDTH-1:0] s_axis_desc_ram_addr,
input wire [PORTS*IMM_WIDTH-1:0] s_axis_desc_imm,
input wire [PORTS-1:0] s_axis_desc_imm_en,
input wire [PORTS*LEN_WIDTH-1:0] s_axis_desc_len,
input wire [PORTS*S_TAG_WIDTH-1:0] s_axis_desc_tag,
input wire [PORTS-1:0] s_axis_desc_valid,
@ -136,6 +144,8 @@ wire [CL_PORTS-1:0] grant_encoded;
reg [DMA_ADDR_WIDTH-1:0] m_axis_desc_dma_addr_int;
reg [M_RAM_SEL_WIDTH-1:0] m_axis_desc_ram_sel_int;
reg [RAM_ADDR_WIDTH-1:0] m_axis_desc_ram_addr_int;
reg [IMM_WIDTH-1:0] m_axis_desc_imm_int;
reg m_axis_desc_imm_en_int;
reg [LEN_WIDTH-1:0] m_axis_desc_len_int;
reg [M_TAG_WIDTH-1:0] m_axis_desc_tag_int;
reg m_axis_desc_valid_int;
@ -148,6 +158,8 @@ assign s_axis_desc_ready = (m_axis_desc_ready_int_reg && grant_valid) << grant_e
wire [DMA_ADDR_WIDTH-1:0] current_s_desc_dma_addr = s_axis_desc_dma_addr[grant_encoded*DMA_ADDR_WIDTH +: DMA_ADDR_WIDTH];
wire [S_RAM_SEL_WIDTH-1:0] current_s_desc_ram_sel = s_axis_desc_ram_sel[grant_encoded*S_RAM_SEL_WIDTH +: S_RAM_SEL_WIDTH_INT];
wire [RAM_ADDR_WIDTH-1:0] current_s_desc_ram_addr = s_axis_desc_ram_addr[grant_encoded*RAM_ADDR_WIDTH +: RAM_ADDR_WIDTH];
wire [IMM_WIDTH-1:0] current_s_desc_imm = s_axis_desc_imm[grant_encoded*IMM_WIDTH +: IMM_WIDTH];
wire current_s_desc_imm_en = s_axis_desc_imm_en[grant_encoded];
wire [LEN_WIDTH-1:0] current_s_desc_len = s_axis_desc_len[grant_encoded*LEN_WIDTH +: LEN_WIDTH];
wire [S_TAG_WIDTH-1:0] current_s_desc_tag = s_axis_desc_tag[grant_encoded*S_TAG_WIDTH +: S_TAG_WIDTH];
wire current_s_desc_valid = s_axis_desc_valid[grant_encoded];
@ -178,12 +190,17 @@ always @* begin
// pass through selected packet data
m_axis_desc_dma_addr_int = current_s_desc_dma_addr;
m_axis_desc_ram_sel_int = current_s_desc_ram_sel;
if (PORTS > 1) begin
if (EXTEND_RAM_SEL && PORTS > 1) begin
m_axis_desc_ram_sel_int[M_RAM_SEL_WIDTH-1:M_RAM_SEL_WIDTH-CL_PORTS] = grant_encoded;
end
m_axis_desc_ram_addr_int = current_s_desc_ram_addr;
m_axis_desc_imm_int = current_s_desc_imm;
m_axis_desc_imm_en_int = current_s_desc_imm_en;
m_axis_desc_len_int = current_s_desc_len;
m_axis_desc_tag_int = {grant_encoded, current_s_desc_tag};
m_axis_desc_tag_int = current_s_desc_tag;
if (PORTS > 1) begin
m_axis_desc_tag_int[M_TAG_WIDTH-1:M_TAG_WIDTH-CL_PORTS] = grant_encoded;
end
m_axis_desc_valid_int = current_s_desc_valid && m_axis_desc_ready_int_reg && grant_valid;
end
@ -191,6 +208,8 @@ end
reg [DMA_ADDR_WIDTH-1:0] m_axis_desc_dma_addr_reg = {DMA_ADDR_WIDTH{1'b0}};
reg [M_RAM_SEL_WIDTH-1:0] m_axis_desc_ram_sel_reg = {M_RAM_SEL_WIDTH{1'b0}};
reg [RAM_ADDR_WIDTH-1:0] m_axis_desc_ram_addr_reg = {RAM_ADDR_WIDTH{1'b0}};
reg [IMM_WIDTH-1:0] m_axis_desc_imm_reg = {IMM_WIDTH{1'b0}};
reg m_axis_desc_imm_en_reg = 1'b0;
reg [LEN_WIDTH-1:0] m_axis_desc_len_reg = {LEN_WIDTH{1'b0}};
reg [M_TAG_WIDTH-1:0] m_axis_desc_tag_reg = {M_TAG_WIDTH{1'b0}};
reg m_axis_desc_valid_reg = 1'b0, m_axis_desc_valid_next;
@ -198,6 +217,8 @@ reg m_axis_desc_valid_reg = 1'b0, m_axis_desc_valid_ne
reg [DMA_ADDR_WIDTH-1:0] temp_m_axis_desc_dma_addr_reg = {DMA_ADDR_WIDTH{1'b0}};
reg [M_RAM_SEL_WIDTH-1:0] temp_m_axis_desc_ram_sel_reg = {M_RAM_SEL_WIDTH{1'b0}};
reg [RAM_ADDR_WIDTH-1:0] temp_m_axis_desc_ram_addr_reg = {RAM_ADDR_WIDTH{1'b0}};
reg [IMM_WIDTH-1:0] temp_m_axis_desc_imm_reg = {IMM_WIDTH{1'b0}};
reg temp_m_axis_desc_imm_en_reg = 1'b0;
reg [LEN_WIDTH-1:0] temp_m_axis_desc_len_reg = {LEN_WIDTH{1'b0}};
reg [M_TAG_WIDTH-1:0] temp_m_axis_desc_tag_reg = {M_TAG_WIDTH{1'b0}};
reg temp_m_axis_desc_valid_reg = 1'b0, temp_m_axis_desc_valid_next;
@ -210,6 +231,8 @@ reg store_axis_temp_to_output;
assign m_axis_desc_dma_addr = m_axis_desc_dma_addr_reg;
assign m_axis_desc_ram_sel = m_axis_desc_ram_sel_reg;
assign m_axis_desc_ram_addr = m_axis_desc_ram_addr_reg;
assign m_axis_desc_imm = IMM_ENABLE ? m_axis_desc_imm_reg : {IMM_WIDTH{1'b0}};
assign m_axis_desc_imm_en = IMM_ENABLE ? m_axis_desc_imm_en_reg : 1'b0;
assign m_axis_desc_len = m_axis_desc_len_reg;
assign m_axis_desc_tag = m_axis_desc_tag_reg;
assign m_axis_desc_valid = m_axis_desc_valid_reg;
@ -261,12 +284,16 @@ always @(posedge clk) begin
m_axis_desc_dma_addr_reg <= m_axis_desc_dma_addr_int;
m_axis_desc_ram_sel_reg <= m_axis_desc_ram_sel_int;
m_axis_desc_ram_addr_reg <= m_axis_desc_ram_addr_int;
m_axis_desc_imm_reg <= m_axis_desc_imm_int;
m_axis_desc_imm_en_reg <= m_axis_desc_imm_en_int;
m_axis_desc_len_reg <= m_axis_desc_len_int;
m_axis_desc_tag_reg <= m_axis_desc_tag_int;
end else if (store_axis_temp_to_output) begin
m_axis_desc_dma_addr_reg <= temp_m_axis_desc_dma_addr_reg;
m_axis_desc_ram_sel_reg <= temp_m_axis_desc_ram_sel_reg;
m_axis_desc_ram_addr_reg <= temp_m_axis_desc_ram_addr_reg;
m_axis_desc_imm_reg <= temp_m_axis_desc_imm_reg;
m_axis_desc_imm_en_reg <= temp_m_axis_desc_imm_en_reg;
m_axis_desc_len_reg <= temp_m_axis_desc_len_reg;
m_axis_desc_tag_reg <= temp_m_axis_desc_tag_reg;
end
@ -275,6 +302,8 @@ always @(posedge clk) begin
temp_m_axis_desc_dma_addr_reg <= m_axis_desc_dma_addr_int;
temp_m_axis_desc_ram_sel_reg <= m_axis_desc_ram_sel_int;
temp_m_axis_desc_ram_addr_reg <= m_axis_desc_ram_addr_int;
temp_m_axis_desc_imm_reg <= m_axis_desc_imm_int;
temp_m_axis_desc_imm_en_reg <= m_axis_desc_imm_en_int;
temp_m_axis_desc_len_reg <= m_axis_desc_len_int;
temp_m_axis_desc_tag_reg <= m_axis_desc_tag_int;
end

View File

@ -52,6 +52,10 @@ module dma_if_mux #
parameter RAM_ADDR_WIDTH = SEG_ADDR_WIDTH+$clog2(SEG_COUNT)+$clog2(SEG_BE_WIDTH),
// DMA address width
parameter DMA_ADDR_WIDTH = 64,
// Immediate enable
parameter IMM_ENABLE = 0,
// Immediate width
parameter IMM_WIDTH = 32,
// Length field width
parameter LEN_WIDTH = 16,
// Input tag field width
@ -92,6 +96,8 @@ module dma_if_mux #
output wire [DMA_ADDR_WIDTH-1:0] m_axis_write_desc_dma_addr,
output wire [M_RAM_SEL_WIDTH-1:0] m_axis_write_desc_ram_sel,
output wire [RAM_ADDR_WIDTH-1:0] m_axis_write_desc_ram_addr,
output wire [IMM_WIDTH-1:0] m_axis_write_desc_imm,
output wire m_axis_write_desc_imm_en,
output wire [LEN_WIDTH-1:0] m_axis_write_desc_len,
output wire [M_TAG_WIDTH-1:0] m_axis_write_desc_tag,
output wire m_axis_write_desc_valid,
@ -128,6 +134,8 @@ module dma_if_mux #
input wire [PORTS*DMA_ADDR_WIDTH-1:0] s_axis_write_desc_dma_addr,
input wire [PORTS*S_RAM_SEL_WIDTH-1:0] s_axis_write_desc_ram_sel,
input wire [PORTS*RAM_ADDR_WIDTH-1:0] s_axis_write_desc_ram_addr,
input wire [PORTS*IMM_WIDTH-1:0] s_axis_write_desc_imm,
input wire [PORTS-1:0] s_axis_write_desc_imm_en,
input wire [PORTS*LEN_WIDTH-1:0] s_axis_write_desc_len,
input wire [PORTS*S_TAG_WIDTH-1:0] s_axis_write_desc_tag,
input wire [PORTS-1:0] s_axis_write_desc_valid,
@ -266,6 +274,8 @@ dma_if_mux_wr #(
.M_RAM_SEL_WIDTH(M_RAM_SEL_WIDTH),
.RAM_ADDR_WIDTH(RAM_ADDR_WIDTH),
.DMA_ADDR_WIDTH(DMA_ADDR_WIDTH),
.IMM_ENABLE(IMM_ENABLE),
.IMM_WIDTH(IMM_WIDTH),
.LEN_WIDTH(LEN_WIDTH),
.S_TAG_WIDTH(S_TAG_WIDTH),
.M_TAG_WIDTH(M_TAG_WIDTH),
@ -282,6 +292,8 @@ dma_if_mux_wr_inst (
.m_axis_write_desc_dma_addr(m_axis_write_desc_dma_addr),
.m_axis_write_desc_ram_sel(m_axis_write_desc_ram_sel),
.m_axis_write_desc_ram_addr(m_axis_write_desc_ram_addr),
.m_axis_write_desc_imm(m_axis_write_desc_imm),
.m_axis_write_desc_imm_en(m_axis_write_desc_imm_en),
.m_axis_write_desc_len(m_axis_write_desc_len),
.m_axis_write_desc_tag(m_axis_write_desc_tag),
.m_axis_write_desc_valid(m_axis_write_desc_valid),
@ -300,6 +312,8 @@ dma_if_mux_wr_inst (
.s_axis_write_desc_dma_addr(s_axis_write_desc_dma_addr),
.s_axis_write_desc_ram_sel(s_axis_write_desc_ram_sel),
.s_axis_write_desc_ram_addr(s_axis_write_desc_ram_addr),
.s_axis_write_desc_imm(s_axis_write_desc_imm),
.s_axis_write_desc_imm_en(s_axis_write_desc_imm_en),
.s_axis_write_desc_len(s_axis_write_desc_len),
.s_axis_write_desc_tag(s_axis_write_desc_tag),
.s_axis_write_desc_valid(s_axis_write_desc_valid),

View File

@ -134,6 +134,7 @@ dma_if_desc_mux #(
.M_RAM_SEL_WIDTH(M_RAM_SEL_WIDTH),
.RAM_ADDR_WIDTH(RAM_ADDR_WIDTH),
.DMA_ADDR_WIDTH(DMA_ADDR_WIDTH),
.IMM_ENABLE(0),
.LEN_WIDTH(LEN_WIDTH),
.S_TAG_WIDTH(S_TAG_WIDTH),
.M_TAG_WIDTH(M_TAG_WIDTH),
@ -150,6 +151,8 @@ dma_if_desc_mux_inst (
.m_axis_desc_dma_addr(m_axis_read_desc_dma_addr),
.m_axis_desc_ram_sel(m_axis_read_desc_ram_sel),
.m_axis_desc_ram_addr(m_axis_read_desc_ram_addr),
.m_axis_desc_imm(),
.m_axis_desc_imm_en(),
.m_axis_desc_len(m_axis_read_desc_len),
.m_axis_desc_tag(m_axis_read_desc_tag),
.m_axis_desc_valid(m_axis_read_desc_valid),
@ -168,6 +171,8 @@ dma_if_desc_mux_inst (
.s_axis_desc_dma_addr(s_axis_read_desc_dma_addr),
.s_axis_desc_ram_sel(s_axis_read_desc_ram_sel),
.s_axis_desc_ram_addr(s_axis_read_desc_ram_addr),
.s_axis_desc_imm(32'd0),
.s_axis_desc_imm_en(1'b0),
.s_axis_desc_len(s_axis_read_desc_len),
.s_axis_desc_tag(s_axis_read_desc_tag),
.s_axis_desc_valid(s_axis_read_desc_valid),

View File

@ -52,6 +52,10 @@ module dma_if_mux_wr #
parameter RAM_ADDR_WIDTH = SEG_ADDR_WIDTH+$clog2(SEG_COUNT)+$clog2(SEG_BE_WIDTH),
// DMA address width
parameter DMA_ADDR_WIDTH = 64,
// Immediate enable
parameter IMM_ENABLE = 0,
// Immediate width
parameter IMM_WIDTH = 32,
// Length field width
parameter LEN_WIDTH = 16,
// Input tag field width
@ -74,6 +78,8 @@ module dma_if_mux_wr #
output wire [DMA_ADDR_WIDTH-1:0] m_axis_write_desc_dma_addr,
output wire [M_RAM_SEL_WIDTH-1:0] m_axis_write_desc_ram_sel,
output wire [RAM_ADDR_WIDTH-1:0] m_axis_write_desc_ram_addr,
output wire [IMM_WIDTH-1:0] m_axis_write_desc_imm,
output wire m_axis_write_desc_imm_en,
output wire [LEN_WIDTH-1:0] m_axis_write_desc_len,
output wire [M_TAG_WIDTH-1:0] m_axis_write_desc_tag,
output wire m_axis_write_desc_valid,
@ -92,6 +98,8 @@ module dma_if_mux_wr #
input wire [PORTS*DMA_ADDR_WIDTH-1:0] s_axis_write_desc_dma_addr,
input wire [PORTS*S_RAM_SEL_WIDTH-1:0] s_axis_write_desc_ram_sel,
input wire [PORTS*RAM_ADDR_WIDTH-1:0] s_axis_write_desc_ram_addr,
input wire [PORTS*IMM_WIDTH-1:0] s_axis_write_desc_imm,
input wire [PORTS-1:0] s_axis_write_desc_imm_en,
input wire [PORTS*LEN_WIDTH-1:0] s_axis_write_desc_len,
input wire [PORTS*S_TAG_WIDTH-1:0] s_axis_write_desc_tag,
input wire [PORTS-1:0] s_axis_write_desc_valid,
@ -134,6 +142,8 @@ dma_if_desc_mux #(
.M_RAM_SEL_WIDTH(M_RAM_SEL_WIDTH),
.RAM_ADDR_WIDTH(RAM_ADDR_WIDTH),
.DMA_ADDR_WIDTH(DMA_ADDR_WIDTH),
.IMM_ENABLE(IMM_ENABLE),
.IMM_WIDTH(IMM_WIDTH),
.LEN_WIDTH(LEN_WIDTH),
.S_TAG_WIDTH(S_TAG_WIDTH),
.M_TAG_WIDTH(M_TAG_WIDTH),
@ -150,6 +160,8 @@ dma_if_desc_mux_inst (
.m_axis_desc_dma_addr(m_axis_write_desc_dma_addr),
.m_axis_desc_ram_sel(m_axis_write_desc_ram_sel),
.m_axis_desc_ram_addr(m_axis_write_desc_ram_addr),
.m_axis_desc_imm(m_axis_write_desc_imm),
.m_axis_desc_imm_en(m_axis_write_desc_imm_en),
.m_axis_desc_len(m_axis_write_desc_len),
.m_axis_desc_tag(m_axis_write_desc_tag),
.m_axis_desc_valid(m_axis_write_desc_valid),
@ -168,6 +180,8 @@ dma_if_desc_mux_inst (
.s_axis_desc_dma_addr(s_axis_write_desc_dma_addr),
.s_axis_desc_ram_sel(s_axis_write_desc_ram_sel),
.s_axis_desc_ram_addr(s_axis_write_desc_ram_addr),
.s_axis_desc_imm(s_axis_write_desc_imm),
.s_axis_desc_imm_en(s_axis_write_desc_imm_en),
.s_axis_desc_len(s_axis_write_desc_len),
.s_axis_desc_tag(s_axis_write_desc_tag),
.s_axis_desc_valid(s_axis_write_desc_valid),

View File

@ -63,6 +63,10 @@ module dma_if_pcie #
parameter PCIE_ADDR_WIDTH = 64,
// PCIe tag count
parameter PCIE_TAG_COUNT = 256,
// Immediate enable
parameter IMM_ENABLE = 0,
// Immediate width
parameter IMM_WIDTH = 32,
// Length field width
parameter LEN_WIDTH = 16,
// Tag field width
@ -160,6 +164,8 @@ module dma_if_pcie #
input wire [PCIE_ADDR_WIDTH-1:0] s_axis_write_desc_pcie_addr,
input wire [RAM_SEL_WIDTH-1:0] s_axis_write_desc_ram_sel,
input wire [RAM_ADDR_WIDTH-1:0] s_axis_write_desc_ram_addr,
input wire [IMM_WIDTH-1:0] s_axis_write_desc_imm,
input wire s_axis_write_desc_imm_en,
input wire [LEN_WIDTH-1:0] s_axis_write_desc_len,
input wire [TAG_WIDTH-1:0] s_axis_write_desc_tag,
input wire s_axis_write_desc_valid,
@ -385,6 +391,8 @@ dma_if_pcie_wr #(
.RAM_SEG_BE_WIDTH(RAM_SEG_BE_WIDTH),
.RAM_SEG_ADDR_WIDTH(RAM_SEG_ADDR_WIDTH),
.PCIE_ADDR_WIDTH(PCIE_ADDR_WIDTH),
.IMM_ENABLE(IMM_ENABLE),
.IMM_WIDTH(IMM_WIDTH),
.LEN_WIDTH(LEN_WIDTH),
.TAG_WIDTH(TAG_WIDTH),
.OP_TABLE_SIZE(WRITE_OP_TABLE_SIZE),
@ -426,6 +434,8 @@ dma_if_pcie_wr_inst (
.s_axis_write_desc_pcie_addr(s_axis_write_desc_pcie_addr),
.s_axis_write_desc_ram_sel(s_axis_write_desc_ram_sel),
.s_axis_write_desc_ram_addr(s_axis_write_desc_ram_addr),
.s_axis_write_desc_imm(s_axis_write_desc_imm),
.s_axis_write_desc_imm_en(s_axis_write_desc_imm_en),
.s_axis_write_desc_len(s_axis_write_desc_len),
.s_axis_write_desc_tag(s_axis_write_desc_tag),
.s_axis_write_desc_valid(s_axis_write_desc_valid),

View File

@ -772,7 +772,7 @@ always @* begin
req_pcie_tag_valid_next = 1'b0;
stat_rd_req_start_tag_next = req_pcie_tag_reg;
stat_rd_req_start_len_next = req_tlp_count_next;
stat_rd_req_start_len_next = req_zero_len_reg ? 0 : req_tlp_count_next;
stat_rd_req_start_valid_next = 1'b1;
if (!req_last_tlp) begin
@ -1061,19 +1061,19 @@ always @* begin
end else begin
// no error
if (zero_len_next) begin
status_fifo_mask_next = 1'b0;
end else begin
tlp_data_int_next = rx_cpl_tlp_data;
tlp_data_valid_int_next = 1'b1;
status_fifo_mask_next = 1'b1;
end
tlp_data_int_next = rx_cpl_tlp_data;
tlp_data_valid_int_next = 1'b1;
status_fifo_mask_next = 1'b1;
status_fifo_finish_next = 1'b0;
status_fifo_error_next = DMA_ERROR_NONE;
status_fifo_we_next = 1'b1;
if (zero_len_next) begin
tlp_data_valid_int_next = 1'b0;
status_fifo_mask_next = 1'b0;
end
stat_rd_req_finish_tag_next = pcie_tag_next;
stat_rd_req_finish_status_next = DMA_ERROR_NONE;

View File

@ -1064,19 +1064,19 @@ always @* begin
end else begin
// no error
if (zero_len_next) begin
status_fifo_mask_next = 1'b0;
end else begin
rc_tdata_int_next = s_axis_rc_tdata;
rc_tvalid_int_next = 1'b1;
status_fifo_mask_next = 1'b1;
end
rc_tdata_int_next = s_axis_rc_tdata;
rc_tvalid_int_next = 1'b1;
status_fifo_mask_next = 1'b1;
status_fifo_finish_next = 1'b0;
status_fifo_error_next = DMA_ERROR_NONE;
status_fifo_we_next = 1'b1;
if (zero_len_next) begin
rc_tvalid_int_next = 1'b0;
status_fifo_mask_next = 1'b0;
end
if (last_cycle) begin
if (final_cpl_next) begin
// last completion in current read request (PCIe tag)

View File

@ -1074,6 +1074,7 @@ always @* begin
// skip idle state if possible
tlp_addr_next = op_table_pcie_addr[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_len_next = op_table_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_zero_len_next = op_table_zero_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
dword_count_next = op_table_dword_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
offset_next = op_table_offset[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
cycle_count_next = op_table_cycle_count[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
@ -1139,6 +1140,7 @@ always @* begin
// skip idle state if possible
tlp_addr_next = op_table_pcie_addr[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_len_next = op_table_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_zero_len_next = op_table_zero_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
dword_count_next = op_table_dword_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
offset_next = op_table_offset[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
cycle_count_next = op_table_cycle_count[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];

View File

@ -61,6 +61,10 @@ module dma_if_pcie_wr #
parameter RAM_SEG_ADDR_WIDTH = RAM_ADDR_WIDTH-$clog2(RAM_SEG_COUNT*RAM_SEG_BE_WIDTH),
// PCIe address width
parameter PCIE_ADDR_WIDTH = 64,
// Immediate enable
parameter IMM_ENABLE = 0,
// Immediate width
parameter IMM_WIDTH = 32,
// Length field width
parameter LEN_WIDTH = 16,
// Tag field width
@ -108,6 +112,8 @@ module dma_if_pcie_wr #
input wire [PCIE_ADDR_WIDTH-1:0] s_axis_write_desc_pcie_addr,
input wire [RAM_SEL_WIDTH-1:0] s_axis_write_desc_ram_sel,
input wire [RAM_ADDR_WIDTH-1:0] s_axis_write_desc_ram_addr,
input wire [IMM_WIDTH-1:0] s_axis_write_desc_imm,
input wire s_axis_write_desc_imm_en,
input wire [LEN_WIDTH-1:0] s_axis_write_desc_len,
input wire [TAG_WIDTH-1:0] s_axis_write_desc_tag,
input wire s_axis_write_desc_valid,
@ -230,6 +236,11 @@ initial begin
$error("Error: RAM_ADDR_WIDTH does not match RAM configuration (instance %m)");
$finish;
end
if (IMM_ENABLE && IMM_WIDTH > TLP_DATA_WIDTH) begin
$error("Error: IMM_WIDTH must not be larger than the PCIe interface width (instance %m)");
$finish;
end
end
localparam [2:0]
@ -265,6 +276,8 @@ reg read_cmd_ready;
reg [PCIE_ADDR_WIDTH-1:0] pcie_addr_reg = {PCIE_ADDR_WIDTH{1'b0}}, pcie_addr_next;
reg [RAM_SEL_WIDTH-1:0] ram_sel_reg = {RAM_SEL_WIDTH{1'b0}}, ram_sel_next;
reg [RAM_ADDR_WIDTH-1:0] ram_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, ram_addr_next;
reg [IMM_WIDTH-1:0] imm_reg = {IMM_WIDTH{1'b0}}, imm_next;
reg imm_en_reg = 1'b0, imm_en_next;
reg [LEN_WIDTH-1:0] op_count_reg = {LEN_WIDTH{1'b0}}, op_count_next;
reg [LEN_WIDTH-1:0] tr_count_reg = {LEN_WIDTH{1'b0}}, tr_count_next;
reg [12:0] tlp_count_reg = 13'd0, tlp_count_next;
@ -274,6 +287,7 @@ reg zero_len_reg = 1'b0, zero_len_next;
reg [PCIE_ADDR_WIDTH-1:0] read_pcie_addr_reg = {PCIE_ADDR_WIDTH{1'b0}}, read_pcie_addr_next;
reg [RAM_SEL_WIDTH-1:0] read_ram_sel_reg = {RAM_SEL_WIDTH{1'b0}}, read_ram_sel_next;
reg [RAM_ADDR_WIDTH-1:0] read_ram_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, read_ram_addr_next;
reg read_imm_en_reg = 1'b0, read_imm_en_next;
reg [LEN_WIDTH-1:0] read_len_reg = {LEN_WIDTH{1'b0}}, read_len_next;
reg [RAM_SEG_COUNT-1:0] read_ram_mask_reg = {RAM_SEG_COUNT{1'b0}}, read_ram_mask_next;
reg [RAM_SEG_COUNT-1:0] read_ram_mask_0_reg = {RAM_SEG_COUNT{1'b0}}, read_ram_mask_0_next;
@ -286,6 +300,8 @@ reg [RAM_OFFSET_WIDTH-1:0] start_offset_reg = {RAM_OFFSET_WIDTH{1'b0}}, start_of
reg [RAM_OFFSET_WIDTH-1:0] end_offset_reg = {RAM_OFFSET_WIDTH{1'b0}}, end_offset_next;
reg [PCIE_ADDR_WIDTH-1:0] tlp_addr_reg = {PCIE_ADDR_WIDTH{1'b0}}, tlp_addr_next;
reg [IMM_WIDTH-1:0] tlp_imm_reg = {IMM_WIDTH{1'b0}}, tlp_imm_next;
reg tlp_imm_en_reg = 1'b0, tlp_imm_en_next;
reg [11:0] tlp_len_reg = 12'd0, tlp_len_next;
reg tlp_zero_len_reg = 1'b0, tlp_zero_len_next;
reg [RAM_OFFSET_WIDTH-1:0] offset_reg = {RAM_OFFSET_WIDTH{1'b0}}, offset_next;
@ -299,6 +315,7 @@ reg tlp_frame_reg = 1'b0, tlp_frame_next;
reg [PCIE_ADDR_WIDTH-1:0] read_cmd_pcie_addr_reg = {PCIE_ADDR_WIDTH{1'b0}}, read_cmd_pcie_addr_next;
reg [RAM_SEL_WIDTH-1:0] read_cmd_ram_sel_reg = {RAM_SEL_WIDTH{1'b0}}, read_cmd_ram_sel_next;
reg [RAM_ADDR_WIDTH-1:0] read_cmd_ram_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, read_cmd_ram_addr_next;
reg read_cmd_imm_en_reg = 1'b0, read_cmd_imm_en_next;
reg [11:0] read_cmd_len_reg = 12'd0, read_cmd_len_next;
reg [CYCLE_COUNT_WIDTH-1:0] read_cmd_cycle_count_reg = {CYCLE_COUNT_WIDTH{1'b0}}, read_cmd_cycle_count_next;
reg read_cmd_last_cycle_reg = 1'b0, read_cmd_last_cycle_next;
@ -395,6 +412,8 @@ assign stat_wr_tx_stall = stat_wr_tx_stall_reg;
// operation tag management
reg [OP_TAG_WIDTH+1-1:0] op_table_start_ptr_reg = 0;
reg [PCIE_ADDR_WIDTH-1:0] op_table_start_pcie_addr;
reg [IMM_WIDTH-1:0] op_table_start_imm;
reg op_table_start_imm_en;
reg [11:0] op_table_start_len;
reg op_table_start_zero_len;
reg [9:0] op_table_start_dword_len;
@ -415,6 +434,10 @@ reg [2**OP_TAG_WIDTH-1:0] op_table_tx_done = 0;
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [PCIE_ADDR_WIDTH-1:0] op_table_pcie_addr[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [IMM_WIDTH-1:0] op_table_imm[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg op_table_imm_en[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg [11:0] op_table_len[2**OP_TAG_WIDTH-1:0];
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
reg op_table_zero_len[2**OP_TAG_WIDTH-1:0];
@ -434,6 +457,8 @@ integer i;
initial begin
for (i = 0; i < 2**OP_TAG_WIDTH; i = i + 1) begin
op_table_pcie_addr[i] = 0;
op_table_imm[i] = 0;
op_table_imm_en[i] = 0;
op_table_len[i] = 0;
op_table_zero_len[i] = 0;
op_table_dword_len[i] = 0;
@ -463,6 +488,8 @@ always @* begin
pcie_addr_next = pcie_addr_reg;
ram_sel_next = ram_sel_reg;
ram_addr_next = ram_addr_reg;
imm_next = imm_reg;
imm_en_next = imm_en_reg;
op_count_next = op_count_reg;
tr_count_next = tr_count_reg;
tlp_count_next = tlp_count_reg;
@ -472,12 +499,15 @@ always @* begin
read_cmd_pcie_addr_next = read_cmd_pcie_addr_reg;
read_cmd_ram_sel_next = read_cmd_ram_sel_reg;
read_cmd_ram_addr_next = read_cmd_ram_addr_reg;
read_cmd_imm_en_next = read_cmd_imm_en_reg;
read_cmd_len_next = read_cmd_len_reg;
read_cmd_cycle_count_next = read_cmd_cycle_count_reg;
read_cmd_last_cycle_next = read_cmd_last_cycle_reg;
read_cmd_valid_next = read_cmd_valid_reg && !read_cmd_ready;
op_table_start_pcie_addr = pcie_addr_reg;
op_table_start_imm = imm_reg;
op_table_start_imm_en = imm_en_reg;
op_table_start_len = tlp_count_reg;
op_table_start_zero_len = zero_len_reg;
op_table_start_dword_len = (tlp_count_reg + pcie_addr_reg[1:0] + 3) >> 2;
@ -494,8 +524,15 @@ always @* begin
s_axis_write_desc_ready_next = !op_table_active[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] && ($unsigned(op_table_start_ptr_reg - op_table_finish_ptr_reg) < 2**OP_TAG_WIDTH) && enable;
pcie_addr_next = s_axis_write_desc_pcie_addr;
ram_sel_next = s_axis_write_desc_ram_sel;
ram_addr_next = s_axis_write_desc_ram_addr;
if (IMM_ENABLE && s_axis_write_desc_imm_en) begin
ram_sel_next = 0;
ram_addr_next = 0;
end else begin
ram_sel_next = s_axis_write_desc_ram_sel;
ram_addr_next = s_axis_write_desc_ram_addr;
end
imm_next = s_axis_write_desc_imm;
imm_en_next = IMM_ENABLE && s_axis_write_desc_imm_en;
if (s_axis_write_desc_len == 0) begin
// zero-length operation
op_count_next = 1;
@ -544,6 +581,7 @@ always @* begin
read_cmd_pcie_addr_next = pcie_addr_reg;
read_cmd_ram_sel_next = ram_sel_reg;
read_cmd_ram_addr_next = ram_addr_reg;
read_cmd_imm_en_next = imm_en_reg;
read_cmd_len_next = tlp_count_reg;
read_cmd_cycle_count_next = (tlp_count_reg + pcie_addr_reg[1:0] - 1) >> $clog2(TLP_DATA_WIDTH_BYTES);
op_table_start_cycle_count = read_cmd_cycle_count_next;
@ -555,6 +593,8 @@ always @* begin
op_count_next = op_count_reg - tlp_count_reg;
op_table_start_pcie_addr = pcie_addr_reg;
op_table_start_imm = imm_reg;
op_table_start_imm_en = imm_en_reg;
op_table_start_len = tlp_count_reg;
op_table_start_zero_len = zero_len_reg;
op_table_start_dword_len = (tlp_count_reg + pcie_addr_reg[1:0] + 3) >> 2;
@ -565,7 +605,7 @@ always @* begin
op_table_start_en = 1'b1;
stat_wr_req_start_tag_next = op_table_start_ptr_reg;
stat_wr_req_start_len_next = tlp_count_reg;
stat_wr_req_start_len_next = zero_len_reg ? 0 : tlp_count_reg;
stat_wr_req_start_valid_next = 1'b1;
// TLP size computation
@ -614,6 +654,7 @@ always @* begin
read_pcie_addr_next = read_pcie_addr_reg;
read_ram_sel_next = read_ram_sel_reg;
read_ram_addr_next = read_ram_addr_reg;
read_imm_en_next = read_imm_en_reg;
read_len_next = read_len_reg;
read_ram_mask_next = read_ram_mask_reg;
read_ram_mask_0_next = read_ram_mask_0_reg;
@ -636,6 +677,7 @@ always @* begin
read_pcie_addr_next = read_cmd_pcie_addr_reg;
read_ram_sel_next = read_cmd_ram_sel_reg;
read_ram_addr_next = read_cmd_ram_addr_reg;
read_imm_en_next = read_cmd_imm_en_reg;
read_len_next = read_cmd_len_reg;
read_cycle_count_next = read_cmd_cycle_count_reg;
read_last_cycle_next = read_cmd_last_cycle_reg;
@ -681,14 +723,14 @@ always @* begin
if (read_ram_mask_reg[i]) begin
ram_rd_cmd_sel_next[i*RAM_SEL_WIDTH +: RAM_SEL_WIDTH] = read_ram_sel_reg;
ram_rd_cmd_addr_next[i*RAM_SEG_ADDR_WIDTH +: RAM_SEG_ADDR_WIDTH] = read_ram_addr_reg[RAM_ADDR_WIDTH-1:RAM_ADDR_WIDTH-RAM_SEG_ADDR_WIDTH];
ram_rd_cmd_valid_next[i] = 1'b1;
ram_rd_cmd_valid_next[i] = !(IMM_ENABLE && read_imm_en_reg);
end
if (read_ram_mask_1_reg[i]) begin
ram_rd_cmd_addr_next[i*RAM_SEG_ADDR_WIDTH +: RAM_SEG_ADDR_WIDTH] = read_ram_addr_reg[RAM_ADDR_WIDTH-1:RAM_ADDR_WIDTH-RAM_SEG_ADDR_WIDTH]+1;
end
end
mask_fifo_wr_mask = read_ram_mask_reg;
mask_fifo_wr_mask = (IMM_ENABLE && read_imm_en_reg) ? 0 : read_ram_mask_reg;
mask_fifo_we = 1'b1;
if (read_len_next > TLP_DATA_WIDTH_BYTES) begin
@ -718,6 +760,7 @@ always @* begin
read_pcie_addr_next = read_cmd_pcie_addr_reg;
read_ram_sel_next = read_cmd_ram_sel_reg;
read_ram_addr_next = read_cmd_ram_addr_reg;
read_imm_en_next = read_cmd_imm_en_reg;
read_len_next = read_cmd_len_reg;
read_cycle_count_next = read_cmd_cycle_count_reg;
read_last_cycle_next = read_cmd_last_cycle_reg;
@ -769,6 +812,8 @@ always @* begin
stat_wr_req_finish_valid_next = 1'b0;
tlp_addr_next = tlp_addr_reg;
tlp_imm_next = tlp_imm_reg;
tlp_imm_en_next = tlp_imm_en_reg;
tlp_len_next = tlp_len_reg;
tlp_zero_len_next = tlp_zero_len_reg;
dword_count_next = dword_count_reg;
@ -839,6 +884,8 @@ always @* begin
tlp_frame_next = 1'b0;
tlp_addr_next = op_table_pcie_addr[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_imm_next = op_table_imm[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_imm_en_next = op_table_imm_en[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_len_next = op_table_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_zero_len_next = op_table_zero_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
dword_count_next = op_table_dword_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
@ -857,7 +904,7 @@ always @* begin
// transfer state, transfer data
if (!tx_wr_req_tlp_valid_reg || tx_wr_req_tlp_ready) begin
tx_wr_req_tlp_data_next = {2{ram_rd_resp_data}} >> (RAM_DATA_WIDTH-offset_reg*8);
tx_wr_req_tlp_data_next = ((IMM_ENABLE && tlp_imm_en_reg) ? {2{{RAM_DATA_WIDTH{1'b0}} | tlp_imm_reg}} : {2{ram_rd_resp_data}}) >> (RAM_DATA_WIDTH-offset_reg*8);
if (dword_count_reg >= TLP_STRB_WIDTH) begin
tx_wr_req_tlp_strb_next = {TLP_STRB_WIDTH{1'b1}};
end else begin
@ -895,7 +942,10 @@ always @* begin
// skip idle state if possible
tlp_addr_next = op_table_pcie_addr[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_imm_next = op_table_imm[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_imm_en_next = op_table_imm_en[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_len_next = op_table_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_zero_len_next = op_table_zero_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
dword_count_next = op_table_dword_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
offset_next = op_table_offset[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
cycle_count_next = op_table_cycle_count[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
@ -976,6 +1026,8 @@ always @(posedge clk) begin
pcie_addr_reg <= pcie_addr_next;
ram_sel_reg <= ram_sel_next;
ram_addr_reg <= ram_addr_next;
imm_reg <= imm_next;
imm_en_reg <= imm_en_next;
op_count_reg <= op_count_next;
tr_count_reg <= tr_count_next;
tlp_count_reg <= tlp_count_next;
@ -985,6 +1037,7 @@ always @(posedge clk) begin
read_pcie_addr_reg <= read_pcie_addr_next;
read_ram_sel_reg <= read_ram_sel_next;
read_ram_addr_reg <= read_ram_addr_next;
read_imm_en_reg <= read_imm_en_next;
read_len_reg <= read_len_next;
read_ram_mask_reg <= read_ram_mask_next;
read_ram_mask_0_reg <= read_ram_mask_0_next;
@ -997,6 +1050,8 @@ always @(posedge clk) begin
end_offset_reg <= end_offset_next;
tlp_addr_reg <= tlp_addr_next;
tlp_imm_reg <= tlp_imm_next;
tlp_imm_en_reg <= tlp_imm_en_next;
tlp_len_reg <= tlp_len_next;
tlp_zero_len_reg <= tlp_zero_len_next;
dword_count_reg <= dword_count_next;
@ -1010,6 +1065,7 @@ always @(posedge clk) begin
read_cmd_pcie_addr_reg <= read_cmd_pcie_addr_next;
read_cmd_ram_sel_reg <= read_cmd_ram_sel_next;
read_cmd_ram_addr_reg <= read_cmd_ram_addr_next;
read_cmd_imm_en_reg <= read_cmd_imm_en_next;
read_cmd_len_reg <= read_cmd_len_next;
read_cmd_cycle_count_reg <= read_cmd_cycle_count_next;
read_cmd_last_cycle_reg <= read_cmd_last_cycle_next;
@ -1065,6 +1121,8 @@ always @(posedge clk) begin
op_table_active[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= 1'b1;
op_table_tx_done[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= 1'b0;
op_table_pcie_addr[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_pcie_addr;
op_table_imm[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_imm;
op_table_imm_en[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_imm_en;
op_table_len[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_len;
op_table_zero_len[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_zero_len;
op_table_dword_len[op_table_start_ptr_reg[OP_TAG_WIDTH-1:0]] <= op_table_start_dword_len;

View File

@ -55,8 +55,8 @@ module pcie_axi_master_rd #
parameter TLP_FORCE_64_BIT_ADDR = 0
)
(
input wire clk,
input wire rst,
input wire clk,
input wire rst,
/*
* TLP input (request)
@ -443,7 +443,7 @@ always @* begin
// report correctable error
status_error_cor_next = 1'b1;
// // UR completion
// UR completion
tlp_cmd_status_next = CPL_STATUS_UR;
tlp_cmd_byte_len_next = 12'd0;
tlp_cmd_dword_len_next = 10'd0;

View File

@ -318,7 +318,7 @@ always @* begin
wr_req_fifo_wr_data[63:32] = tx_wr_req_tlp_hdr[95:64];
wr_req_fifo_wr_data[95:64] = tx_wr_req_tlp_hdr[63:32];
if (wr_req_payload_offset_next) begin
wr_req_fifo_wr_data[127:96] = tx_rd_req_tlp_hdr[31:0];
wr_req_fifo_wr_data[127:96] = tx_wr_req_tlp_hdr[31:0];
wr_req_fifo_wr_data[SEG_COUNT*SEG_DATA_WIDTH-1:128] = tx_wr_req_tlp_data;
end else begin
wr_req_fifo_wr_data[SEG_COUNT*SEG_DATA_WIDTH-1:96] = tx_wr_req_tlp_data;

View File

@ -864,6 +864,7 @@ always @* begin
// skip idle state if possible
tlp_addr_next = op_table_pcie_addr[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_len_next = op_table_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_zero_len_next = op_table_zero_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
dword_count_next = op_table_dword_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
offset_next = op_table_offset[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
input_cycle_count_next = op_table_input_cycle_count[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
@ -990,6 +991,7 @@ always @* begin
// skip idle state if possible
tlp_addr_next = op_table_pcie_addr[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_len_next = op_table_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
tlp_zero_len_next = op_table_zero_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
dword_count_next = op_table_dword_len[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
offset_next = op_table_offset[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];
input_cycle_count_next = op_table_input_cycle_count[op_table_tx_start_ptr_reg[OP_TAG_WIDTH-1:0]];

View File

@ -25,17 +25,16 @@ fi
echo "Disabling fatal error reporting on port $port..."
cmd=$(setpci -s $port COMMAND)
echo "Command:" $cmd
echo "Command:" $(setpci -s $port COMMAND)
# clear SERR bit in command register
setpci -s $port COMMAND=$(printf "%04x" $((0x$cmd & ~0x0100)))
setpci -s $port COMMAND=0000:0100
ctrl=$(setpci -s $port CAP_EXP+8.w)
echo "Command:" $(setpci -s $port COMMAND)
echo "Device control:" $ctrl
echo "Device control:" $(setpci -s $port CAP_EXP+8.w)
# clear fatal error reporting enable bit in device control register
setpci -s $port CAP_EXP+8.w=$(printf "%04x" $((0x$ctrl & ~0x0004)))
setpci -s $port CAP_EXP+8.w=0000:0004
echo "Device control:" $(setpci -s $port CAP_EXP+8.w)

View File

@ -22,23 +22,14 @@ if [ ! -e "/sys/bus/pci/devices/$dev" ]; then
exit 1
fi
ctrl=$(setpci -s $dev CAP_EXP+8.w)
echo "Device control:" $(setpci -s $dev CAP_EXP+8.w)
if (($en > 0)); then
echo "Enabling ext tag on $dev..."
echo "Device control:" $ctrl
setpci -s $dev CAP_EXP+8.w=$(printf "%04x" $((0x$ctrl | 0x0100)))
setpci -s $dev CAP_EXP+8.w=0100:0100
else
echo "Disabling ext tag on $dev..."
echo "Device control:" $ctrl
setpci -s $dev CAP_EXP+8.w=$(printf "%04x" $((0x$ctrl & ~0x0100)))
setpci -s $dev CAP_EXP+8.w=0000:0100
fi
echo "Device control:" $(setpci -s $dev CAP_EXP+8.w)

View File

@ -29,13 +29,11 @@ echo 1 > "/sys/bus/pci/devices/$dev/remove"
echo "Performing hot reset of port $port..."
bc=$(setpci -s $port BRIDGE_CONTROL)
echo "Bridge control:" $(setpci -s $port BRIDGE_CONTROL)
echo "Bridge control:" $bc
setpci -s $port BRIDGE_CONTROL=$(printf "%04x" $((0x$bc | 0x40)))
sleep 0.01
setpci -s $port BRIDGE_CONTROL=$bc
setpci -s $port BRIDGE_CONTROL=40:40
sleep 0.5
setpci -s $port BRIDGE_CONTROL=00:40
sleep 0.5
echo "Rescanning bus..."

View File

@ -60,15 +60,7 @@ setpci -s $dev CAP_EXP+30.L=$lc2n
echo "Triggering link retraining..."
lc=$(setpci -s $dev CAP_EXP+10.L)
echo "Original link control:" $lc
lcn=$(printf "%08x" $((0x$lc | 0x20)))
echo "New link control:" $lcn
setpci -s $dev CAP_EXP+10.L=$lcn
setpci -s $dev CAP_EXP+10.L=20:20
sleep 0.1

View File

@ -117,7 +117,7 @@ async def run_test_read(dut, idle_inserter=None, backpressure_inserter=None):
tb.dut.enable.value = 1
for length in list(range(1, ram_byte_lanes+3))+list(range(128-4, 128+4))+[1024]:
for length in list(range(0, ram_byte_lanes+3))+list(range(128-4, 128+4))+[1024]:
for axi_offset in list(range(axi_byte_lanes+1))+list(range(4096-axi_byte_lanes, 4096)):
for ram_offset in range(ram_byte_lanes+1):
tb.log.info("length %d, axi_offset %d, ram_offset %d", length, axi_offset, ram_offset)

View File

@ -42,6 +42,8 @@ export PARAM_RAM_SEG_COUNT ?= 2
export PARAM_RAM_SEG_DATA_WIDTH ?= $(shell expr $(PARAM_AXI_DATA_WIDTH) \* 2 / $(PARAM_RAM_SEG_COUNT) )
export PARAM_RAM_SEG_BE_WIDTH ?= $(shell expr $(PARAM_RAM_SEG_DATA_WIDTH) / 8 )
export PARAM_RAM_SEG_ADDR_WIDTH ?= $(shell python -c "print($(PARAM_RAM_ADDR_WIDTH) - ($(PARAM_RAM_SEG_COUNT)*$(PARAM_RAM_SEG_BE_WIDTH)-1).bit_length())")
export PARAM_IMM_ENABLE ?= 1
export PARAM_IMM_WIDTH ?= $(PARAM_AXI_DATA_WIDTH)
export PARAM_LEN_WIDTH ?= 16
export PARAM_TAG_WIDTH ?= 8
export PARAM_OP_TABLE_SIZE ?= $(shell python -c "print(2**$(PARAM_AXI_ID_WIDTH))")
@ -60,6 +62,8 @@ ifeq ($(SIM), icarus)
COMPILE_ARGS += -P $(TOPLEVEL).RAM_SEG_DATA_WIDTH=$(PARAM_RAM_SEG_DATA_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).RAM_SEG_BE_WIDTH=$(PARAM_RAM_SEG_BE_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).RAM_SEG_ADDR_WIDTH=$(PARAM_RAM_SEG_ADDR_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).IMM_ENABLE=$(PARAM_IMM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).IMM_WIDTH=$(PARAM_IMM_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).LEN_WIDTH=$(PARAM_LEN_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).TAG_WIDTH=$(PARAM_TAG_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).OP_TABLE_SIZE=$(PARAM_OP_TABLE_SIZE)
@ -82,6 +86,8 @@ else ifeq ($(SIM), verilator)
COMPILE_ARGS += -GRAM_SEG_DATA_WIDTH=$(PARAM_RAM_SEG_DATA_WIDTH)
COMPILE_ARGS += -GRAM_SEG_BE_WIDTH=$(PARAM_RAM_SEG_BE_WIDTH)
COMPILE_ARGS += -GRAM_SEG_ADDR_WIDTH=$(PARAM_RAM_SEG_ADDR_WIDTH)
COMPILE_ARGS += -GIMM_WIDTH=$(PARAM_IMM_WIDTH)
COMPILE_ARGS += -GIMM_ENABLE=$(PARAM_IMM_ENABLE)
COMPILE_ARGS += -GLEN_WIDTH=$(PARAM_LEN_WIDTH)
COMPILE_ARGS += -GTAG_WIDTH=$(PARAM_TAG_WIDTH)
COMPILE_ARGS += -GOP_TABLE_SIZE=$(PARAM_OP_TABLE_SIZE)

View File

@ -50,7 +50,7 @@ except ImportError:
del sys.path[0]
DescBus, DescTransaction, DescSource, DescSink, DescMonitor = define_stream("Desc",
signals=["axi_addr", "ram_addr", "ram_sel", "len", "tag", "valid", "ready"]
signals=["axi_addr", "ram_addr", "ram_sel", "imm", "imm_en", "len", "tag", "valid", "ready"]
)
DescStatusBus, DescStatusTransaction, DescStatusSource, DescStatusSink, DescStatusMonitor = define_stream("DescStatus",
@ -118,7 +118,7 @@ async def run_test_write(dut, idle_inserter=None, backpressure_inserter=None):
tb.dut.enable.value = 1
for length in list(range(1, ram_byte_lanes+3))+list(range(128-4, 128+4))+[1024]:
for length in list(range(0, ram_byte_lanes+3))+list(range(128-4, 128+4))+[1024]:
# for axi_offset in axi_offsets:
for axi_offset in list(range(axi_byte_lanes+1))+list(range(4096-axi_byte_lanes, 4096)):
for ram_offset in range(ram_byte_lanes+1):
@ -153,6 +153,54 @@ async def run_test_write(dut, idle_inserter=None, backpressure_inserter=None):
await RisingEdge(dut.clk)
async def run_test_write_imm(dut, idle_inserter=None, backpressure_inserter=None):
tb = TB(dut)
axi_byte_lanes = tb.axi_ram.byte_lanes
tag_count = 2**len(tb.write_desc_source.bus.tag)
cur_tag = 1
tb.set_idle_generator(idle_inserter)
tb.set_backpressure_generator(backpressure_inserter)
await tb.cycle_reset()
tb.dut.enable.value = 1
for length in list(range(1, len(dut.s_axis_write_desc_imm) // 8)):
# for axi_offset in axi_offsets:
for axi_offset in list(range(axi_byte_lanes+1))+list(range(4096-axi_byte_lanes, 4096)):
tb.log.info("length %d, axi_offset %d", length, axi_offset)
axi_addr = axi_offset+0x1000
test_data = bytearray([x % 256 for x in range(length)])
imm = int.from_bytes(test_data, 'little')
tb.axi_ram.write(axi_addr-128, b'\xaa'*(len(test_data)+256))
tb.log.debug("Immediate: 0x%x", imm)
desc = DescTransaction(axi_addr=axi_addr, ram_addr=0, ram_sel=0, imm=imm, imm_en=1, len=len(test_data), tag=cur_tag)
await tb.write_desc_source.send(desc)
status = await tb.write_desc_status_sink.recv()
tb.log.info("status: %s", status)
assert int(status.tag) == cur_tag
assert int(status.error) == 0
tb.log.debug("%s", tb.axi_ram.hexdump_str((axi_addr & ~0xf)-16, (((axi_addr & 0xf)+length-1) & ~0xf)+48, prefix="AXI "))
assert tb.axi_ram.read(axi_addr-1, len(test_data)+2) == b'\xaa'+test_data+b'\xaa'
cur_tag = (cur_tag + 1) % tag_count
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
def cycle_pause():
return itertools.cycle([1, 1, 1, 0])
@ -164,6 +212,11 @@ if cocotb.SIM_NAME:
factory.add_option("backpressure_inserter", [None, cycle_pause])
factory.generate_tests()
factory = TestFactory(run_test_write_imm)
factory.add_option("idle_inserter", [None, cycle_pause])
factory.add_option("backpressure_inserter", [None, cycle_pause])
factory.generate_tests()
# cocotb-test
@ -201,6 +254,8 @@ def test_dma_if_axi_wr(request, axi_data_width):
parameters['RAM_SEG_DATA_WIDTH'] = ram_seg_data_width
parameters['RAM_SEG_BE_WIDTH'] = ram_seg_be_width
parameters['RAM_SEG_ADDR_WIDTH'] = ram_seg_addr_width
parameters['IMM_ENABLE'] = 1
parameters['IMM_WIDTH'] = parameters['AXI_DATA_WIDTH']
parameters['LEN_WIDTH'] = 16
parameters['TAG_WIDTH'] = 8
parameters['OP_TABLE_SIZE'] = 2**parameters['AXI_ID_WIDTH']

View File

@ -46,6 +46,8 @@ export PARAM_RAM_SEG_DATA_WIDTH ?= $(shell expr $(PARAM_TLP_SEG_COUNT) \* $(PARA
export PARAM_RAM_SEG_BE_WIDTH ?= $(shell expr $(PARAM_RAM_SEG_DATA_WIDTH) / 8 )
export PARAM_RAM_SEG_ADDR_WIDTH ?= $(shell python -c "print($(PARAM_RAM_ADDR_WIDTH) - ($(PARAM_RAM_SEG_COUNT)*$(PARAM_RAM_SEG_BE_WIDTH)-1).bit_length())")
export PARAM_PCIE_ADDR_WIDTH ?= 64
export PARAM_IMM_ENABLE ?= 1
export PARAM_IMM_WIDTH ?= $(shell expr $(PARAM_TLP_SEG_COUNT) \* $(PARAM_TLP_SEG_DATA_WIDTH) )
export PARAM_LEN_WIDTH ?= 20
export PARAM_TAG_WIDTH ?= 8
export PARAM_OP_TABLE_SIZE ?= $(shell echo "$$(( 1 << ($(PARAM_TX_SEQ_NUM_WIDTH)-1) ))" )
@ -70,6 +72,8 @@ ifeq ($(SIM), icarus)
COMPILE_ARGS += -P $(TOPLEVEL).RAM_SEG_BE_WIDTH=$(PARAM_RAM_SEG_BE_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).RAM_SEG_ADDR_WIDTH=$(PARAM_RAM_SEG_ADDR_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_ADDR_WIDTH=$(PARAM_PCIE_ADDR_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).IMM_ENABLE=$(PARAM_IMM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).IMM_WIDTH=$(PARAM_IMM_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).LEN_WIDTH=$(PARAM_LEN_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).TAG_WIDTH=$(PARAM_TAG_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).OP_TABLE_SIZE=$(PARAM_OP_TABLE_SIZE)
@ -98,6 +102,8 @@ else ifeq ($(SIM), verilator)
COMPILE_ARGS += -GRAM_SEG_BE_WIDTH=$(PARAM_RAM_SEG_BE_WIDTH)
COMPILE_ARGS += -GRAM_SEG_ADDR_WIDTH=$(PARAM_RAM_SEG_ADDR_WIDTH)
COMPILE_ARGS += -GPCIE_ADDR_WIDTH=$(PARAM_PCIE_ADDR_WIDTH)
COMPILE_ARGS += -GIMM_WIDTH=$(PARAM_IMM_WIDTH)
COMPILE_ARGS += -GIMM_ENABLE=$(PARAM_IMM_ENABLE)
COMPILE_ARGS += -GLEN_WIDTH=$(PARAM_LEN_WIDTH)
COMPILE_ARGS += -GTAG_WIDTH=$(PARAM_TAG_WIDTH)
COMPILE_ARGS += -GOP_TABLE_SIZE=$(PARAM_OP_TABLE_SIZE)

View File

@ -53,7 +53,7 @@ except ImportError:
del sys.path[0]
DescBus, DescTransaction, DescSource, DescSink, DescMonitor = define_stream("Desc",
signals=["pcie_addr", "ram_addr", "ram_sel", "len", "tag", "valid", "ready"]
signals=["pcie_addr", "ram_addr", "ram_sel", "imm", "imm_en", "len", "tag", "valid", "ready"]
)
DescStatusBus, DescStatusTransaction, DescStatusSource, DescStatusSink, DescStatusMonitor = define_stream("DescStatus",
@ -184,6 +184,64 @@ async def run_test_write(dut, idle_inserter=None, backpressure_inserter=None):
await RisingEdge(dut.clk)
async def run_test_write_imm(dut, idle_inserter=None, backpressure_inserter=None):
tb = TB(dut)
if os.getenv("PCIE_OFFSET") is None:
pcie_offsets = list(range(4))+list(range(4096-4, 4096))
else:
pcie_offsets = [int(os.getenv("PCIE_OFFSET"))]
byte_lanes = tb.dma_ram.byte_lanes
tag_count = 2**len(tb.write_desc_source.bus.tag)
cur_tag = 1
tb.set_idle_generator(idle_inserter)
tb.set_backpressure_generator(backpressure_inserter)
await tb.cycle_reset()
await tb.rc.enumerate(enable_bus_mastering=True)
mem = tb.rc.mem_pool.alloc_region(16*1024*1024)
mem_base = mem.get_absolute_address(0)
tb.dut.enable <= 1
for length in list(range(0, len(dut.s_axis_write_desc_imm) // 8 + 1)):
for pcie_offset in pcie_offsets:
tb.log.info("length %d, pcie_offset %d", length, pcie_offset)
pcie_addr = pcie_offset+0x1000
test_data = bytearray([x % 256 for x in range(length)])
imm = int.from_bytes(test_data, 'little')
mem[pcie_addr-128:pcie_addr-128+len(test_data)+256] = b'\xaa'*(len(test_data)+256)
tb.log.debug("Immediate: 0x%x", imm)
desc = DescTransaction(pcie_addr=mem_base+pcie_addr, ram_addr=0, ram_sel=0, imm=imm, imm_en=1, len=len(test_data), tag=cur_tag)
await tb.write_desc_source.send(desc)
status = await tb.write_desc_status_sink.recv()
await Timer(100 + (length // byte_lanes), 'ns')
tb.log.info("status: %s", status)
assert int(status.tag) == cur_tag
assert int(status.error) == 0
tb.log.debug("%s", hexdump_str(mem, (pcie_addr & ~0xf)-16, (((pcie_addr & 0xf)+length-1) & ~0xf)+48, prefix="PCIe "))
assert mem[pcie_addr-1:pcie_addr+len(test_data)+1] == b'\xaa'+test_data+b'\xaa'
cur_tag = (cur_tag + 1) % tag_count
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
def cycle_pause():
return itertools.cycle([1, 1, 1, 0])
@ -194,6 +252,10 @@ if cocotb.SIM_NAME:
factory.add_option(("idle_inserter", "backpressure_inserter"), [(None, None), (cycle_pause, cycle_pause)])
factory.generate_tests()
factory = TestFactory(run_test_write_imm)
factory.add_option(("idle_inserter", "backpressure_inserter"), [(None, None), (cycle_pause, cycle_pause)])
factory.generate_tests()
# cocotb-test
@ -241,6 +303,8 @@ def test_dma_if_pcie_wr(request, pcie_data_width, pcie_offset):
parameters['RAM_SEG_BE_WIDTH'] = ram_seg_be_width
parameters['RAM_SEG_ADDR_WIDTH'] = ram_seg_addr_width
parameters['PCIE_ADDR_WIDTH'] = 64
parameters['IMM_ENABLE'] = 1
parameters['IMM_WIDTH'] = parameters['TLP_SEG_COUNT'] * parameters['TLP_SEG_DATA_WIDTH']
parameters['LEN_WIDTH'] = 20
parameters['TAG_WIDTH'] = 8
parameters['OP_TABLE_SIZE'] = 2**(parameters['TX_SEQ_NUM_WIDTH']-1)