Add artiq.gateware.rtio.sed.layouts

This commit is contained in:
Donald Sebastian Leung 2020-09-25 13:26:01 +08:00
parent 9e81676fd2
commit a788c17e3d
2 changed files with 80 additions and 1 deletions

View File

@ -11,7 +11,7 @@ Formally verified implementation of the ARTIQ RTIO core in nMigen
- - [x] `artiq.gateware.rtio.rtlink` - - [x] `artiq.gateware.rtio.rtlink`
- - [x] `artiq.gateware.rtio.channel` - - [x] `artiq.gateware.rtio.channel`
- - [ ] `artiq.gateware.rtio.sed.core` - - [ ] `artiq.gateware.rtio.sed.core`
- - [ ] `artiq.gateware.rtio.sed.layouts` - - [x] `artiq.gateware.rtio.sed.layouts`
- - [ ] `artiq.gateware.rtio.sed.lane_distributor` - - [ ] `artiq.gateware.rtio.sed.lane_distributor`
- - [ ] `artiq.gateware.rtio.sed.fifos` - - [ ] `artiq.gateware.rtio.sed.fifos`
- - [ ] `artiq.gateware.rtio.sed.gates` - - [ ] `artiq.gateware.rtio.sed.gates`

View File

@ -0,0 +1,79 @@
from nmigen import *
from nmigen.utils import *
from nmigen.hdl.rec import *
from artiq.gateware.rtio import rtlink
def fifo_payload(channels):
address_width = max(rtlink.get_address_width(channel.interface.o)
for channel in channels)
data_width = max(rtlink.get_data_width(channel.interface.o)
for channel in channels)
layout = [
("channel", bits_for(len(channels)-1)),
("timestamp", 64)
]
if address_width:
layout.append(("address", address_width))
if data_width:
layout.append(("data", data_width))
return layout
def seqn_width(lane_count, fifo_depth):
# There must be a unique sequence number for every possible event in every FIFO.
# Plus 2 bits to detect and handle wraparounds.
return bits_for(lane_count*fifo_depth-1) + 2
def fifo_ingress(seqn_width, layout_payload):
return [
("we", 1, DIR_FANOUT),
("writable", 1, DIR_FANIN),
("seqn", seqn_width, DIR_FANOUT),
("payload", [(a, b, DIR_FANOUT) for a, b in layout_payload])
]
def fifo_egress(seqn_width, layout_payload):
return [
("re", 1, DIR_FANIN),
("readable", 1, DIR_FANOUT),
("seqn", seqn_width, DIR_FANOUT),
("payload", [(a, b, DIR_FANOUT) for a, b in layout_payload])
]
# We use glbl_fine_ts_width in the output network so that collisions due
# to insufficiently increasing timestamps are always reliably detected.
# We can still have undetected collisions on the address by making it wrap
# around, but those are more rare and easier to debug, and addresses are
# not normally exposed directly to the ARTIQ user.
def output_network_payload(channels, glbl_fine_ts_width):
address_width = max(rtlink.get_address_width(channel.interface.o)
for channel in channels)
data_width = max(rtlink.get_data_width(channel.interface.o)
for channel in channels)
layout = [("channel", bits_for(len(channels)-1))]
if glbl_fine_ts_width:
layout.append(("fine_ts", glbl_fine_ts_width))
if address_width:
layout.append(("address", address_width))
if data_width:
layout.append(("data", data_width))
return layout
def output_network_node(seqn_width, layout_payload):
return [
("valid", 1),
("seqn", seqn_width),
("replace_occured", 1),
("nondata_replace_occured", 1),
("payload", layout_payload)
]