mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
etherbone: code wishbone master
This commit is contained in:
parent
384fc3c868
commit
eee07e6eec
5 changed files with 105 additions and 117 deletions
|
@ -276,7 +276,8 @@ def eth_etherbone_record_description(dw):
|
|||
|
||||
def eth_etherbone_mmap_description(dw):
|
||||
payload_layout = [
|
||||
("data_addr", max(32, dw)),
|
||||
("addr", 32),
|
||||
("data", dw)
|
||||
]
|
||||
param_layout = [
|
||||
("count", 8),
|
||||
|
|
|
@ -6,6 +6,7 @@ from liteeth.generic.dispatcher import Dispatcher
|
|||
from liteeth.core.etherbone.packet import *
|
||||
from liteeth.core.etherbone.probe import *
|
||||
from liteeth.core.etherbone.record import *
|
||||
from liteeth.core.etherbone.wishbone import *
|
||||
|
||||
class LiteEthEtherbone(Module):
|
||||
def __init__(self, udp, udp_port):
|
||||
|
@ -19,3 +20,12 @@ class LiteEthEtherbone(Module):
|
|||
|
||||
arbiter = Arbiter([probe.source, record.source], packet.sink)
|
||||
self.submodules += arbiter
|
||||
|
||||
self.submodules.wishbone = wishbone = LiteEthEtherboneWishboneMaster()
|
||||
self.comb += [
|
||||
Record.connect(record.receiver.wr_source, wishbone.wr_sink),
|
||||
Record.connect(record.receiver.rd_source, wishbone.rd_sink),
|
||||
Record.connect(wishbone.wr_source, record.sender.wr_sink),
|
||||
Record.connect(wishbone.rd_source, record.sender.rd_sink)
|
||||
]
|
||||
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
from liteeth.common import *
|
||||
|
||||
class LiteEthEtherboneWishboneMaster(Module):
|
||||
def __init__(self):
|
||||
self.sink = sink = Sink(eth_etherbone_user_description(32))
|
||||
self.source = source = Source(eth_etherbone_description(32))
|
||||
self.bus = bus = wishbone.Interface()
|
||||
###
|
||||
|
||||
self.submodules.base_addr = base_addr = FlipFlop(32)
|
||||
self.comb += self.base_addr.d.eq(self.sink.data)
|
||||
self.submodules.counter = counter = Counter(32)
|
||||
|
||||
self.submodules.fifo = fifo = SyncFIFO([("data", 32)], 256)
|
||||
|
||||
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
||||
fsm.act("IDLE",
|
||||
sink.ack.eq(1),
|
||||
counter.reset.eq(1),
|
||||
If(sink.stb & sink.sop,
|
||||
If(sink.wcount > 0,
|
||||
self.base_addr.ce.eq(1),
|
||||
NextState("WRITE_DATA")
|
||||
).Elif(sink.rcount > 0,
|
||||
self.base_addr.ce.eq(1),
|
||||
NextState("READ_DATA")
|
||||
)
|
||||
)
|
||||
)
|
||||
fsm.act("WRITE_DATA",
|
||||
bus.adr.eq(base_addr + self.counter.value),
|
||||
bus.dat_w.eq(sink.data),
|
||||
bus.sel.eq(0xf), # XXX?
|
||||
bus.stb.eq(sink.stb),
|
||||
bus.we.eq(1),
|
||||
bus.cyc.eq(1),
|
||||
If(bus.stb & bus.ack,
|
||||
sink.ack.eq(1),
|
||||
counter.ce.eq(1),
|
||||
If(counter.value == sink.wcount-1,
|
||||
If(sink.rcount > 0,
|
||||
counter.reset.eq(1)
|
||||
NextState("READ_DATA")
|
||||
).Else(
|
||||
NextState("TERMINATE")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
fsm.act("CHECK_READ",
|
||||
If(sink.rcount > 0,
|
||||
If(sink.stb,
|
||||
sink.ack.eq(1),
|
||||
base_addr.ce.eq(1),
|
||||
NextState("READ_DATA")
|
||||
)
|
||||
).Else(
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
fsm.act("READ_DATA",
|
||||
bus.adr.eq(self.sink.data),
|
||||
bus.sel.eq(0xf),
|
||||
bus.stb.eq(1),
|
||||
bus.we.eq(0),
|
||||
bus.cyc.eq(1),
|
||||
If(bus.stb & bus.ack,
|
||||
sink.ack.eq(1),
|
||||
counter.ce.eq(1),
|
||||
fifo.sink.stb.eq(1),
|
||||
fifo.sink.sop.eq(counter == 0),
|
||||
fifo.sink.data.eq(bus.dat_r),
|
||||
If(counter.value == sink.rcount-1,
|
||||
fifo.sink.eop.eq(1),
|
||||
NextState("PRESENT_DATA")
|
||||
)
|
||||
)
|
||||
)
|
||||
fsm.act("PRESENT_DATA",
|
||||
source.stb.eq(fifo.stb),
|
||||
source.sop.eq(fifo.sop),
|
||||
source.eop.eq(fifo.eop),
|
||||
fifo.ack.eq(source.ack),
|
||||
source.length.eq(sink.rcount+1),
|
||||
source.wcount.eq(sink.rcount),
|
||||
source.rcount.eq(0),
|
||||
If(source.stb & source.eop & source.ack,
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
|
@ -21,8 +21,8 @@ class LiteEthEtherboneRecordDepacketizer(LiteEthDepacketizer):
|
|||
class LiteEthEtherboneRecordReceiver(Module):
|
||||
def __init__(self):
|
||||
self.sink = sink = Sink(eth_etherbone_record_description(32))
|
||||
self.write_source = write_source = Source(eth_etherbone_mmap_description(32))
|
||||
self.read_source = read_source = Source(eth_etherbone_mmap_description(32))
|
||||
self.wr_source = wr_source = Source(eth_etherbone_mmap_description(32))
|
||||
self.rd_source = rd_source = Source(eth_etherbone_mmap_description(32))
|
||||
###
|
||||
|
||||
self.submodules.base_addr = base_addr = FlipFlop(32)
|
||||
|
@ -44,16 +44,17 @@ class LiteEthEtherboneRecordReceiver(Module):
|
|||
)
|
||||
)
|
||||
fsm.act("RECEIVE_WRITES",
|
||||
write_source.stb.eq(sink.stb),
|
||||
write_source.sop.eq(counter.value == 0),
|
||||
write_source.eop.eq(counter.value == sink.wcount-1),
|
||||
write_source.count.eq(sink.wcount),
|
||||
write_source.base_addr.eq(base_addr.q),
|
||||
write_source.data_addr.eq(sink.data),
|
||||
sink.ack.eq(write_source.ack),
|
||||
If(write_source.stb & write_source.ack,
|
||||
wr_source.stb.eq(sink.stb),
|
||||
wr_source.sop.eq(counter.value == 0),
|
||||
wr_source.eop.eq(counter.value == sink.wcount-1),
|
||||
wr_source.count.eq(sink.wcount),
|
||||
wr_source.be.eq(sink.byte_enable),
|
||||
wr_source.addr.eq(base_addr.q + counter.value),
|
||||
wr_source.data.eq(sink.data),
|
||||
sink.ack.eq(wr_source.ack),
|
||||
If(wr_source.stb & wr_source.ack,
|
||||
counter.ce.eq(1),
|
||||
If(write_source.eop,
|
||||
If(wr_source.eop,
|
||||
If(sink.rcount,
|
||||
NextState("RECEIVE_BASE_RET_ADDR")
|
||||
).Else(
|
||||
|
@ -70,16 +71,16 @@ class LiteEthEtherboneRecordReceiver(Module):
|
|||
)
|
||||
)
|
||||
fsm.act("RECEIVE_READS",
|
||||
read_source.stb.eq(sink.stb),
|
||||
read_source.sop.eq(counter.value == 0),
|
||||
read_source.eop.eq(counter.value == sink.rcount-1),
|
||||
read_source.count.eq(sink.rcount),
|
||||
read_source.base_addr.eq(base_addr.q),
|
||||
read_source.data_addr.eq(sink.data),
|
||||
sink.ack.eq(read_source.ack),
|
||||
If(read_source.stb & read_source.ack,
|
||||
rd_source.stb.eq(sink.stb),
|
||||
rd_source.sop.eq(counter.value == 0),
|
||||
rd_source.eop.eq(counter.value == sink.rcount-1),
|
||||
rd_source.count.eq(sink.rcount),
|
||||
rd_source.base_addr.eq(base_addr.q),
|
||||
rd_source.addr.eq(sink.data),
|
||||
sink.ack.eq(rd_source.ack),
|
||||
If(rd_source.stb & rd_source.ack,
|
||||
counter.ce.eq(1),
|
||||
If(read_source.eop,
|
||||
If(rd_source.eop,
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
|
@ -95,15 +96,11 @@ class LiteEthEtherboneRecordSender(Module):
|
|||
self.submodules.wr_buffer = wr_buffer = PacketBuffer(eth_etherbone_mmap_description(32), 512)
|
||||
self.comb += Record.connect(wr_sink, wr_buffer.sink)
|
||||
|
||||
self.submodules.base_addr = base_addr = FlipFlop(32)
|
||||
self.comb += base_addr.d.eq(wr_buffer.source.data_addr)
|
||||
|
||||
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
||||
fsm.act("IDLE",
|
||||
wr_buffer.source.ack.eq(1),
|
||||
If(wr_buffer.source.stb & wr_buffer.source.sop,
|
||||
wr_buffer.source.ack.eq(0),
|
||||
base_addr.ce.eq(1),
|
||||
NextState("SEND_BASE_ADDRESS")
|
||||
)
|
||||
)
|
||||
|
@ -117,7 +114,7 @@ class LiteEthEtherboneRecordSender(Module):
|
|||
source.stb.eq(wr_buffer.source.stb),
|
||||
source.sop.eq(1),
|
||||
source.eop.eq(0),
|
||||
source.data.eq(base_addr.q),
|
||||
source.data.eq(wr_buffer.source.base_addr),
|
||||
If(source.ack,
|
||||
NextState("SEND_DATA")
|
||||
)
|
||||
|
@ -126,7 +123,7 @@ class LiteEthEtherboneRecordSender(Module):
|
|||
source.stb.eq(wr_buffer.source.stb),
|
||||
source.sop.eq(0),
|
||||
source.eop.eq(wr_buffer.source.eop),
|
||||
source.data.eq(wr_buffer.source.data_addr),
|
||||
source.data.eq(wr_buffer.source.data),
|
||||
If(source.stb & source.eop & source.ack,
|
||||
NextState("IDLE")
|
||||
)
|
||||
|
|
70
liteeth/core/etherbone/wishbone.py
Normal file
70
liteeth/core/etherbone/wishbone.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
from liteeth.common import *
|
||||
from migen.bus import wishbone
|
||||
|
||||
class LiteEthEtherboneWishboneMaster(Module):
|
||||
def __init__(self):
|
||||
self.wr_sink = wr_sink = Sink(eth_etherbone_mmap_description(32))
|
||||
self.rd_sink = rd_sink = Sink(eth_etherbone_mmap_description(32))
|
||||
self.wr_source = wr_source = Source(eth_etherbone_mmap_description(32))
|
||||
self.rd_source = rd_source = Source(eth_etherbone_mmap_description(32))
|
||||
self.bus = bus = wishbone.Interface()
|
||||
###s
|
||||
|
||||
data = FlipFlop(32)
|
||||
self.submodules += data
|
||||
self.comb += data.d.eq(bus.dat_r)
|
||||
|
||||
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
||||
fsm.act("IDLE",
|
||||
wr_sink.ack.eq(1),
|
||||
rd_sink.ack.eq(1),
|
||||
If(wr_sink.stb & wr_sink.sop,
|
||||
wr_sink.ack.eq(0),
|
||||
NextState("WRITE_DATA")
|
||||
).Elif(rd_sink.stb & rd_sink.sop,
|
||||
rd_sink.ack.eq(0),
|
||||
NextState("READ_DATA")
|
||||
)
|
||||
)
|
||||
fsm.act("WRITE_DATA",
|
||||
bus.adr.eq(wr_sink.addr),
|
||||
bus.dat_w.eq(wr_sink.data),
|
||||
bus.sel.eq(wr_sink.be),
|
||||
bus.stb.eq(wr_sink.stb),
|
||||
bus.we.eq(1),
|
||||
bus.cyc.eq(1),
|
||||
If(bus.stb & bus.ack,
|
||||
wr_sink.ack.eq(1),
|
||||
If(wr_sink.eop,
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
)
|
||||
fsm.act("READ_DATA",
|
||||
bus.adr.eq(rd_sink.addr),
|
||||
bus.sel.eq(rd_sink.be),
|
||||
bus.stb.eq(rd_sink.stb),
|
||||
bus.cyc.eq(1),
|
||||
If(bus.stb & bus.ack,
|
||||
data.ce.eq(1),
|
||||
NextState("SEND_DATA")
|
||||
)
|
||||
)
|
||||
fsm.act("SEND_DATA",
|
||||
wr_source.stb.eq(rd_sink.stb),
|
||||
wr_source.sop.eq(rd_sink.sop),
|
||||
wr_source.eop.eq(rd_sink.eop),
|
||||
wr_source.base_addr.eq(rd_sink.base_addr),
|
||||
wr_source.addr.eq(rd_sink.addr),
|
||||
wr_source.count.eq(rd_sink.count),
|
||||
wr_source.be.eq(rd_sink.be),
|
||||
wr_source.data.eq(data.q),
|
||||
If(wr_source.stb & wr_source.ack,
|
||||
rd_sink.ack.eq(1),
|
||||
If(wr_source.eop,
|
||||
NextState("IDLE")
|
||||
).Else(
|
||||
NextState("READ_DATA")
|
||||
)
|
||||
)
|
||||
)
|
Loading…
Reference in a new issue