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