使用握手信号实现跨时钟域数据传输(verilog)

news2024/9/20 18:43:38

大家好,最近汇总了2021年oppo哲库招聘手撕代码题目,本文章一共含有以下几个题目:

一,使用握手信号实现跨时钟域数据传输(verilog)

二,自动售卖机(verilog)

三,序列发生器(verilog)

四,根据RTL图编写Verilog程序(verilog)

下面对各自题目分别进行解析:

一,使用握手信号实现跨时钟域数据传输(verilog)

1)题目

分别编写一个数据发送模块和一个数据接收模块,模块的时钟信号分别为clk_a,clk_b。两个时钟的频率不相同。数据发送模块循环发送0-7,在每个数据传输完成之后,间隔5个时钟,发送下一个数据。请在两个模块之间添加必要的握手信号,保证数据传输不丢失。
    模块的接口信号图如下:

图1:接口图

 

 

其中:
data_req表示数据请求接受信号。当data_out发出时,该信号拉高,在确认数据被成功接收之前,保持为高,期间data应该保持不变,等待接收端接收数据。当数据接收端检测到data_req为高,表示该时刻的信号data有效,保存数据,并拉高data_ack。当数据发送端检测到data_ack,表示上一个发送的数据已经被接收。撤销data_req,然后可以改变数据data。等到下次发送时,再一次拉高data_req。

其中:

clk_a:发送端时钟信号

clk_b:接收端时钟信号

rst_n:复位信号,低电平有效

data_ack:数据接收确认信号

data:发送的数据

data_req:请求接收数据

2)解题逻辑

所谓握手信号即加入一些指示信号,在两个模块间确认数据已经被接受之后再进行下一个数据的传输。一般来说,发送端随数据发出一个数据有效信号,或者称为数据请求接受信号data_req,接收端在data_req有效时,采集数据data,进行缓存或者其他处理,所以要保证在data_req有效期间,也就是还没收到data_ack确认信号之前,传输的数据data不能发生变化。然后接收端发送一个数据确认信号data_ack,告知发送端,数据已经接受,可以开始下一个数据的传输,发送端在接收到data_ack之后,撤销data_req,并可以改变数据,为下一步传输做准备。

①首先是数据发送端,发送数据的标志是data_req拉高,在data_req拉高期间,data需要保持不变,一直到接收端完成数据的接收,即接收端发送data_ack确认信号。所以取data_ack的上升沿信号作为data_req撤销和data_out改变的指示信号。

②同时在data_ack有效之后,开始计数五个时钟,之后发送新的数据,也就是再一次拉高data_req.

③接收端的逻辑较为简单,首先是探测data_req的电平,如果data_req为高,表示有数据正在传输,则保存该时刻的数据,然后拉高data_ack告知发送端数据已经接收,直到发送端撤销data_req。

3)代码:

其中:

shakehand_tx是发送模块; 

shakehand_rx是发送模块; 

shakehand_top是顶层模块,负责将上述两个模块端口连接; 

shakehand_top_TB是shakehand_top的仿真文件;

`timescale 1ns / 1ps
/
module shakehand_tx(
	input clk_a,
	input rst_n,
	input data_ack,
	output reg [3:0]data,
	output reg data_req,
	output [3:0] cnt
    );
	 
reg data_ack_r1,data_ack_r2;
always@(posedge clk_a or negedge rst_n)
begin
	if(rst_n==0)
		begin
			data_ack_r1 <= 1'b0;
			data_ack_r2 <= 1'b0;
		end
	else
		begin
			data_ack_r1 <= data_ack;
			data_ack_r2 <= data_ack_r1;
		end	
end

always@(posedge clk_a or negedge rst_n)
begin
	if(rst_n==0 || (data == 4'd8))
		begin
			data <= 4'b0;			
		end
	else
		if(data_ack_r1 && !data_ack_r2 )
			begin
				data<= data +1'b1 ;
			end	
		else
			begin
				data<= data   ;
			end
end

reg [3:0] cnt=4'd0 ;
always@(posedge clk_a or negedge rst_n)
begin
	if(rst_n==0 || (data_ack_r1 && !data_ack_r2) )
					cnt <= 4'b0;
	else	if( data_req==1'b1) //捕捉上升沿				
					cnt<= cnt   ;				
	else				
					cnt<= cnt + 1'b1;
				
end

always@(posedge clk_a or negedge rst_n)
begin
	if(rst_n==0 ||(data_ack_r1 && !data_ack_r2)  )		
			data_req <= 1'b0;			
	else	if(cnt ==4'd4)			
			data_req<= 1'b1  ;				
	else			
			data_req<= data_req ;		
			
end




endmodule

下面是rx:

`timescale 1ns / 1ps
///
module shakehand_rx(
	 input clk_b,
    input rst_n,
    output reg data_ack,
    input [3:0]data,
    input data_req,
	 output [3:0] data_reg
    );
