Skip to content
Snippets Groups Projects
Commit 2e6d559d authored by Kia's avatar Kia
Browse files

unoptimized_lr/skidbuffer.py

parent b5031fe8
No related branches found
No related tags found
No related merge requests found
from nmigen import *
from nmigen.cli import main
class NonRegisteredSkidBuffer(Elaboratable): # non-registered
def __init__(self, width):
self.width = width
self.upstream_valid_in = Signal(1)
self.upstream_ready_out = Signal(1)
self.upstream_data_in = Signal(self.width)
self.downstream_valid_out = Signal(1)
self.downstream_ready_in = Signal(1)
self.downstream_data_out = Signal(self.width)
def elaborate(self, platform):
m = Module()
skid_buffer = Signal(self.width)
skid_buffer_frozen = Signal(1)
# we signal ready to upstream if and only if the skid buffer is empty
m.d.comb += self.upstream_ready_out.eq(~skid_buffer_frozen)
# should we capture a value in the skid buffer?
# we should if upstream has data for us *and* downstream cannot accept
# If we want to fill our skid buffer, we need:
# 1. valid input data (upstream_valid_in == 1)
# 2. a buffer that is empty (skid_buffer_frozen == 0)
# 3. stalled downstream (downstream_ready_in == 0)
with m.If(self.upstream_valid_in & (~skid_buffer_frozen) & (~self.downstream_ready_in)):
m.d.sync += skid_buffer_frozen.eq(1)
# if downstream is accepting data again, we will flush our skid buffer
with m.If(self.downstream_ready_in == 1):
m.d.sync += skid_buffer_frozen.eq(0)
m.d.comb += self.downstream_valid_out.eq(self.upstream_valid_in | skid_buffer_frozen)
# data path
# always clock data into the skid buffer as long as the buffer isn't frozen
with m.If(skid_buffer_frozen == 0):
m.d.sync += skid_buffer.eq(self.upstream_data_in)
with m.If(skid_buffer_frozen == 1):
m.d.comb += self.downstream_data_out.eq(skid_buffer)
# NON registered
with m.Elif(self.upstream_valid_in == 1):
m.d.comb += self.downstream_data_out.eq(self.upstream_data_in)
return m
class RegisteredSkidBuffer(Elaboratable): # registered
def __init__(self, width):
self.width = width
self.upstream_valid_in = Signal(1)
self.upstream_ready_out = Signal(1)
self.upstream_data_in = Signal(self.width)
self.downstream_valid_out = Signal(1)
self.downstream_ready_in = Signal(1)
self.downstream_data_out = Signal(self.width)
def elaborate(self, platform):
m = Module()
skid_buffer = Signal(self.width)
skid_buffer_frozen = Signal(1)
# we signal ready to upstream if and only if the skid buffer is empty
m.d.comb += self.upstream_ready_out.eq(~skid_buffer_frozen)
# should we capture a value in the skid buffer?
# we should if upstream has data for us *and* downstream cannot accept
# If we want to fill our skid buffer, we need:
# 1. valid input data (upstream_valid_in == 1)
# 2. a buffer that is empty (skid_buffer_frozen == 0)
# 3. stalled downstream (downstream_ready_in == 0) & (downstream_valid_out == 1)
with m.If(self.upstream_valid_in & (~skid_buffer_frozen) & (~self.downstream_ready_in) & (self.downstream_valid_out)):
m.d.sync += skid_buffer_frozen.eq(1)
# if downstream is accepting data again, we will flush our skid buffer
with m.If(self.downstream_ready_in == 1):
m.d.sync += skid_buffer_frozen.eq(0)
# Stalled == (downstream_ready_in == 0 & downstream_valid_out == 1)
# so not stalled = !(downstream_ready_in == 0 & downstream_valid_out == 1)
# = downstream_ready_in == 1 | downstream_valid_out == 0
# by de Morgan
with m.If((self.downstream_ready_in) | (~self.downstream_valid_out)):
m.d.sync += self.downstream_valid_out.eq(self.upstream_valid_in | skid_buffer_frozen)
# data path
# always clock data into the skid buffer as long as the buffer isn't filled
with m.If(skid_buffer_frozen == 0):
m.d.sync += skid_buffer.eq(self.upstream_data_in)
# not stalled condition
with m.If((self.downstream_ready_in) | (~self.downstream_valid_out)):
with m.If(skid_buffer_frozen == 1):
m.d.sync += self.downstream_data_out.eq(skid_buffer)
with m.Elif(self.upstream_valid_in == 1):
m.d.sync += self.downstream_data_out.eq(self.upstream_data_in)
return m
class DummyPlug(Elaboratable):
def elaborate(self, platform):
m = Module()
egg = RegisteredSkidBuffer(8)
m.submodules += egg
cntr = Signal(8)
intctr = Signal(8)
data_in = Signal(8)
m.d.sync += intctr.eq(intctr +1)
m.d.comb += egg.upstream_data_in.eq(data_in)
upstream_valid = Signal(1)
m.d.comb += egg.upstream_valid_in.eq(upstream_valid)
m.d.comb += upstream_valid.eq(1)
downstream_ready = Signal(1)
m.d.comb += egg.downstream_ready_in.eq(downstream_ready)
m.d.comb += downstream_ready.eq(1)
m.d.comb += data_in.eq(cntr)
with m.If((intctr == 4) | (intctr == 5) | (intctr == 6)):
m.d.comb += downstream_ready.eq(0)
# with m.If((intctr == 4) | (intctr == 5)):
# m.d.comb += upstream_valid.eq(0)
# m.d.comb += data_in.eq(0)
with m.If(egg.upstream_ready_out == 1):
m.d.sync += cntr.eq(cntr+1)
return m
if __name__ == '__main__':
baka =DummyPlug()
main(baka)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment