from migen.actorlib.packet import *
from migen.bank.description import *
+class Port:
+ def connect(self, port):
+ r = [
+ Record.connect(self.source, port.sink),
+ Record.connect(port.source, self.sink)
+ ]
+ return r
+
eth_mtu = 1532
eth_min_len = 46
eth_interpacket_gap = 12
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from misoclib.com.liteeth.mac import LiteEthMAC
from misoclib.com.liteeth.core.arp import LiteEthARP
from misoclib.com.liteeth.core.ip import LiteEthIP
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-from misoclib.com.liteeth.generic.depacketizer import LiteEthDepacketizer
-from misoclib.com.liteeth.generic.packetizer import LiteEthPacketizer
_arp_table_layout = [
("reply", 1),
]
-class LiteEthARPPacketizer(LiteEthPacketizer):
+class LiteEthARPPacketizer(Packetizer):
def __init__(self):
- LiteEthPacketizer.__init__(self,
+ Packetizer.__init__(self,
eth_arp_description(8),
eth_mac_description(8),
arp_header)
)
-class LiteEthARPDepacketizer(LiteEthDepacketizer):
+class LiteEthARPDepacketizer(Depacketizer):
def __init__(self):
- LiteEthDepacketizer.__init__(self,
+ Depacketizer.__init__(self,
eth_mac_description(8),
eth_arp_description(8),
arp_header)
+++ /dev/null
-from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-from misoclib.com.liteeth.core.etherbone.packet import *
-from misoclib.com.liteeth.core.etherbone.probe import *
-from misoclib.com.liteeth.core.etherbone.record import *
-from misoclib.com.liteeth.core.etherbone.wishbone import *
-
-
-class LiteEthEtherbone(Module):
- def __init__(self, udp, udp_port):
- # decode/encode etherbone packets
- self.submodules.packet = packet = LiteEthEtherbonePacket(udp, udp_port)
-
- # packets can be probe (etherbone discovering) or records with
- # writes and reads
- self.submodules.probe = probe = LiteEthEtherboneProbe()
- self.submodules.record = record = LiteEthEtherboneRecord()
-
- # arbitrate/dispatch probe/records packets
- dispatcher = Dispatcher(packet.source, [probe.sink, record.sink])
- self.comb += dispatcher.sel.eq(~packet.source.pf)
- arbiter = Arbiter([probe.source, record.source], packet.sink)
- self.submodules += dispatcher, arbiter
-
- # create mmap ŵishbone master
- self.submodules.master = master = LiteEthEtherboneWishboneMaster()
- self.comb += [
- Record.connect(record.receiver.source, master.sink),
- Record.connect(master.source, record.sender.sink)
- ]
+++ /dev/null
---[[---------------
-LuaBit v0.4
--------------------
-a bitwise operation lib for lua.
-
-http://luaforge.net/projects/bit/
-
-How to use:
--------------------
- bit.bnot(n) -- bitwise not (~n)
- bit.band(m, n) -- bitwise and (m & n)
- bit.bor(m, n) -- bitwise or (m | n)
- bit.bxor(m, n) -- bitwise xor (m ^ n)
- bit.brshift(n, bits) -- right shift (n >> bits)
- bit.blshift(n, bits) -- left shift (n << bits)
- bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>)
-
-Please note that bit.brshift and bit.blshift only support number within
-32 bits.
-
-2 utility functions are provided too:
- bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence)
- -- high bits first
- bit.tonumb(bit_tbl) -- convert a bit table into a number
--------------------
-
-Under the MIT license.
-
-copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com)
---]]---------------
-
-do
-
-------------------------
--- bit lib implementions
-
-local function check_int(n)
- -- checking not float
- if(n - math.floor(n) > 0) then
- error("trying to use bitwise operation on non-integer!")
- end
-end
-
-local function to_bits(n)
- check_int(n)
- if(n < 0) then
- -- negative
- return to_bits(bit.bnot(math.abs(n)) + 1)
- end
- -- to bits table
- local tbl = {}
- local cnt = 1
- while (n > 0) do
- local last = math.mod(n,2)
- if(last == 1) then
- tbl[cnt] = 1
- else
- tbl[cnt] = 0
- end
- n = (n-last)/2
- cnt = cnt + 1
- end
-
- return tbl
-end
-
-local function tbl_to_number(tbl)
- local n = table.getn(tbl)
-
- local rslt = 0
- local power = 1
- for i = 1, n do
- rslt = rslt + tbl[i]*power
- power = power*2
- end
-
- return rslt
-end
-
-local function expand(tbl_m, tbl_n)
- local big = {}
- local small = {}
- if(table.getn(tbl_m) > table.getn(tbl_n)) then
- big = tbl_m
- small = tbl_n
- else
- big = tbl_n
- small = tbl_m
- end
- -- expand small
- for i = table.getn(small) + 1, table.getn(big) do
- small[i] = 0
- end
-
-end
-
-local function bit_or(m, n)
- local tbl_m = to_bits(m)
- local tbl_n = to_bits(n)
- expand(tbl_m, tbl_n)
-
- local tbl = {}
- local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
- for i = 1, rslt do
- if(tbl_m[i]== 0 and tbl_n[i] == 0) then
- tbl[i] = 0
- else
- tbl[i] = 1
- end
- end
-
- return tbl_to_number(tbl)
-end
-
-local function bit_and(m, n)
- local tbl_m = to_bits(m)
- local tbl_n = to_bits(n)
- expand(tbl_m, tbl_n)
-
- local tbl = {}
- local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
- for i = 1, rslt do
- if(tbl_m[i]== 0 or tbl_n[i] == 0) then
- tbl[i] = 0
- else
- tbl[i] = 1
- end
- end
-
- return tbl_to_number(tbl)
-end
-
-local function bit_not(n)
-
- local tbl = to_bits(n)
- local size = math.max(table.getn(tbl), 32)
- for i = 1, size do
- if(tbl[i] == 1) then
- tbl[i] = 0
- else
- tbl[i] = 1
- end
- end
- return tbl_to_number(tbl)
-end
-
-local function bit_xor(m, n)
- local tbl_m = to_bits(m)
- local tbl_n = to_bits(n)
- expand(tbl_m, tbl_n)
-
- local tbl = {}
- local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
- for i = 1, rslt do
- if(tbl_m[i] ~= tbl_n[i]) then
- tbl[i] = 1
- else
- tbl[i] = 0
- end
- end
-
- --table.foreach(tbl, print)
-
- return tbl_to_number(tbl)
-end
-
-local function bit_rshift(n, bits)
- check_int(n)
-
- local high_bit = 0
- if(n < 0) then
- -- negative
- n = bit_not(math.abs(n)) + 1
- high_bit = 2147483648 -- 0x80000000
- end
-
- for i=1, bits do
- n = n/2
- n = bit_or(math.floor(n), high_bit)
- end
- return math.floor(n)
-end
-
--- logic rightshift assures zero filling shift
-local function bit_logic_rshift(n, bits)
- check_int(n)
- if(n < 0) then
- -- negative
- n = bit_not(math.abs(n)) + 1
- end
- for i=1, bits do
- n = n/2
- end
- return math.floor(n)
-end
-
-local function bit_lshift(n, bits)
- check_int(n)
-
- if(n < 0) then
- -- negative
- n = bit_not(math.abs(n)) + 1
- end
-
- for i=1, bits do
- n = n*2
- end
- return bit_and(n, 4294967295) -- 0xFFFFFFFF
-end
-
-local function bit_xor2(m, n)
- local rhs = bit_or(bit_not(m), bit_not(n))
- local lhs = bit_or(m, n)
- local rslt = bit_and(lhs, rhs)
- return rslt
-end
-
---------------------
--- bit lib interface
-
-bit = {
- -- bit operations
- bnot = bit_not,
- band = bit_and,
- bor = bit_or,
- bxor = bit_xor,
- brshift = bit_rshift,
- blshift = bit_lshift,
- bxor2 = bit_xor2,
- blogic_rshift = bit_logic_rshift,
-
- -- utility func
- tobits = to_bits,
- tonumb = tbl_to_number,
-}
-
-end
-
---[[
-for i = 1, 100 do
- for j = 1, 100 do
- if(bit.bxor(i, j) ~= bit.bxor2(i, j)) then
- error("bit.xor failed.")
- end
- end
-end
---]]
-
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
--- Etherbone Dissector
--- Copyright 2013 OHWR.org
--- Copyright 2015 EnjoyDigital (global clean up)
-
-local bit = require("bit")
-
-local VALS_BOOL = {[0] = "False", [1] = "True"}
-local VALS_RES = {[0] = "not set", [1] = "set, bad data?"}
-local VALS_SIZE = {
-[0x00] = "Bad Value",
-[0x01] = "8 bit",
-[0x02] = "16 bit",
-[0x03] = "16,8 bit",
-[0x04] = "32 bit",
-[0x05] = "32,8 bit",
-[0x06] = "32,16 bit",
-[0x07] = "32,16,8 bit",
-[0x08] = "64 bit",
-[0x09] = "64,8 bit",
-[0x0A] = "64,16 bit",
-[0x0B] = "64,16,8 bit",
-[0x0C] = "64,32 bit",
-[0x0D] = "64,32,8 bit",
-[0x0E] = "64,32,16 bit",
-[0x0F] = "64,32,16,8 bit",
-}
-
-function num2hex(num)
- local hexstr = '0123456789abcdef'
- local s = ''
- while num > 0 do
- local mod = math.fmod(num, 16)
- s = string.sub(hexstr, mod+1, mod+1) .. s
- num = math.floor(num / 16)
- end
- if s == '' then s = '0' end
- return s
-end
-
-function max(a, b)
- if a > b then
- return a
- else
- return b
- end
-end
-
--- declare protocol
-proto_eb = Proto("eb", "Etherbone")
-
--- declare fields
-local eb = proto_eb.fields
-eb.hdr = ProtoField.uint32("eb.hdr", "Header", base.HEX)
-eb.rec = ProtoField.bytes("eb.rec", "Record ", base.HEX)
-
-eb.hdr_magic = ProtoField.uint16("eb.hdr.magic", "Magic ", base.HEX, nil, 0xFFFF)
-eb.hdr_ver = ProtoField.uint16("eb.hdr.ver", "Version ", base.DEC, nil, 0xF000)
-eb.hdr_noreads = ProtoField.uint16("eb.hdr.noreads", "No Reads ", base.DEC, VALS_BOOL, 0x0400)
-eb.hdr_proberep = ProtoField.uint16("eb.hdr.proberes", "Probe Reply ", base.DEC, VALS_BOOL, 0x0200)
-eb.hdr_probereq = ProtoField.uint16("eb.hdr.probereq", "Probe Flag ", base.DEC, VALS_BOOL, 0x0100)
-eb.hdr_adrs = ProtoField.uint16("eb.hdr.adrw", "Address Width ", base.DEC, VALS_SIZE , 0x00F0)
-eb.hdr_ports = ProtoField.uint16("eb.hdr.portw", "Port Width ", base.DEC, VALS_SIZE , 0x000F)
-
-eb.rec_hdr = ProtoField.uint32("eb.rec.hdr", "Header ", base.HEX)
-eb.rec_writes = ProtoField.bytes("eb.rec.writes", "Writes ", base.HEX)
-eb.rec_reads = ProtoField.bytes("eb.rec.reads", "Reads ", base.HEX)
-
-eb.rec_hdr_flags = ProtoField.uint8("eb.rec.hdr.flags", "Flags ", base.HEX)
-eb.rec_hdr_select = ProtoField.uint8("eb.rec.hdr.select", "Select ", base.HEX)
-eb.rec_hdr_wr = ProtoField.uint8("eb.rec.hdr.wr", "Writes ", base.DEC)
-eb.rec_hdr_rd = ProtoField.uint8("eb.rec.hdr.rd", "Reads ", base.DEC)
-
-eb.rec_hdr_flags_adrcfg = ProtoField.uint8("eb.rec.hdr.flags.adrcfg", "ReplyToCfgSpace ", base.DEC, VALS_BOOL, 0x80)
-eb.rec_hdr_flags_rbacfg = ProtoField.uint8("eb.rec.hdr.adrcfg", "ReadFromCfgSpace ", base.DEC, VALS_BOOL, 0x40)
-eb.rec_hdr_flags_rdfifo = ProtoField.uint8("eb.rec.hdr.adrcfg", "ReadFIFO ", base.DEC, VALS_BOOL, 0x20)
-eb.rec_hdr_flags_dropcyc= ProtoField.uint8("eb.rec.hdr.adrcfg", "DropCycle ", base.DEC, VALS_BOOL, 0x08)
-eb.rec_hdr_flags_wbacfg = ProtoField.uint8("eb.rec.hdr.adrcfg", "WriteToCfgSpace ", base.DEC, VALS_BOOL, 0x04)
-eb.rec_hdr_flags_wrfifo = ProtoField.uint8("eb.rec.hdr.adrcfg", "WriteFIFO ", base.DEC, VALS_BOOL, 0x02)
-
-eb.rec_wrsadr8 = ProtoField.uint8("eb.rec.wrsadr8", "BaseAddr8 ", base.HEX)
-eb.rec_wrsadr16 = ProtoField.uint16("eb.rec.wrsadr16", "BaseAddr16 ", base.HEX)
-eb.rec_wrsadr32 = ProtoField.uint32("eb.rec.wrsadr32", "BaseAddr32 ", base.HEX)
-eb.rec_wrsadr64 = ProtoField.uint64("eb.rec.wrsadr64", "BaseAddr64 ", base.HEX)
-eb.rec_wrdata8 = ProtoField.uint8("eb.rec.wrdata8", "Value8 ", base.HEX)
-eb.rec_wrdata16 = ProtoField.uint16("eb.rec.wrdata16", "Value16 ", base.HEX)
-eb.rec_wrdata32 = ProtoField.uint32("eb.rec.wrdata32", "Value32 ", base.HEX)
-eb.rec_wrdata64 = ProtoField.uint64("eb.rec.wrdata64", "Value64 ", base.HEX)
-
-eb.rec_rdbadr8 = ProtoField.uint8("eb.rec.rdbadr8", "ReplyAddr8 ", base.HEX)
-eb.rec_rdbadr16 = ProtoField.uint16("eb.rec.rdbadr16", "ReplyAddr16 ", base.HEX)
-eb.rec_rdbadr32 = ProtoField.uint32("eb.rec.rdbadr32", "ReplyAddr32 ", base.HEX)
-eb.rec_rdbadr64 = ProtoField.uint64("eb.rec.rdbadr64", "ReplyAddr64 ", base.HEX)
-eb.rec_rddata8 = ProtoField.uint8("eb.rec.rddata8", "Address8 ", base.HEX)
-eb.rec_rddata16 = ProtoField.uint16("eb.rec.rddata16", "Address16 ", base.HEX)
-eb.rec_rddata32 = ProtoField.uint32("eb.rec.rddata32", "Address32 ", base.HEX)
-eb.rec_rddata64 = ProtoField.uint64("eb.rec.rddata64", "Address64 ", base.HEX)
-
--- define the dissector
-function proto_eb.dissector(buf, pinfo, tree)
- if (buf:len() < 4) then
- return 0 -- too short, go to default protocol
- end
-
- local mylen = buf:len()
- pinfo.cols.protocol = "eb"
-
- -- add packet to the tree root, fields will be added to subtree
- local t = tree:add( proto_eb, buf(0, mylen) )
- local t_hdr = t:add( eb.hdr, buf(0,4) )
-
- local magic = num2hex(tonumber(buf(0,2):uint()))
- if(magic == "4e6f") then
-
- t_hdr:add( eb.hdr_magic, buf(0,2)) -- magic
- t_hdr:add( eb.hdr_ver, buf(2,2)) -- version
- t_hdr:add( eb.hdr_noreads, buf(2,2)) -- no reads
- t_hdr:add( eb.hdr_proberep, buf(2,2)) -- probe response
- t_hdr:add( eb.hdr_probereq, buf(2,2)) -- probe request
-
- t_hdr:add( eb.hdr_adrs, buf(2,2)) -- supported addr size
- t_hdr:add( eb.hdr_ports, buf(2,2)) -- supported port size
-
- local probe = tonumber(buf(2,1):uint()) % 4
- if (probe == 0) then
- local widths = tonumber(buf(3,1):uint())
- local data_width = widths % 16
- local addr_width = (widths - data_width) / 16
- local alignment = max(max(addr_width, data_width), 2)
-
- local record_alignment = max(alignment, 4)
- local offset = max(alignment, 4)
-
- local recordcnt = 0
- while (offset < buf:len()) do
- local wr = tonumber(buf(offset+2,1):uint())
- local rd = tonumber(buf(offset+3,1):uint())
-
- local rdadr = 0
- local wradr = 0
- if(rd > 0) then
- rdadr = 1
- end
- if(wr > 0) then
- wradr = 1
- end
-
- if((wr == 0) and (rd == 0)) then
- offset = offset + record_alignment
- else
- local t_rec = t:add( "Record "..tostring(recordcnt).." (W"..tostring(wr).." R"..tostring(rd)..")", buf(offset, (record_alignment+(rd+wr+rdadr+wradr)*alignment)))
- recordcnt = recordcnt + 1
-
- local t_rec_hdr = t_rec:add( eb.rec_hdr, buf(offset,4))
- local t_rec_hdr_flags = t_rec_hdr:add( eb.rec_hdr_flags, buf(offset,1))
- t_rec_hdr_flags:add( eb.rec_hdr_flags_adrcfg, buf(offset,1))
- t_rec_hdr_flags:add( eb.rec_hdr_flags_rbacfg, buf(offset,1))
- t_rec_hdr_flags:add( eb.rec_hdr_flags_rdfifo, buf(offset,1))
- t_rec_hdr_flags:add( eb.rec_hdr_flags_dropcyc , buf(offset,1))
- t_rec_hdr_flags:add( eb.rec_hdr_flags_wbacfg , buf(offset,1))
- t_rec_hdr_flags:add( eb.rec_hdr_flags_wrfifo, buf(offset,1))
- t_rec_hdr:add( eb.rec_hdr_select, buf(offset+1,1))
- t_rec_hdr:add( eb.rec_hdr_wr, buf(offset+2,1))
- t_rec_hdr:add( eb.rec_hdr_rd, buf(offset+3,1))
- offset = offset + record_alignment
- local tmp_offset
-
- if(wr > 0) then
- local t_writes = t_rec:add( eb.rec_writes, buf(offset,(1+wr)*alignment))
-
- if addr_width==1 then t_writes:add(eb.rec_wrsadr8, buf(offset+alignment-1, 1))
- elseif addr_width==2 then t_writes:add(eb.rec_wrsadr16, buf(offset+alignment-2, 2))
- elseif addr_width==4 then t_writes:add(eb.rec_wrsadr32, buf(offset+alignment-4, 4))
- elseif addr_width==8 then t_writes:add(eb.rec_wrsadr64, buf(offset+alignment-8, 8))
- end
- offset = offset + alignment
-
- tmp_offset = offset
- while (tmp_offset < offset+wr*alignment) do
- if data_width==1 then t_writes:add( eb.rec_wrdata8, buf(tmp_offset+alignment-1, 1))
- elseif data_width==2 then t_writes:add( eb.rec_wrdata16, buf(tmp_offset+alignment-2, 2))
- elseif data_width==4 then t_writes:add( eb.rec_wrdata32, buf(tmp_offset+alignment-4, 4))
- elseif data_width==8 then t_writes:add( eb.rec_wrdata64, buf(tmp_offset+alignment-8, 8))
- end
- tmp_offset = tmp_offset + alignment
- end
- offset = tmp_offset
- end
-
- if(rd > 0) then
- local t_reads = t_rec:add( eb.rec_reads, buf(offset,(1+rd)*alignment))
-
- if addr_width==1 then t_reads:add( eb.rec_rdbadr8, buf(offset+alignment-1, 1))
- elseif addr_width==2 then t_reads:add( eb.rec_rdbadr16, buf(offset+alignment-2, 2))
- elseif addr_width==4 then t_reads:add( eb.rec_rdbadr32, buf(offset+alignment-4, 4))
- elseif addr_width==8 then t_reads:add( eb.rec_rdbadr64, buf(offset+alignment-8, 8))
- end
- offset = offset + alignment
-
- tmp_offset = offset
- while (tmp_offset < offset+rd*alignment) do
- if addr_width==1 then t_reads:add( eb.rec_rddata8, buf(tmp_offset+alignment-1, 1))
- elseif addr_width==2 then t_reads:add( eb.rec_rddata16, buf(tmp_offset+alignment-2, 2))
- elseif addr_width==4 then t_reads:add( eb.rec_rddata32, buf(tmp_offset+alignment-4, 4))
- elseif addr_width==8 then t_reads:add( eb.rec_rddata64, buf(tmp_offset+alignment-8, 8))
- end
- tmp_offset = tmp_offset + alignment
- end
- offset = tmp_offset
- end
- end
- end
-
- end
-
- else
- return 0
- end
-
-end
-
--- register eb protocol on UDP port 20000
-local tab = DissectorTable.get("udp.port")
-tab:add(20000, proto_eb)
+++ /dev/null
-from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-from misoclib.com.liteeth.generic.depacketizer import LiteEthDepacketizer
-from misoclib.com.liteeth.generic.packetizer import LiteEthPacketizer
-
-
-class LiteEthEtherbonePacketPacketizer(LiteEthPacketizer):
- def __init__(self):
- LiteEthPacketizer.__init__(self,
- eth_etherbone_packet_description(32),
- eth_udp_user_description(32),
- etherbone_packet_header)
-
-
-class LiteEthEtherbonePacketTX(Module):
- def __init__(self, udp_port):
- self.sink = sink = Sink(eth_etherbone_packet_user_description(32))
- self.source = source = Source(eth_udp_user_description(32))
-
- # # #
-
- self.submodules.packetizer = packetizer = LiteEthEtherbonePacketPacketizer()
- self.comb += [
- packetizer.sink.stb.eq(sink.stb),
- packetizer.sink.sop.eq(sink.sop),
- packetizer.sink.eop.eq(sink.eop),
- sink.ack.eq(packetizer.sink.ack),
-
- packetizer.sink.magic.eq(etherbone_magic),
- packetizer.sink.port_size.eq(32//8),
- packetizer.sink.addr_size.eq(32//8),
- packetizer.sink.pf.eq(sink.pf),
- packetizer.sink.pr.eq(sink.pr),
- packetizer.sink.nr.eq(sink.nr),
- packetizer.sink.version.eq(etherbone_version),
-
- packetizer.sink.data.eq(sink.data)
- ]
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- packetizer.source.ack.eq(1),
- If(packetizer.source.stb & packetizer.source.sop,
- packetizer.source.ack.eq(0),
- NextState("SEND")
- )
- )
- fsm.act("SEND",
- Record.connect(packetizer.source, source),
- source.src_port.eq(udp_port),
- source.dst_port.eq(udp_port),
- source.ip_address.eq(sink.ip_address),
- source.length.eq(sink.length + etherbone_packet_header.length),
- If(source.stb & source.eop & source.ack,
- NextState("IDLE")
- )
- )
-
-
-class LiteEthEtherbonePacketDepacketizer(LiteEthDepacketizer):
- def __init__(self):
- LiteEthDepacketizer.__init__(self,
- eth_udp_user_description(32),
- eth_etherbone_packet_description(32),
- etherbone_packet_header)
-
-
-class LiteEthEtherbonePacketRX(Module):
- def __init__(self):
- self.sink = sink = Sink(eth_udp_user_description(32))
- self.source = source = Source(eth_etherbone_packet_user_description(32))
-
- # # #
-
- self.submodules.depacketizer = depacketizer = LiteEthEtherbonePacketDepacketizer()
- self.comb += Record.connect(sink, depacketizer.sink)
-
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- depacketizer.source.ack.eq(1),
- If(depacketizer.source.stb & depacketizer.source.sop,
- depacketizer.source.ack.eq(0),
- NextState("CHECK")
- )
- )
- valid = Signal()
- self.sync += valid.eq(
- depacketizer.source.stb &
- (depacketizer.source.magic == etherbone_magic)
- )
- fsm.act("CHECK",
- If(valid,
- NextState("PRESENT")
- ).Else(
- NextState("DROP")
- )
- )
- self.comb += [
- source.sop.eq(depacketizer.source.sop),
- source.eop.eq(depacketizer.source.eop),
-
- source.pf.eq(depacketizer.source.pf),
- source.pr.eq(depacketizer.source.pr),
- source.nr.eq(depacketizer.source.nr),
-
- source.data.eq(depacketizer.source.data),
-
- source.src_port.eq(sink.src_port),
- source.dst_port.eq(sink.dst_port),
- source.ip_address.eq(sink.ip_address),
- source.length.eq(sink.length - etherbone_packet_header.length)
- ]
- fsm.act("PRESENT",
- source.stb.eq(depacketizer.source.stb),
- depacketizer.source.ack.eq(source.ack),
- If(source.stb & source.eop & source.ack,
- NextState("IDLE")
- )
- )
- fsm.act("DROP",
- depacketizer.source.ack.eq(1),
- If(depacketizer.source.stb &
- depacketizer.source.eop &
- depacketizer.source.ack,
- NextState("IDLE")
- )
- )
-
-
-class LiteEthEtherbonePacket(Module):
- def __init__(self, udp, udp_port):
- self.submodules.tx = tx = LiteEthEtherbonePacketTX(udp_port)
- self.submodules.rx = rx = LiteEthEtherbonePacketRX()
- udp_port = udp.crossbar.get_port(udp_port, dw=32)
- self.comb += [
- Record.connect(tx.source, udp_port.sink),
- Record.connect(udp_port.source, rx.sink)
- ]
- self.sink, self.source = self.tx.sink, self.rx.source
+++ /dev/null
-from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-
-
-class LiteEthEtherboneProbe(Module):
- def __init__(self):
- self.sink = sink = Sink(eth_etherbone_packet_user_description(32))
- self.source = source = Source(eth_etherbone_packet_user_description(32))
-
- # # #
-
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- sink.ack.eq(1),
- If(sink.stb & sink.sop,
- sink.ack.eq(0),
- NextState("PROBE_RESPONSE")
- )
- )
- fsm.act("PROBE_RESPONSE",
- Record.connect(sink, source),
- source.pf.eq(0),
- source.pr.eq(1),
- If(source.stb & source.eop & source.ack,
- NextState("IDLE")
- )
- )
+++ /dev/null
-from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-from misoclib.com.liteeth.generic.depacketizer import LiteEthDepacketizer
-from misoclib.com.liteeth.generic.packetizer import LiteEthPacketizer
-
-
-class LiteEthEtherboneRecordPacketizer(LiteEthPacketizer):
- def __init__(self):
- LiteEthPacketizer.__init__(self,
- eth_etherbone_record_description(32),
- eth_etherbone_packet_user_description(32),
- etherbone_record_header)
-
-
-class LiteEthEtherboneRecordDepacketizer(LiteEthDepacketizer):
- def __init__(self):
- LiteEthDepacketizer.__init__(self,
- eth_etherbone_packet_user_description(32),
- eth_etherbone_record_description(32),
- etherbone_record_header)
-
-
-class LiteEthEtherboneRecordReceiver(Module):
- def __init__(self, buffer_depth=256):
- self.sink = sink = Sink(eth_etherbone_record_description(32))
- self.source = source = Source(eth_etherbone_mmap_description(32))
-
- # # #
-
- fifo = SyncFIFO(eth_etherbone_record_description(32), buffer_depth,
- buffered=True)
- self.submodules += fifo
- self.comb += Record.connect(sink, fifo.sink)
-
- self.submodules.base_addr = base_addr = FlipFlop(32)
- self.comb += base_addr.d.eq(fifo.source.data)
-
- self.submodules.counter = counter = Counter(max=512)
-
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- fifo.source.ack.eq(1),
- counter.reset.eq(1),
- If(fifo.source.stb & fifo.source.sop,
- base_addr.ce.eq(1),
- If(fifo.source.wcount,
- NextState("RECEIVE_WRITES")
- ).Elif(fifo.source.rcount,
- NextState("RECEIVE_READS")
- )
- )
- )
- fsm.act("RECEIVE_WRITES",
- source.stb.eq(fifo.source.stb),
- source.sop.eq(counter.value == 0),
- source.eop.eq(counter.value == fifo.source.wcount-1),
- source.count.eq(fifo.source.wcount),
- source.be.eq(fifo.source.byte_enable),
- source.addr.eq(base_addr.q[2:] + counter.value),
- source.we.eq(1),
- source.data.eq(fifo.source.data),
- fifo.source.ack.eq(source.ack),
- If(source.stb & source.ack,
- counter.ce.eq(1),
- If(source.eop,
- If(fifo.source.rcount,
- NextState("RECEIVE_BASE_RET_ADDR")
- ).Else(
- NextState("IDLE")
- )
- )
- )
- )
- fsm.act("RECEIVE_BASE_RET_ADDR",
- counter.reset.eq(1),
- If(fifo.source.stb & fifo.source.sop,
- base_addr.ce.eq(1),
- NextState("RECEIVE_READS")
- )
- )
- fsm.act("RECEIVE_READS",
- source.stb.eq(fifo.source.stb),
- source.sop.eq(counter.value == 0),
- source.eop.eq(counter.value == fifo.source.rcount-1),
- source.count.eq(fifo.source.rcount),
- source.base_addr.eq(base_addr.q),
- source.addr.eq(fifo.source.data[2:]),
- fifo.source.ack.eq(source.ack),
- If(source.stb & source.ack,
- counter.ce.eq(1),
- If(source.eop,
- NextState("IDLE")
- )
- )
- )
-
-
-class LiteEthEtherboneRecordSender(Module):
- def __init__(self, buffer_depth=256):
- self.sink = sink = Sink(eth_etherbone_mmap_description(32))
- self.source = source = Source(eth_etherbone_record_description(32))
-
- # # #
-
- pbuffer = Buffer(eth_etherbone_mmap_description(32), buffer_depth)
- self.submodules += pbuffer
- self.comb += Record.connect(sink, pbuffer.sink)
-
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- pbuffer.source.ack.eq(1),
- If(pbuffer.source.stb & pbuffer.source.sop,
- pbuffer.source.ack.eq(0),
- NextState("SEND_BASE_ADDRESS")
- )
- )
- self.comb += [
- source.byte_enable.eq(pbuffer.source.be),
- If(pbuffer.source.we,
- source.wcount.eq(pbuffer.source.count)
- ).Else(
- source.rcount.eq(pbuffer.source.count)
- )
- ]
-
- fsm.act("SEND_BASE_ADDRESS",
- source.stb.eq(pbuffer.source.stb),
- source.sop.eq(1),
- source.eop.eq(0),
- source.data.eq(pbuffer.source.base_addr),
- If(source.ack,
- NextState("SEND_DATA")
- )
- )
- fsm.act("SEND_DATA",
- source.stb.eq(pbuffer.source.stb),
- source.sop.eq(0),
- source.eop.eq(pbuffer.source.eop),
- source.data.eq(pbuffer.source.data),
- If(source.stb & source.ack,
- pbuffer.source.ack.eq(1),
- If(source.eop,
- NextState("IDLE")
- )
- )
- )
-
-
-# Limitation: For simplicity we only support 1 record per packet
-class LiteEthEtherboneRecord(Module):
- def __init__(self, endianness="big"):
- self.sink = sink = Sink(eth_etherbone_packet_user_description(32))
- self.source = source = Sink(eth_etherbone_packet_user_description(32))
-
- # # #
-
- # receive record, decode it and generate mmap stream
- self.submodules.depacketizer = depacketizer = LiteEthEtherboneRecordDepacketizer()
- self.submodules.receiver = receiver = LiteEthEtherboneRecordReceiver()
- self.comb += [
- Record.connect(sink, depacketizer.sink),
- Record.connect(depacketizer.source, receiver.sink)
- ]
- if endianness is "big":
- self.comb += receiver.sink.data.eq(reverse_bytes(depacketizer.source.data))
-
- # save last ip address
- last_ip_address = Signal(32)
- self.sync += [
- If(sink.stb & sink.sop & sink.ack,
- last_ip_address.eq(sink.ip_address)
- )
- ]
-
- # receive mmap stream, encode it and send records
- self.submodules.sender = sender = LiteEthEtherboneRecordSender()
- self.submodules.packetizer = packetizer = LiteEthEtherboneRecordPacketizer()
- self.comb += [
- Record.connect(sender.source, packetizer.sink),
- Record.connect(packetizer.source, source),
- # XXX improve this
- source.length.eq(sender.source.wcount*4 + 4 + etherbone_record_header.length),
- source.ip_address.eq(last_ip_address)
- ]
- if endianness is "big":
- self.comb += packetizer.sink.data.eq(reverse_bytes(sender.source.data))
+++ /dev/null
-from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-from migen.bus import wishbone
-
-
-class LiteEthEtherboneWishboneMaster(Module):
- def __init__(self):
- self.sink = sink = Sink(eth_etherbone_mmap_description(32))
- self.source = source = Source(eth_etherbone_mmap_description(32))
- self.bus = bus = wishbone.Interface()
-
- # # #
-
- self.submodules.data = data = FlipFlop(32)
- self.comb += data.d.eq(bus.dat_r)
-
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- sink.ack.eq(1),
- If(sink.stb & sink.sop,
- sink.ack.eq(0),
- If(sink.we,
- NextState("WRITE_DATA")
- ).Else(
- NextState("READ_DATA")
- )
- )
- )
- fsm.act("WRITE_DATA",
- bus.adr.eq(sink.addr),
- bus.dat_w.eq(sink.data),
- bus.sel.eq(sink.be),
- bus.stb.eq(sink.stb),
- bus.we.eq(1),
- bus.cyc.eq(1),
- If(bus.stb & bus.ack,
- sink.ack.eq(1),
- If(sink.eop,
- NextState("IDLE")
- )
- )
- )
- fsm.act("READ_DATA",
- bus.adr.eq(sink.addr),
- bus.sel.eq(sink.be),
- bus.stb.eq(sink.stb),
- bus.cyc.eq(1),
- If(bus.stb & bus.ack,
- data.ce.eq(1),
- NextState("SEND_DATA")
- )
- )
- fsm.act("SEND_DATA",
- source.stb.eq(sink.stb),
- source.sop.eq(sink.sop),
- source.eop.eq(sink.eop),
- source.base_addr.eq(sink.base_addr),
- source.addr.eq(sink.addr),
- source.count.eq(sink.count),
- source.be.eq(sink.be),
- source.we.eq(1),
- source.data.eq(data.q),
- If(source.stb & source.ack,
- sink.ack.eq(1),
- If(source.eop,
- NextState("IDLE")
- ).Else(
- NextState("READ_DATA")
- )
- )
- )
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-from misoclib.com.liteeth.generic.depacketizer import LiteEthDepacketizer
-from misoclib.com.liteeth.generic.packetizer import LiteEthPacketizer
-class LiteEthICMPPacketizer(LiteEthPacketizer):
+class LiteEthICMPPacketizer(Packetizer):
def __init__(self):
- LiteEthPacketizer.__init__(self,
+ Packetizer.__init__(self,
eth_icmp_description(8),
eth_ipv4_user_description(8),
icmp_header)
)
-class LiteEthICMPDepacketizer(LiteEthDepacketizer):
+class LiteEthICMPDepacketizer(Depacketizer):
def __init__(self):
- LiteEthDepacketizer.__init__(self,
+ Depacketizer.__init__(self,
eth_ipv4_user_description(8),
eth_icmp_description(8),
icmp_header)
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from misoclib.com.liteeth.core.ip.checksum import *
from misoclib.com.liteeth.core.ip.crossbar import *
-from misoclib.com.liteeth.generic.depacketizer import LiteEthDepacketizer
-from misoclib.com.liteeth.generic.packetizer import LiteEthPacketizer
-class LiteEthIPV4Packetizer(LiteEthPacketizer):
+class LiteEthIPV4Packetizer(Packetizer):
def __init__(self):
- LiteEthPacketizer.__init__(self,
+ Packetizer.__init__(self,
eth_ipv4_description(8),
eth_mac_description(8),
ipv4_header)
)
-class LiteEthIPV4Depacketizer(LiteEthDepacketizer):
+class LiteEthIPV4Depacketizer(Depacketizer):
def __init__(self):
- LiteEthDepacketizer.__init__(self,
+ Depacketizer.__init__(self,
eth_mac_description(8),
eth_ipv4_description(8),
ipv4_header)
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
class LiteEthIPV4Checksum(Module):
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-from misoclib.com.liteeth.generic.crossbar import LiteEthCrossbar
+from misoclib.com.liteeth.crossbar import LiteEthCrossbar
class LiteEthIPV4MasterPort:
+++ /dev/null
-from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-
-
-class LiteEthTTYTX(Module):
- def __init__(self, ip_address, udp_port, fifo_depth=None):
- self.sink = sink = Sink(eth_tty_description(8))
- self.source = source = Source(eth_udp_user_description(8))
-
- # # #
-
- if fifo_depth is None:
- self.comb += [
- source.stb.eq(sink.stb),
- source.sop.eq(1),
- source.eop.eq(1),
- source.length.eq(1),
- source.data.eq(sink.data),
- sink.ack.eq(source.ack)
- ]
- else:
- self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth)
- self.comb += Record.connect(sink, fifo.sink)
-
- self.submodules.level = level = FlipFlop(max=fifo_depth)
- self.comb += level.d.eq(fifo.fifo.level)
-
- self.submodules.counter = counter = Counter(max=fifo_depth)
-
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- If(fifo.source.stb,
- level.ce.eq(1),
- counter.reset.eq(1),
- NextState("SEND")
- )
- )
- fsm.act("SEND",
- source.stb.eq(fifo.source.stb),
- source.sop.eq(counter.value == 0),
- If(level.q == 0,
- source.eop.eq(1),
- ).Else(
- source.eop.eq(counter.value == (level.q-1)),
- ),
- source.src_port.eq(udp_port),
- source.dst_port.eq(udp_port),
- source.ip_address.eq(ip_address),
- If(level.q == 0,
- source.length.eq(1),
- ).Else(
- source.length.eq(level.q),
- ),
- source.data.eq(fifo.source.data),
- fifo.source.ack.eq(source.ack),
- If(source.stb & source.ack,
- counter.ce.eq(1),
- If(source.eop,
- NextState("IDLE")
- )
- )
- )
-
-
-class LiteEthTTYRX(Module):
- def __init__(self, ip_address, udp_port, fifo_depth=None):
- self.sink = sink = Sink(eth_udp_user_description(8))
- self.source = source = Source(eth_tty_description(8))
-
- # # #
-
- valid = Signal()
- self.comb += valid.eq(
- (sink.ip_address == ip_address) &
- (sink.dst_port == udp_port)
- )
- if fifo_depth is None:
- self.comb += [
- source.stb.eq(sink.stb & valid),
- source.data.eq(sink.data),
- sink.ack.eq(source.ack)
- ]
- else:
- self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth)
- self.comb += [
- fifo.sink.stb.eq(sink.stb & valid),
- fifo.sink.data.eq(sink.data),
- sink.ack.eq(fifo.sink.ack),
- Record.connect(fifo.source, source)
- ]
-
-
-class LiteEthTTY(Module):
- def __init__(self, udp, ip_address, udp_port,
- rx_fifo_depth=64,
- tx_fifo_depth=64):
- self.submodules.tx = tx = LiteEthTTYTX(ip_address, udp_port, tx_fifo_depth)
- self.submodules.rx = rx = LiteEthTTYRX(ip_address, udp_port, rx_fifo_depth)
- udp_port = udp.crossbar.get_port(udp_port, dw=8)
- self.comb += [
- Record.connect(tx.source, udp_port.sink),
- Record.connect(udp_port.source, rx.sink)
- ]
- self.sink, self.source = self.tx.sink, self.rx.source
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from misoclib.com.liteeth.core.udp.crossbar import *
-from misoclib.com.liteeth.generic.depacketizer import LiteEthDepacketizer
-from misoclib.com.liteeth.generic.packetizer import LiteEthPacketizer
-class LiteEthUDPPacketizer(LiteEthPacketizer):
+class LiteEthUDPPacketizer(Packetizer):
def __init__(self):
- LiteEthPacketizer.__init__(self,
+ Packetizer.__init__(self,
eth_udp_description(8),
eth_ipv4_user_description(8),
udp_header)
)
-class LiteEthUDPDepacketizer(LiteEthDepacketizer):
+class LiteEthUDPDepacketizer(Depacketizer):
def __init__(self):
- LiteEthDepacketizer.__init__(self,
+ Depacketizer.__init__(self,
eth_ipv4_user_description(8),
eth_udp_description(8),
udp_header)
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-
-from misoclib.com.liteeth.generic.crossbar import LiteEthCrossbar
+from misoclib.com.liteeth.crossbar import LiteEthCrossbar
class LiteEthUDPMasterPort:
--- /dev/null
+from collections import OrderedDict
+
+from misoclib.com.liteeth.common import *
+
+class LiteEthCrossbar(Module):
+ def __init__(self, master_port, dispatch_param):
+ self.users = OrderedDict()
+ self.master = master_port(8)
+ self.dispatch_param = dispatch_param
+
+ # overload this in derived classes
+ def get_port(self, *args, **kwargs):
+ pass
+
+ def do_finalize(self):
+ # TX arbitrate
+ sinks = [port.sink for port in self.users.values()]
+ self.submodules.arbiter = Arbiter(sinks, self.master.source)
+
+ # RX dispatch
+ sources = [port.source for port in self.users.values()]
+ self.submodules.dispatcher = Dispatcher(self.master.sink,
+ sources,
+ one_hot=True)
+ cases = {}
+ cases["default"] = self.dispatcher.sel.eq(0)
+ for i, (k, v) in enumerate(self.users.items()):
+ cases[k] = self.dispatcher.sel.eq(2**i)
+ self.comb += \
+ Case(getattr(self.master.sink, self.dispatch_param), cases)
from misoclib.tools.litescope.core.port import LiteScopeTerm
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from misoclib.com.liteeth.phy.gmii import LiteEthPHYGMII
from misoclib.com.liteeth.core import LiteEthUDPIPCore
from misoclib.tools.litescope.core.port import LiteScopeTerm
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from targets.base import BaseSoC
-from misoclib.com.liteeth.core.etherbone import LiteEthEtherbone
+from misoclib.com.liteeth.frontend.etherbone import LiteEthEtherbone
class EtherboneSoC(BaseSoC):
from misoclib.com.liteeth.generic import *
from targets.base import BaseSoC
-from misoclib.com.liteeth.core.tty import LiteEthTTY
+from misoclib.com.liteeth.frontend.tty import LiteEthTTY
class TTYSoC(BaseSoC):
from misoclib.tools.litescope.core.port import LiteScopeTerm
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from targets.base import BaseSoC
--- /dev/null
+from misoclib.com.liteeth.common import *
+from misoclib.com.liteeth.core.etherbone.packet import *
+from misoclib.com.liteeth.core.etherbone.probe import *
+from misoclib.com.liteeth.core.etherbone.record import *
+from misoclib.com.liteeth.core.etherbone.wishbone import *
+
+
+class LiteEthEtherbone(Module):
+ def __init__(self, udp, udp_port):
+ # decode/encode etherbone packets
+ self.submodules.packet = packet = LiteEthEtherbonePacket(udp, udp_port)
+
+ # packets can be probe (etherbone discovering) or records with
+ # writes and reads
+ self.submodules.probe = probe = LiteEthEtherboneProbe()
+ self.submodules.record = record = LiteEthEtherboneRecord()
+
+ # arbitrate/dispatch probe/records packets
+ dispatcher = Dispatcher(packet.source, [probe.sink, record.sink])
+ self.comb += dispatcher.sel.eq(~packet.source.pf)
+ arbiter = Arbiter([probe.source, record.source], packet.sink)
+ self.submodules += dispatcher, arbiter
+
+ # create mmap ŵishbone master
+ self.submodules.master = master = LiteEthEtherboneWishboneMaster()
+ self.comb += [
+ Record.connect(record.receiver.source, master.sink),
+ Record.connect(master.source, record.sender.sink)
+ ]
--- /dev/null
+--[[---------------
+LuaBit v0.4
+-------------------
+a bitwise operation lib for lua.
+
+http://luaforge.net/projects/bit/
+
+How to use:
+-------------------
+ bit.bnot(n) -- bitwise not (~n)
+ bit.band(m, n) -- bitwise and (m & n)
+ bit.bor(m, n) -- bitwise or (m | n)
+ bit.bxor(m, n) -- bitwise xor (m ^ n)
+ bit.brshift(n, bits) -- right shift (n >> bits)
+ bit.blshift(n, bits) -- left shift (n << bits)
+ bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>)
+
+Please note that bit.brshift and bit.blshift only support number within
+32 bits.
+
+2 utility functions are provided too:
+ bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence)
+ -- high bits first
+ bit.tonumb(bit_tbl) -- convert a bit table into a number
+-------------------
+
+Under the MIT license.
+
+copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com)
+--]]---------------
+
+do
+
+------------------------
+-- bit lib implementions
+
+local function check_int(n)
+ -- checking not float
+ if(n - math.floor(n) > 0) then
+ error("trying to use bitwise operation on non-integer!")
+ end
+end
+
+local function to_bits(n)
+ check_int(n)
+ if(n < 0) then
+ -- negative
+ return to_bits(bit.bnot(math.abs(n)) + 1)
+ end
+ -- to bits table
+ local tbl = {}
+ local cnt = 1
+ while (n > 0) do
+ local last = math.mod(n,2)
+ if(last == 1) then
+ tbl[cnt] = 1
+ else
+ tbl[cnt] = 0
+ end
+ n = (n-last)/2
+ cnt = cnt + 1
+ end
+
+ return tbl
+end
+
+local function tbl_to_number(tbl)
+ local n = table.getn(tbl)
+
+ local rslt = 0
+ local power = 1
+ for i = 1, n do
+ rslt = rslt + tbl[i]*power
+ power = power*2
+ end
+
+ return rslt
+end
+
+local function expand(tbl_m, tbl_n)
+ local big = {}
+ local small = {}
+ if(table.getn(tbl_m) > table.getn(tbl_n)) then
+ big = tbl_m
+ small = tbl_n
+ else
+ big = tbl_n
+ small = tbl_m
+ end
+ -- expand small
+ for i = table.getn(small) + 1, table.getn(big) do
+ small[i] = 0
+ end
+
+end
+
+local function bit_or(m, n)
+ local tbl_m = to_bits(m)
+ local tbl_n = to_bits(n)
+ expand(tbl_m, tbl_n)
+
+ local tbl = {}
+ local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
+ for i = 1, rslt do
+ if(tbl_m[i]== 0 and tbl_n[i] == 0) then
+ tbl[i] = 0
+ else
+ tbl[i] = 1
+ end
+ end
+
+ return tbl_to_number(tbl)
+end
+
+local function bit_and(m, n)
+ local tbl_m = to_bits(m)
+ local tbl_n = to_bits(n)
+ expand(tbl_m, tbl_n)
+
+ local tbl = {}
+ local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
+ for i = 1, rslt do
+ if(tbl_m[i]== 0 or tbl_n[i] == 0) then
+ tbl[i] = 0
+ else
+ tbl[i] = 1
+ end
+ end
+
+ return tbl_to_number(tbl)
+end
+
+local function bit_not(n)
+
+ local tbl = to_bits(n)
+ local size = math.max(table.getn(tbl), 32)
+ for i = 1, size do
+ if(tbl[i] == 1) then
+ tbl[i] = 0
+ else
+ tbl[i] = 1
+ end
+ end
+ return tbl_to_number(tbl)
+end
+
+local function bit_xor(m, n)
+ local tbl_m = to_bits(m)
+ local tbl_n = to_bits(n)
+ expand(tbl_m, tbl_n)
+
+ local tbl = {}
+ local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
+ for i = 1, rslt do
+ if(tbl_m[i] ~= tbl_n[i]) then
+ tbl[i] = 1
+ else
+ tbl[i] = 0
+ end
+ end
+
+ --table.foreach(tbl, print)
+
+ return tbl_to_number(tbl)
+end
+
+local function bit_rshift(n, bits)
+ check_int(n)
+
+ local high_bit = 0
+ if(n < 0) then
+ -- negative
+ n = bit_not(math.abs(n)) + 1
+ high_bit = 2147483648 -- 0x80000000
+ end
+
+ for i=1, bits do
+ n = n/2
+ n = bit_or(math.floor(n), high_bit)
+ end
+ return math.floor(n)
+end
+
+-- logic rightshift assures zero filling shift
+local function bit_logic_rshift(n, bits)
+ check_int(n)
+ if(n < 0) then
+ -- negative
+ n = bit_not(math.abs(n)) + 1
+ end
+ for i=1, bits do
+ n = n/2
+ end
+ return math.floor(n)
+end
+
+local function bit_lshift(n, bits)
+ check_int(n)
+
+ if(n < 0) then
+ -- negative
+ n = bit_not(math.abs(n)) + 1
+ end
+
+ for i=1, bits do
+ n = n*2
+ end
+ return bit_and(n, 4294967295) -- 0xFFFFFFFF
+end
+
+local function bit_xor2(m, n)
+ local rhs = bit_or(bit_not(m), bit_not(n))
+ local lhs = bit_or(m, n)
+ local rslt = bit_and(lhs, rhs)
+ return rslt
+end
+
+--------------------
+-- bit lib interface
+
+bit = {
+ -- bit operations
+ bnot = bit_not,
+ band = bit_and,
+ bor = bit_or,
+ bxor = bit_xor,
+ brshift = bit_rshift,
+ blshift = bit_lshift,
+ bxor2 = bit_xor2,
+ blogic_rshift = bit_logic_rshift,
+
+ -- utility func
+ tobits = to_bits,
+ tonumb = tbl_to_number,
+}
+
+end
+
+--[[
+for i = 1, 100 do
+ for j = 1, 100 do
+ if(bit.bxor(i, j) ~= bit.bxor2(i, j)) then
+ error("bit.xor failed.")
+ end
+ end
+end
+--]]
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+-- Etherbone Dissector
+-- Copyright 2013 OHWR.org
+-- Copyright 2015 EnjoyDigital (global clean up)
+
+local bit = require("bit")
+
+local VALS_BOOL = {[0] = "False", [1] = "True"}
+local VALS_RES = {[0] = "not set", [1] = "set, bad data?"}
+local VALS_SIZE = {
+[0x00] = "Bad Value",
+[0x01] = "8 bit",
+[0x02] = "16 bit",
+[0x03] = "16,8 bit",
+[0x04] = "32 bit",
+[0x05] = "32,8 bit",
+[0x06] = "32,16 bit",
+[0x07] = "32,16,8 bit",
+[0x08] = "64 bit",
+[0x09] = "64,8 bit",
+[0x0A] = "64,16 bit",
+[0x0B] = "64,16,8 bit",
+[0x0C] = "64,32 bit",
+[0x0D] = "64,32,8 bit",
+[0x0E] = "64,32,16 bit",
+[0x0F] = "64,32,16,8 bit",
+}
+
+function num2hex(num)
+ local hexstr = '0123456789abcdef'
+ local s = ''
+ while num > 0 do
+ local mod = math.fmod(num, 16)
+ s = string.sub(hexstr, mod+1, mod+1) .. s
+ num = math.floor(num / 16)
+ end
+ if s == '' then s = '0' end
+ return s
+end
+
+function max(a, b)
+ if a > b then
+ return a
+ else
+ return b
+ end
+end
+
+-- declare protocol
+proto_eb = Proto("eb", "Etherbone")
+
+-- declare fields
+local eb = proto_eb.fields
+eb.hdr = ProtoField.uint32("eb.hdr", "Header", base.HEX)
+eb.rec = ProtoField.bytes("eb.rec", "Record ", base.HEX)
+
+eb.hdr_magic = ProtoField.uint16("eb.hdr.magic", "Magic ", base.HEX, nil, 0xFFFF)
+eb.hdr_ver = ProtoField.uint16("eb.hdr.ver", "Version ", base.DEC, nil, 0xF000)
+eb.hdr_noreads = ProtoField.uint16("eb.hdr.noreads", "No Reads ", base.DEC, VALS_BOOL, 0x0400)
+eb.hdr_proberep = ProtoField.uint16("eb.hdr.proberes", "Probe Reply ", base.DEC, VALS_BOOL, 0x0200)
+eb.hdr_probereq = ProtoField.uint16("eb.hdr.probereq", "Probe Flag ", base.DEC, VALS_BOOL, 0x0100)
+eb.hdr_adrs = ProtoField.uint16("eb.hdr.adrw", "Address Width ", base.DEC, VALS_SIZE , 0x00F0)
+eb.hdr_ports = ProtoField.uint16("eb.hdr.portw", "Port Width ", base.DEC, VALS_SIZE , 0x000F)
+
+eb.rec_hdr = ProtoField.uint32("eb.rec.hdr", "Header ", base.HEX)
+eb.rec_writes = ProtoField.bytes("eb.rec.writes", "Writes ", base.HEX)
+eb.rec_reads = ProtoField.bytes("eb.rec.reads", "Reads ", base.HEX)
+
+eb.rec_hdr_flags = ProtoField.uint8("eb.rec.hdr.flags", "Flags ", base.HEX)
+eb.rec_hdr_select = ProtoField.uint8("eb.rec.hdr.select", "Select ", base.HEX)
+eb.rec_hdr_wr = ProtoField.uint8("eb.rec.hdr.wr", "Writes ", base.DEC)
+eb.rec_hdr_rd = ProtoField.uint8("eb.rec.hdr.rd", "Reads ", base.DEC)
+
+eb.rec_hdr_flags_adrcfg = ProtoField.uint8("eb.rec.hdr.flags.adrcfg", "ReplyToCfgSpace ", base.DEC, VALS_BOOL, 0x80)
+eb.rec_hdr_flags_rbacfg = ProtoField.uint8("eb.rec.hdr.adrcfg", "ReadFromCfgSpace ", base.DEC, VALS_BOOL, 0x40)
+eb.rec_hdr_flags_rdfifo = ProtoField.uint8("eb.rec.hdr.adrcfg", "ReadFIFO ", base.DEC, VALS_BOOL, 0x20)
+eb.rec_hdr_flags_dropcyc= ProtoField.uint8("eb.rec.hdr.adrcfg", "DropCycle ", base.DEC, VALS_BOOL, 0x08)
+eb.rec_hdr_flags_wbacfg = ProtoField.uint8("eb.rec.hdr.adrcfg", "WriteToCfgSpace ", base.DEC, VALS_BOOL, 0x04)
+eb.rec_hdr_flags_wrfifo = ProtoField.uint8("eb.rec.hdr.adrcfg", "WriteFIFO ", base.DEC, VALS_BOOL, 0x02)
+
+eb.rec_wrsadr8 = ProtoField.uint8("eb.rec.wrsadr8", "BaseAddr8 ", base.HEX)
+eb.rec_wrsadr16 = ProtoField.uint16("eb.rec.wrsadr16", "BaseAddr16 ", base.HEX)
+eb.rec_wrsadr32 = ProtoField.uint32("eb.rec.wrsadr32", "BaseAddr32 ", base.HEX)
+eb.rec_wrsadr64 = ProtoField.uint64("eb.rec.wrsadr64", "BaseAddr64 ", base.HEX)
+eb.rec_wrdata8 = ProtoField.uint8("eb.rec.wrdata8", "Value8 ", base.HEX)
+eb.rec_wrdata16 = ProtoField.uint16("eb.rec.wrdata16", "Value16 ", base.HEX)
+eb.rec_wrdata32 = ProtoField.uint32("eb.rec.wrdata32", "Value32 ", base.HEX)
+eb.rec_wrdata64 = ProtoField.uint64("eb.rec.wrdata64", "Value64 ", base.HEX)
+
+eb.rec_rdbadr8 = ProtoField.uint8("eb.rec.rdbadr8", "ReplyAddr8 ", base.HEX)
+eb.rec_rdbadr16 = ProtoField.uint16("eb.rec.rdbadr16", "ReplyAddr16 ", base.HEX)
+eb.rec_rdbadr32 = ProtoField.uint32("eb.rec.rdbadr32", "ReplyAddr32 ", base.HEX)
+eb.rec_rdbadr64 = ProtoField.uint64("eb.rec.rdbadr64", "ReplyAddr64 ", base.HEX)
+eb.rec_rddata8 = ProtoField.uint8("eb.rec.rddata8", "Address8 ", base.HEX)
+eb.rec_rddata16 = ProtoField.uint16("eb.rec.rddata16", "Address16 ", base.HEX)
+eb.rec_rddata32 = ProtoField.uint32("eb.rec.rddata32", "Address32 ", base.HEX)
+eb.rec_rddata64 = ProtoField.uint64("eb.rec.rddata64", "Address64 ", base.HEX)
+
+-- define the dissector
+function proto_eb.dissector(buf, pinfo, tree)
+ if (buf:len() < 4) then
+ return 0 -- too short, go to default protocol
+ end
+
+ local mylen = buf:len()
+ pinfo.cols.protocol = "eb"
+
+ -- add packet to the tree root, fields will be added to subtree
+ local t = tree:add( proto_eb, buf(0, mylen) )
+ local t_hdr = t:add( eb.hdr, buf(0,4) )
+
+ local magic = num2hex(tonumber(buf(0,2):uint()))
+ if(magic == "4e6f") then
+
+ t_hdr:add( eb.hdr_magic, buf(0,2)) -- magic
+ t_hdr:add( eb.hdr_ver, buf(2,2)) -- version
+ t_hdr:add( eb.hdr_noreads, buf(2,2)) -- no reads
+ t_hdr:add( eb.hdr_proberep, buf(2,2)) -- probe response
+ t_hdr:add( eb.hdr_probereq, buf(2,2)) -- probe request
+
+ t_hdr:add( eb.hdr_adrs, buf(2,2)) -- supported addr size
+ t_hdr:add( eb.hdr_ports, buf(2,2)) -- supported port size
+
+ local probe = tonumber(buf(2,1):uint()) % 4
+ if (probe == 0) then
+ local widths = tonumber(buf(3,1):uint())
+ local data_width = widths % 16
+ local addr_width = (widths - data_width) / 16
+ local alignment = max(max(addr_width, data_width), 2)
+
+ local record_alignment = max(alignment, 4)
+ local offset = max(alignment, 4)
+
+ local recordcnt = 0
+ while (offset < buf:len()) do
+ local wr = tonumber(buf(offset+2,1):uint())
+ local rd = tonumber(buf(offset+3,1):uint())
+
+ local rdadr = 0
+ local wradr = 0
+ if(rd > 0) then
+ rdadr = 1
+ end
+ if(wr > 0) then
+ wradr = 1
+ end
+
+ if((wr == 0) and (rd == 0)) then
+ offset = offset + record_alignment
+ else
+ local t_rec = t:add( "Record "..tostring(recordcnt).." (W"..tostring(wr).." R"..tostring(rd)..")", buf(offset, (record_alignment+(rd+wr+rdadr+wradr)*alignment)))
+ recordcnt = recordcnt + 1
+
+ local t_rec_hdr = t_rec:add( eb.rec_hdr, buf(offset,4))
+ local t_rec_hdr_flags = t_rec_hdr:add( eb.rec_hdr_flags, buf(offset,1))
+ t_rec_hdr_flags:add( eb.rec_hdr_flags_adrcfg, buf(offset,1))
+ t_rec_hdr_flags:add( eb.rec_hdr_flags_rbacfg, buf(offset,1))
+ t_rec_hdr_flags:add( eb.rec_hdr_flags_rdfifo, buf(offset,1))
+ t_rec_hdr_flags:add( eb.rec_hdr_flags_dropcyc , buf(offset,1))
+ t_rec_hdr_flags:add( eb.rec_hdr_flags_wbacfg , buf(offset,1))
+ t_rec_hdr_flags:add( eb.rec_hdr_flags_wrfifo, buf(offset,1))
+ t_rec_hdr:add( eb.rec_hdr_select, buf(offset+1,1))
+ t_rec_hdr:add( eb.rec_hdr_wr, buf(offset+2,1))
+ t_rec_hdr:add( eb.rec_hdr_rd, buf(offset+3,1))
+ offset = offset + record_alignment
+ local tmp_offset
+
+ if(wr > 0) then
+ local t_writes = t_rec:add( eb.rec_writes, buf(offset,(1+wr)*alignment))
+
+ if addr_width==1 then t_writes:add(eb.rec_wrsadr8, buf(offset+alignment-1, 1))
+ elseif addr_width==2 then t_writes:add(eb.rec_wrsadr16, buf(offset+alignment-2, 2))
+ elseif addr_width==4 then t_writes:add(eb.rec_wrsadr32, buf(offset+alignment-4, 4))
+ elseif addr_width==8 then t_writes:add(eb.rec_wrsadr64, buf(offset+alignment-8, 8))
+ end
+ offset = offset + alignment
+
+ tmp_offset = offset
+ while (tmp_offset < offset+wr*alignment) do
+ if data_width==1 then t_writes:add( eb.rec_wrdata8, buf(tmp_offset+alignment-1, 1))
+ elseif data_width==2 then t_writes:add( eb.rec_wrdata16, buf(tmp_offset+alignment-2, 2))
+ elseif data_width==4 then t_writes:add( eb.rec_wrdata32, buf(tmp_offset+alignment-4, 4))
+ elseif data_width==8 then t_writes:add( eb.rec_wrdata64, buf(tmp_offset+alignment-8, 8))
+ end
+ tmp_offset = tmp_offset + alignment
+ end
+ offset = tmp_offset
+ end
+
+ if(rd > 0) then
+ local t_reads = t_rec:add( eb.rec_reads, buf(offset,(1+rd)*alignment))
+
+ if addr_width==1 then t_reads:add( eb.rec_rdbadr8, buf(offset+alignment-1, 1))
+ elseif addr_width==2 then t_reads:add( eb.rec_rdbadr16, buf(offset+alignment-2, 2))
+ elseif addr_width==4 then t_reads:add( eb.rec_rdbadr32, buf(offset+alignment-4, 4))
+ elseif addr_width==8 then t_reads:add( eb.rec_rdbadr64, buf(offset+alignment-8, 8))
+ end
+ offset = offset + alignment
+
+ tmp_offset = offset
+ while (tmp_offset < offset+rd*alignment) do
+ if addr_width==1 then t_reads:add( eb.rec_rddata8, buf(tmp_offset+alignment-1, 1))
+ elseif addr_width==2 then t_reads:add( eb.rec_rddata16, buf(tmp_offset+alignment-2, 2))
+ elseif addr_width==4 then t_reads:add( eb.rec_rddata32, buf(tmp_offset+alignment-4, 4))
+ elseif addr_width==8 then t_reads:add( eb.rec_rddata64, buf(tmp_offset+alignment-8, 8))
+ end
+ tmp_offset = tmp_offset + alignment
+ end
+ offset = tmp_offset
+ end
+ end
+ end
+
+ end
+
+ else
+ return 0
+ end
+
+end
+
+-- register eb protocol on UDP port 20000
+local tab = DissectorTable.get("udp.port")
+tab:add(20000, proto_eb)
--- /dev/null
+from misoclib.com.liteeth.common import *
+
+
+class LiteEthEtherbonePacketPacketizer(Packetizer):
+ def __init__(self):
+ Packetizer.__init__(self,
+ eth_etherbone_packet_description(32),
+ eth_udp_user_description(32),
+ etherbone_packet_header)
+
+
+class LiteEthEtherbonePacketTX(Module):
+ def __init__(self, udp_port):
+ self.sink = sink = Sink(eth_etherbone_packet_user_description(32))
+ self.source = source = Source(eth_udp_user_description(32))
+
+ # # #
+
+ self.submodules.packetizer = packetizer = LiteEthEtherbonePacketPacketizer()
+ self.comb += [
+ packetizer.sink.stb.eq(sink.stb),
+ packetizer.sink.sop.eq(sink.sop),
+ packetizer.sink.eop.eq(sink.eop),
+ sink.ack.eq(packetizer.sink.ack),
+
+ packetizer.sink.magic.eq(etherbone_magic),
+ packetizer.sink.port_size.eq(32//8),
+ packetizer.sink.addr_size.eq(32//8),
+ packetizer.sink.pf.eq(sink.pf),
+ packetizer.sink.pr.eq(sink.pr),
+ packetizer.sink.nr.eq(sink.nr),
+ packetizer.sink.version.eq(etherbone_version),
+
+ packetizer.sink.data.eq(sink.data)
+ ]
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ packetizer.source.ack.eq(1),
+ If(packetizer.source.stb & packetizer.source.sop,
+ packetizer.source.ack.eq(0),
+ NextState("SEND")
+ )
+ )
+ fsm.act("SEND",
+ Record.connect(packetizer.source, source),
+ source.src_port.eq(udp_port),
+ source.dst_port.eq(udp_port),
+ source.ip_address.eq(sink.ip_address),
+ source.length.eq(sink.length + etherbone_packet_header.length),
+ If(source.stb & source.eop & source.ack,
+ NextState("IDLE")
+ )
+ )
+
+
+class LiteEthEtherbonePacketDepacketizer(Depacketizer):
+ def __init__(self):
+ Depacketizer.__init__(self,
+ eth_udp_user_description(32),
+ eth_etherbone_packet_description(32),
+ etherbone_packet_header)
+
+
+class LiteEthEtherbonePacketRX(Module):
+ def __init__(self):
+ self.sink = sink = Sink(eth_udp_user_description(32))
+ self.source = source = Source(eth_etherbone_packet_user_description(32))
+
+ # # #
+
+ self.submodules.depacketizer = depacketizer = LiteEthEtherbonePacketDepacketizer()
+ self.comb += Record.connect(sink, depacketizer.sink)
+
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ depacketizer.source.ack.eq(1),
+ If(depacketizer.source.stb & depacketizer.source.sop,
+ depacketizer.source.ack.eq(0),
+ NextState("CHECK")
+ )
+ )
+ valid = Signal()
+ self.sync += valid.eq(
+ depacketizer.source.stb &
+ (depacketizer.source.magic == etherbone_magic)
+ )
+ fsm.act("CHECK",
+ If(valid,
+ NextState("PRESENT")
+ ).Else(
+ NextState("DROP")
+ )
+ )
+ self.comb += [
+ source.sop.eq(depacketizer.source.sop),
+ source.eop.eq(depacketizer.source.eop),
+
+ source.pf.eq(depacketizer.source.pf),
+ source.pr.eq(depacketizer.source.pr),
+ source.nr.eq(depacketizer.source.nr),
+
+ source.data.eq(depacketizer.source.data),
+
+ source.src_port.eq(sink.src_port),
+ source.dst_port.eq(sink.dst_port),
+ source.ip_address.eq(sink.ip_address),
+ source.length.eq(sink.length - etherbone_packet_header.length)
+ ]
+ fsm.act("PRESENT",
+ source.stb.eq(depacketizer.source.stb),
+ depacketizer.source.ack.eq(source.ack),
+ If(source.stb & source.eop & source.ack,
+ NextState("IDLE")
+ )
+ )
+ fsm.act("DROP",
+ depacketizer.source.ack.eq(1),
+ If(depacketizer.source.stb &
+ depacketizer.source.eop &
+ depacketizer.source.ack,
+ NextState("IDLE")
+ )
+ )
+
+
+class LiteEthEtherbonePacket(Module):
+ def __init__(self, udp, udp_port):
+ self.submodules.tx = tx = LiteEthEtherbonePacketTX(udp_port)
+ self.submodules.rx = rx = LiteEthEtherbonePacketRX()
+ udp_port = udp.crossbar.get_port(udp_port, dw=32)
+ self.comb += [
+ Record.connect(tx.source, udp_port.sink),
+ Record.connect(udp_port.source, rx.sink)
+ ]
+ self.sink, self.source = self.tx.sink, self.rx.source
--- /dev/null
+from misoclib.com.liteeth.common import *
+
+
+class LiteEthEtherboneProbe(Module):
+ def __init__(self):
+ self.sink = sink = Sink(eth_etherbone_packet_user_description(32))
+ self.source = source = Source(eth_etherbone_packet_user_description(32))
+
+ # # #
+
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ sink.ack.eq(1),
+ If(sink.stb & sink.sop,
+ sink.ack.eq(0),
+ NextState("PROBE_RESPONSE")
+ )
+ )
+ fsm.act("PROBE_RESPONSE",
+ Record.connect(sink, source),
+ source.pf.eq(0),
+ source.pr.eq(1),
+ If(source.stb & source.eop & source.ack,
+ NextState("IDLE")
+ )
+ )
--- /dev/null
+from misoclib.com.liteeth.common import *
+
+
+class LiteEthEtherboneRecordPacketizer(Packetizer):
+ def __init__(self):
+ Packetizer.__init__(self,
+ eth_etherbone_record_description(32),
+ eth_etherbone_packet_user_description(32),
+ etherbone_record_header)
+
+
+class LiteEthEtherboneRecordDepacketizer(Depacketizer):
+ def __init__(self):
+ Depacketizer.__init__(self,
+ eth_etherbone_packet_user_description(32),
+ eth_etherbone_record_description(32),
+ etherbone_record_header)
+
+
+class LiteEthEtherboneRecordReceiver(Module):
+ def __init__(self, buffer_depth=256):
+ self.sink = sink = Sink(eth_etherbone_record_description(32))
+ self.source = source = Source(eth_etherbone_mmap_description(32))
+
+ # # #
+
+ fifo = SyncFIFO(eth_etherbone_record_description(32), buffer_depth,
+ buffered=True)
+ self.submodules += fifo
+ self.comb += Record.connect(sink, fifo.sink)
+
+ self.submodules.base_addr = base_addr = FlipFlop(32)
+ self.comb += base_addr.d.eq(fifo.source.data)
+
+ self.submodules.counter = counter = Counter(max=512)
+
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ fifo.source.ack.eq(1),
+ counter.reset.eq(1),
+ If(fifo.source.stb & fifo.source.sop,
+ base_addr.ce.eq(1),
+ If(fifo.source.wcount,
+ NextState("RECEIVE_WRITES")
+ ).Elif(fifo.source.rcount,
+ NextState("RECEIVE_READS")
+ )
+ )
+ )
+ fsm.act("RECEIVE_WRITES",
+ source.stb.eq(fifo.source.stb),
+ source.sop.eq(counter.value == 0),
+ source.eop.eq(counter.value == fifo.source.wcount-1),
+ source.count.eq(fifo.source.wcount),
+ source.be.eq(fifo.source.byte_enable),
+ source.addr.eq(base_addr.q[2:] + counter.value),
+ source.we.eq(1),
+ source.data.eq(fifo.source.data),
+ fifo.source.ack.eq(source.ack),
+ If(source.stb & source.ack,
+ counter.ce.eq(1),
+ If(source.eop,
+ If(fifo.source.rcount,
+ NextState("RECEIVE_BASE_RET_ADDR")
+ ).Else(
+ NextState("IDLE")
+ )
+ )
+ )
+ )
+ fsm.act("RECEIVE_BASE_RET_ADDR",
+ counter.reset.eq(1),
+ If(fifo.source.stb & fifo.source.sop,
+ base_addr.ce.eq(1),
+ NextState("RECEIVE_READS")
+ )
+ )
+ fsm.act("RECEIVE_READS",
+ source.stb.eq(fifo.source.stb),
+ source.sop.eq(counter.value == 0),
+ source.eop.eq(counter.value == fifo.source.rcount-1),
+ source.count.eq(fifo.source.rcount),
+ source.base_addr.eq(base_addr.q),
+ source.addr.eq(fifo.source.data[2:]),
+ fifo.source.ack.eq(source.ack),
+ If(source.stb & source.ack,
+ counter.ce.eq(1),
+ If(source.eop,
+ NextState("IDLE")
+ )
+ )
+ )
+
+
+class LiteEthEtherboneRecordSender(Module):
+ def __init__(self, buffer_depth=256):
+ self.sink = sink = Sink(eth_etherbone_mmap_description(32))
+ self.source = source = Source(eth_etherbone_record_description(32))
+
+ # # #
+
+ pbuffer = Buffer(eth_etherbone_mmap_description(32), buffer_depth)
+ self.submodules += pbuffer
+ self.comb += Record.connect(sink, pbuffer.sink)
+
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ pbuffer.source.ack.eq(1),
+ If(pbuffer.source.stb & pbuffer.source.sop,
+ pbuffer.source.ack.eq(0),
+ NextState("SEND_BASE_ADDRESS")
+ )
+ )
+ self.comb += [
+ source.byte_enable.eq(pbuffer.source.be),
+ If(pbuffer.source.we,
+ source.wcount.eq(pbuffer.source.count)
+ ).Else(
+ source.rcount.eq(pbuffer.source.count)
+ )
+ ]
+
+ fsm.act("SEND_BASE_ADDRESS",
+ source.stb.eq(pbuffer.source.stb),
+ source.sop.eq(1),
+ source.eop.eq(0),
+ source.data.eq(pbuffer.source.base_addr),
+ If(source.ack,
+ NextState("SEND_DATA")
+ )
+ )
+ fsm.act("SEND_DATA",
+ source.stb.eq(pbuffer.source.stb),
+ source.sop.eq(0),
+ source.eop.eq(pbuffer.source.eop),
+ source.data.eq(pbuffer.source.data),
+ If(source.stb & source.ack,
+ pbuffer.source.ack.eq(1),
+ If(source.eop,
+ NextState("IDLE")
+ )
+ )
+ )
+
+
+# Limitation: For simplicity we only support 1 record per packet
+class LiteEthEtherboneRecord(Module):
+ def __init__(self, endianness="big"):
+ self.sink = sink = Sink(eth_etherbone_packet_user_description(32))
+ self.source = source = Sink(eth_etherbone_packet_user_description(32))
+
+ # # #
+
+ # receive record, decode it and generate mmap stream
+ self.submodules.depacketizer = depacketizer = LiteEthEtherboneRecordDepacketizer()
+ self.submodules.receiver = receiver = LiteEthEtherboneRecordReceiver()
+ self.comb += [
+ Record.connect(sink, depacketizer.sink),
+ Record.connect(depacketizer.source, receiver.sink)
+ ]
+ if endianness is "big":
+ self.comb += receiver.sink.data.eq(reverse_bytes(depacketizer.source.data))
+
+ # save last ip address
+ last_ip_address = Signal(32)
+ self.sync += [
+ If(sink.stb & sink.sop & sink.ack,
+ last_ip_address.eq(sink.ip_address)
+ )
+ ]
+
+ # receive mmap stream, encode it and send records
+ self.submodules.sender = sender = LiteEthEtherboneRecordSender()
+ self.submodules.packetizer = packetizer = LiteEthEtherboneRecordPacketizer()
+ self.comb += [
+ Record.connect(sender.source, packetizer.sink),
+ Record.connect(packetizer.source, source),
+ # XXX improve this
+ source.length.eq(sender.source.wcount*4 + 4 + etherbone_record_header.length),
+ source.ip_address.eq(last_ip_address)
+ ]
+ if endianness is "big":
+ self.comb += packetizer.sink.data.eq(reverse_bytes(sender.source.data))
--- /dev/null
+from misoclib.com.liteeth.common import *
+from migen.bus import wishbone
+
+
+class LiteEthEtherboneWishboneMaster(Module):
+ def __init__(self):
+ self.sink = sink = Sink(eth_etherbone_mmap_description(32))
+ self.source = source = Source(eth_etherbone_mmap_description(32))
+ self.bus = bus = wishbone.Interface()
+
+ # # #
+
+ self.submodules.data = data = FlipFlop(32)
+ self.comb += data.d.eq(bus.dat_r)
+
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ sink.ack.eq(1),
+ If(sink.stb & sink.sop,
+ sink.ack.eq(0),
+ If(sink.we,
+ NextState("WRITE_DATA")
+ ).Else(
+ NextState("READ_DATA")
+ )
+ )
+ )
+ fsm.act("WRITE_DATA",
+ bus.adr.eq(sink.addr),
+ bus.dat_w.eq(sink.data),
+ bus.sel.eq(sink.be),
+ bus.stb.eq(sink.stb),
+ bus.we.eq(1),
+ bus.cyc.eq(1),
+ If(bus.stb & bus.ack,
+ sink.ack.eq(1),
+ If(sink.eop,
+ NextState("IDLE")
+ )
+ )
+ )
+ fsm.act("READ_DATA",
+ bus.adr.eq(sink.addr),
+ bus.sel.eq(sink.be),
+ bus.stb.eq(sink.stb),
+ bus.cyc.eq(1),
+ If(bus.stb & bus.ack,
+ data.ce.eq(1),
+ NextState("SEND_DATA")
+ )
+ )
+ fsm.act("SEND_DATA",
+ source.stb.eq(sink.stb),
+ source.sop.eq(sink.sop),
+ source.eop.eq(sink.eop),
+ source.base_addr.eq(sink.base_addr),
+ source.addr.eq(sink.addr),
+ source.count.eq(sink.count),
+ source.be.eq(sink.be),
+ source.we.eq(1),
+ source.data.eq(data.q),
+ If(source.stb & source.ack,
+ sink.ack.eq(1),
+ If(source.eop,
+ NextState("IDLE")
+ ).Else(
+ NextState("READ_DATA")
+ )
+ )
+ )
--- /dev/null
+from misoclib.com.liteeth.common import *
+
+
+class LiteEthTTYTX(Module):
+ def __init__(self, ip_address, udp_port, fifo_depth=None):
+ self.sink = sink = Sink(eth_tty_description(8))
+ self.source = source = Source(eth_udp_user_description(8))
+
+ # # #
+
+ if fifo_depth is None:
+ self.comb += [
+ source.stb.eq(sink.stb),
+ source.sop.eq(1),
+ source.eop.eq(1),
+ source.length.eq(1),
+ source.data.eq(sink.data),
+ sink.ack.eq(source.ack)
+ ]
+ else:
+ self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth)
+ self.comb += Record.connect(sink, fifo.sink)
+
+ self.submodules.level = level = FlipFlop(max=fifo_depth)
+ self.comb += level.d.eq(fifo.fifo.level)
+
+ self.submodules.counter = counter = Counter(max=fifo_depth)
+
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ If(fifo.source.stb,
+ level.ce.eq(1),
+ counter.reset.eq(1),
+ NextState("SEND")
+ )
+ )
+ fsm.act("SEND",
+ source.stb.eq(fifo.source.stb),
+ source.sop.eq(counter.value == 0),
+ If(level.q == 0,
+ source.eop.eq(1),
+ ).Else(
+ source.eop.eq(counter.value == (level.q-1)),
+ ),
+ source.src_port.eq(udp_port),
+ source.dst_port.eq(udp_port),
+ source.ip_address.eq(ip_address),
+ If(level.q == 0,
+ source.length.eq(1),
+ ).Else(
+ source.length.eq(level.q),
+ ),
+ source.data.eq(fifo.source.data),
+ fifo.source.ack.eq(source.ack),
+ If(source.stb & source.ack,
+ counter.ce.eq(1),
+ If(source.eop,
+ NextState("IDLE")
+ )
+ )
+ )
+
+
+class LiteEthTTYRX(Module):
+ def __init__(self, ip_address, udp_port, fifo_depth=None):
+ self.sink = sink = Sink(eth_udp_user_description(8))
+ self.source = source = Source(eth_tty_description(8))
+
+ # # #
+
+ valid = Signal()
+ self.comb += valid.eq(
+ (sink.ip_address == ip_address) &
+ (sink.dst_port == udp_port)
+ )
+ if fifo_depth is None:
+ self.comb += [
+ source.stb.eq(sink.stb & valid),
+ source.data.eq(sink.data),
+ sink.ack.eq(source.ack)
+ ]
+ else:
+ self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth)
+ self.comb += [
+ fifo.sink.stb.eq(sink.stb & valid),
+ fifo.sink.data.eq(sink.data),
+ sink.ack.eq(fifo.sink.ack),
+ Record.connect(fifo.source, source)
+ ]
+
+
+class LiteEthTTY(Module):
+ def __init__(self, udp, ip_address, udp_port,
+ rx_fifo_depth=64,
+ tx_fifo_depth=64):
+ self.submodules.tx = tx = LiteEthTTYTX(ip_address, udp_port, tx_fifo_depth)
+ self.submodules.rx = rx = LiteEthTTYRX(ip_address, udp_port, rx_fifo_depth)
+ udp_port = udp.crossbar.get_port(udp_port, dw=8)
+ self.comb += [
+ Record.connect(tx.source, udp_port.sink),
+ Record.connect(udp_port.source, rx.sink)
+ ]
+ self.sink, self.source = self.tx.sink, self.rx.source
+++ /dev/null
-from migen.fhdl.decorators import ModuleTransformer
-from misoclib.com.liteeth.common import *
-
-
-# Generic classes
-class Port:
- def connect(self, port):
- r = [
- Record.connect(self.source, port.sink),
- Record.connect(port.source, self.sink)
- ]
- return r
+++ /dev/null
-from collections import OrderedDict
-
-from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-
-
-class LiteEthCrossbar(Module):
- def __init__(self, master_port, dispatch_param):
- self.users = OrderedDict()
- self.master = master_port(8)
- self.dispatch_param = dispatch_param
-
- # overload this in derived classes
- def get_port(self, *args, **kwargs):
- pass
-
- def do_finalize(self):
- # TX arbitrate
- sinks = [port.sink for port in self.users.values()]
- self.submodules.arbiter = Arbiter(sinks, self.master.source)
-
- # RX dispatch
- sources = [port.source for port in self.users.values()]
- self.submodules.dispatcher = Dispatcher(self.master.sink,
- sources,
- one_hot=True)
- cases = {}
- cases["default"] = self.dispatcher.sel.eq(0)
- for i, (k, v) in enumerate(self.users.items()):
- cases[k] = self.dispatcher.sel.eq(2**i)
- self.comb += \
- Case(getattr(self.master.sink, self.dispatch_param), cases)
+++ /dev/null
-from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-
-
-class LiteEthDepacketizer(Module):
- def __init__(self, sink_description, source_description, header):
- self.sink = sink = Sink(sink_description)
- self.source = source = Source(source_description)
- self.header = Signal(header.length*8)
-
- # # #
-
- dw = flen(sink.data)
-
- header_words = (header.length*8)//dw
-
- shift = Signal()
- counter = Counter(max=max(header_words, 2))
- self.submodules += counter
-
- if header_words == 1:
- self.sync += \
- If(shift,
- self.header.eq(sink.data)
- )
- else:
- self.sync += \
- If(shift,
- self.header.eq(Cat(self.header[dw:], sink.data))
- )
-
- fsm = FSM(reset_state="IDLE")
- self.submodules += fsm
-
- if header_words == 1:
- idle_next_state = "COPY"
- else:
- idle_next_state = "RECEIVE_HEADER"
-
- fsm.act("IDLE",
- sink.ack.eq(1),
- counter.reset.eq(1),
- If(sink.stb,
- shift.eq(1),
- NextState(idle_next_state)
- )
- )
- if header_words != 1:
- fsm.act("RECEIVE_HEADER",
- sink.ack.eq(1),
- If(sink.stb,
- counter.ce.eq(1),
- shift.eq(1),
- If(counter.value == header_words-2,
- NextState("COPY")
- )
- )
- )
- no_payload = Signal()
- self.sync += \
- If(fsm.before_entering("COPY"),
- source.sop.eq(1),
- no_payload.eq(sink.eop)
- ).Elif(source.stb & source.ack,
- source.sop.eq(0)
- )
- self.comb += [
- source.eop.eq(sink.eop | no_payload),
- source.data.eq(sink.data),
- source.error.eq(sink.error),
- header.decode(self.header, source)
- ]
- fsm.act("COPY",
- sink.ack.eq(source.ack),
- source.stb.eq(sink.stb | no_payload),
- If(source.stb & source.ack & source.eop,
- NextState("IDLE")
- )
- )
+++ /dev/null
-from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-
-
-class LiteEthPacketizer(Module):
- def __init__(self, sink_description, source_description, header):
- self.sink = sink = Sink(sink_description)
- self.source = source = Source(source_description)
- self.header = Signal(header.length*8)
-
- # # #
-
- dw = flen(self.sink.data)
-
- header_reg = Signal(header.length*8)
- header_words = (header.length*8)//dw
- load = Signal()
- shift = Signal()
- counter = Counter(max=max(header_words, 2))
- self.submodules += counter
-
- self.comb += header.encode(sink, self.header)
- if header_words == 1:
- self.sync += [
- If(load,
- header_reg.eq(self.header)
- )
- ]
- else:
- self.sync += [
- If(load,
- header_reg.eq(self.header)
- ).Elif(shift,
- header_reg.eq(Cat(header_reg[dw:], Signal(dw)))
- )
- ]
-
- fsm = FSM(reset_state="IDLE")
- self.submodules += fsm
-
- if header_words == 1:
- idle_next_state = "COPY"
- else:
- idle_next_state = "SEND_HEADER"
-
- fsm.act("IDLE",
- sink.ack.eq(1),
- counter.reset.eq(1),
- If(sink.stb & sink.sop,
- sink.ack.eq(0),
- source.stb.eq(1),
- source.sop.eq(1),
- source.eop.eq(0),
- source.data.eq(self.header[:dw]),
- If(source.stb & source.ack,
- load.eq(1),
- NextState(idle_next_state)
- )
- )
- )
- if header_words != 1:
- fsm.act("SEND_HEADER",
- source.stb.eq(1),
- source.sop.eq(0),
- source.eop.eq(0),
- source.data.eq(header_reg[dw:2*dw]),
- If(source.stb & source.ack,
- shift.eq(1),
- counter.ce.eq(1),
- If(counter.value == header_words-2,
- NextState("COPY")
- )
- )
- )
- fsm.act("COPY",
- source.stb.eq(sink.stb),
- source.sop.eq(0),
- source.eop.eq(sink.eop),
- source.data.eq(sink.data),
- source.error.eq(sink.error),
- If(source.stb & source.ack,
- sink.ack.eq(1),
- If(source.eop,
- NextState("IDLE")
- )
- )
- )
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from misoclib.com.liteeth.mac.common import *
from misoclib.com.liteeth.mac.core import LiteEthMACCore
from misoclib.com.liteeth.mac.frontend.wishbone import LiteEthMACWishboneInterface
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-from misoclib.com.liteeth.generic.depacketizer import LiteEthDepacketizer
-from misoclib.com.liteeth.generic.packetizer import LiteEthPacketizer
-from misoclib.com.liteeth.generic.crossbar import LiteEthCrossbar
+from misoclib.com.liteeth.crossbar import LiteEthCrossbar
-class LiteEthMACDepacketizer(LiteEthDepacketizer):
+class LiteEthMACDepacketizer(Depacketizer):
def __init__(self):
- LiteEthDepacketizer.__init__(self,
+ Depacketizer.__init__(self,
eth_phy_description(8),
eth_mac_description(8),
mac_header)
-class LiteEthMACPacketizer(LiteEthPacketizer):
+class LiteEthMACPacketizer(Packetizer):
def __init__(self):
- LiteEthPacketizer.__init__(self,
+ Packetizer.__init__(self,
eth_mac_description(8),
eth_phy_description(8),
mac_header)
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from misoclib.com.liteeth.mac.core import gap, preamble, crc, padding, last_be
from misoclib.com.liteeth.phy.sim import LiteEthPHYSim
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
class LiteEthMACCRCEngine(Module):
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
-
class LiteEthMACGap(Module):
def __init__(self, dw, ack_on_gap=False):
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
class LiteEthMACTXLastBE(Module):
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
class LiteEthMACPaddingInserter(Module):
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
class LiteEthMACPreambleInserter(Module):
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from migen.bank.description import *
from migen.bank.eventmanager import *
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from misoclib.com.liteeth.mac.frontend import sram
from migen.bus import wishbone
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
def LiteEthPHY(clock_pads, pads, **kwargs):
from migen.genlib.io import DDROutput
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
class LiteEthPHYGMIITX(Module):
from migen.genlib.cdc import PulseSynchronizer
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from misoclib.com.liteeth.phy.gmii import LiteEthPHYGMIICRG
from misoclib.com.liteeth.phy.mii import LiteEthPHYMIITX, LiteEthPHYMIIRX
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
def converter_description(dw):
import os
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
class LiteEthPHYSimCRG(Module, AutoCSR):
self.packet = self.packets.pop(0)
if not self.packet.ongoing and not self.packet.done:
selfp.source.stb = 1
- selfp.source.sop = 1
+ if self.source.description.packetized:
+ selfp.source.sop = 1
selfp.source.data = self.packet.pop(0)
self.packet.ongoing = True
elif selfp.source.stb == 1 and selfp.source.ack == 1:
- selfp.source.sop = 0
- if len(self.packet) == 1:
- selfp.source.eop = 1
- if self.last_be is not None:
- selfp.source.last_be = self.last_be
- else:
- selfp.source.eop = 0
- if self.last_be is not None:
- selfp.source.last_be = 0
+ if self.source.description.packetized:
+ selfp.source.sop = 0
+ if len(self.packet) == 1:
+ selfp.source.eop = 1
+ if self.last_be is not None:
+ selfp.source.last_be = self.last_be
+ else:
+ selfp.source.eop = 0
+ if self.last_be is not None:
+ selfp.source.last_be = 0
if len(self.packet) > 0:
selfp.source.stb = 1
selfp.source.data = self.packet.pop(0)
def do_simulation(self, selfp):
selfp.sink.ack = 1
- if selfp.sink.stb == 1 and selfp.sink.sop == 1:
- self.packet = Packet()
- self.packet.append(selfp.sink.data)
- elif selfp.sink.stb:
- self.packet.append(selfp.sink.data)
- if selfp.sink.stb == 1 and selfp.sink.eop == 1:
- self.packet.done = True
+ if selfp.sink.stb:
+ if self.sink.description.packetized:
+ if selfp.sink.sop:
+ self.packet = Packet()
+ self.packet.append(selfp.sink.data)
+ else:
+ self.packet.append(selfp.sink.data)
+ if selfp.sink.eop:
+ self.packet.done = True
+ else:
+ self.packet.append(selfp.sink.data)
class AckRandomizer(Module):
from misoclib.com.liteeth.common import *
from misoclib.com.liteeth.core import LiteEthUDPIPCore
-from misoclib.com.liteeth.core.etherbone import LiteEthEtherbone
+from misoclib.com.liteeth.frontend.etherbone import LiteEthEtherbone
from misoclib.com.liteeth.test.common import *
from misoclib.com.liteeth.test.model import phy, mac, arp, ip, udp, etherbone