练习九-利用状态机实现比较复杂的接口设计

练习九-利用状态机实现比较复杂的接口设计

      • 1,任务目的:
      • 2,RTL代码
      • 3,RTL原理框图
      • 4,测试代码
      • 5,波形输出

1,任务目的:

(1)学习运用状态机控制的逻辑开关,并设计出一个比较复杂的接口逻辑;
(2)在复杂设计中使用任务(task)结构,以提高程序的可读性;
(3)加深对可综合风格模块的认识。

下面例子是一个并行数据转换为串行位流的变换器,利用双向总线输出。该案例来自于EPROM读写器,电路工作的步骤是:
(1)把并行地址存入寄存器; (2)把并行数据存入寄存器; (3)连接串行单总线; (4)地址的串行输出; (5)数据的串行输出; (6)挂起串行单总线; (7)给信号源应答; (8)让信号源给出下一个操作对象; (9)结束写操作。

2,RTL代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/11/22 10:52:02
// Design Name: 
// Module Name: writing
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module writing(
rst_n, clk, address, data, sda, ack);

input			rst_n, clk;
input	[7:0]	data, address;

inout			sda;			// 	串行数据的输出或者输入接口
output			ack;			//	模块给出的应答信号
reg				link_write;		// link_write决定何时输出

reg		[3:0]	state;			//	主状态机的状态字
reg		[4:0]	sh8out_state;	// 从状态机的状态字
reg		[7:0]	sh8out_buf;		// 输入数据缓冲
reg				finish_F;		//	用以判断是否处理完一个操作对象
reg				ack;

parameter	idle 		= 0;
parameter	addr_write	= 1;
parameter	data_write	= 2;
parameter	stop_ack	= 3;

parameter	bit0		= 1;
parameter	bit1		= 2;
parameter	bit2		= 3;
parameter	bit3		= 4;
parameter	bit4		= 5;
parameter	bit5		= 6;
parameter	bit6		= 7;
parameter	bit7		= 8;

assign		sda = link_write ? sh8out_buf[7] : 1'bz;

always@(posedge clk)	begin
	if(!rst_n)	begin	// 复位
		link_write		<= 0;		// 挂起串行总线
		sh8out_state	<= idle;
		sh8out_buf		<= 0;
		state			<= idle;
		finish_F		<= 0;		// 结束标志清零
		ack				<= 0;
		end
		
	else	
		case(state)
			idle:	begin
				link_write		<= 0;	// 断开串行单总线
				sh8out_state	<= idle;
				sh8out_buf		<= address;	// 并行地址存入寄存器
				state			<= addr_write;	// 进入下一个状态
				finish_F		<= 0;				
				ack				<= 0;
				end
			
			addr_write:		// 地址的输入
				if(finish_F == 0)	
					shift8_out	;	// 地址的串行输出
					//	?	任务
				else	begin
				
					sh8out_state	<= idle;
					sh8out_buf		<= data;	// 并行数据存入寄存器
					state			<= data_write;
					finish_F		<= 0;
					
					end
			
			data_write:		// 数据的写入
				if(finish_F	== 0)
					shift8_out	;	//	数据的串行输出
					// 任务
				else	begin
					link_write	<= 0;
					
					state		<= stop_ack;
					finish_F	<= 0;
					ack			<= 1;	// 向信号源发出应答
					end
				
			stop_ack:	begin // 向信号源发出应答结果
				ack		<= 0;
				state	<= idle;
				end
		endcase
end

task	shift8_out;	// 地址和数据的串行输出
begin
  case(sh8out_state)
	idle:	begin
		link_write		<= 1;	// 连接串行单总线,立即输出地址或数据的最高位(MSB)
		sh8out_state	<= bit7;
		end
	bit7:	begin
		link_write		<= 1;	// 连接串行单总线
		sh8out_state	<= bit6;
		sh8out_buf		<= sh8out_buf << 1;	// 输出地址或数据的次高位(bit6)
		end
	bit6:	begin
		sh8out_state	<= bit5;
		sh8out_buf		<= sh8out_buf << 1;
		end
	bit5:	begin
		sh8out_state	<= bit4;
		sh8out_buf		<= sh8out_buf << 1;
		end
	bit4:	begin
		sh8out_state	<= bit3;
		sh8out_buf		<= sh8out_buf << 1;
		end
	bit3:	begin
		sh8out_state	<= bit2;
		sh8out_buf		<= sh8out_buf << 1;
		end
	bit2:	begin
		sh8out_state	<= bit1;
		sh8out_buf		<= sh8out_buf << 1;
		end
	bit1:	begin
		sh8out_state	<= bit0;
		sh8out_buf		<= sh8out_buf << 1;	// 输出地址或数据的最低位(LSB)
		end
	bit0:	begin
		link_write		<= 0;	// 挂起串行单总线
		finish_F		<= 1;	// 建立结束标志
		end
  endcase