reg [3:0] data_reg=4'd0;
reg data_req_r1,data_req_r2;
always@(posedge clk_b or negedge rst_n)
begin
	if(rst_n==0)
		begin
			data_req_r1 <= 1'b0;
			data_req_r2 <= 1'b0;
		end
	else
		begin
			data_req_r1 <= data_req;
			data_req_r2 <= data_req_r1;
		end	
end

always@(posedge clk_b or negedge rst_n)
begin
	if(rst_n==0)
		begin
			data_ack <= 1'b0;
			data_reg <= 4'd0;
		end
	else if(data_req_r1 && !data_req_r2)
		begin
			data_ack <= 1'b1;
			data_reg <= data;
		end	
	else
		begin
			data_ack <= 1'b0;
			data_reg <= data_reg;
		end
end

endmodule

下面是top:

`timescale 1ns / 1ps
/
module shakehand_top(
input sys_clk,
input rst_n,
output [3:0] data,
output data_ack,
output data_req,
output [3:0] cnt,
output [3:0] data_reg,
output clk_a,
output clk_b
    );
reg [15:0] cnt_clk=16'd0;
always@(posedge sys_clk or negedge rst_n)
begin
	if(rst_n==0 || cnt_clk ==16'b0000_0000_1111_1111) cnt_clk <= 16'd0;
	else cnt_clk <= cnt_clk + 1'b1;	 
end

reg  clk_a = 1'd0;
reg  clk_b = 1'd0;
always@(posedge sys_clk or negedge rst_n)
begin
	if(rst_n==0 || cnt_clk[2:0] ==3'd4) 
			clk_a <= 1'd0;
	else if(cnt_clk[2:0] == 3'd0) 
			clk_a <= 1'b1;	 
	else 
			clk_a <= clk_a;
end

always@(posedge sys_clk or negedge rst_n)
begin
	if(rst_n==0 || cnt_clk[3:0] ==4'd8) 
			clk_b <= 1'd0;
	else if(cnt_clk[3:0] == 4'd0)
			clk_b <= 1'b1;	
	else
			clk_b <= clk_b;
end	  
	 
	 
	 
	 
wire [3:0] data;
wire data_req;
wire data_ack;
wire [3:0] cnt;
wire [3:0] data_reg;
shakehand_tx myshakehand_tx 
(
    .clk_a(clk_a),			//input
    .rst_n(rst_n),			//input
    .data_ack(data_ack),	//input
    .data(data),			//output
	 .data_req(data_req),	//output
	 .cnt(cnt)
  );
  
  

shakehand_rx myshakehand_rx 
(
    .clk_b(clk_b),			//input
    .rst_n(rst_n),			//input
    .data_ack(data_ack),//output
    .data(data),				//input
	 .data_req(data_req),		//input
	 .data_reg(data_reg)
  );
  
  
endmodule

 下面是TB:

`timescale 1ns / 1ps



module shakehand_top_TB;

	// Inputs
	reg sys_clk;
	reg rst_n;

	// Outputs
	wire [3:0] data;
	wire data_ack;
	wire data_req;
	wire [3:0] cnt;
	wire [3:0] data_reg;
	wire clk_a;
	wire clk_b;
	
	// Instantiate the Unit Under Test (UUT)
	shakehand_top uut (
		.sys_clk(sys_clk), 
		.rst_n(rst_n), 
		.data(data), 
		.data_ack(data_ack), 
		.data_req(data_req), 
		.cnt(cnt), 
		.data_reg(data_reg),
		.clk_a(clk_a),
		.clk_b(clk_b)
	);

	initial begin
		// Initialize Inputs
		sys_clk = 0;
		 
		rst_n = 0;

		// Wait 100 ns for global reset to finish
		#100;rst_n = 1;
        forever 
		  begin
			#500 sys_clk = ~sys_clk;
			 
		   end
		// Add stimulus here

	end
      
