From: Florent Kermarrec Date: Tue, 28 Apr 2015 16:51:40 +0000 (+0200) Subject: liteeth: use Migen's Packetizer/Depacketizer, remove generic and move etherbone/tty... X-Git-Tag: 24jan2021_ls180~2289 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d253adee61ad9f795f872d7dacdeac2f63c4883f;p=litex.git liteeth: use Migen's Packetizer/Depacketizer, remove generic and move etherbone/tty to frontend --- diff --git a/misoclib/com/liteeth/common.py b/misoclib/com/liteeth/common.py index 0bc1b01c..f933a34e 100644 --- a/misoclib/com/liteeth/common.py +++ b/misoclib/com/liteeth/common.py @@ -12,6 +12,14 @@ from migen.actorlib.fifo import SyncFIFO, AsyncFIFO 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 diff --git a/misoclib/com/liteeth/core/__init__.py b/misoclib/com/liteeth/core/__init__.py index 83451316..f789ac7e 100644 --- a/misoclib/com/liteeth/core/__init__.py +++ b/misoclib/com/liteeth/core/__init__.py @@ -1,5 +1,4 @@ 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 diff --git a/misoclib/com/liteeth/core/arp/__init__.py b/misoclib/com/liteeth/core/arp/__init__.py index 0c8b68a0..b46522a5 100644 --- a/misoclib/com/liteeth/core/arp/__init__.py +++ b/misoclib/com/liteeth/core/arp/__init__.py @@ -1,7 +1,4 @@ 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), @@ -11,9 +8,9 @@ _arp_table_layout = [ ] -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) @@ -76,9 +73,9 @@ class LiteEthARPTX(Module): ) -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) diff --git a/misoclib/com/liteeth/core/etherbone/__init__.py b/misoclib/com/liteeth/core/etherbone/__init__.py deleted file mode 100644 index 3c7d6f9a..00000000 --- a/misoclib/com/liteeth/core/etherbone/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -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) - ] diff --git a/misoclib/com/liteeth/core/etherbone/dissector/bit.lua b/misoclib/com/liteeth/core/etherbone/dissector/bit.lua deleted file mode 100644 index d9fd4ceb..00000000 --- a/misoclib/com/liteeth/core/etherbone/dissector/bit.lua +++ /dev/null @@ -1,260 +0,0 @@ ---[[--------------- -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 ---]] - - - - - - - - - - - - - diff --git a/misoclib/com/liteeth/core/etherbone/dissector/etherbone.lua b/misoclib/com/liteeth/core/etherbone/dissector/etherbone.lua deleted file mode 100644 index 0a629a43..00000000 --- a/misoclib/com/liteeth/core/etherbone/dissector/etherbone.lua +++ /dev/null @@ -1,223 +0,0 @@ --- 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) diff --git a/misoclib/com/liteeth/core/etherbone/packet.py b/misoclib/com/liteeth/core/etherbone/packet.py deleted file mode 100644 index 2a236d57..00000000 --- a/misoclib/com/liteeth/core/etherbone/packet.py +++ /dev/null @@ -1,138 +0,0 @@ -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 diff --git a/misoclib/com/liteeth/core/etherbone/probe.py b/misoclib/com/liteeth/core/etherbone/probe.py deleted file mode 100644 index 9e9671f7..00000000 --- a/misoclib/com/liteeth/core/etherbone/probe.py +++ /dev/null @@ -1,27 +0,0 @@ -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") - ) - ) diff --git a/misoclib/com/liteeth/core/etherbone/record.py b/misoclib/com/liteeth/core/etherbone/record.py deleted file mode 100644 index 263234c4..00000000 --- a/misoclib/com/liteeth/core/etherbone/record.py +++ /dev/null @@ -1,186 +0,0 @@ -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)) diff --git a/misoclib/com/liteeth/core/etherbone/wishbone.py b/misoclib/com/liteeth/core/etherbone/wishbone.py deleted file mode 100644 index fbaf0630..00000000 --- a/misoclib/com/liteeth/core/etherbone/wishbone.py +++ /dev/null @@ -1,71 +0,0 @@ -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") - ) - ) - ) diff --git a/misoclib/com/liteeth/core/icmp/__init__.py b/misoclib/com/liteeth/core/icmp/__init__.py index e1ddeee8..fc3bdff1 100644 --- a/misoclib/com/liteeth/core/icmp/__init__.py +++ b/misoclib/com/liteeth/core/icmp/__init__.py @@ -1,12 +1,9 @@ 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) @@ -51,9 +48,9 @@ class LiteEthICMPTX(Module): ) -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) diff --git a/misoclib/com/liteeth/core/ip/__init__.py b/misoclib/com/liteeth/core/ip/__init__.py index 88a2f3cd..db564aac 100644 --- a/misoclib/com/liteeth/core/ip/__init__.py +++ b/misoclib/com/liteeth/core/ip/__init__.py @@ -1,14 +1,11 @@ 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) @@ -98,9 +95,9 @@ class LiteEthIPTX(Module): ) -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) diff --git a/misoclib/com/liteeth/core/ip/checksum.py b/misoclib/com/liteeth/core/ip/checksum.py index 266713b6..34e84676 100644 --- a/misoclib/com/liteeth/core/ip/checksum.py +++ b/misoclib/com/liteeth/core/ip/checksum.py @@ -1,5 +1,4 @@ from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * class LiteEthIPV4Checksum(Module): diff --git a/misoclib/com/liteeth/core/ip/crossbar.py b/misoclib/com/liteeth/core/ip/crossbar.py index 6228c9e7..4570f4fe 100644 --- a/misoclib/com/liteeth/core/ip/crossbar.py +++ b/misoclib/com/liteeth/core/ip/crossbar.py @@ -1,6 +1,5 @@ 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: diff --git a/misoclib/com/liteeth/core/tty/__init__.py b/misoclib/com/liteeth/core/tty/__init__.py deleted file mode 100644 index d88d7273..00000000 --- a/misoclib/com/liteeth/core/tty/__init__.py +++ /dev/null @@ -1,104 +0,0 @@ -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 diff --git a/misoclib/com/liteeth/core/udp/__init__.py b/misoclib/com/liteeth/core/udp/__init__.py index 20bd9ec6..b0f02d55 100644 --- a/misoclib/com/liteeth/core/udp/__init__.py +++ b/misoclib/com/liteeth/core/udp/__init__.py @@ -1,13 +1,10 @@ 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) @@ -52,9 +49,9 @@ class LiteEthUDPTX(Module): ) -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) diff --git a/misoclib/com/liteeth/core/udp/crossbar.py b/misoclib/com/liteeth/core/udp/crossbar.py index e0024ed7..16b2b20c 100644 --- a/misoclib/com/liteeth/core/udp/crossbar.py +++ b/misoclib/com/liteeth/core/udp/crossbar.py @@ -1,7 +1,5 @@ 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: diff --git a/misoclib/com/liteeth/crossbar.py b/misoclib/com/liteeth/crossbar.py new file mode 100644 index 00000000..d2ee22d3 --- /dev/null +++ b/misoclib/com/liteeth/crossbar.py @@ -0,0 +1,30 @@ +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) diff --git a/misoclib/com/liteeth/example_designs/targets/base.py b/misoclib/com/liteeth/example_designs/targets/base.py index 6f5f11d6..83b47ff1 100644 --- a/misoclib/com/liteeth/example_designs/targets/base.py +++ b/misoclib/com/liteeth/example_designs/targets/base.py @@ -9,7 +9,6 @@ from misoclib.tools.litescope.frontend.la import LiteScopeLA 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 diff --git a/misoclib/com/liteeth/example_designs/targets/etherbone.py b/misoclib/com/liteeth/example_designs/targets/etherbone.py index 7e5d141b..cf6dc51e 100644 --- a/misoclib/com/liteeth/example_designs/targets/etherbone.py +++ b/misoclib/com/liteeth/example_designs/targets/etherbone.py @@ -3,10 +3,9 @@ from misoclib.tools.litescope.frontend.la import LiteScopeLA 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): diff --git a/misoclib/com/liteeth/example_designs/targets/tty.py b/misoclib/com/liteeth/example_designs/targets/tty.py index a915c857..a05fee00 100644 --- a/misoclib/com/liteeth/example_designs/targets/tty.py +++ b/misoclib/com/liteeth/example_designs/targets/tty.py @@ -6,7 +6,7 @@ from misoclib.com.liteeth.common import * 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): diff --git a/misoclib/com/liteeth/example_designs/targets/udp.py b/misoclib/com/liteeth/example_designs/targets/udp.py index 9aea0c23..c793f2a2 100644 --- a/misoclib/com/liteeth/example_designs/targets/udp.py +++ b/misoclib/com/liteeth/example_designs/targets/udp.py @@ -3,7 +3,6 @@ from misoclib.tools.litescope.frontend.la import LiteScopeLA 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 diff --git a/misoclib/com/liteeth/frontend/__init__.py b/misoclib/com/liteeth/frontend/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/misoclib/com/liteeth/frontend/etherbone/__init__.py b/misoclib/com/liteeth/frontend/etherbone/__init__.py new file mode 100644 index 00000000..b2e958f1 --- /dev/null +++ b/misoclib/com/liteeth/frontend/etherbone/__init__.py @@ -0,0 +1,29 @@ +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) + ] diff --git a/misoclib/com/liteeth/frontend/etherbone/dissector/bit.lua b/misoclib/com/liteeth/frontend/etherbone/dissector/bit.lua new file mode 100644 index 00000000..d9fd4ceb --- /dev/null +++ b/misoclib/com/liteeth/frontend/etherbone/dissector/bit.lua @@ -0,0 +1,260 @@ +--[[--------------- +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 +--]] + + + + + + + + + + + + + diff --git a/misoclib/com/liteeth/frontend/etherbone/dissector/etherbone.lua b/misoclib/com/liteeth/frontend/etherbone/dissector/etherbone.lua new file mode 100644 index 00000000..0a629a43 --- /dev/null +++ b/misoclib/com/liteeth/frontend/etherbone/dissector/etherbone.lua @@ -0,0 +1,223 @@ +-- 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) diff --git a/misoclib/com/liteeth/frontend/etherbone/packet.py b/misoclib/com/liteeth/frontend/etherbone/packet.py new file mode 100644 index 00000000..e628bd96 --- /dev/null +++ b/misoclib/com/liteeth/frontend/etherbone/packet.py @@ -0,0 +1,135 @@ +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 diff --git a/misoclib/com/liteeth/frontend/etherbone/probe.py b/misoclib/com/liteeth/frontend/etherbone/probe.py new file mode 100644 index 00000000..ade1305d --- /dev/null +++ b/misoclib/com/liteeth/frontend/etherbone/probe.py @@ -0,0 +1,26 @@ +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") + ) + ) diff --git a/misoclib/com/liteeth/frontend/etherbone/record.py b/misoclib/com/liteeth/frontend/etherbone/record.py new file mode 100644 index 00000000..15879fd2 --- /dev/null +++ b/misoclib/com/liteeth/frontend/etherbone/record.py @@ -0,0 +1,183 @@ +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)) diff --git a/misoclib/com/liteeth/frontend/etherbone/wishbone.py b/misoclib/com/liteeth/frontend/etherbone/wishbone.py new file mode 100644 index 00000000..b9b8c3bc --- /dev/null +++ b/misoclib/com/liteeth/frontend/etherbone/wishbone.py @@ -0,0 +1,70 @@ +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") + ) + ) + ) diff --git a/misoclib/com/liteeth/frontend/tty/__init__.py b/misoclib/com/liteeth/frontend/tty/__init__.py new file mode 100644 index 00000000..56867af9 --- /dev/null +++ b/misoclib/com/liteeth/frontend/tty/__init__.py @@ -0,0 +1,103 @@ +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 diff --git a/misoclib/com/liteeth/generic/__init__.py b/misoclib/com/liteeth/generic/__init__.py deleted file mode 100644 index 71d0d077..00000000 --- a/misoclib/com/liteeth/generic/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -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 diff --git a/misoclib/com/liteeth/generic/crossbar.py b/misoclib/com/liteeth/generic/crossbar.py deleted file mode 100644 index abde85b3..00000000 --- a/misoclib/com/liteeth/generic/crossbar.py +++ /dev/null @@ -1,32 +0,0 @@ -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) diff --git a/misoclib/com/liteeth/generic/depacketizer.py b/misoclib/com/liteeth/generic/depacketizer.py deleted file mode 100644 index 20a85bb0..00000000 --- a/misoclib/com/liteeth/generic/depacketizer.py +++ /dev/null @@ -1,79 +0,0 @@ -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") - ) - ) diff --git a/misoclib/com/liteeth/generic/packetizer.py b/misoclib/com/liteeth/generic/packetizer.py deleted file mode 100644 index 23a83c2a..00000000 --- a/misoclib/com/liteeth/generic/packetizer.py +++ /dev/null @@ -1,87 +0,0 @@ -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") - ) - ) - ) diff --git a/misoclib/com/liteeth/mac/__init__.py b/misoclib/com/liteeth/mac/__init__.py index f951c38b..5c2a0675 100644 --- a/misoclib/com/liteeth/mac/__init__.py +++ b/misoclib/com/liteeth/mac/__init__.py @@ -1,5 +1,4 @@ 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 diff --git a/misoclib/com/liteeth/mac/common.py b/misoclib/com/liteeth/mac/common.py index 809ad4fb..f12cc3e7 100644 --- a/misoclib/com/liteeth/mac/common.py +++ b/misoclib/com/liteeth/mac/common.py @@ -1,21 +1,18 @@ 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) diff --git a/misoclib/com/liteeth/mac/core/__init__.py b/misoclib/com/liteeth/mac/core/__init__.py index 7322c42f..f8b18f73 100644 --- a/misoclib/com/liteeth/mac/core/__init__.py +++ b/misoclib/com/liteeth/mac/core/__init__.py @@ -1,5 +1,4 @@ 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 diff --git a/misoclib/com/liteeth/mac/core/crc.py b/misoclib/com/liteeth/mac/core/crc.py index d3549791..ba7c5319 100644 --- a/misoclib/com/liteeth/mac/core/crc.py +++ b/misoclib/com/liteeth/mac/core/crc.py @@ -1,5 +1,4 @@ from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * class LiteEthMACCRCEngine(Module): diff --git a/misoclib/com/liteeth/mac/core/gap.py b/misoclib/com/liteeth/mac/core/gap.py index d4caf3c6..c1bd9162 100644 --- a/misoclib/com/liteeth/mac/core/gap.py +++ b/misoclib/com/liteeth/mac/core/gap.py @@ -1,6 +1,4 @@ from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * - class LiteEthMACGap(Module): def __init__(self, dw, ack_on_gap=False): diff --git a/misoclib/com/liteeth/mac/core/last_be.py b/misoclib/com/liteeth/mac/core/last_be.py index 29844f38..42f7c641 100644 --- a/misoclib/com/liteeth/mac/core/last_be.py +++ b/misoclib/com/liteeth/mac/core/last_be.py @@ -1,5 +1,4 @@ from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * class LiteEthMACTXLastBE(Module): diff --git a/misoclib/com/liteeth/mac/core/padding.py b/misoclib/com/liteeth/mac/core/padding.py index 7874d874..38b2a3da 100644 --- a/misoclib/com/liteeth/mac/core/padding.py +++ b/misoclib/com/liteeth/mac/core/padding.py @@ -1,5 +1,4 @@ from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * class LiteEthMACPaddingInserter(Module): diff --git a/misoclib/com/liteeth/mac/core/preamble.py b/misoclib/com/liteeth/mac/core/preamble.py index 2854fab9..18e86f83 100644 --- a/misoclib/com/liteeth/mac/core/preamble.py +++ b/misoclib/com/liteeth/mac/core/preamble.py @@ -1,5 +1,4 @@ from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * class LiteEthMACPreambleInserter(Module): diff --git a/misoclib/com/liteeth/mac/frontend/sram.py b/misoclib/com/liteeth/mac/frontend/sram.py index 3a6a8c29..fc3d8c27 100644 --- a/misoclib/com/liteeth/mac/frontend/sram.py +++ b/misoclib/com/liteeth/mac/frontend/sram.py @@ -1,5 +1,4 @@ from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * from migen.bank.description import * from migen.bank.eventmanager import * diff --git a/misoclib/com/liteeth/mac/frontend/wishbone.py b/misoclib/com/liteeth/mac/frontend/wishbone.py index 5b9d5563..91c227f1 100644 --- a/misoclib/com/liteeth/mac/frontend/wishbone.py +++ b/misoclib/com/liteeth/mac/frontend/wishbone.py @@ -1,5 +1,4 @@ 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 diff --git a/misoclib/com/liteeth/phy/__init__.py b/misoclib/com/liteeth/phy/__init__.py index d06352ac..16413b9b 100644 --- a/misoclib/com/liteeth/phy/__init__.py +++ b/misoclib/com/liteeth/phy/__init__.py @@ -1,5 +1,4 @@ from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * def LiteEthPHY(clock_pads, pads, **kwargs): diff --git a/misoclib/com/liteeth/phy/gmii.py b/misoclib/com/liteeth/phy/gmii.py index 998522b3..cdf07180 100644 --- a/misoclib/com/liteeth/phy/gmii.py +++ b/misoclib/com/liteeth/phy/gmii.py @@ -1,7 +1,6 @@ from migen.genlib.io import DDROutput from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * class LiteEthPHYGMIITX(Module): diff --git a/misoclib/com/liteeth/phy/gmii_mii.py b/misoclib/com/liteeth/phy/gmii_mii.py index d1bd7d7f..ec3e5855 100644 --- a/misoclib/com/liteeth/phy/gmii_mii.py +++ b/misoclib/com/liteeth/phy/gmii_mii.py @@ -3,7 +3,6 @@ from migen.flow.plumbing import Multiplexer, Demultiplexer 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 diff --git a/misoclib/com/liteeth/phy/mii.py b/misoclib/com/liteeth/phy/mii.py index 5f121cdf..e687e763 100644 --- a/misoclib/com/liteeth/phy/mii.py +++ b/misoclib/com/liteeth/phy/mii.py @@ -1,5 +1,4 @@ from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * def converter_description(dw): diff --git a/misoclib/com/liteeth/phy/sim.py b/misoclib/com/liteeth/phy/sim.py index d4067b3e..eda52d6e 100644 --- a/misoclib/com/liteeth/phy/sim.py +++ b/misoclib/com/liteeth/phy/sim.py @@ -1,7 +1,6 @@ import os from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * class LiteEthPHYSimCRG(Module, AutoCSR): diff --git a/misoclib/com/liteeth/test/common.py b/misoclib/com/liteeth/test/common.py index 4f72b6fa..716443c3 100644 --- a/misoclib/com/liteeth/test/common.py +++ b/misoclib/com/liteeth/test/common.py @@ -108,19 +108,21 @@ class PacketStreamer(Module): 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) @@ -144,13 +146,17 @@ class PacketLogger(Module): 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): diff --git a/misoclib/com/liteeth/test/etherbone_tb.py b/misoclib/com/liteeth/test/etherbone_tb.py index c070a32b..8f868474 100644 --- a/misoclib/com/liteeth/test/etherbone_tb.py +++ b/misoclib/com/liteeth/test/etherbone_tb.py @@ -5,7 +5,7 @@ from migen.sim.generic import run_simulation 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