JEDSD204B标准verilog实现7-传输层代码实现及仿真

本文在之前传输层协议解析的基础上完成verilog代码的开发及仿真,并详细给出设计思路。

协议参考: JEDSD204B标准verilog实现5-传输层协议解析1 JEDSD204B标准verilog实现6-传输层协议解析2 ,代码实现思路如下:

JEDSD204B标准verilog实现7-传输层代码实现及仿真

第一将数据排开,然后向lane上映射。注意,由于不同器件的大小端、数据映射方式等不完全按照204C协议进行,因此在下图红框位置会增加bit、byte等路由配置,增加代码的灵活性。

根据系统要求,传输层可能需要增加控制位和结束位,形成 半字节组, 这些半字节组按照帧格式组帧,然后将帧数据发送到路层。JESD204B 链路配置参数决定采样数据组帧和解帧成为8位字节的方式,然后分配数据到JESD204B逻辑通道。由前面的协议分析可以知道,帧组装器与M、SN、CF、CS、HD、F等参数相关,但是并非所有转换器器件都必须支持全部配置参数,各器件的数据手册会规定支持哪些配置参数组合, 有些JESD204B 链路配置参数是相互依存的, 本连载也仅对经典场景进行描述。

在协议控制器中,通过传输层和数据链路层的数据一般都是并行的,而并行数据总线的宽度在芯片、FPGA设计中一般取决于serdes的架构。一般地,当JESD204B 串行通道速率增加时,serdes的并行数据的位宽也会增加,从而使得数字处理时钟速率保持在可控水平。对于串行比特率超过6Gbits 的器件,一般采用 的并行 32 位数据传输。本次设计的组帧器使用32 位数据的并行数据总线,即在JESD204B 协议规定的最高 12.5 Gbit's 的串行速率下,数字处理模块只需工作在 312.5MHz (12.5 GHz/40)。以xilinx的GTY serdes为例,用户数据接口位宽可以是64bit或者32bit,一般在204C场景下线速率高时使用64bit接口。对于204B一般使用32bit用户接口,本连载的serdes接口设计按照32bit进行。 因此,整个链路层代码设计时均会以32bit并行架构设计。

第一以 F=1 (F=1时N仅支持16)为例进行map代码设计,整体代码如下:

// ============================================================// File Name: jesd204b_transport_tx// VERSION : V1.0// DATA : 2025/09/11// Author : FPGA自学笔记分享// ============================================================// 说明:// 1)TX MAP 仅支持N=12/16,CF=0,CS=0 的场景,// 2)link层数据处理时的位宽为32,用于对接xilinx/intel的serdes// 3)F=1 (F=1时N仅支持16)// delay : // ============================================================

`timescale 1ns/1psmodule jesd204b_transport_tx_f1 #( parameter C_JESD204B_M = 4 , // 参数满足 M*N = L*F*8 parameter C_JESD204B_N = 16 , parameter C_JESD204B_L = 8 ) // L = M*N/8( input wire I_user_clk , /// 应用层用户时钟 input wire I_link_clk , /// 链路层链路时钟 input wire [C_JESD204B_M*C_JESD204B_N-1:0] I_data_in , /// 输入数据 {M0 M1 M2 M3 ....} output reg [32*C_JESD204B_L-1:0] O_data_out /// 输出数据 );// ============================================================// wire reg// ============================================================localparam C_JESD204B_F = 1 ;
reg [C_JESD204B_F*8-1:0] S_data_in_f [C_JESD204B_L-1:0] ; /// 输入数据分组reg [C_JESD204B_F*8-1:0] S_data_in_f_d1 [C_JESD204B_L-1:0] ; /// 输入数据分组打拍reg [C_JESD204B_F*8-1:0] S_data_in_f_d2 [C_JESD204B_L-1:0] ; /// 输入数据分组打拍reg [C_JESD204B_F*8-1:0] S_data_in_f_d3 [C_JESD204B_L-1:0] ; /// 输入数据分组打拍wire [31:0] S_data_in_32bit [C_JESD204B_L-1:0] ; /// 输入数据拼接为LANE数据reg [31:0] S_data_in_mem [C_JESD204B_L-1:0][15:0] ; /// 输入数据进缓存,跨时钟域reg [1:0] S_clk_cnt ;reg [3:0] S_wr_addr ;reg S_wr_flag ;wire S_wr_flag_rd ;reg [3:0] S_rd_addr ;// ============================================================// main code// ============================================================
// ============================================================// clk_a// ============================================================always @(posedge I_user_clk) S_clk_cnt 'd1;
always @(posedge I_user_clk) if(&S_clk_cnt) S_wr_addr
always @(posedge I_user_clk) S_wr_flag
cm_cdc_fr cm_cdc_flag ( .I_clk_a (I_user_clk ), ///输入时钟a .I_clk_b (I_link_clk ), ///输入时钟b .I_fr (S_wr_flag ), ///输入时钟a下的flag .O_fr (S_wr_flag_rd ) ///输入时钟b下的flag );
// ============================================================// clk_b// ============================================================always @(posedge I_link_clk) if(S_wr_flag_rd) S_rd_addr 'd0; else S_rd_addr
genvar L ;
generate for(L=0;Lbegin:L_pro /// 第一对数据分组 always @(posedge I_user_clk) S_data_in_f[L] 1)*C_JESD204B_F*8+:C_JESD204B_F*8];
always @(posedge I_user_clk) begin S_data_in_f_d1[L] S_data_in_f_d2[L] S_data_in_f_d3[L] end
assign S_data_in_32bit[L] = {S_data_in_f_d3[L],S_data_in_f_d2[L],S_data_in_f_d1[L],S_data_in_f[L]};

always @(posedge I_user_clk) if(&S_clk_cnt) S_data_in_mem [L][S_wr_addr]
always @(posedge I_link_clk) O_data_out[32*L+:32]
endendgenerate
endmodule

代码设计思路如下:

JEDSD204B标准verilog实现7-传输层代码实现及仿真

仿真结果如下:

输入数据:

JEDSD204B标准verilog实现7-传输层代码实现及仿真

输出数据:

JEDSD204B标准verilog实现7-传输层代码实现及仿真

可以看到仿真输入按照自加数进入,输出和推导结果一致。

本文对F=1进行说明,后续对F的其他参数进行说明。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容