include efc

This commit is contained in:
occheung 2023-04-26 05:08:33 +08:00
parent ce1f669138
commit 950d9ee8be
5 changed files with 95 additions and 50 deletions

17
comm.py
View File

@ -1,8 +1,8 @@
import serial import serial
def main(): def main(serial_port):
comm = serial.Serial("/dev/ttyUSB3", 115200) comm = serial.Serial(serial_port, 115200)
# comm.write(b"Hello World!") # comm.write(b"Hello World!")
# for _ in range(32): # for _ in range(32):
@ -19,4 +19,15 @@ def main():
# print(f'{byte[0]:0>8b}') # print(f'{byte[0]:0>8b}')
if __name__ == "__main__": if __name__ == "__main__":
main() import argparse
parser = argparse.ArgumentParser()
parser.add_argument("platform")
args = parser.parse_args()
port_dict = {
"kasli": "/dev/ttyUSB3",
"efc": "/dev/ttyACM1",
}
main(port_dict[args.platform])

View File

@ -3,8 +3,8 @@ from migen.build.platforms.sinara import kasli
from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.resetsync import AsyncResetSynchronizer
class KasliCRG(Module): class TransceiverCRG(Module):
def __init__(self, platform): def __init__(self, platform, clk125):
self.platform = platform self.platform = platform
# Generated clock domains # Generated clock domains
@ -16,7 +16,6 @@ class KasliCRG(Module):
# Configure system clock using GTP ports # Configure system clock using GTP ports
self.sys_clk_freq = 125e6 self.sys_clk_freq = 125e6
clk125 = self.platform.request("clk125_gtp")
clk125_buf = Signal() clk125_buf = Signal()
clk125_div2 = Signal() clk125_div2 = Signal()

View File

