diff --git a/src/manta/uart/cobs_decode.py b/src/manta/uart/cobs_decode.py index f8028a8..9d9b5e0 100644 --- a/src/manta/uart/cobs_decode.py +++ b/src/manta/uart/cobs_decode.py @@ -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): diff --git a/src/manta/uart/cobs_encode.py b/src/manta/uart/cobs_encode.py index 3adf3a5..69fc94a 100644 --- a/src/manta/uart/cobs_encode.py +++ b/src/manta/uart/cobs_encode.py @@ -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 diff --git a/src/manta/uart/stream_packer.py b/src/manta/uart/stream_packer.py index c8bb7e8..8586d9f 100644 --- a/src/manta/uart/stream_packer.py +++ b/src/manta/uart/stream_packer.py @@ -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 diff --git a/src/manta/uart/stream_unpacker.py b/src/manta/uart/stream_unpacker.py index 912d13b..10c1c7e 100644 --- a/src/manta/uart/stream_unpacker.py +++ b/src/manta/uart/stream_unpacker.py @@ -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