【FPGA项目】沙盘演练——基础版报文收发

​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ 第1个虚拟项目

前言

点灯开启了我们的FPGA之路,那么我们来继续沙盘演练。

用一个虚拟项目,来入门练习,以此步入数字逻辑的大门。

****Key Words:****FIFO 、SOF 、EOF、计数器、缓存、时序图、方案设计

一、项目要求

  1. 输入报文长度64~2048字节;
  2. 输入报文之间最小间隔为两拍;
  3. 输出报文的前两拍添加16bit报文长度信息;第1拍为报文长度高8位;第2拍为报文长度低8位;第3拍开始为输入报文;

|------------|-----|----|----------------|
| 信号 | I/O | 位宽 | 描述 |
| 系统接口信号 ||||
| i_sys_clk | I | 1 | 系统时钟,125Mhz |
| i_rst_n | I | 1 | 硬复位,低有效 |
| 输入接口信号 ||||
| i_sop_in | I | 1 | 输入报文头指示信号,高有效 |
| i_eop_in | I | 1 | 输入报文尾指示信号,高有效 |
| i_vld_in | I | 1 | 输入报文数据有效信号,高有效 |
| i_data_in | I | 8 | 输入报文数据 |
| 输出接口信号 ||||
| o_sop_out | O | 1 | 输出报文头指示信号,高有效 |
| o_eop_out | O | 1 | 输出报文尾指示信号,高有效 |
| o_vld_out | O | 1 | 输出报文数据有效信号,高有效 |
| o_data_out | O | 8 | 输出报文数据 |

输入接口时序

输出接口时序

二、项目方案设计

2.1项目需求

  1. 输出报文;
  2. 输出报文长度;
  3. 报文与报文长度输出满足时序要求;

2.2项目方案

  1. 要求输出报文,且报文输出在报文长度输出之后,所以需要先对输入报文进行缓存,根据输入报文的位宽和长度范围,此处选择合适的同步FIFO即可;(如果是IC,那么就需要自己写FIFO,可以参考本博客的FIFO介绍)

这里项目提出了第1个要求,掌握FIFO的使用。

  1. 要求输出报文长度,所以需要对输入报文长度进行计数,并将其缓存;

此处有坑,若只用寄存器对长度进行缓存,存在被后续报文长度覆盖的风险,故需要第2个FIFO对报文长度进行缓存。

  1. 要求先输出报文长度然后紧跟着输出报文,此处需要对时序进行设计,需要掌握FIFO的读写时序,需要理解fpga的时钟沿采样。

理解:时钟沿采样及数据下一时钟沿变化。

2.3项目代码

cpp 复制代码
module zmj0001(
	input 			sys_clk,
	input 			rst_n,
	
	input			sop_in,
	input 			eop_in,
	input 			vld_in,
	input	[7:0]	data_in,
	
	output 			sop_out,
	output			eop_out,
	output			vld_out,
	output 	[7:0] 	data_out
	);

当然这不是唯一的设计方案,可以先自行考虑设计及验证。

若需完整代码工程,🐟搜索"zmj0001"

项目重难点:

  1. FIFO的使用及时序的设计
  2. 考虑包间隔2 clk cycle
  3. 考虑长包+超短包的情况

时序设计可以用TimingDesigner软件,简单易用,需要的可以下载。

​​​​​​​三、仿真验证

可以使用计数器来产生数据源data_in;

