altera ddio调试

做一个记录关于前段时间调试altera ddio_out双沿输出


1、FPGA(cyclone 4 系列E55)与外围器件通过rgmii接口相连,示意图如下:




FPGA提供参考时钟phy_ref_clk.

2、具体解决方案

方案1:

时钟方案如下:

62.5Mhz经过pll生成2路时钟62.5 M , 125M ,125M时钟直接作为rgmii的参数时钟即phy_ref_clk输出至mcu。

mcu输出125M时钟经pll内部生成3路时钟,c0(125M),c1(250M),c2(125M),各时钟作用如下:

c0:pll直接调整相位,采样mcu发送数据,使用altera ip_core:ddio_in获取双沿数据;

c1:rgmii发送时钟,直接调整pll的相位,使发送时钟stup,hold满足mcu要求

c2:发送rgmii时钟数据。因为rgmii是125M时钟的双沿数据,但是我用signal tap抓管脚信号时没有抓到,以为自己ddio_out没有使用正确,就采用发送数据125M的倍频250M来单沿(上升沿)发送数据,这样也能达到125M双沿的输出结果

sdc约束:

create_clock -name "board_clk" -period 16.000ns [get_ports {board_clk}]
create_clock -name "rgmii_rx_clk" -period 8.000ns [get_ports {rgmii_rx_clk}]

derive_pll_clocks -create_base_clocks

derive_clock_uncertainty

只约束了时钟输入管脚和pll,通过调整c2的相位最终fpga和mcu通信成功,但是同样的sof文件在不同的板子上有不同的现象,有的能通,有的不能通。


我曾经怀疑可能是芯片或者pcb的问题,但是采样上述方案的sof不能通信的板子,我用rgmii回环(fpga直接将mcu输出的数据assign输出)有些mcu能够收到。我初步断定应该是约束出了问题。要么是这样的时钟方案不太好,要么就是哪些约束不正确。基于这种考虑我详细看了看ddio_out的使用,重新列化后,将一个时钟经过ddio_out输出至一个管脚,通过示波器确认是否有输出