endmodule

4)仿真结果:

图3:仿真结果

 为了说明结果,对图3进行放大得到图4:

图4:放大图

 下面对图4进行解释:

①在A时刻,clk_a下cnt计数到4开始传输数据,data_req变1;

②在B时刻,clk_b下的data_ack捕捉到data_req则data_ack变1,开始接受数据,所以data_reg变1;

③在C时刻,clk_a下的data_req变0则表示结束本次传输,cnt开始从0计数准备下一次传输。同时,clk_b下的data_ack变0,表示传输结束。

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

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

相关文章

Jenkins执行shell脚本报错:bash: kubectl: command not found

问题描述 搭建好Jenkins之后&#xff0c;通过shell脚本构建k8s应用&#xff0c;但是脚本报错&#xff1a; bash: kubectl: command not found网上找了很多解决办法都不正确&#xff0c;并不适用于我的问题。 先说明&#xff0c;我的Jenkins和k8s各自独立的&#xff0c;不在同…

如何实现自有App上的小程序第三方微信授权登陆?

对于微信小程序来说&#xff0c;有 OpenID 或 UnionID 作为唯一标识&#xff0c;微信授权登陆小程序账号是很容易实现的&#xff0c;但对于其他应用上的小程序来说&#xff08;如支付宝、百度等&#xff09;&#xff0c;打通该登陆方式是比较麻烦的。 之前在FinClip开发了小程…

OPC Expert 最新版 Crack-2022-12-05

使用 OPC Expert 进行故障排除只是开始&#xff01;像专业人士一样解决您的 OPC 和 DCOM 连接问题&#xff01; 快速修复 OPC 和 DCOM 错误&#xff1a;使用 OPC Expert&#xff0c;您无需任何经验即可解决和修复 OPC 连接问题。OPC Expert 为您完成繁重的工作&#xff0c;以快…

excel根据颜色赋值 Excel填充颜色单元格替换成数字 excel把所有红色变成1

法/步骤 案例中&#xff0c;周一到周五产生倒班的&#xff0c;是用橙色标识的。周六周日的倒班是用蓝色标识的。然后&#xff0c;我们要将橙色的单元格替换成数字30&#xff0c;蓝色的单元格替换成数字50&#xff0c;分别代表30元和50元的倒班费。 使用快捷键CtrlH进入替换对…

如何把小程序游戏运行到自有App中?(IOS篇)

千呼万唤始出来&#xff01;FinClip 终于支持小游戏了。 我们团队算是 FinClip 的老用户了&#xff0c;年初就向官方提出了希望 FinClip 支持微信小游戏的建议。随着前段时间 “羊了个羊” 微信小游戏的爆火&#xff0c;官方也把小游戏支持提上了日程&#xff0c;近期官方开启…

[附源码]JAVA毕业设计时间管理系统(系统+LW)

[附源码]JAVA毕业设计时间管理系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&…

通过Node + SSE 做了一个构建日志推送

1.注册页是什么 当我们使用一个从未使用过的网站时,想要注册账号,点击注册账号时看到的网页就是注册页> 注册页例子如下: 我们看到以下的注册页中,有两大类信息: 第一大类是用户信息类,> 包括用户名,密码和email,他们都有自己的 取值规则 ,例如用户名显示不得小于3个字符…

哪款TWS耳机音质比较好?音质最好的TWS耳机推荐

现如今&#xff0c;喜欢戴蓝牙耳机听歌的人越来越多&#xff0c;甚至一些高端的蓝牙耳机在音质上可以媲美有线耳机。最近看到很多人问&#xff0c;哪款TWS耳机音质比较好&#xff1f;下面&#xff0c;我来给大家推荐几款音质最好的TWS耳机&#xff0c;可以当个参考。 一、南卡…

jsp社区医院信息系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 jsp社区医院信息系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql&#xff0c;使用…

将苹果手机数据导入苹果手机苹果?如何传输苹果手机数据

当用户需要将数据传输到苹果手机&#xff0c;应该怎么操作呢&#xff1f;所以&#xff0c;在本文中&#xff0c;易我小编将讲解将苹果手机数据导入苹果手机苹果&#xff1f; 方法1、利用iOS的快速迁移功能 如果是使用版本iOS 12.4及更高版本系统&#xff0c;新手机还没进行任何…