end
endtask

endmodule

3,RTL原理框图

在这里插入图片描述

4,测试代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/11/22 10:53:46
// Design Name: 
// Module Name: writing_top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

// 测试代码
`define	clk_cycle	50
module	writing_top;
reg		rst_n,	clk;
reg		[7:0]	data, address;
wire	ack,	sda;

always #`clk_cycle	clk = ~clk;

initial	begin
	clk 	= 0;
	rst_n	= 1;
	data	= 0;
	address	= 0;
	#(2   * `clk_cycle)		rst_n = 0;
	#(2   * `clk_cycle)		rst_n = 1;
	#(100 * `clk_cycle)		$stop;
end

always@(posedge ack)	begin
	// 接收到应答信号后,给出下一个处理对象
	data 	= data + 1;
	address	= address + 1;
end

writing u_writing(
.rst_n			(rst_n		),
.clk			(clk		),
.data			(data		),
.address		(address	),
.ack			(ack		),
.sda			(sda		)
);

endmodule

5,波形输出

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

101. 对称二叉树

101. 对称二叉树 题目&#xff1a; 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例&#xff1a; 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输…

【云原生-Kurbernetes篇】 玩转K8S不得不会的HELM

Helm 一、Helm1.1 使用背景1.2 Helm简介1.3 Helm的几个概念1.4 helm2 和 helm3 的区别1.5 chart包的关键组成 二、Helm相关命令2.1 应用管理操作2.2 Helm repository仓库管理命令2.2 Helm chart包管理命令2.3 Helm release(实例) 管理命令2.4 Helm私有仓库管理命令 三、部署He…

react大文件上传

目录 大文件上传优点&#xff1a; 大文件上传缺点: 大文件上传原理&#xff1a; 为什么要用md5 实现流程&#xff1a; 部分代码1&#xff1a; 部分代码2&#xff1a;​ 大文件上传优点&#xff1a; 文件太大分片上传能加快上传速度,提高用户体验能断点续传 如果上次上传失败…

C++:继承

一、继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保 持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象 程序设计的层次结构&#xff0c…

网络异常检测

随着社交网络、视频流、点对点技术、云计算和 SaaS 的出现&#xff0c;可以肯定地说&#xff0c;现代企业的好坏取决于他们的网络&#xff0c;尤其是在它们提供的带宽和安全性方面。无论是银行保护其数据免遭盗窃&#xff0c;还是商业组织保护其网络免受安全威胁和攻击&#xf…

Linux 中 .tar 和 tar.gz 的区别

1、前言 有时候你会发现&#xff0c;即便是有些拥有 3 年左右工作经验的运维或开发工程师对 .tar 和 .tar.gz 的区别并不是很清楚。.tar 和 .tar.gz 是在 Linux 系统中用于打包和压缩文件的两种常见格式。它们之间的主要区别在于压缩算法和文件扩展名。 2、区别 .tar .tar 是…

python练习题(markdown中的60道题)

