采样数据传输模块功能

设计目的

将上端的采样数据信号在子卡上进行编码,通过高速收发器发送编码信号到主卡,主卡收到编码信号后解码获得采样数据。

模块划分

  1. 数据采样模块:通过周期性的采样触发信号控制,获取采样数据,同时生成读使能信号供下方编码模块读取采样数据。
  2. 数据编码模块:将上方数据采样模块发送来的采样数据编码,使数据易于通过高速收发器传输,编码信号传输至高速收发器,让高速收发器发送到主卡解码并接收。
  3. 高速收发器:连接子卡与主卡,将在子卡编码后的采样数据发送到主卡,由主卡解码获取采样数据。
  4. 数据对齐模块:高速收发器传输数据时可能出现数据错位未对齐的问题,根据编码规则分析并修复未对齐数据;
  5. 数据解码模块:接收高速收发器传输的编码信号,对其解码使主卡可以获取采样数据,同时生成读使能信号使主卡易于读取。

数据编码模块

模块接口信号功能

module ad7606info_encode #(
	parameter AD_IN_DW  	=	16 ,        //ad数据每个通道位宽
	parameter AD_IN_CHANNEL =   32 ,        //ad数据通道数
	parameter CODED_OUT_DW  =   32         //编码后gt通道发送数据位宽
)
(
	input   				   rst_n    ,              // 复位信号,低电平有效
	input					   ad_wr_clk  ,            // fifo的写时钟
	input       			   coded_clk,              // 编码时钟,控制编码流程与fifo读时钟
	input   				   ad_en   ,               // 同步ad采集模块采样触发信号,使数据编码模块与ad采集模块工作状态同步
	input   				   wr_en   ,               // 写使能信号,高电平期间将上端的采样数据写入到fifo中
	input  		[AD_IN_DW-1:0]            ad_data ,  	    //写入的16位ad采样信号	
		    
	output reg	[CODED_OUT_DW-1:0]        coded_data,      //输出的编码信号
	output reg	[3:0]                     coded_ctr	   //输出的控制信号,用于控制数据对齐并判断数据是采样数据还是功能信号
);

模块功能实现

编码模块整体分为两部分功能,一部分是fifo缓冲采样数据,一部分是对采样数据进行编码。

fifo缓冲采样数据:

  1. 写数据端,当采样模块发送过来的写使能信号wr_en高电平时,将采样信号ad_data写入到fifo中,写入数据位宽为AD_IN_DW,默认16位;
  2. 读数据端,在编码模块状态为data_sending时,若fifo非空,则将fifo数据读出,读出数据位宽为CODED_OUT_DW,默认为32位。

采样数据编码:

  1. 发送的数据分为采样数据与功能信号。当数据为功能信号时,同步发送的coded_ctr为4'b0001,用于表明该信号不是采样数据,且可以辅助高速收发器rx端对齐数据;
  2. 通过状态机来控制编码状态跳转。
     localparam idle             = 0,    //负责清空fifo,避免上次循环写进fifo中数据过多
               data_waiting1    = 1,    //等待信号上升沿到来开始读取采集数据,等待期间发送无效数据
               data_reading     = 2,    //信号上升沿到来,开始读取数据到fifo中
               fifo_begin       = 3,    //表明fifo即将传输数据,同时发送数据表明本次将要发送多少数据
               data_sending     = 4,    //将fifo中数据发送过去
               fifo_end0        = 5,    //fifo数据传输结束
               fifo_end1        = 6;    //end状态用两个,降低采样数据与特定信号重合的概率
    
  3. 初始状态下为idle状态,idle状态下发送32'haa_aa_01_bc清空fifo,然后直接跳转到data_waiting1状态。
  4. data_waiting状态发送32'haa_aa_02_bc,等待ad_en信号上升沿到来,因为ad_en信号高电平期间,上方的采集数据模块才会开始采集数据。
  5. ad_en信号上升沿到来后跳转到data_reading状态,此时将可以开始读取数据采样模块发送的采样信号到fifo中,同时该状态下发送32'haa_aa_03_bc提示将要开始发送编码数据,之后跳转到fifo_begin状态。
  6. fifo_begin状态发送{8'h55,FIFO_SEND_NUM,8'hbc}告诉解码模块将要发送的32位采样数据有多少个,其中FIFO_SEND_NUM为16位数据,表明后面会发送的编码数据个数;然后跳转到data_sending状态。
  7. data_sending状态下,当fifo非空时,从fifo中读出32位数据并发送;而fifo如果被读空,则发送特定的功能信号32'haa_aa_04_bc,表明该数据不是采样数据;使用计数器对一轮循环中读出的32位采样数据计数,当读出FIFO_SEND_NUM个32位采样数据后,结束数据读取,跳到fifo_end0状态。
  8. fifo_end0与fifo_end1状态都是表示本轮循环结束,使用两个状态来降低采样数据与功能信号重合概率;两个状态分别发送32'haa_aa_05_bc32'haa_aa_06_bc;之后跳转到IDLE状态。

数据解码模块

模块接口信号功能