cpp 复制代码
`timescale 1ns / 1ps

module zmj0001_tb();

reg					sys_clk				;
reg					rst_n				;
reg 	[7	:0]		data_in				;
reg					vld_in				;
reg					sop_in				;
reg					eop_in				;
reg		[11	:0]		cnt					;									
wire 				sop_out  			;
wire 				eop_out             ;
wire				vld_out             ;
wire 	[7:0] 		data_out            ;

initial
begin
	sys_clk		=	0;
	rst_n		=	0;
	#100
	rst_n		=	1;
end
always #5	sys_clk	=	~sys_clk;	//100Mhz
//用计数器来产生data_in
always @(posedge	sys_clk	or	negedge	rst_n)begin
	if(~rst_n)
		cnt				<=		12'b0;
	else if(cnt > 2048)
		cnt				<=		cnt;
	else
		cnt				<=		cnt	+	12'b1;
end
always @(posedge	sys_clk	or	negedge	rst_n)begin
	if(~rst_n)begin
		data_in			<=		8'b0;
		sop_in			<=		1'b0;
		eop_in			<=		1'b0;
		vld_in			<=		1'b0;
		end
	else begin
		data_in			<=		8'b0;
		sop_in			<=		1'b0;
		eop_in			<=		1'b0;
		vld_in			<=		1'b0;
		if((cnt > 'd10  &&   cnt  <=  'd60)|(cnt > 'd68  &&   cnt  <=  'd668))begin
			data_in		<=		data_in + 1'b1;
			vld_in		<=		1'b1;
			end
		if((cnt == 'd11)|(cnt == 'd69))
			sop_in		<=		1'b1;
		if((cnt == 'd60)|(cnt == 'd668))
			eop_in		<=		1'b1;
		if((cnt == 'd62) | (cnt == 'd63))begin  //63  66
			data_in		<=		data_in + 1'b1;
			vld_in		<=		1'b1;
			sop_in 		<= 		1'b1;
			eop_in 		<= 		1'b1;
			end
		
		end
end	


zmj0001		u_zmj0001(
	.sys_clk			(sys_clk   ),	
	.rst_n              (rst_n     ),
						 			
	.sop_in             (sop_in    ),
	.eop_in             (eop_in    ),
	.vld_in             (vld_in    ),
	.data_in            (data_in   ),
						 			
	.sop_out            (sop_out   ),
	.eop_out            (eop_out   ),
	.vld_out            (vld_out   ),
	.data_out           (data_out  )
	);

endmodule

具体modelsim使用及与vivado的联合仿真,脚本编写请参考其他博文,后续FPGA其他专栏再考虑写相关内容。

验证时重点关注边界情况

输入:

共4包数据,长包+超短包+超短包+长包,包间隔均为2clk cycle

****data_in :****第1包:1-50的累加数;第2包:1;第3包:1;

输出:

若包间隔<2 clk?

输入:

输出:

可以看到,本设计甚至支持背靠背的超短包输入。

四、项目收获

  1. 方案设计的重要性:任何项目都是始于方案设计,前期需要花大量的功夫去理清思路,方案设计完成,代码实现只不过是水到渠成的事情。
  2. 仿真的学习:通过本项目,完成了testbench的编写,仿真验证,是对自己设计的一次检验,是实际项目缩短调试时间的最佳利器。
  3. 对xilinx IP的使用,对datasheet的阅读学习。
  4. 对时序的理解,时钟是FPGA的心跳:任何时序操作都是发生在时钟的跳变沿。当采样发生在当前上升沿时刻,数据变化是发生在下一时刻的上升沿。
  5. 绘画时序图,TimingDesigner的使用。有了时序图,代码就很容易实现了。

五、进阶考虑

本次虚拟项目旨在用最简单的例子带大家了解数字逻辑设计的一些基本概念,所以很多东西是没有考虑的。比如:

  1. 如果包间隔小于2个时钟周期怎么办? -----握手与反压
  2. 如果输入数据有错误怎么办? -----CRC校验
  3. 如果需要跨时钟域传输呢? -----CDC处理
  4. 报文只是简单转发,如果需要做处理呢?-----数据处理
  5. ...

所以,下一篇将沿着这个思路展开,进阶版的虚拟项目,同样可以作为公司的入职培训。

咱们下期见!

相关推荐
不是笨小孩i1 小时前
基于Zynq FPGA对雷龙SD NAND的测试
fpga开发·sd nand·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
FPGA_ADDA1 小时前
FMC 扩展子卡6 路 422,8 组 LVDS,8 路 GPIO
fpga开发·gpio·422·lvds·fmc 扩展子卡
搬砖的小码农_Sky7 小时前
单片机和FPGA有什么区别?
单片机·嵌入式硬件·fpga开发
Jade-YYS10 小时前
如何判断FPGA能够接入几个Camera
fpga开发
apple_ttt1 天前
SystemVerilog学习——虚拟接口(Virtual Interface)
fpga开发·fpga·systemverilog·uvm
学习路上_write2 天前
FPGA/Verilog,Quartus环境下if-else语句和case语句RT视图对比/学习记录
单片机·嵌入式硬件·qt·学习·fpga开发·github·硬件工程
jjjxxxhhh1232 天前
FPGA,使用场景,相比于单片机的优势
单片机·嵌入式硬件·fpga开发
诚实可靠小郎君95272 天前
FPGA高速设计之Aurora64B/66B的应用与不足的修正
fpga开发·aurora·高速通信
百锦再2 天前
基于Zynq FPGA对雷龙SD NAND的测试
fpga开发
∑狸猫不是猫2 天前
HDLBIts习题(4):边沿检测、分频计数器、多位BCD计数器
fpga开发