1.Demo01 摄氏温度转化为华氏温度 celsius float(input(输入摄氏温度&#xff1a;)) fahrenheit (9/5)*celsius 32 print(%0.1f 摄氏温度转为华氏温度为 %0.1f % (celsius, fahrenheit))结果&#xff1a; 2.Demo02 计算圆柱体的体积 h, r map(float, input().split())# …

581. 最短无序连续子数组

581. 最短无序连续子数组 题目&#xff1a; 给你一个整数数组 nums &#xff0c;你需要找出一个 连续子数组 &#xff0c;如果对这个子数组进行升序排序&#xff0c;那么整个数组都会变为升序排序。 请你找出符合题意的 最短 子数组&#xff0c;并输出它的长度。 示例&…

【Android】声浪 UI 效果并附上详细代码

声浪效果是基于第三方实现的。 https://github.com/xfans/VoiceWaveView 将三方的 Kotlin 代码转 java 使用&#xff08;按照他的readme 进行依赖&#xff0c;好像少了点东西&#xff0c;至少本项目跑不起来&#xff09; 声浪效果在android 8 以上都是比较好的&#xff0c;不会…

【JavaEE】操作系统与进程

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

Oracle的控制文件多路复用,控制文件备份,控制文件手工恢复

一.配置控制文件多路复用 1.查询Oracle的控制文件所在位置 SQL> select name from v$controlfile;NAME -------------------------------------------------------------------------------- /u01/app/oracle/oradata/orcl/control01.ctl /u01/app/oracle/fast_recovery_a…

规划类3d全景线上云展馆帮助企业轻松拓展海外市场

科技3D线上云展馆作为一种基于VR虚拟现实和互联网技术的新一代展览平台。可以在线上虚拟空间中模拟真实的展馆&#xff0c;让观众无需亲自到场&#xff0c;即可获得沉浸式的参观体验。通过这个展馆&#xff0c;您可以充分、全面、立体展示您的产品、服务以及各种创意作品&#…

实用篇 | T-SNE可视化工具详情及代码示例

本文主要是为了快速的了解t-sne和如何快速使用&#xff01; 简要了解TSNE TSNE&#xff0c;降维方法之一。降维在机器学习中非常重要。这是因为如果使用高维数据创建模型&#xff0c;则很容易欠拟合。换句话说&#xff0c;有太多无用的数据需要学习。可以通过从各种数据中仅…

Golang版本处理Skywalking Trace上报数据

Tips: 中间记录了解决问题的过程&#xff0c;如不感兴趣可直接跳至结尾 首先去es里查询skywalking trace的元数据 可以拿到一串base64加密后的data_binary(直接解密不能用&#xff0c;会有乱码&#xff0c;可参考https://github.com/apache/skywalking/issues/7423) 对data_b…

第四代智能井盖传感器:智能井盖位移怎么进行监测

井盖是城市基础设施的一个重要组成部分&#xff0c;若井盖出现移位等现象&#xff0c;可能会对路过的车辆和行人造成潜在危险。特别是那些含有甲烷气体的井盖&#xff0c;一旦气体超过阈值且被意外踩踏&#xff0c;可能会导致气体的释放&#xff0c;这便会引发一系列安全事故&a…

Linux wait函数用法

wait 函数是用于等待子进程结束并获取子进程的终止状态的系统调用。它在父进程中使用&#xff0c;用于等待其子进程终止并获得子进程的退出状态。 函数原型&#xff1a; pid_t wait(int *status);status 是一个指向整型的指针&#xff0c;用于存储子进程终止时的退出状态&…

clang+llvm多进程gdb调试

clangllvm多进程gdb调试 前言1. 命令行gdb2. 父进程调试3. 子进程调试4. 返回父进程 前言 在学习新增llvm的优化pass时&#xff0c;需要跟踪clang及llvm的调用栈。然而llvm通过posix_spawn()创建了新进程&#xff0c;这使得gdb调试必须有一定的技巧了。 1. 命令行gdb 以下命…

小红书干货类笔记怎么写?建议收藏

小红书干货类笔记是指在小红书这个社交平台上&#xff0c;用户分享的各种实用、有价值的生活技巧、经验、心得等内容的笔记。这类笔记通常具有以下特点&#xff1a;内容详实、实用性强、独特见解、图文并茂。 比如&#xff1a;某个妆要怎么化、某种技能该怎么学、某个城市该怎…

详细梳理山姆·奥特曼离职闹剧 仍试图重返OpenAI

大家好,我是极智视界,欢迎关注我的公众号,获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码和资源下载,链接:https://t.zsxq.com/0aiNxERDq OpenAI 与微软围绕 Sam Altman 的离职风波,这场肥皂剧似乎还没到终结的样子。目前 …

跨越行业边界,CodeMeter护航AI领域安全与合规

在人工智能&#xff08;AI&#xff09;技术如ChatGPT的推动下&#xff0c;工业视觉、医疗诊断和智能驾驶等领域正在经历重大变革。这些技术不仅扩大了应用范围&#xff0c;也带来了数据安全、软件授权保护和合规性等新挑战。 AI工业视觉正在推动制造和自动化的快速发展&#x…