module ad7606info_decode #(
	parameter AD_OUT_DW  	=	16 ,         //fifo读出的解码ad信号位宽
	parameter CODED_IN_DW  =   32 ,         //fifo写入的编码信号位宽
	parameter AD_OUT_CHANNEL 	=   32          //当fifo中写入数据数量达到FIFO_CODED时,开始将fifo中数据读出
)
(
	input 						rst_n    	  ,      //复位信号

	input               		ad_rd_clk      ,	 //fifo读信号时钟,用于将fifo中缓存的ad采集数据读出
	output reg         			ad_en_out      ,     //高电平时表明在此期间可以根据rd_en_out进行数据读取
	output reg          		rd_en_out      ,     //高电平期间外部模块可以读出fifo数据
	output     [AD_OUT_DW-1 :0]	ad_data   	   ,     //从fifo中读出的16位ad信号
	
	input 						    coded_clk	,          //控制编码信号解码的时钟,并控制fifo写数据
	input 	   [CODED_IN_DW-1:0] 	coded_data	,          //编码信号
	input 	   [3:0]  			    coded_ctr              //控制信号,用于控制数据对齐
    );

模块功能实现

编码模块整体分为两部分功能,一部分是对高速收发器发送过来的编码数据进行解码还原为采集数据,一部分是fifo缓冲并输出还原的采集数据。

编码数据解码

  1. 通过状态机控制解码模块状态跳转。
    localparam  RESET       = 0,
                IDLE        = 1,
                WRITE_BEGIN = 2,
                WRITE_DATA  = 3,
                WRITE_OVER  = 4;
    
  2. 解码模块初始状态下为RESET状态,持续一个时钟周期,期间进行fifo复位,之后跳转到IDLE状态。
  3. IDLE状态等待接收到{8'h55,FIFO_SEND_NUM,8'hbc}信号,当接受到时,获取本次需要读取的32位采集数据个数,然后跳转到WRITE_BEGIN状态。
  4. WRITE_BEGIN状态,拉高ad_en_out,提示后面接收ad采集数据的模块,可以开始根据rd_en_out读出ad_data,然后跳转到WRITE_DATA状态;与此同时,发送过来的32位采集数据也开始写入到fifo中,对写入fifo32位采集数据使用wr_cnt进行计数;
  5. WRITE_DATA状态下,当fifo非空时,拉高rd_en_out从而将fifo中数据读出;同时,每读出一个16位ad采集数据,rd_cnt计数加1,使用rd_cnt统计fifo读出的ad采集数据数量;当wr_cnt达到了FIFO_SEND_NUM,或者连续收到32'haa_aa_05_bc32'haa_aa_06_bc时,两者均可以表示发送端发送的32位采集数据已经全部写入fifo,状态机可以跳转到WRITE_OVER状态。
  6. 到达WRITE_OVER状态,此时不会有新的采集数据写入到fifo里面,但是fifo里面的数据还没有完全读取完,需要等待rd_cnt到达指定值,此时才能表明fifo数据全部读完了,然后再跳到RESET状态进行fifo复位,开始下一轮循环。

高速收发器

高速收发器用于将编码模块的编码信号发送至解码模块进行解码。其中,编码模块信号只和gt0的tx0连接,解码模块信号只接收gt1的rx端。

module gtwizard_0_exdes #
(
    ......
)
(
    ......
     
    //gt0端只使用tx0
    output                 tx0_clk       ,   //tx端生成时钟,控制编码模块fifo读使能时钟信号
    input        [31:0]    tx0_data      ,   //从编码模块读出编码信号并发送至rx端
    input        [3:0]     tx0_kchar     ,   //从编码模块读出控制信号并发送至rx端
    output                 rx0_clk       , 
    output        [31:0]   rx0_data      , 
    output        [3:0]    rx0_kchar     , 
    output                 gt0_tx_system_rstn  ,   //生成复位信号,控制编码模块复位功能
    output                 gt0_rx_system_rstn  , 
     
    //gt1端只使用rx1
    output                 tx1_clk       , 
    input        [31:0]    tx1_data      , 
    input        [3:0]     tx1_kchar     , 
    output                 rx1_clk       , //rx端生成时钟,控制解码模块fifo写使能时钟信号
    output        [31:0]   rx1_data      , //将编码信号发送至解码模块
    output        [3:0]    rx1_kchar     , 
    output                 gt1_tx_system_rstn  , 
    output                 gt1_rx_system_rstn  , //生成复位信号,控制解码模块复位功能
     
    ......
);

数据对齐模块

数据移位问题

32位数据在经过gt通道传输后,可能会出现数据移位的情况。具体来说,就是两个相邻的32位数据,一个数据的低16位可能与另一个的高16位拼接,并被解码模块识别成新的一个32位数据。当出现这种情况时,数据的K码(即所有功能信号末尾的8'hbc)也会移位,K码的移位可以在伴随的coded_ctr控制信号中体现。可以发现,此时控制信号同样发生了移位,原来的4'b0001变成了4'b0100。出现上述情况时,再根据coded_ctr的移位情况即可对移位数据进行还原。

模块接口信号功能

module data_align(
	input 					rst_n			,  //复位信号,低电平有效
	input 					rx_clk			,  //gt1的rx端产生的时钟信号,与解码模块写时钟同一个
	input		[31:0] 		rx_data			,  //gt通道发送过来的未检查是否移位的编码信号
	input		[3:0] 		rx_ctrl			,  //用于检查是否移位的控制信号
	output reg	[31:0] 		rx_data_align	,  //已完成数据对齐的编码信号
	output reg	[3:0] 		rx_ctrl_align      //已恢复的控制信号
    );

模块功能实现

  1. 由于一次数据移位会干扰到两个信号,因此使用寄存器rx_data_r与rx_ctrl_r将上一时钟周期的rx_data与rx_ctrl寄存起来;
  2. 当根据rx_data检查发现数据移位现象时,将rx_data_align 赋值为 {rx_data[15:0],rx_data_r[31:16]},否则直接给rx_data_align赋值rx_data;同时复原控制信号。

本文章使用limfx的vscode插件快速发布