def __init__(self, width, depth): _FIFOInterface.__init__(self, width, depth) ### depth_bits = log2_int(depth, True) produce = ClockDomainsRenamer("write")(GrayCounter(depth_bits + 1)) consume = ClockDomainsRenamer("read")(GrayCounter(depth_bits + 1)) self.submodules += produce, consume self.comb += [ produce.ce.eq(self.writable & self.we), consume.ce.eq(self.readable & self.re) ] produce_rdomain = Signal(depth_bits + 1) self.specials += [ NoRetiming(produce.q), MultiReg(produce.q, produce_rdomain, "read") ] consume_wdomain = Signal(depth_bits + 1) self.specials += [ NoRetiming(consume.q), MultiReg(consume.q, consume_wdomain, "write") ] if depth_bits == 1: self.comb += self.writable.eq( (produce.q[-1] == consume_wdomain[-1]) | (produce.q[-2] == consume_wdomain[-2])) else: self.comb += [ self.writable.eq((produce.q[-1] == consume_wdomain[-1]) | (produce.q[-2] == consume_wdomain[-2]) | (produce.q[:-2] != consume_wdomain[:-2])) ] self.comb += self.readable.eq(consume.q != produce_rdomain) storage = Memory(self.width, depth) self.specials += storage wrport = storage.get_port(write_capable=True, clock_domain="write") self.specials += wrport self.comb += [ wrport.adr.eq(produce.q_binary[:-1]), wrport.dat_w.eq(self.din), wrport.we.eq(produce.ce) ] rdport = storage.get_port(clock_domain="read") self.specials += rdport self.comb += [ rdport.adr.eq(consume.q_next_binary[:-1]), self.dout.eq(rdport.dat_r) ]
def __init__(self, width, depth): _FIFOInterface.__init__(self, width, depth) ### depth_bits = log2_int(depth, True) produce = ClockDomainsRenamer("write")(GrayCounter(depth_bits+1)) consume = ClockDomainsRenamer("read")(GrayCounter(depth_bits+1)) self.submodules += produce, consume self.comb += [ produce.ce.eq(self.writable & self.we), consume.ce.eq(self.readable & self.re) ] produce_rdomain = Signal(depth_bits+1) self.specials += [ NoRetiming(produce.q), MultiReg(produce.q, produce_rdomain, "read") ] consume_wdomain = Signal(depth_bits+1) self.specials += [ NoRetiming(consume.q), MultiReg(consume.q, consume_wdomain, "write") ] if depth_bits == 1: self.comb += self.writable.eq((produce.q[-1] == consume_wdomain[-1]) | (produce.q[-2] == consume_wdomain[-2])) else: self.comb += [ self.writable.eq((produce.q[-1] == consume_wdomain[-1]) | (produce.q[-2] == consume_wdomain[-2]) | (produce.q[:-2] != consume_wdomain[:-2])) ] self.comb += self.readable.eq(consume.q != produce_rdomain) storage = Memory(self.width, depth) self.specials += storage wrport = storage.get_port(write_capable=True, clock_domain="write") self.specials += wrport self.comb += [ wrport.adr.eq(produce.q_binary[:-1]), wrport.dat_w.eq(self.din), wrport.we.eq(produce.ce) ] rdport = storage.get_port(clock_domain="read") self.specials += rdport self.comb += [ rdport.adr.eq(consume.q_next_binary[:-1]), self.dout.eq(rdport.dat_r) ]
def __init__(self, width, depth, fwft=True): _FIFOInterface.__init__(self, width, depth) self.level = Signal(max=depth+1) self.replace = Signal() ### produce = Signal(max=depth) consume = Signal(max=depth) storage = Memory(self.width, depth) self.specials += storage wrport = storage.get_port(write_capable=True) self.specials += wrport self.comb += [ If(self.replace, wrport.adr.eq(produce-1) ).Else( wrport.adr.eq(produce) ), wrport.dat_w.eq(self.din), wrport.we.eq(self.we & (self.writable | self.replace)) ] self.sync += If(self.we & self.writable & ~self.replace, _inc(produce, depth)) do_read = Signal() self.comb += do_read.eq(self.readable & self.re) rdport = storage.get_port(async_read=fwft, has_re=not fwft) self.specials += rdport self.comb += [ rdport.adr.eq(consume), self.dout.eq(rdport.dat_r) ] if not fwft: self.comb += rdport.re.eq(do_read) self.sync += If(do_read, _inc(consume, depth)) self.sync += \ If(self.we & self.writable & ~self.replace, If(~do_read, self.level.eq(self.level + 1)) ).Elif(do_read, self.level.eq(self.level - 1) ) self.comb += [ self.writable.eq(self.level != depth), self.readable.eq(self.level != 0) ]
def __init__(self, width, depth, fwft=True): _FIFOInterface.__init__(self, width, depth) self.level = Signal(max=depth + 1) self.replace = Signal() ### produce = Signal(max=depth) consume = Signal(max=depth) storage = Memory(self.width, depth) self.specials += storage wrport = storage.get_port(write_capable=True) self.specials += wrport self.comb += [ If(self.replace, wrport.adr.eq(produce - 1)).Else(wrport.adr.eq(produce)), wrport.dat_w.eq(self.din), wrport.we.eq(self.we & (self.writable | self.replace)) ] self.sync += If(self.we & self.writable & ~self.replace, _inc(produce, depth)) do_read = Signal() self.comb += do_read.eq(self.readable & self.re) rdport = storage.get_port(async_read=fwft, has_re=not fwft) self.specials += rdport self.comb += [rdport.adr.eq(consume), self.dout.eq(rdport.dat_r)] if not fwft: self.comb += rdport.re.eq(do_read) self.sync += If(do_read, _inc(consume, depth)) self.sync += \ If(self.we & self.writable & ~self.replace, If(~do_read, self.level.eq(self.level + 1)) ).Elif(do_read, self.level.eq(self.level - 1) ) self.comb += [ self.writable.eq(self.level != depth), self.readable.eq(self.level != 0) ]
def __init__(self, width, depth, idomain, odomain): self.din = Signal(width) self.dout = Signal(width) # # # reset = Signal() cd_write = ClockDomain() cd_read = ClockDomain() self.comb += [ cd_write.clk.eq(ClockSignal(idomain)), cd_read.clk.eq(ClockSignal(odomain)), reset.eq(ResetSignal(idomain) | ResetSignal(odomain)) ] self.specials += [ AsyncResetSynchronizer(cd_write, reset), AsyncResetSynchronizer(cd_read, reset) ] self.clock_domains += cd_write, cd_read wrpointer = Signal(max=depth, reset=depth//2) rdpointer = Signal(max=depth) storage = Memory(width, depth) self.specials += storage wrport = storage.get_port(write_capable=True, clock_domain="write") rdport = storage.get_port(clock_domain="read") self.specials += wrport, rdport self.sync.write += wrpointer.eq(wrpointer + 1) self.sync.read += rdpointer.eq(rdpointer + 1) self.comb += [ wrport.we.eq(1), wrport.adr.eq(wrpointer), wrport.dat_w.eq(self.din), rdport.adr.eq(rdpointer), self.dout.eq(rdport.dat_r) ]
def __init__(self, width, depth, idomain, odomain): self.din = Signal(width) self.dout = Signal(width) # # # reset = Signal() cd_write = ClockDomain() cd_read = ClockDomain() self.comb += [ cd_write.clk.eq(ClockSignal(idomain)), cd_read.clk.eq(ClockSignal(odomain)), reset.eq(ResetSignal(idomain) | ResetSignal(odomain)) ] self.specials += [ AsyncResetSynchronizer(cd_write, reset), AsyncResetSynchronizer(cd_read, reset) ] self.clock_domains += cd_write, cd_read wrpointer = Signal(max=depth, reset=depth // 2) rdpointer = Signal(max=depth) storage = Memory(width, depth) self.specials += storage wrport = storage.get_port(write_capable=True, clock_domain="write") rdport = storage.get_port(clock_domain="read") self.specials += wrport, rdport self.sync.write += wrpointer.eq(wrpointer + 1) self.sync.read += rdpointer.eq(rdpointer + 1) self.comb += [ wrport.we.eq(1), wrport.adr.eq(wrpointer), wrport.dat_w.eq(self.din), rdport.adr.eq(rdpointer), self.dout.eq(rdport.dat_r) ]