当前位置: 首页 > news >正文

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

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

      • 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)	beginif(!rst_n)	begin	// 复位link_write		<= 0;		// 挂起串行总线sh8out_state	<= idle;sh8out_buf		<= 0;state			<= idle;finish_F		<= 0;		// 结束标志清零ack				<= 0;endelse	case(state)idle:	beginlink_write		<= 0;	// 断开串行单总线sh8out_state	<= idle;sh8out_buf		<= address;	// 并行地址存入寄存器state			<= addr_write;	// 进入下一个状态finish_F		<= 0;				ack				<= 0;endaddr_write:		// 地址的输入if(finish_F == 0)	shift8_out	;	// 地址的串行输出//	?	任务else	beginsh8out_state	<= idle;sh8out_buf		<= data;	// 并行数据存入寄存器state			<= data_write;finish_F		<= 0;enddata_write:		// 数据的写入if(finish_F	== 0)shift8_out	;	//	数据的串行输出// 任务else	beginlink_write	<= 0;state		<= stop_ack;finish_F	<= 0;ack			<= 1;	// 向信号源发出应答endstop_ack:	begin // 向信号源发出应答结果ack		<= 0;state	<= idle;endendcase
endtask	shift8_out;	// 地址和数据的串行输出
begincase(sh8out_state)idle:	beginlink_write		<= 1;	// 连接串行单总线,立即输出地址或数据的最高位(MSB)sh8out_state	<= bit7;endbit7:	beginlink_write		<= 1;	// 连接串行单总线sh8out_state	<= bit6;sh8out_buf		<= sh8out_buf << 1;	// 输出地址或数据的次高位(bit6)endbit6:	beginsh8out_state	<= bit5;sh8out_buf		<= sh8out_buf << 1;endbit5:	beginsh8out_state	<= bit4;sh8out_buf		<= sh8out_buf << 1;endbit4:	beginsh8out_state	<= bit3;sh8out_buf		<= sh8out_buf << 1;endbit3:	beginsh8out_state	<= bit2;sh8out_buf		<= sh8out_buf << 1;endbit2:	beginsh8out_state	<= bit1;sh8out_buf		<= sh8out_buf << 1;endbit1:	beginsh8out_state	<= bit0;sh8out_buf		<= sh8out_buf << 1;	// 输出地址或数据的最低位(LSB)endbit0:	beginlink_write		<= 0;	// 挂起串行单总线finish_F		<= 1;	// 建立结束标志endendcase
end
endtaskendmodule

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	beginclk 	= 0;rst_n	= 1;data	= 0;address	= 0;#(2   * `clk_cycle)		rst_n = 0;#(2   * `clk_cycle)		rst_n = 1;#(100 * `clk_cycle)		$stop;
endalways@(posedge ack)	begin// 接收到应答信号后,给出下一个处理对象data 	= data + 1;address	= address + 1;
endwriting u_writing(
.rst_n			(rst_n		),
.clk			(clk		),
.data			(data		),
.address		(address	),
.ack			(ack		),
.sda			(sda		)
);endmodule

5,波形输出

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

相关文章:

  • 如何往excel中写子表?
  • 概率论与数理统计中常见的随机变量分布律、数学期望、方差及其介绍
  • Springboot+vue的客户关系管理系统(有报告),Javaee项目,springboot vue前后端分离项目
  • [C++]指针与结构体
  • linux 搭建Nginx网页(编译安装)
  • 基本的弹层,点击弹出
  • 函数指针数组指针数组传参的本质字符指针
  • SQL函数使用大全
  • 《微信小程序从入门到精通》---笔记1
  • 【Axure高保真原型】3D金字塔图_移入显示数据标签
  • 通过视频文件地址截取图像生成图片保存为封面图
  • 中低压MOSFET 2N7002KW 60V 300mA 双N通道 SOT-323封装
  • 【JMeter】不同场景下的接口请求
  • opencv-利用DeepLabV3+模型进行图像分割去除输入图像的背景
  • MySQL--锁
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • Angular 2 DI - IoC DI - 1
  • fetch 从初识到应用
  • IndexedDB
  • Java 23种设计模式 之单例模式 7种实现方式
  • Tornado学习笔记(1)
  • XForms - 更强大的Form
  • 多线程 start 和 run 方法到底有什么区别?
  • 基于axios的vue插件,让http请求更简单
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 讲清楚之javascript作用域
  • 解析 Webpack中import、require、按需加载的执行过程
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 新书推荐|Windows黑客编程技术详解
  • 原生JS动态加载JS、CSS文件及代码脚本
  • linux 淘宝开源监控工具tsar
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • #宝哥教你#查看jquery绑定的事件函数
  • (39)STM32——FLASH闪存
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (分类)KNN算法- 参数调优
  • (六)vue-router+UI组件库
  • (十三)Flask之特殊装饰器详解
  • (一)python发送HTTP 请求的两种方式(get和post )
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .java 9 找不到符号_java找不到符号
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET Micro Framework初体验(二)
  • .NET 读取 JSON格式的数据
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .NET关于 跳过SSL中遇到的问题
  • /bin/bash^M: bad interpreter: No such file or directory
  • /proc/interrupts 和 /proc/stat 查看中断的情况
  • @synthesize和@dynamic分别有什么作用?