博世XC事业部李胤:自动驾驶降温不意外,但这条路肯定会走下去

“&#xff08;今年自动驾驶&#xff09;有些降温&#xff0c;这是正常的。所有的新技术不可能一路发展直上云天&#xff0c;总有坎坷。”2022年11月22日下午&#xff0c;博世智能驾驶与控制事业部&#xff08;以下简称“博世XC事业部”&#xff09;中国区总裁李胤在媒体群访中…

脑电信号分类问题的数据预处理方法

脑电波介绍 脑电波&#xff08;Electroencephalogram, EEG&#xff09;是应用电生理指标来记录大脑活动的方法。大脑在活动时&#xff0c;神经元同步发生突触后电位反应在了头皮表面&#xff0c;研究者将电机放置在被试者的头皮上检测脑电波信号。电机位置大概如下&#xff1a;…

[python] 基于wordcloud库绘制词云图

词云Wordcloud是文本数据的一种可视化表示方式。它通过设置不同的字体大小或颜色来表现每个术语的重要性。词云在社交媒体中被广泛使用&#xff0c;因为它能够让读者快速感知最突出的术语。然而&#xff0c;词云的输出结果没有统一的标准&#xff0c;也缺乏逻辑性。对于词频相差…

Log,SqlServerProfile, EFProfile三种监视EntityFramework中的sql流

大家在学习entityframework的时候,都知道那linq写的叫一个爽,再也不用区分不同RDMS的sql版本差异了,但是呢,高效率带来了差灵活性,我们 无法控制sql的生成策略,所以必须不要让自己缺乏好的工具去监控sql,本篇给大家介绍的三种监控手段Log和SqlServer profile,ef profi…

QA | SWCF2022 笔记:卫星传输链路中的关键技术分享

2022年度SWCF卫星通信与仿真测试研讨会正在进行中。精彩演讲&#xff1a;卫星传输链路中的关键技术分享&#xff0c;收到一些粉丝的技术问题&#xff0c;我们汇总了热点问题并请讲师详细解答。 主题&#xff1a;卫星传输链路中的关键技术分享 认识卫星通信与传输链路过程 1. …

来看看火爆全网的ChatGPT机器人写的武侠小说,我直呼内行!

作为一个程序员&#xff0c;不免对最近爆火的ChatGPT聊天机器人非常好奇&#xff0c;晚上睡不着觉&#xff0c;经过一番折腾&#xff0c;总算和ChatGPT聊上了。然后突发奇想&#xff0c;让它写武侠小说如何&#xff0c;会让小说家失业吗&#xff1f;结果机器人的反应让我直呼内…

RfDNet 在Ubuntu16下的配置与运行——(二)数据准备与训练

RfDNet 在Ubuntu16下的配置与运行——(二)数据准备与训练 相关博客&#xff1a;RfDNet 在Ubuntu16下的配置与运行——(一)运行Demo 接上篇&#xff0c;现在需要下载数据&#xff0c;官方使用的训练数据为&#xff1a; ScanNet 数据集 Scan2CAD 数据集&#xff1a;Scan2CAD ali…

Linux(常用命令)

(1)目录操作 ls 列出当前目录下都有啥ls / 或者 跟个具体的路径可以查看指定目录的内容ls -l 缩写为 ll 可以以列表的形式展示目录内容pwd 查看当前路径对应的绝对路径 cd / 切换到根目…

Redis缓存篇:高频问题横扫核心知识点,面试高级工程师必备知识体系

文章目录Redis 为什么这么快&#xff1f;到底有多快&#xff1f;基于内存实现高效的数据结构SDS 简单动态字符串优势zipList 压缩列表quicklistskipList 跳跃表整数数组&#xff08;intset&#xff09;单线程模型I/O 多路复用模型Redis 全局 hash 字典Hash 冲突怎么办&#xff…

vue 如何获取路由详细内容信息

目录前言&#xff1a;路由&#xff08;router&#xff09;的信息&#xff1a;获取路由的所有信息获取路由中每个信息的单个值获取路由中需要显示的值总结&#xff1a;前言&#xff1a; vue 中路由&#xff08;router&#xff09;的功能就是&#xff1a;把 url 与 应用中的对应…