use custom Records instead of Sink/Source (semms easier, but will be reverted if not)

This commit is contained in:
Florent Kermarrec 2013-09-22 13:04:18 +02:00
parent 39f1f2146f
commit 27f26dac03
6 changed files with 68 additions and 48 deletions

View File

@ -58,10 +58,7 @@ class SoC(Module):
# MiLa
term = Term(trig_w)
range_detector = RangeDetector(trig_w)
edge_detector = EdgeDetector(trig_w)
trigger = Trigger(trig_w, [term, range_detector, edge_detector])
trigger = Trigger(trig_w, [term])
recorder = Recorder(dat_w, rec_size)
self.submodules.mila = MiLa(trigger, recorder)
@ -108,7 +105,7 @@ class SoC(Module):
#
self.comb +=[
self.mila.sink.stb.eq(1),
self.mila.sink.payload.d.eq(Cat(
self.mila.sink.dat.eq(Cat(
self.freqgen.o,
self.eventgen_rising.o,
self.eventgen_falling.o,

View File

@ -16,12 +16,12 @@ class MiLa(Module, AutoCSR):
self.comb +=[
recorder.sink.stb.eq(trigger.source.stb),
recorder.sink.payload.hit.eq(trigger.source.payload.hit),
recorder.sink.hit.eq(trigger.source.hit),
trigger.source.ack.eq(recorder.sink.ack)
]
# Todo; Insert configurable delay to support pipelined
# triggers elements
self.comb +=[
recorder.sink.payload.d.eq(self.sink.payload.d),
recorder.sink.dat.eq(self.sink.dat),
]

View File

@ -0,0 +1,26 @@
from migen.genlib.record import *
def rec_dat(width):
layout = [
("stb", 1, DIR_M_TO_S),
("ack", 1, DIR_S_TO_M),
("dat", width, DIR_M_TO_S)
]
return Record(layout)
def rec_hit():
layout = [
("stb", 1, DIR_M_TO_S),
("ack", 1, DIR_S_TO_M),
("hit", 1, DIR_M_TO_S)
]
return Record(layout)
def rec_dat_hit(width):
layout = [
("stb", 1, DIR_M_TO_S),
("ack", 1, DIR_S_TO_M),
("hit", 1, DIR_M_TO_S),
("dat", width, DIR_M_TO_S)
]
return Record(layout)

View File

@ -1,7 +1,7 @@
import sys
import datetime
from miscope.tools.misc import *
from miscope.std.misc import *
def get_bits(values, width, low, high=None):
r = []

View File

@ -5,22 +5,24 @@ from migen.fhdl.specials import Memory
from migen.bus import csr
from migen.bank import description, csrgen
from migen.bank.description import *
from migen.actorlib.fifo import SyncFIFO
from migen.genlib.fifo import SyncFIFO
from miscope.std import *
class RunLenghEncoder(Module, AutoCSR):
def __init__(self, width, length):
self.width = width
self.length = length
self.sink = Sink([("d", width)])
self.source = Source([("d", width)])
self.sink = rec_dat(width)
self.source = rec_dat(width)
self._r_enable = CSRStorage()
###
enable = self._r_enable.storage
stb_i = self.sink.stb
dat_i = self.sink.payload.d
dat_i = self.sink.dat
ack_i = self.sink.ack
# Register Input
@ -57,7 +59,7 @@ class RunLenghEncoder(Module, AutoCSR):
# Mux RLE word and data
stb_o = self.source.stb
dat_o = self.source.payload.d
dat_o = self.source.dat
ack_o = self.source.ack
comb +=[
@ -74,13 +76,11 @@ class RunLenghEncoder(Module, AutoCSR):
ack_i.eq(1) #FIXME
]
class Recorder(Module, AutoCSR):
def __init__(self, width, depth):
self.width = width
self.sink = Sink([("hit", 1), ("d", width)])
self.sink = rec_dat_hit(width)
self._r_trigger = CSR()
self._r_length = CSRStorage(bits_for(depth))
@ -100,15 +100,15 @@ class Recorder(Module, AutoCSR):
cnt = Signal(max=depth)
fifo = SyncFIFO([("d", width)], depth)
fifo = SyncFIFO(width, depth)
self.submodules += fifo
# Write fifo is done only when done = 0
# Fifo must always be pulled by software between
# acquisition (Todo: add a flush funtionnality)
self.comb +=[
fifo.sink.stb.eq(self.sink.stb & ~done),
fifo.sink.payload.d.eq(self.sink.payload.d),
fifo.we.eq(self.sink.stb & ~done),
fifo.din.eq(self.sink.dat),
self.sink.ack.eq(1)
]
@ -132,16 +132,16 @@ class Recorder(Module, AutoCSR):
If(self._r_trigger.re & self._r_trigger.r, done.eq(0)
).Elif(cnt==length, done.eq(1)),
If(self.sink.stb & self.sink.payload.hit & ~done, ongoing.eq(1)
If(self.sink.stb & self.sink.hit & ~done, ongoing.eq(1)
).Elif(done, ongoing.eq(0)),
]
# fifo ack & csr connection
self.comb += [
If(~done & ~ongoing & (cnt >= offset), fifo.source.ack.eq(1)
).Else(fifo.source.ack.eq(self._r_read_en.re & self._r_read_en.r)),
self._r_read_empty.status.eq(~fifo.source.stb),
self._r_read_dat.status.eq(fifo.source.payload.d),
If(~done & ~ongoing & (cnt >= offset), fifo.re.eq(1)
).Else(fifo.re.eq(self._r_read_en.re & self._r_read_en.r)),
self._r_read_empty.status.eq(~fifo.readable),
self._r_read_dat.status.eq(fifo.dout),
self._r_done.status.eq(done)
]
@ -149,7 +149,7 @@ class Recorder(Module, AutoCSR):
self.sync += [
If(done == 1,
cnt.eq(0)
).Elif(fifo.sink.stb & fifo.sink.ack & ~(fifo.source.stb & fifo.source.ack),
).Elif(fifo.we & fifo.writable & ~(fifo.re & fifo.readable),
cnt.eq(cnt+1),
)
]

View File

@ -6,14 +6,14 @@ from migen.bus import csr
from migen.bank import description, csrgen
from migen.bank.description import *
from miscope.std import *
class Term(Module, AutoCSR):
def __init__(self, width):
self.width = width
self.sink = Sink([("d", width)])
self.source = Source([("hit", 1)])
self.busy = Signal()
self.sink = rec_dat(width)
self.source = rec_hit()
self._r_trig = CSRStorage(width)
self._r_mask = CSRStorage(width)
@ -22,24 +22,21 @@ class Term(Module, AutoCSR):
trig = self._r_trig.storage
mask = self._r_mask.storage
dat = self.sink.payload.d
hit = self.source.payload.hit
dat = self.sink.dat
hit = self.source.hit
self.comb +=[
hit.eq((dat & mask) == trig),
self.source.stb.eq(self.sink.stb),
self.sink.ack.eq(self.sink.ack),
self.source.payload.hit.eq(hit)
]
class RangeDetector(Module, AutoCSR):
def __init__(self, width):
self.width = width
self.sink = Sink([("d", width)])
self.source = Source([("hit", 1)])
self.busy = Signal()
self.sink = rec_dat(width)
self.source = rec_hit()
self._r_low = CSRStorage(width)
self._r_high = CSRStorage(width)
@ -47,8 +44,8 @@ class RangeDetector(Module, AutoCSR):
###
low = self._r_low.storage
high = self._r_high.storage
dat = self.sink.payload.d
hit = self.source.payload.hit
dat = self.sink.dat
hit = self.source.hit
self.comb +=[
hit.eq((dat >= low) & (dat <= high)),
@ -61,8 +58,8 @@ class EdgeDetector(Module, AutoCSR):
def __init__(self, width):
self.width = width
self.sink = Sink([("d", width)])
self.source = Source([("hit", 1)])
self.sink = rec_dat(width)
self.source = rec_hit()
self._r_rising_mask = CSRStorage(width)
self._r_falling_mask = CSRStorage(width)
@ -73,12 +70,12 @@ class EdgeDetector(Module, AutoCSR):
falling_mask = self._r_falling_mask.storage
both_mask = self._r_both_mask.storage
dat = self.sink.payload.d
dat = self.sink.dat
dat_d = Signal(width)
rising_hit = Signal()
falling_hit = Signal()
both_hit = Signal()
hit = self.source.payload.hit
hit = self.source.hit
self.sync += dat_d.eq(dat)
@ -94,8 +91,8 @@ class EdgeDetector(Module, AutoCSR):
class Sum(Module, AutoCSR):
def __init__(self, ports=4):
self.sinks = [Sink([("hit", 1)]) for p in range(ports)]
self.source = Source([("hit", 1)])
self.sinks = [rec_hit() for p in range(ports)]
self.source = rec_hit()
self._r_prog_we = CSRStorage()
self._r_prog_adr = CSRStorage(ports) #FIXME
@ -118,12 +115,12 @@ class Sum(Module, AutoCSR):
# Lut read
for i, sink in enumerate(self.sinks):
self.comb += lut_port.adr[i].eq(sink.payload.hit)
self.comb += lut_port.adr[i].eq(sink.hit)
# Drive source
self.comb +=[
self.source.stb.eq(optree("&", [sink.stb for sink in self.sinks])),
self.source.payload.hit.eq(lut_port.dat_r),
self.source.hit.eq(lut_port.dat_r),
[sink.ack.eq(self.source.ack) for sink in self.sinks]
]
@ -141,7 +138,7 @@ class Trigger(Module, AutoCSR):
tmp = "self.submodules.port"+str(i)+" = port"
exec(tmp)
self.sink = Sink([("d", width)])
self.sink = rec_dat(width)
self.source = self.sum.source
self.busy = Signal()
@ -149,6 +146,6 @@ class Trigger(Module, AutoCSR):
for i, port in enumerate(ports):
self.comb +=[
port.sink.stb.eq(self.sink.stb),
port.sink.payload.d.eq(self.sink.payload.d),
port.sink.dat.eq(self.sink.dat),
port.source.connect(self.sum.sinks[i])
]