send_dataio send_dataio_test (
.datain_h (1'b1),
.datain_l (1'b0]),
.outclock (main_clk),
.dataout (test_signal)
);


通过示波器发现有信号输出,且输出信号频率等于main_clk。得出结论:signal tap抓不了双沿输出信号。


方案2

时钟方案基本同方案1;只是输出数据的时钟以及内部逻辑主时钟全部由62.5M产生,另外一个pll只采用mcu发送数据,通过fifo隔离内部逻辑时钟与接收数据时钟。

详细阅读altera官方文档 AN 433(Constraining and Analyzing Source-Synchronous Interfaces).pdf,根据第38页列子,结合我采用的实际方案,增加相关的时钟约束。

对这些约束,最大的问题就是set_output_delay的两个值max,min,根据公式无论我写那几个值,最后时序分析报告总是出错(飘红),输出至mcu的时钟的setup,hold时序总是不满足。

约束如下:


#base clock
create_clock -name board_clk -period 16.000 -waveform {0 8} [get_ports {board_clk}]
create_clock -name rgmii_rx_clk -period 8.000 -waveform {0 4} [get_ports {rgmii_rx_clk}]

#pll output clock
#pll from board_clk
create_generated_clock -name main_clk -source [get_pins {encrypt_clk|rgmii_clk|altpll_component|auto_generated|pll1|inclk[0]}] -divide_by 1 -multiply_by 2 -duty_cycle 50 [get_pins {encrypt_clk|rgmii_clk|altpll_component|auto_generated|pll1|clk[0]}]
create_generated_clock -name rgmii_phy_clk -source [get_pins {encrypt_clk|rgmii_clk|altpll_component|auto_generated|pll1|inclk[0]}] -divide_by 1 -multiply_by 2 -duty_cycle 50.000 -phase 90 [get_pins {encrypt_clk|rgmii_clk|altpll_component|auto_generated|pll1|clk[1]}]
create_generated_clock -name tx_clk -source [get_pins {encrypt_clk|rgmii_clk|altpll_component|auto_generated|pll1|inclk[0]}] -divide_by 1 -multiply_by 2 -duty_cycle 50.000 -phase 90 [get_pins {encrypt_clk|rgmii_clk|altpll_component|auto_generated|pll1|clk[2]}]

#pll from rgmii_rx_clk
create_generated_clock -name io_rx_clk -source [get_pins {encrypt_clk|rgmii_clk2|altpll_component|auto_generated|pll1|inclk[0]}] -divide_by 1 -multiply_by 1 -duty_cycle 50.000 -phase 0 [get_pins {encrypt_clk|rgmii_clk2|altpll_component|auto_generated|pll1|clk[0]}]


#oddr clock 
create_generated_clock -name p1010_ref_clk -source [get_pins {encrypt_clk|rgmii_outio_phyclk|ALTDDIO_OUT_component|auto_generated|ddio_outa[0]|dataout}] [get_ports {p1010_ref_clk}]
create_generated_clock -name rgmii_tx_clk -source [get_pins {encrypt_clk|rgmii_clk|altpll_component|auto_generated|pll1|clk[2]}] [get_ports {rgmii_tx_clk}]

#output delay ,删除output_delay
#set_output_delay -clock { rgmii_tx_clk } -max 1.6 [get_ports {rgmii_tx_data[0] rgmii_tx_data[1] rgmii_tx_data[2] rgmii_tx_data[3] rgmii_tx_valid}]
#set_output_delay -clock { rgmii_tx_clk } -min -7.5 [get_ports {rgmii_tx_data[0] rgmii_tx_data[1] rgmii_tx_data[2] rgmii_tx_data[3] rgmii_tx_valid}] -add_delay
#
#set_output_delay -clock { rgmii_tx_clk } -clock_fall -max 1.6 [get_ports {rgmii_tx_data[0] rgmii_tx_data[1] rgmii_tx_data[2] rgmii_tx_data[3] rgmii_tx_valid}] -add_delay
#set_output_delay -clock { rgmii_tx_clk } -clock_fall -min -7.5 [get_ports {rgmii_tx_data[0] rgmii_tx_data[1] rgmii_tx_data[2] rgmii_tx_data[3] rgmii_tx_valid}] -add_delay


# Destination multicycle exceptions
set_multicycle_path -setup -end 0 -rise_from [get_clocks main_clk] -rise_to [get_clocks rgmii_tx_clk]
set_multicycle_path -setup -end 0 -fall_from [get_clocks main_clk] -fall_to [get_clocks rgmii_tx_clk]
set_multicycle_path -hold -end -1 -rise_from [get_clocks main_clk] -rise_to [get_clocks rgmii_tx_clk]
set_multicycle_path -hold -end -1 -fall_from [get_clocks main_clk] -fall_to [get_clocks rgmii_tx_clk]


#set virtual path
set_false_path -setup -rise_from [get_clocks main_clk] -fall_to [get_clocks rgmii_tx_clk]
set_false_path -setup -fall_from [get_clocks main_clk] -rise_to [get_clocks rgmii_tx_clk]
set_false_path -hold  -rise_from [get_clocks main_clk] -fall_to [get_clocks rgmii_tx_clk]
set_false_path -hold  -fall_from [get_clocks main_clk] -rise_to [get_clocks rgmii_tx_clk]


#set_clock_uncertainty
set_clock_uncertainty -rise_from [get_clocks {main_clk}] -rise_to [get_clocks {main_clk}] -setup 0.010
set_clock_uncertainty -rise_from [get_clocks {main_clk}] -fall_to [get_clocks {main_clk}] -setup 0.010
set_clock_uncertainty -fall_from [get_clocks {main_clk}] -rise_to [get_clocks {main_clk}] -setup 0.010
set_clock_uncertainty -fall_from [get_clocks {main_clk}] -fall_to [get_clocks {main_clk}] -setup 0.010

set_clock_uncertainty -rise_from [get_clocks {tx_clk}] -rise_to [get_clocks {tx_clk}] -setup 0.010
set_clock_uncertainty -rise_from [get_clocks {tx_clk}] -fall_to [get_clocks {tx_clk}] -setup 0.010
set_clock_uncertainty -fall_from [get_clocks {tx_clk}] -rise_to [get_clocks {tx_clk}] -setup 0.010
set_clock_uncertainty -fall_from [get_clocks {tx_clk}] -fall_to [get_clocks {tx_clk}] -setup 0.010


最后我去除了set_output_delay的约束,直接在输出至mcu的时钟约束里面加了-phase 90(也就是还是通过pll移动时钟相位)来满足时序要求,最终调通了fpga与mcu之间的通信,目前生成的sof文件比较稳定。


3、问题

还是不明白set_output_delay的参数,data的arrive time和requre time我计算了几遍还是不满足。希望有人能告诉,指点我以下,不胜感激。呵呵~




你可能感兴趣的:(FPGA)