【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的使用。

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

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

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

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

2.3项目代码

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;

`timescale 1ns / 1psmodule 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
beginsys_clk		=	0;rst_n		=	0;#100rst_n		=	1;
end
always #5	sys_clk	=	~sys_clk;	//100Mhz
//用计数器来产生data_in
always @(posedge	sys_clk	or	negedge	rst_n)beginif(~rst_n)cnt				<=		12'b0;else if(cnt > 2048)cnt				<=		cnt;elsecnt				<=		cnt	+	12'b1;
end
always @(posedge	sys_clk	or	negedge	rst_n)beginif(~rst_n)begindata_in			<=		8'b0;sop_in			<=		1'b0;eop_in			<=		1'b0;vld_in			<=		1'b0;endelse begindata_in			<=		8'b0;sop_in			<=		1'b0;eop_in			<=		1'b0;vld_in			<=		1'b0;if((cnt > 'd10  &&   cnt  <=  'd60)|(cnt > 'd68  &&   cnt  <=  'd668))begindata_in		<=		data_in + 1'b1;vld_in		<=		1'b1;endif((cnt == 'd11)|(cnt == 'd69))sop_in		<=		1'b1;if((cnt == 'd60)|(cnt == 'd668))eop_in		<=		1'b1;if((cnt == 'd62) | (cnt == 'd63))begin  //63  66data_in		<=		data_in + 1'b1;vld_in		<=		1'b1;sop_in 		<= 		1'b1;eop_in 		<= 		1'b1;endend
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. ...

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

咱们下期见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/69883.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网络编程】TCP/IP协议(互联网的基石)

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

Go语言最全面试题,拿offer全靠它,附带免积分下载pdf

面试题文档下链接点击这里免积分下载 go语言入门到精通点击这里免积分下载 文章目录 Go 基础类GO 语言当中 NEW 和 MAKE 有什么区别吗&#xff1f;PRINTF(),SPRINTF(),FPRINTF() 都是格式化输出&#xff0c;有什么不同&#xff1f;GO 语言当中数组和切片的区别是什么&#xf…

华为云云服务器评测|云耀云服务器实例基础使用实践

&#x1f996;我是Sam9029&#xff0c;一个前端 Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主 **&#x1f431;‍&#x1f409;&#x1f431;‍&#x1f409;恭喜你&#xff0c;若此文你认为写的不错&#xff0c;不要吝啬你的赞扬&#xff0c;求…

leetcode669. 修剪二叉搜索树(java)

修剪二叉搜索树 题目描述递归代码演示&#xff1a; 题目描述 难度 - 中等 LC - 669. 修剪二叉搜索树 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留…

搭建HTTPS服务器

HTTPS代理服务器的作用与价值 HTTPS代理服务器可以帮助我们实现网络流量的转发和加密&#xff0c;提高网络安全性和隐私保护。本文将指导您从零开始搭建自己的HTTPS代理服务器&#xff0c;让您更自由、安全地访问互联网。 1. 准备工作&#xff1a;选择服务器与操作系统 a. 选…

python爬虫关于ip代理池的获取和随机生成

前言 在进行爬虫开发时&#xff0c;代理IP池是一个非常重要的概念。代理IP池是指一个包含多个可用代理IP的集合&#xff0c;这些代理IP可以用来绕过网站的防爬虫策略&#xff0c;从而提高爬取数据的成功率。 在本文中&#xff0c;我们将介绍如何获取代理IP池&#xff0c;并且随…

【C++杂货铺】探索list的底层实现

文章目录 一、list的介绍及使用1.1 list的介绍1.2 list的使用1.2.1 list的构造1.2.2 list iterator的使用1.2.3 list capacity&#xff08;容量相关&#xff09;1.2.4 list element access&#xff08;元素访问&#xff09;1.2.5 list modifiers&#xff08;链表修改&#xff0…

anaconda navigator打不开,一直在loading画面

anaconda navigator打不开&#xff0c;一直在loading画面。百度解决方法&#xff0c;用网上的方法在命令窗口里运行conda update anaconda结果一直显示 solving environment卡在那里。又尝试用管理员身份运行还是不行&#xff0c;打开后出现There in aninstance of Anaconda Na…

C标准输入与标准输出——stdin,stdout

&#x1f517; 《C语言趣味教程》&#x1f448; 猛戳订阅&#xff01;&#xff01;&#xff01; ​—— 热门专栏《维生素C语言》的重制版 —— &#x1f4ad; 写在前面&#xff1a;这是一套 C 语言趣味教学专栏&#xff0c;目前正在火热连载中&#xff0c;欢迎猛戳订阅&#…

iOS系统下轻松构建自动化数据收集流程

在当今信息爆炸的时代&#xff0c;我们经常需要从各种渠道获取大量的数据。然而&#xff0c;手动收集这些数据不仅耗费时间和精力&#xff0c;还容易出错。幸运的是&#xff0c;在现代科技发展中有两个强大工具可以帮助我们解决这一问题——Python编程语言和iOS设备上预装的Sho…

动态规划之简单多状态

简单多状态 1. 按摩师&#xff08;easy&#xff09;2. 打家劫舍II &#xff08;medium&#xff09;3. 删除并获得点数&#xff08;medium&#xff09;4. 买卖股票的最佳时机含冷冻期&#xff08;medium&#xff09;5. 买卖股票的最佳时机III&#xff08;hard&#xff09; 1. 按…

c++(c语言)通用版本的单链表的头插法创建

我们创建一个长度为n的链表时&#xff0c;可以采取头插法创建或者尾插法创建&#xff0c;本篇博客我们采取头插法来创建&#xff0c;&#xff08;作者只学了头插&#xff0c;尾插等以后来补qwq)。 我们先来画图来看看头插的创建形式把&#xff0c;会了原理再写代码。 首先是我…

自定义TimeLine实现卡拉OK轨

系列文章目录 自定义TimeLine 自定义TimeLine 系列文章目录前言正文UI部分代码部分Data&#xff08;数据&#xff09;Clip&#xff08;片段&#xff09;Track&#xff08;轨道&#xff09;Mixer&#xff08;混合&#xff09;被控制物体 总结 前言 自定义TimeLine实际上就是自定…

Redis缓存的高并发问题

Redis 做缓存虽减轻了 DBMS 的压力&#xff0c;减小了 RT&#xff0c;但在高并发情况下也是可能会出现各 种问题的。 1 缓存穿透 当用户访问的数据既不在缓存也不在数据库中时&#xff0c;就会导致每个用户查询都会“穿透” 缓存“直抵”数据库。这种情况就称为缓存穿透。一个…

OpenCV(十):图像缩放、翻转、拼接的介绍与使用

目录 &#xff08;1&#xff09;图像缩放&#xff1a;resize() &#xff08;2&#xff09;图像翻转&#xff1a; flip() &#xff08;3&#xff09;图像拼接&#xff1a;hconcat() 和vconcat() &#xff08;1&#xff09;图像缩放&#xff1a;resize() 使用 cv2.resize() 函…

sql:SQL优化知识点记录(十一)

&#xff08;1&#xff09;用Show Profile进行sql分析 新的一个优化的方式show Profile 运行一些查询sql&#xff1a; 查看一下我们执行过的sql 显示sql查询声明周期完整的过程&#xff1a; 当执行过程出现了下面这4个中的时&#xff0c;就会有问题导致效率慢 8这个sql创建…

搬家快递服务小程序的便利性

在当今快节奏的生活中&#xff0c;搬家可能是很多人都需要面对的问题。无论是新房子还是新办公室&#xff0c;都需要高效、便捷的搬家服务。本文将介绍如何使用第三方小程序制作平台&#xff0c;如乔拓云平台&#xff0c;开发一款高效便捷的搬家服务小程序。 1. 注册登录第三方…

【易售小程序项目】修改“我的”界面前端实现;查看、重新编辑、下架自己发布的商品【后端基于若依管理系统开发】

文章目录 “我的”界面修改效果界面实现界面整体代码 查看已发布商品界面效果商品数据表后端上架、下架商品ControllerMapper 界面整体代码back方法 编辑商品、商品发布、保存草稿后端商品校验方法Controller 页面整体代码 同项目其他文章 “我的”界面修改 效果 界面实现 界…

【C++设计模式】详解装饰模式

2023年8月31日&#xff0c;周四上午 这是我目前碰到的最难的设计模式..... 非常难以理解而且比较灵活多半&#xff0c;学得贼难受&#xff0c;写得贼费劲..... 2023年8月31日&#xff0c;周四晚上19:48 终于写完了&#xff0c;花了一天的时间来学习装饰模式和写这篇博客。 …

序列到序列学习(seq2seq)

permute(1,0,2)&#xff0c;将batch_size 放在中间state 最后一个时刻&#xff0c;每个层的输出