uart: implement stream (un)packing, tidy interfaces on COBS encoder
This commit is contained in:
parent
62049bac84
commit
ba8462968e
|
|
@ -23,17 +23,18 @@ class COBSDecode(Elaboratable):
|
|||
|
||||
# State Machine:
|
||||
with m.FSM():
|
||||
with m.State("WAIT_FOR_PACKET_START"):
|
||||
with m.If((self.data_i == 0) & (self.valid_i)):
|
||||
m.next = "START_OF_PACKET"
|
||||
# TODO: determine if wait for packet logic should stay
|
||||
# with m.State("WAIT_FOR_PACKET_START"):
|
||||
# with m.If((self.data_i == 0) & (self.valid_i)):
|
||||
# m.next = "START_OF_PACKET"
|
||||
|
||||
with m.State("START_OF_PACKET"):
|
||||
with m.If(self.valid_i):
|
||||
m.d.sync += counter.eq(self.data_i - 1)
|
||||
m.next = "DECODING"
|
||||
|
||||
with m.Else():
|
||||
m.next = "START_OF_PACKET"
|
||||
# with m.Else():
|
||||
# m.next = "START_OF_PACKET"
|
||||
|
||||
with m.State("DECODING"):
|
||||
with m.If(self.valid_i):
|
||||
|
|
|
|||
|
|
@ -5,13 +5,11 @@ from amaranth.lib.memory import Memory
|
|||
class COBSEncode(Elaboratable):
|
||||
def __init__(self):
|
||||
# Top-Level IO
|
||||
self.start = Signal()
|
||||
self.done = Signal()
|
||||
|
||||
# Stream-like data input
|
||||
self.data_i = Signal(8)
|
||||
self.valid_i = Signal()
|
||||
self.ready_o = Signal()
|
||||
self.last_i = Signal()
|
||||
|
||||
# Stream-like data output
|
||||
self.data_o = Signal(8)
|
||||
|
|
@ -44,7 +42,7 @@ class COBSEncode(Elaboratable):
|
|||
# State Machine:
|
||||
with m.FSM() as fsm:
|
||||
with m.State("IDLE"):
|
||||
with m.If(self.start):
|
||||
with m.If(self.last_i):
|
||||
m.d.sync += head_pointer.eq(0)
|
||||
m.d.sync += tail_pointer.eq(0)
|
||||
m.d.sync += rd_port.addr.eq(0)
|
||||
|
|
@ -108,4 +106,6 @@ class COBSEncode(Elaboratable):
|
|||
m.d.comb += wr_port.data.eq(self.data_i)
|
||||
m.d.sync += wr_port.addr.eq(wr_port.addr + wr_port.en)
|
||||
|
||||
m.d.comb += self.ready_o.eq(fsm.ongoing("IDLE"))
|
||||
|
||||
return m
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ class StreamPacker(Elaboratable):
|
|||
def __init__(self):
|
||||
self.data_i = Signal(8)
|
||||
self.valid_i = Signal()
|
||||
self.ready_o = Signal(init=1)
|
||||
self.last_i = Signal()
|
||||
|
||||
self.data_o = Signal(32)
|
||||
|
|
@ -14,4 +15,26 @@ class StreamPacker(Elaboratable):
|
|||
|
||||
def elaborate(self, platform):
|
||||
m = Module()
|
||||
|
||||
count = Signal(range(4))
|
||||
|
||||
with m.If(self.ready_o):
|
||||
with m.If(self.valid_i):
|
||||
m.d.sync += self.data_o.eq(Cat(self.data_o[8:], self.data_i))
|
||||
m.d.sync += count.eq(count + 1)
|
||||
|
||||
with m.If(count == 3):
|
||||
m.d.sync += self.ready_o.eq(0)
|
||||
m.d.sync += self.valid_o.eq(1)
|
||||
m.d.sync += self.last_o.eq(self.last_i)
|
||||
|
||||
with m.Else():
|
||||
with m.If(self.valid_o & self.ready_i):
|
||||
m.d.sync += self.ready_o.eq(1)
|
||||
m.d.sync += self.valid_o.eq(0)
|
||||
|
||||
# TODO: not necessary, but makes debugging much easier!
|
||||
m.d.sync += self.data_o.eq(0)
|
||||
m.d.sync += self.last_o.eq(0)
|
||||
|
||||
return m
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ class StreamUnpacker(Elaboratable):
|
|||
def __init__(self):
|
||||
self.data_i = Signal(32)
|
||||
self.valid_i = Signal()
|
||||
self.ready_o = Signal()
|
||||
self.ready_o = Signal(init=1)
|
||||
self.last_i = Signal()
|
||||
|
||||
self.data_o = Signal(8)
|
||||
|
|
@ -15,4 +15,40 @@ class StreamUnpacker(Elaboratable):
|
|||
|
||||
def elaborate(self, platform):
|
||||
m = Module()
|
||||
|
||||
# Turn a stream of 32-bit numbers into a stream of 8-bit numbers
|
||||
buf = Signal(24)
|
||||
last = Signal()
|
||||
count = Signal(range(3))
|
||||
|
||||
with m.If(self.ready_o):
|
||||
with m.If(self.valid_i):
|
||||
m.d.sync += buf.eq(self.data_i[8:])
|
||||
m.d.sync += last.eq(self.last_i)
|
||||
m.d.sync += self.ready_o.eq(0)
|
||||
|
||||
m.d.sync += self.data_o.eq(self.data_i[:7])
|
||||
m.d.sync += self.valid_o.eq(1)
|
||||
|
||||
m.d.sync += count.eq(0)
|
||||
|
||||
# Have some data in the buffer
|
||||
with m.Else():
|
||||
with m.If(self.valid_o & self.ready_i):
|
||||
# if done, clean up and signal ready for next word
|
||||
with m.If(count == 3):
|
||||
m.d.sync += self.valid_o.eq(0)
|
||||
m.d.sync += self.ready_o.eq(1)
|
||||
|
||||
# TODO: not necessary, but makes debugging much easier!
|
||||
m.d.sync += self.data_o.eq(0)
|
||||
m.d.sync += self.last_o.eq(0)
|
||||
|
||||
# if not done, clock out next byte
|
||||
with m.Else():
|
||||
m.d.sync += self.data_o.eq(buf[8:])
|
||||
m.d.sync += buf.eq(buf >> 8)
|
||||
m.d.sync += count.eq(count + 1)
|
||||
|
||||
m.d.sync += self.last_o.eq((last) & (count == 2))
|
||||
return m
|
||||
|
|
|
|||
Loading…
Reference in New Issue