host: add Etherbone driver
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 16 Feb 2015 22:11:22 +0000 (23:11 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 17 Feb 2015 00:09:53 +0000 (01:09 +0100)
README
litescope/host/driver.py

diff --git a/README b/README
index 3dc94529a03822a212157b4d54a09dbe17feeaf8..216f4a047562f16540d0f7c39a915176971a7221 100644 (file)
--- a/README
+++ b/README
@@ -52,6 +52,9 @@ external Rx/Tx pins to be ready to debug or control all your Wishbone peripheral
   - Subsampling
   - Storage qualifier
   - Data storage in block rams
+- Bridges:
+  - UART2Wishbone
+  - Ethernet2Wishbone ("Etherbone")
 
 [> Possible improvements
 -------------------------
@@ -60,7 +63,6 @@ external Rx/Tx pins to be ready to debug or control all your Wishbone peripheral
 - add signals injection/generation
 - add storage in DRAM
 - add storage in HDD with LiteSATA core (to be released soon!)
-- add Ethernet Wishbone bridge
 - add PCIe Wishbone bridge with LitePCIe (to be released soon!)
 - ... See below Support and consulting :)
 
index 904b9fef13822edadc4391fe06f11b6dd276bbd1..0a49fe49dab2110b7d5c164cb86b478254e58e07 100644 (file)
@@ -3,12 +3,19 @@ import time
 import sys
 import string
 import serial
+import socket
 from struct import *
 from migen.fhdl.structure import *
 from litescope.host.reg import *
 from litescope.host.dump import *
 from litescope.host.truthtable import *
 
+# XXX FIXME
+try:
+       from liteeth.test.model.etherbone import *
+except:
+       pass
+
 def write_b(uart, data):
        uart.write(pack('B',data))
 
@@ -93,6 +100,84 @@ class LiteScopeUART2WBDriver:
                        if self.debug:
                                print("WR %08X @ %08X" %(data, (addr * 4)))
 
+class LiteScopeEtherboneDriver:
+       def __init__(self, ip_address, udp_port=20000, addrmap=None, busword=8, debug=False):
+               self.ip_address = ip_address
+               self.udp_port = udp_port
+               self.debug = debug
+
+               self.tx_sock = None
+               self.rx_sock = None
+               self.regs = build_map(addrmap, busword, self.read, self.write)
+
+       def open(self):
+               self.tx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+               self.rx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+               self.rx_sock.bind(("", self.udp_port))
+
+       def close(self):
+               pass
+
+       def read(self, addr, burst_length=1):
+               reads_addrs = [addr+4*j for j in range(burst_length)]
+               reads = EtherboneReads(base_ret_addr=0x1000, addrs=reads_addrs)
+               record = EtherboneRecord()
+               record.writes = None
+               record.reads = reads
+               record.bca = 0
+               record.rca = 0
+               record.rff = 0
+               record.cyc = 0
+               record.wca = 0
+               record.wff = 0
+               record.byte_enable = 0xf
+               record.wcount = 0
+               record.rcount = len(reads_addrs)
+
+               packet = EtherbonePacket()
+               packet.records = [record]
+               packet.encode()
+               self.tx_sock.sendto(bytes(packet), (self.ip_address, self.udp_port))
+
+               datas, addrs = self.rx_sock.recvfrom(8192)
+               packet = EtherbonePacket(datas)
+               packet.decode()
+               values = packet.records.pop().writes.get_datas()
+               if self.debug:
+                       for i, val in enumerate(values):
+                               print("RD %08X @ %08X" %(val, addr + 4*i))
+               if burst_length == 1:
+                       return values[0]
+               else:
+                       return values
+
+       def write(self, addr, datas):
+               if not isinstance(datas, list):
+                       datas = [datas]
+               writes_datas = [d for d in datas]
+               writes = EtherboneWrites(base_addr=addr, datas=writes_datas)
+               record = EtherboneRecord()
+               record.writes = writes
+               record.reads = None
+               record.bca = 0
+               record.rca = 0
+               record.rff = 0
+               record.cyc = 0
+               record.wca = 0
+               record.wff = 0
+               record.byte_enable = 0xf
+               record.wcount = len(writes_datas)
+               record.rcount = 0
+
+               packet = EtherbonePacket()
+               packet.records = [record]
+               packet.encode()
+               self.tx_sock.sendto(bytes(packet), (self.ip_address, self.udp_port))
+
+               if self.debug:
+                       for i, data in enumerate(datas):
+                               print("WR %08X @ %08X" %(data, addr + 4*i))
+
 class LiteScopeIODriver():
        def __init__(self, regs, name):
                self.regs = regs