Skip to content

Instantly share code, notes, and snippets.

@cathalmccabe
Created March 16, 2017 08:12
Show Gist options
  • Save cathalmccabe/8438990760122d176e8316386af4049c to your computer and use it in GitHub Desktop.
Save cathalmccabe/8438990760122d176e8316386af4049c to your computer and use it in GitHub Desktop.
PYNQ DMA FIFO loopback example
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"# DMA to streamed interfaces example\n",
"\n",
"Overlay consists of two DMAs and an AXI Stream FIFO (input and output AXI stream interfaces). The FIFO represents an accelerator.\n",
"\n",
"One DMA with read channel enabled is connected from DDR to IP input stream. (Reads from DDR, sends to AXI stream)\n",
"The other DMA has a write channel enabled and is connected to IP output stream to DDR. (received from AXI stream, writes to DDR)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"from pynq import Overlay\n",
"ol = Overlay(\"pynq_tutorial.bit\")\n",
"ol.download()"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Check addresses of IP in the overlay"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"data": {
"text/plain": [
"{'SEG_axi_dma_from_pl_to_ps_Reg': [1078001664, 65536, None],\n",
" 'SEG_axi_dma_from_ps_to_pl_Reg': [1077936128, 65536, None],\n",
" 'SEG_btns_gpio_Reg': [1092681728, 65536, None],\n",
" 'SEG_mb_bram_ctrl_1_Mem0': [1073741824, 65536, None],\n",
" 'SEG_mb_bram_ctrl_2_Mem0': [1107296256, 65536, None],\n",
" 'SEG_rgbleds_gpio_Reg': [1092747264, 65536, None],\n",
" 'SEG_swsleds_gpio_Reg': [1092616192, 65536, None],\n",
" 'SEG_system_interrupts_Reg': [1098907648, 65536, None]}"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ol.ip_dict"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Create DMA instances"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"from pynq.drivers import DMA\n",
"\n",
"# dma_read reads from DDR and sends to Stream\n",
"dma_read_addr = ol.ip_dict[\"SEG_axi_dma_from_ps_to_pl_Reg\"][0]\n",
"dma_read = DMA(dma_read_addr, 0) # 'DMA_TO_DEV'\n",
"\n",
"dma_write_addr = ol.ip_dict[\"SEG_axi_dma_from_pl_to_ps_Reg\"][0]\n",
"dma_write = DMA(dma_write_addr, 1) # 'DMA_FROM_DEV'"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"source": [
"## Debug DMA\n",
"\n",
"Create some debug functions to print control and status info from DMAs"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"from pynq import MMIO\n",
"dma_read_s = MMIO(dma_read_addr, 128)\n",
"dma_write_s = MMIO(dma_write_addr, 128)\n",
"\n",
"def print_dma_status():\n",
"\n",
" print(\"Read from Memory, Write to FIFO\")\n",
"\n",
" print(\"MM 2 Stream Ctrl : \" + format(dma_read_s.read(0x0), '02x'))\n",
" print(\"Binary : \" + format(dma_read_s.read(0x0), '0b'))\n",
" print(\"MM 2 Stream Status : \" + format(dma_read_s.read(0x4), '02x'))\n",
" print(\"Binary : \" + format(dma_read_s.read(0x4), '0b'))\n",
" \n",
" print(\"\\nRead from FIFO, Write to Memory\")\n",
" \n",
" print(\"Stream to MM Ctrl : \" + format(dma_write_s.read(0x30), '02x'))\n",
" print(\"Binary : \" + format(dma_write_s.read(0x30), '0b'))\n",
" print(\"Stream to MM Status : \" + format(dma_write_s.read(0x34), '02x'))\n",
" print(\"Binary : \" + format(dma_write_s.read(0x34), '0b'))\n",
"\n",
"def dma_reset_irq():\n",
" control = dma_read_s.read(0x4)\n",
" control = control | 0x1000\n",
" dma_read_s.write(0x4, control)\n",
" \n",
" control = dma_write_s.read(0x34)\n",
" control = control | 0x1000\n",
" dma_write_s.write(0x34, control)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Read from Memory, Write to FIFO\n",
"MM 2 Stream Ctrl : 10002\n",
"Binary : 10000000000000010\n",
"MM 2 Stream Status : 01\n",
"Binary : 1\n",
"\n",
"Read from FIFO, Write to Memory\n",
"Stream to MM Ctrl : 10002\n",
"Binary : 10000000000000010\n",
"Stream to MM Status : 01\n",
"Binary : 1\n"
]
}
],
"source": [
"print_dma_status()\n",
"# Control 10002\n",
"# (1) : Alwyas 1\n",
"# (16): IRQ threshold 1\n",
"# Status 01\n",
"# (0) : 1 = Halted"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"# Read DMA\n",
"Read from memory, write to FIFO\n",
"\n",
"## Create the DMA buffer "
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"dma_read.create_buf(1024)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Get the buffer pointer\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<cdata 'unsigned int *' 0x36fab000>\n"
]
}
],
"source": [
"read_buffer = dma_read.get_buf(32)\n",
"print(read_buffer)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Write some test data to the buffer\n",
"This data will be transferred by the DMA to the FIFO. "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"transfer_size = 10\n",
"for i in range(transfer_size):\n",
" read_buffer[i] = i+0xcafe0000;"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Print data\n",
"Check the contents of the buffer"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"cafe0000\n",
"cafe0001\n",
"cafe0002\n",
"cafe0003\n",
"cafe0004\n",
"cafe0005\n",
"cafe0006\n",
"cafe0007\n",
"cafe0008\n",
"cafe0009\n"
]
}
],
"source": [
"for i in range(transfer_size):\n",
" print(format(read_buffer[i], '02x'))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Carry out DMA transfer from buffer in DDR to FIFO"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"#0 DMA_TO_DEV\n",
"dma_read.transfer(transfer_size*4, 0)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Read from Memory, Write to FIFO\n",
"MM 2 Stream Ctrl : 10003\n",
"Binary : 10000000000000011\n",
"MM 2 Stream Status : 1002\n",
"Binary : 1000000000010\n",
"\n",
"Read from FIFO, Write to Memory\n",
"Stream to MM Ctrl : 10002\n",
"Binary : 10000000000000010\n",
"Stream to MM Status : 01\n",
"Binary : 1\n"
]
}
],
"source": [
"print_dma_status()\n",
"# Control : 10003\n",
"# (0) Run/Stop :1 = Run start DMA ops. Halted bit -> 0\n",
"# (1) : Always 1\n",
"# (16) IRQ threshold\n",
"# Status \n",
"# (0) = 0 ; Halted\n",
"# (1) = 1 ; idle\n",
"# (12) Interrupt on complete"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"# Write DMA\n",
"Read from FIFO stream, write to MM memory\n",
"\n",
"\n",
"## Create a buffer"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"dma_write.create_buf(1024)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Get pointer to buffer"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"write_buffer = dma_write.get_buf(32)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"source": [
"## Check buffer before DMA transfer"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"00\n",
"00\n",
"00\n",
"00\n",
"00\n",
"00\n",
"00\n",
"00\n",
"00\n",
"00\n"
]
}
],
"source": [
"for i in range(transfer_size):\n",
" print(format(write_buffer[i], '02x'))"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"source": [
"## Carry out DMA transfer from FIFO to buffer in DDR"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"#1 DEV_TO_DMA\n",
"dma_write.transfer(transfer_size*4, 1)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Read from Memory, Write to FIFO\n",
"MM 2 Stream Ctrl : 10003\n",
"Binary : 10000000000000011\n",
"MM 2 Stream Status : 1002\n",
"Binary : 1000000000010\n",
"\n",
"Read from FIFO, Write to Memory\n",
"Stream to MM Ctrl : 10003\n",
"Binary : 10000000000000011\n",
"Stream to MM Status : 1002\n",
"Binary : 1000000000010\n"
]
}
],
"source": [
"print_dma_status()"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Check contents of buffer in DDR to confirm transfer was successful"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"cafe0000\n",
"cafe0001\n",
"cafe0002\n",
"cafe0003\n",
"cafe0004\n",
"cafe0005\n",
"cafe0006\n",
"cafe0007\n",
"cafe0008\n",
"cafe0009\n"
]
}
],
"source": [
"for i in range(transfer_size):\n",
" print(format(write_buffer[i], '02x'))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment