原创单总线传输协议b2s (附全部verilog源码)
一、b2s协议背景介绍
本单总线传输协议为精橙FPGA团队原创,含传送端(transmitter)和接收端(receiver)两部分,基于verilog语言,仅使用单个I/O口进行多位数据的传输,传输方向为单向,用于I/O不够用的情况,已上板验证通过,大家可直接使用。
二、b2s协议Verilog源码
ps. 带★号处可根据需要进行修改.
发送端源码:

/******************************************************************************************
File Name: b2s_transmitter.v
Function: b2s发送端,默认发送32bit数据
********************************************************************************************/ module b2s_transmitter
(
clk, //时钟基准,不限频率大小,但必须与接收端一致
din, //待发送数据
b2s_dout //b2s数据输出端口
);
parameter WIDTH=32; //★设定b2s发送数据位数 input clk;
input [WIDTH-1:0] din;
output b2s_dout; //==============================================================
//b2s数据发送时序
//==============================================================
reg b2s_dout_r;
reg [3:0] state;
reg [9:0] cnt;
reg [4:0] count; //★与发送数据位数保持一致(如发送32bit数据时,count宽度为5;发送8bit时,count宽度为4)
always @ (posedge clk)
begin
case(state)
//初始化
0: begin
count<=0;
b2s_dout_r<=1;
if(cnt==19) //b2s_dout_r高电平持续20个时钟
begin
state<=1;
cnt<=0;
end
else
begin
cnt<=cnt+1;
end
end //开始信号时序
1: begin
b2s_dout_r<=0;
if(cnt==19) //b2s_dout_r低电平持续20个时钟
begin
state<=2;
cnt<=0;
end
else
begin
cnt<=cnt+1;
end
end
2: begin
b2s_dout_r<=1;
if(cnt==19) //b2s_dout_r高电平持续20个时钟
begin
cnt<=0;
state<=3;
end
else
begin
cnt<=cnt+1;
end
end //待发送数据的逻辑电平判断
3: begin
if(din[count]==1)
state<=4;
else
state<=8;
end //逻辑1的发送时序
4: begin
b2s_dout_r<=0;
if(cnt==9) //b2s_dout_r低电平持续10个时钟
begin
cnt<=0;
state<=5;
end
else
begin
cnt<=cnt+1;
end
end
5: begin
b2s_dout_r<=1;
if(cnt==29) //b2s_dout_r高电平持续30个时钟
begin
cnt<=0;
state<=6;
end
else
begin
cnt<=cnt+1;
end
end //逻辑0的发送时序
8: begin
b2s_dout_r<=0;
if(cnt==29) //b2s_dout_r低电平持续30个时钟
begin
cnt<=0;
state<=9;
end
else
begin
cnt<=cnt+1;
end
end
9: begin
b2s_dout_r<=1;
if(cnt==9) //b2s_dout_r高电平持续10个时钟
begin
cnt<=0;
state<=6;
end
else
begin
cnt<=cnt+1;
end
end //统计已发送数据位数
6: begin
count<=count+1'b1;
state<=7;
end
7: begin
if(count==WIDTH) //当一组数据所有位发送完毕,返回并继续下一次发送
begin
b2s_dout_r<=1;
if(cnt==999) //b2s_dout_r高电平持续1000个时钟
begin
cnt<=0;
state<=0;
end
else
begin
cnt<=cnt+1;
end
end
else //当一组数据未发送完毕,则继续此组下一位数据的发送
state<=3;
end //default值设定
default: begin
state<=0;
cnt<=0;
count<=0;
end
endcase
end assign b2s_dout=b2s_dout_r; endmodule
接收端源码:

/******************************************************************************************
File Name: b2s_receiver.v
Function: b2s接收端,默认接收32bit数据
********************************************************************************************/ module b2s_receiver
(
clk, //时钟基准,不限频率大小,但必须与发送端一致
b2s_din, //b2s发送端发送过来的信号
dout //b2s接收端解码出的数据
);
parameter WIDTH=32; //★设定b2s接收数据位数 input clk;
input b2s_din;
output [WIDTH-1:0] dout; //==================================================
//b2s_din信号边沿检测
//==================================================
reg [1:0] b2s_din_edge=2'b01;
always @ (posedge clk)
begin
b2s_din_edge[0] <= b2s_din;
b2s_din_edge[1] <= b2s_din_edge[0];
end //==================================================
//time_cnt - 存储b2c_din信号下降沿及其最近的下一个上升沿之间的时间
//==================================================
reg [1:0] state0;
reg [5:0] time_cnt_r;
always @ (posedge clk)
begin
case(state0)
0: begin
time_cnt_r<=0;
state0<=1;
end
1: begin
if(b2s_din_edge==2'b10)
state0<=2;
else
state0<=state0;
end
2: begin
if(b2s_din_edge==2'b01)
begin
state0<=0;
end
else
time_cnt_r<=time_cnt_r+1'b1;
end
default: begin
time_cnt_r<=0;
state0<=0;
end
endcase
end wire [5:0] time_cnt;
assign time_cnt=(b2s_din_edge==2'b01)?time_cnt_r:'b0; //当b2s_din上升沿瞬间,读取time_cnt_r的值 //==================================================
//b2s解码时序
//==================================================
reg [2:0] state;
reg [4:0] count; //★与接收数据位数保持一致(如接收32bit数据时,count宽度为5;接收8bit时,count宽度为4)
reg [WIDTH-1:0] dout_r;
always @ (posedge clk)
begin
case(state)
0: begin
count<=WIDTH;
if((time_cnt>15)&&(time_cnt<25)) //判断起始信号
state<=1;
else
state<=state;
end
1: begin
if((time_cnt>5)&&(time_cnt<15)) //逻辑1的条件
begin
dout_r[WIDTH-1]<=1;
state<=2;
end
else if((time_cnt>25)&&(time_cnt<35))//逻辑0的条件
begin
dout_r[WIDTH-1]<=0;
state<=2;
end
else
begin
state<=state;
end
end
2: begin
count<=count-1'b1; //每读取一个bit,count减1
state<=3;
end
3: if(count==0) //数据读取完毕,返回并继续下一组数据的读取
begin
state<=0;
end
else
state<=4; //数据未读取完毕,则进行移位
4: begin
dout_r<=(dout_r>>1);//数据右移1位
state<=1;
end
default: begin
state<=0;
count<=WIDTH;
end
endcase
end assign dout=(count==0)?dout_r:dout; //每当一组数据读取完毕,则更新一次dout的值 endmodule
三、源码例化方法
调用发送端,通过单个I/O发送出一组32bit数据:

/******************************************************************************************
File Name: b2s_transmitter_test.v
Function: b2s功能测试:通过b2s transmitter模块将预置的32bit数据发送出去
********************************************************************************************/
module b2s_transmitter_test
(
input clk, //基准时钟
output b2s_dout //b2s数据输出端口
);
parameter WIDTH=32; //★设定b2s发送和接收数据位宽,此处可根据需要进行修改 //==============================================================
//预置待发送数据
//==============================================================
wire [WIDTH-1:0] din;
assign din='b01010101_00111100_11011100_11001111; //★此处可根据需要进行修改,不限于固定数值 //================================
//调用b2s_transmitter模块
//================================
b2s_transmitter
#
(
.WIDTH(WIDTH) //例化发送数据位宽
)
b2s_transmitter_isnt0
(
.clk (clk), //时钟基准,不限频率大小,但必须与接收端一致
.din (din), //待发送数据
.b2s_dout (b2s_dout) //b2s数据输出端口
); endmodule
调用接收端,解码发送端所发出的32bit数据:

/******************************************************************************************
File Name: b2s_receiver_test.v
Function: b2s功能测试:通过b2s receiver模块进行对b2s transmitter发送的数据进行接收解码
********************************************************************************************/
module b2s_receiver_test
(
input clk, //基准时钟
input b2s_dout, //b2s发送端发送过来的信号
output [31:0] dout //解码出的32bit数据
);
parameter WIDTH=32; //★设定b2s发送和接收数据位数,此处可根据需要进行修改 //================================
//调用b2s_receiver模块
//================================
b2s_receiver
#
(
.WIDTH (WIDTH) //例化接收数据位宽
)
b2s_receiver_inst0
(
.clk (clk), //时钟基准,不限频率大小,但必须与发送端一致
.b2s_din (b2s_dout), //b2s发送端发送过来的信号
.dout (dout) //b2s接收端解码出的数据
); endmodule
四、总结
本协议优缺点如下:
优点:
1. 仅使用单个I/O口进行多bit数据发送和接收(串行),可节省大量I/O口留作它用。
2. 传输频率不限,只需保证发送端和接收端工作频率一致即可。
3. 接收端所得到的信息始终是最新的,传输频率高时,近乎实时。
4. 发送和接收数据bit数量可根据需要进行增加/减少。
缺点:
1. 由于单线,无其他控制信号,发送端和接收端会一直处于工作状态(发送端一直发,接收端一直接)。

如您有此功能的定制开发或其他的FPGA设计需求,请查看下面这篇文章了解我们的业务范围和联系方式,我们将竭诚为您服务。
精橙FPGA,一个承接FPGA代码设计的资深工程师团队。
原创单总线传输协议b2s (附全部verilog源码)的更多相关文章
- Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码)
Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码) 转 https://blog.csdn.net/lhl1124281072/article/details/800 ...
- HTML与CSS入门经典(第9版)试读 附随书源码 pdf扫描版
HTML与CSS入门经典(第9版)是经典畅销图书<HTML与CSS入门经典>的最新版本,与过去的版本相同,本书采用直观.循序渐进的方法,为读者讲解使用HTML5与CSS3设计.创建并维护世 ...
- NLP大赛冠军总结:300万知乎多标签文本分类任务(附深度学习源码)
NLP大赛冠军总结:300万知乎多标签文本分类任务(附深度学习源码) 七月,酷暑难耐,认识的几位同学参加知乎看山杯,均取得不错的排名.当时天池AI医疗大赛初赛结束,官方正在为复赛进行平台调 ...
- Linux 部署ASP.NET SQLite 应用 的坎坷之旅 附demo及源码
Linux 部署ASP.NET SQLite 应用 的坎坷之旅.文章底部 附示例代码. 有一台闲置的Linux VPS,尝试着部署一下.NET 程序,结果就踏上了坑之路,不过最后算是完美解决问题,遂记 ...
- web框架前言与学生数据库系统(附1.0源码)
对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. import socket def f1(request): ""&quo ...
- 浅析 <路印协议--Loopring> 及整体分析 Relay 源码
作者:林冠宏 / 指尖下的幽灵 前序: 路印协议功能非常之多及强大,本文只做入门级别的分析. 理论部分请细看其白皮书,https://github.com/Loopring/whitepaper 实际 ...
- android优化中国风应用、完整NBA客户端、动态积分效果、文件传输、小说阅读器等源码
Android精选源码 android拖拽下拉关闭效果源码 一款优雅的中国风Android App源码 EasySignSeekBar一个漂亮而强大的自定义view15 android仿蘑菇街,蜜芽宝 ...
- JavaWeb宿舍管理系统(附 演示、源码下载地址)
宿舍管理是高校管理的重要组成部分,一套优秀的管理系统不仅可以降低宿舍管理的难度,也能在一定程度上减少学校管理费用的支出,能是建设现代化高校管理体系的重要标志. 本篇文章将带你从运行环境搭建.系统设计. ...
- 【lwip】08-ARP协议一图笔记及源码实现
目录 前言 8.1 IP地址与MAC地址 8.2 ARP协议简介 8.3 ARP协议报文 8.4 ARP缓存表 8.4.1 ARP缓存表简介 8.4.2 LWIP中的缓存表 8.4.3 ARP缓存表数 ...
- Android Gallery实现3D相册(附效果图+Demo源码)
今天因为要做一个设置开机画面的功能,主要是让用户可以设置自己的开机画面,应用层需要做让用户选择开机画面图片的功能.所以需要做一个简单的图片浏览选择程序.最后选用Gallery作为基本控件.加入了一些炫 ...
随机推荐
- Angular 18+ 高级教程 – HttpClient
前言 HttpClient 是 Angular 对 XMLHttpRequest 和 Fetch 的封装. HttpClient 的 DX (Developer Experience) 比 XMLHt ...
- HTML & CSS – Practice Projects
前言 学完了 w3school 就要练练手了. 这篇是记入我学习的过程, 和知识点. update: 2022-02-27 用文章来表达太难了, 用视频比较合理. 所以我就没有继续写了. 这里记入几篇 ...
- Python 潮流周刊#70:微软 Excel 中的 Python 正式发布!(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- Vscode 远程切换Python虚拟环境
在VSCode中远程切换Python虚拟环境是一个涉及多个步骤的过程,包括安装必要的扩展.连接到远程服务器.创建或激活虚拟环境,并在VSCode中选择相应的Python解释器.以下是一个详细的步骤指南 ...
- 干货必收藏!墨天轮最受DBA欢迎的250份学习文档合集
作为一个DBA,必须要精通SQL命令.各种数据库架构.数据库管理和维护.数据库调优,必要的时候,还需要为开发人员搭建一个健壮.结构良好.性能稳定的数据库环境. 技术也是不断进步的,社会的发展要求DBA ...
- C# 中的数组使用
· // 数组 /// 数组是一组相同类型的数据(ps:js中的数组可以不同类型) 访问通过索引访问数组元素 /// 数组的声明 要使用 new 使用 {} 来初始化数组元素 还需要指定数组的大小 / ...
- 7-11 leetcode 2619
请你编写一段代码实现一个数组方法,使任何数组都可以调用 array.last() 方法,这个方法将返回数组最后一个元素.如果数组中没有元素,则返回 -1 . ps:this 环境变量的使用 ,this ...
- C# 根据主键ID查询数据库的数据 反射和泛型实现
// 引入命名空间 using Zhu.ADO.NET.DBProxy; using Zhu.ADO.NET.Models.models; Console.WriteLine("====== ...
- KubeSphere 社区双周报 | OpenFunction 发布 v1.1.0 | 2023.5.26-6.8
KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...
- Vue最受欢迎的七大跨端框架,你都用过哪几个?
随着移动互联网的快速发展,开发者们不仅需要为Web开发,还需要兼顾iOS.Android.小程序等多个平台.这让"跨端开发"成为了炙手可热的话题.而基于Vue的跨端框架凭借其优异的 ...