forked from M-Labs/artiq-zynq
cxp upconn gw: add low speed serial PHY
testing: add debug fifo output b4 encoder cxp upconn: add low speed serial cxp upconn: add reset, tx_busy, tx_enable cxp upconn: add clockgen module for 20.83Mbps & 41.66Mbps using counters cxp upconn: add oserdes using CEInserter
This commit is contained in:
parent
f158aaf975
commit
8c34921799
142
src/gateware/cxp_upconn.py
Normal file
142
src/gateware/cxp_upconn.py
Normal file
@ -0,0 +1,142 @@
|
||||
from math import ceil
|
||||
|
||||
from migen import *
|
||||
|
||||
from misoc.cores.code_8b10b import SingleEncoder
|
||||
from misoc.interconnect import stream
|
||||
from misoc.interconnect.csr import *
|
||||
|
||||
from cxp_pipeline import char_layout
|
||||
|
||||
@ResetInserter()
|
||||
class ClockGen(Module):
|
||||
def __init__(self, sys_clk_freq):
|
||||
self.clk = Signal()
|
||||
self.clk_10x = Signal() # 20.83MHz 48ns or 41.66MHz 24ns
|
||||
|
||||
self.freq2x_enable = Signal()
|
||||
# # #
|
||||
|
||||
period = 1e9/sys_clk_freq
|
||||
max_count = ceil(48/period)
|
||||
counter = Signal(max=max_count, reset=max_count-1)
|
||||
|
||||
clk_div = Signal(max=10, reset=9)
|
||||
|
||||
self.sync += [
|
||||
self.clk.eq(0),
|
||||
self.clk_10x.eq(0),
|
||||
|
||||
If(counter == 0,
|
||||
self.clk_10x.eq(1),
|
||||
If(self.freq2x_enable,
|
||||
counter.eq(int(max_count/2)-1),
|
||||
).Else(
|
||||
counter.eq(counter.reset),
|
||||
),
|
||||
).Else(
|
||||
counter.eq(counter-1),
|
||||
),
|
||||
|
||||
If(counter == 0,
|
||||
If(clk_div == 0,
|
||||
self.clk.eq(1),
|
||||
clk_div.eq(clk_div.reset),
|
||||
).Else(
|
||||
clk_div.eq(clk_div-1),
|
||||
)
|
||||
)
|
||||
|
||||
]
|
||||
|
||||
@ResetInserter()
|
||||
@CEInserter()
|
||||
class SERDES_10bits(Module):
|
||||
def __init__(self, pad):
|
||||
self.oe = Signal()
|
||||
self.d = Signal(10)
|
||||
|
||||
# # #
|
||||
|
||||
tx_bitcount = Signal(max=10)
|
||||
tx_reg = Signal(10)
|
||||
|
||||
self.sync += [
|
||||
If(self.oe,
|
||||
# send LSB first
|
||||
pad.eq(tx_reg[0]),
|
||||
tx_reg.eq(Cat(tx_reg[1:], 0)),
|
||||
tx_bitcount.eq(tx_bitcount + 1),
|
||||
|
||||
If(tx_bitcount == 9,
|
||||
tx_bitcount.eq(0),
|
||||
tx_reg.eq(self.d),
|
||||
),
|
||||
).Else(
|
||||
pad.eq(0),
|
||||
tx_bitcount.eq(0),
|
||||
)
|
||||
]
|
||||
|
||||
class Transmitter(Module, AutoCSR):
|
||||
def __init__(self, pad, sys_clk_freq):
|
||||
self.bitrate2x_enable = Signal()
|
||||
self.clk_reset = Signal()
|
||||
self.enable = Signal()
|
||||
|
||||
# # #
|
||||
|
||||
self.sink = stream.Endpoint(char_layout)
|
||||
|
||||
self.submodules.cg = cg = ClockGen(sys_clk_freq)
|
||||
self.submodules.encoder = encoder = SingleEncoder(True)
|
||||
|
||||
oe = Signal()
|
||||
self.sync += [
|
||||
If(self.enable,
|
||||
self.sink.ack.eq(0),
|
||||
If(cg.clk,
|
||||
oe.eq(1),
|
||||
encoder.disp_in.eq(encoder.disp_out),
|
||||
self.sink.ack.eq(1),
|
||||
encoder.d.eq(self.sink.data),
|
||||
encoder.k.eq(self.sink.k),
|
||||
)
|
||||
).Else(
|
||||
# discard packets until tx is enabled
|
||||
self.sink.ack.eq(1),
|
||||
oe.eq(0),
|
||||
)
|
||||
]
|
||||
|
||||
self.submodules.serdes = serdes = SERDES_10bits(pad)
|
||||
|
||||
self.comb += [
|
||||
cg.reset.eq(self.clk_reset),
|
||||
cg.freq2x_enable.eq(self.bitrate2x_enable),
|
||||
|
||||
serdes.reset.eq(self.clk_reset),
|
||||
serdes.ce.eq(cg.clk_10x),
|
||||
serdes.d.eq(encoder.output),
|
||||
serdes.oe.eq(oe),
|
||||
]
|
||||
|
||||
class CXP_TXPHYs(Module, AutoCSR):
|
||||
def __init__(self, pads, sys_clk_freq):
|
||||
self.clk_reset = CSR()
|
||||
self.bitrate2x_enable = CSRStorage()
|
||||
self.enable = CSRStorage()
|
||||
|
||||
# # #
|
||||
|
||||
|
||||
self.phys = []
|
||||
for i, pad in enumerate(pads):
|
||||
tx = Transmitter(pad, sys_clk_freq)
|
||||
self.phys.append(tx)
|
||||
setattr(self.submodules, "tx"+str(i), tx)
|
||||
self.sync += [
|
||||
tx.clk_reset.eq(self.clk_reset.re),
|
||||
tx.bitrate2x_enable.eq(self.bitrate2x_enable.storage),
|
||||
tx.enable.eq(self.enable.storage),
|
||||
]
|
Loading…
Reference in New Issue
Block a user