@ -1,8 +1,8 @@
from migen import * from migen import *
from sync_serdes import MultiLineRX, MultiLineTX from sync_serdes import MultiLineRX, MultiLineTX
from migen.genlib.fifo import SyncFIFO from migen.genlib.fifo import SyncFIFO
from migen.build.platforms.sinara import kasli from migen.build.platforms.sinara import kasli, efc
from kasli_crg import KasliCRG from kasli_crg import TransceiverCRG
from eem_helpers import generate_pads from eem_helpers import generate_pads
from uart import UART from uart import UART
from io_loopback import SingleIOLoopback, IOLoopBack from io_loopback import SingleIOLoopback, IOLoopBack
@ -47,11 +47,16 @@ class MultiSerDesLoopBack(Module):
self.submodules.rx_fsm = FSM(reset_state="WAIT_GROUP_ALIGN") self.submodules.rx_fsm = FSM(reset_state="WAIT_GROUP_ALIGN")
sampled_rxdata = Array(Signal(20) for _ in range(16))
sample_idx = Signal(4)
self.rx_fsm.act("WAIT_GROUP_ALIGN", self.rx_fsm.act("WAIT_GROUP_ALIGN",
If(self.rx.err, If(self.rx.err,
NextState("WRITE_ERR_UPPER") NextState("WRITE_ERR_UPPER"),
).Elif(self.rx.rxdata == 0b11111111111111111111, ).Elif(self.rx.rxdata == 0b11111111111111111111,
NextState("SAMPLE_RXDATA") NextValue(sampled_rxdata[0], self.rx.rxdata),
NextValue(sample_idx, 1),
NextState("SAMPLE_RXDATA"),
), ),
) )
@ -71,23 +76,27 @@ class MultiSerDesLoopBack(Module):
), ),
) )
sampled_rxdata = Array(Signal(20) for _ in range(5))
sample_idx = Signal(3)
self.rx_fsm.act("SAMPLE_RXDATA", self.rx_fsm.act("SAMPLE_RXDATA",
If((sample_idx != 0) | (self.rx.rxdata != 0), # If((sample_idx != 0) | (self.rx.rxdata != 0),
If(sample_idx == 5, # If(sample_idx == 15,
NextValue(sample_idx, 0), # NextValue(sample_idx, 0),
NextState("WRITE_PATTERN_FIRST_UPPER"), # NextState("WRITE_PATTERN_FIRST_UPPER"),
).Else( # ).Else(
NextValue(sampled_rxdata[sample_idx], self.rx.rxdata), # NextValue(sampled_rxdata[sample_idx], self.rx.rxdata),
NextValue(sample_idx, sample_idx + 1), # NextValue(sample_idx, sample_idx + 1),
), # ),
# ),
If(sample_idx == 15,
NextValue(sample_idx, 0),
NextState("WRITE_PATTERN_FIRST_UPPER"),
).Else(
NextValue(sampled_rxdata[sample_idx], self.rx.rxdata),
NextValue(sample_idx, sample_idx + 1),
), ),
) )
self.rx_fsm.act("WRITE_PATTERN_FIRST_UPPER", self.rx_fsm.act("WRITE_PATTERN_FIRST_UPPER",
If(sample_idx == 5, If(sample_idx == 15,
NextState("TERMINATE"), NextState("TERMINATE"),
).Elif(self.tx_fifo.writable, ).Elif(self.tx_fifo.writable,
self.tx_fifo.we.eq(1), self.tx_fifo.we.eq(1),
@ -134,11 +143,11 @@ class MultiSerDesLoopBack(Module):
), ),
) )
send_zero_duration = Signal(4) send_zero_duration = Signal(2)
self.tx_fsm.act("SEND_ZERO", self.tx_fsm.act("SEND_ZERO",
self.tx.txdata.eq(0), self.tx.txdata.eq(0),
If(send_zero_duration == 0b1111, If(send_zero_duration == 0b11,
NextState("SEND_PULSE"), NextState("SEND_PULSE"),
).Else( ).Else(
NextValue(send_zero_duration, send_zero_duration + 1), NextValue(send_zero_duration, send_zero_duration + 1),
@ -158,7 +167,7 @@ class MultiSerDesLoopBack(Module):
) )
self.tx_fsm.act("SEND_ARB_DATA", self.tx_fsm.act("SEND_ARB_DATA",
self.tx.txdata.eq(0xDEADB), self.tx.txdata.eq(0b00111001110011100111),
NextState("TERMINATE"), NextState("TERMINATE"),
) )
@ -169,17 +178,36 @@ class MultiSerDesLoopBack(Module):
if __name__ == "__main__": if __name__ == "__main__":
platform = kasli.Platform(hw_rev="v2.0") import argparse
parser = argparse.ArgumentParser()
parser.add_argument("platform")
args = parser.parse_args()
platform_dict = {
"kasli": kasli.Platform(hw_rev="v2.0"),
"efc": efc.Platform(),
}
sysclk_name = {
"kasli": "clk125_gtp",
"efc": "gtp_clk",
}
platform = platform_dict[args.platform]
sysclk = platform.request(sysclk_name[args.platform])
# Generate pads for the I/O blocks # Generate pads for the I/O blocks
eem = 3 # Using EEM1 for both as both EFC and Kasli has EEM1
# EEM1 are not interconnected
eem = 1
generate_pads(platform, eem) generate_pads(platform, eem)
pads = [ pads = [
platform.request("dio{}".format(eem), i) for i in range(4) platform.request("dio{}".format(eem), i+4) for i in range(4)
] ]
# pad = platform.request("dio{}".format(eem), 0) # pad = platform.request("dio{}".format(eem), 0)
crg = KasliCRG(platform) crg = TransceiverCRG(platform, sysclk)
top = MultiSerDesLoopBack(pads, crg.sys_clk_freq) top = MultiSerDesLoopBack(pads, crg.sys_clk_freq)
# Wire up UART core to the pads # Wire up UART core to the pads

View File

@ -3,7 +3,7 @@ from sync_serdes import *
from migen.genlib.fifo import SyncFIFO from migen.genlib.fifo import SyncFIFO
from migen.build.platforms.sinara import kasli from migen.build.platforms.sinara import kasli
from migen.genlib.misc import WaitTimer from migen.genlib.misc import WaitTimer
from kasli_crg import KasliCRG from kasli_crg import TransceiverCRG
from eem_helpers import generate_pads from eem_helpers import generate_pads
from uart import UART from uart import UART
from io_loopback import SingleIOLoopback from io_loopback import SingleIOLoopback
@ -82,11 +82,6 @@ class SingleSerDesLoopBack(Module):
# Debugging logics # Debugging logics
if debug: if debug:
self.comb += [ self.comb += [
# Start the reader initially
self.bitslip_reader.start.eq(1),
self.post_align_reader.start.eq(0),
self.phase_reader.start.eq(0),
self.bitslip_reader.loopback_rxdata.eq(self.rx.rxdata), self.bitslip_reader.loopback_rxdata.eq(self.rx.rxdata),
self.post_align_reader.loopback_rxdata.eq(self.rx.rxdata), self.post_align_reader.loopback_rxdata.eq(self.rx.rxdata),
self.phase_reader.loopback_rxdata.eq(self.rx.rxdata), self.phase_reader.loopback_rxdata.eq(self.rx.rxdata),
@ -212,7 +207,9 @@ class SingleSerDesLoopBack(Module):
self.submodules += fsm self.submodules += fsm
fsm.act("WAIT_DONE", fsm.act("WAIT_DONE",
self.bitslip_reader.start.eq(1),
If(self.bitslip_reader.done, If(self.bitslip_reader.done,
NextValue(bitslip_count, 0),
NextState("WRITE_UPPER"), NextState("WRITE_UPPER"),
), ),
) )
@ -229,10 +226,12 @@ class SingleSerDesLoopBack(Module):
) )
fsm.act("WRITE_LOWER", fsm.act("WRITE_LOWER",
self.tx_fifo.we.eq(1), If(self.tx_fifo.writable,
self.tx_fifo.din.eq(self.bitslip_reader.data_result[bitslip_count][:8]), self.tx_fifo.we.eq(1),
NextValue(bitslip_count, bitslip_count + 1), self.tx_fifo.din.eq(self.bitslip_reader.data_result[bitslip_count][:8]),
NextState("WRITE_UPPER"), NextValue(bitslip_count, bitslip_count + 1),
NextState("WRITE_UPPER"),
)
) )
fsm.act("START_SLAVE_ALIGNER", fsm.act("START_SLAVE_ALIGNER",
@ -373,6 +372,12 @@ class SingleSerDesLoopBack(Module):
If(self.tx_fifo.writable, If(self.tx_fifo.writable,
self.tx_fifo.we.eq(1), self.tx_fifo.we.eq(1),
self.tx_fifo.din.eq(self.delay_solver.opt_delay_tap), self.tx_fifo.din.eq(self.delay_solver.opt_delay_tap),
NextState("WAIT_OPT_DELAY_ACTIVE"),
),
)
fsm.act("WAIT_OPT_DELAY_ACTIVE",
If(self.rx.cnt_out == self.delay_solver.opt_delay_tap,
NextState("RESAMPLE_RXDATA_UPPER"), NextState("RESAMPLE_RXDATA_UPPER"),
), ),
) )
@ -468,15 +473,12 @@ if __name__ == "__main__":
platform = kasli.Platform(hw_rev="v2.0") platform = kasli.Platform(hw_rev="v2.0")
# Generate pads for the I/O blocks # Generate pads for the I/O blocks
eem = 3 eem = 2
generate_pads(platform, eem) generate_pads(platform, eem)
# pads = [
# platform.request("dio{}".format(eem), i) for i in range(4)
# ]
pad = platform.request("dio{}".format(eem), 0) pad = platform.request("dio{}".format(eem), 0)
crg = KasliCRG(platform) crg = TransceiverCRG(platform, platform.request("clk125_gtp"))
top = SingleSerDesLoopBack(pad, crg.sys_clk_freq, False) top = SingleSerDesLoopBack(pad, crg.sys_clk_freq, True)
# Wire up UART core to the pads # Wire up UART core to the pads
uart_pads = platform.request("serial") uart_pads = platform.request("serial")

View File

@ -207,7 +207,6 @@ class SlaveAligner(Module):
self.done = Signal() self.done = Signal()
self.master_bitslip = Signal() self.master_bitslip = Signal()
self.slave_bitslip = Signal() self.slave_bitslip = Signal()
# self.data_result = Array(Signal(10) for _ in range(5))
self.slip_count = Signal(3) self.slip_count = Signal(3)
@ -314,7 +313,7 @@ class SlaveAligner(Module):
# After eliminating the potentially duplicating pattern, # After eliminating the potentially duplicating pattern,
# Shift the entire output pattern for delay tap optimization # Shift the entire output pattern for delay tap optimization
# Ideally, the optimized first edge would be the middle pair # Ideally, the optimized first edge would be the middle pair
# So, shift it until bit 4/5 is set and bit 6 is not set # So, shift it until bit 3/4 is set but bit 5 is not set
fsm.act("SHIFT_WAIT_TIMER", fsm.act("SHIFT_WAIT_TIMER",
self.stab_timer.wait.eq(1), self.stab_timer.wait.eq(1),
If(self.stab_timer.done, If(self.stab_timer.done,
@ -323,7 +322,7 @@ class SlaveAligner(Module):
) )
fsm.act("SHIFT_SAMPLE_PATTERN", fsm.act("SHIFT_SAMPLE_PATTERN",
If((self.loopback_rxdata[4:6] != 0) & ~self.loopback_rxdata[6], If((self.loopback_rxdata[3:4] != 0) & ~self.loopback_rxdata[5],
NextState("TERMINATE"), NextState("TERMINATE"),
).Else( ).Else(
NextState("SHIFT_HIGH_BITSLIP_FIRST"), NextState("SHIFT_HIGH_BITSLIP_FIRST"),
@ -552,7 +551,13 @@ class DelayOptimizer(Module):
fsm.act("LOAD_OPT_DELAY", fsm.act("LOAD_OPT_DELAY",
self.ld.eq(1), self.ld.eq(1),
# The optimal delay tap is prepared in the SAMPLE_PULSE_OUT state # The optimal delay tap is prepared in the SAMPLE_PULSE_OUT state
NextState("TERMINATE"), NextState("WAIT_DELAY_LOAD"),
)
fsm.act("WAIT_DELAY_LOAD",
If(self.delay_tap == self.opt_delay_tap,
NextState("TERMINATE"),
),
) )
fsm.act("TERMINATE", fsm.act("TERMINATE",
@ -698,7 +703,7 @@ class MultiLineRX(Module):
# Signal from each OSERDES group can have a different delay # Signal from each OSERDES group can have a different delay
# So, add delay to the groups that receives the pulse early # So, add delay to the groups that receives the pulse early
# Maximum delay = 8 # Maximum delay = 8
channel_buffer = SyncFIFO(5, 8) channel_buffer = SyncFIFO(5, 16)
self.comb += [ self.comb += [
# Allow data go through the FIFO unless aligning # Allow data go through the FIFO unless aligning