Vivado下时序逻辑模块的仿真

文章目录

  • D触发器
  • 两级D触发器
  • 带异步复位的D触发器
  • 带异步复位和同步置数的D触发器
  • 移位寄存器
  • 单口RAM
  • 伪双口RAM
  • 真双口RAM
  • 单口ROM

组合逻辑电路在逻辑功能上特点是任意时刻的输出仅仅取决于当前时刻的输入,与电路原来的状态无关。
时序逻辑在逻辑功能上的特点是任意时刻的输出不仅仅取决于当前的输入信号,而且还取决于电路原来的状态。
本文中的例子中模块名都是timing,仿真测试文件中的模块名都是sim_timing。


D触发器

D触发器在时钟的上升沿或下降沿存储数据,其输出与时钟跳变之前输入信号的状态相同。
D触发器的设计源代码如下。

module timing(clk,d,q);
input clk;
input d;
output reg q;
always@(posedge clk)
begin q <= d;
end
endmodule

仿真测试源代码如下。

module sim_timing();
reg clk;
reg d;
wire q;initial
begin d = 0;clk = 0;foreverbegin#({$random}%100)d = ~d;end
endalways #10 clk = ~clk;timing uut_timing(.clk(clk),.d(d),.q(q)
);
endmodule

D触发器的仿真输出结果如下图所示。
在这里插入图片描述
由上面仿真结果可以看到,输出在时钟的上升沿发生变化,且其值与时钟跳变之前输入信号的状态相同。
D触发器的RTL图如下。
在这里插入图片描述


两级D触发器

下面例子是一个两级D触发器,可以分析在同一时刻两个D触发器输出数据的不同。
两级D触发器的设计源代码在D触发器设计源代码的基础上再引入一个输出变量,增加一个always块语句,在时钟上升沿到来时,再将本级输出赋值给D触发器的输出,仿真测试源代码中只在例化处加入新的变量即可。
两级D触发器的仿真输出结果如下图所示。
在这里插入图片描述
由上面输出结果可以看到,在q0的值变化后的下一个上升沿到来后,q1的值才等于变化后的q0值。
两级D触发器的RTL图如下。
在这里插入图片描述


带异步复位的D触发器

异步复位独立于时钟,当其有效的时候,就触发复位操作。
带异步复位的D触发器的设计源代码如下。

module timing(clk,rst,d,q);
input clk;
input rst;
input d;
output reg q;always@(posedge clk or negedge rst)
begin if(!rst)q <= 0;elseq <= d;
end
endmodule

仿真测试源代码如下。

module sim_timing();
reg clk;
reg d;
reg rst;
wire q;initial
beginrst = 1;#300rst = 0;#200rst = 1;#200rst = 0;#100rst = 1;
endinitial
begin d = 0;clk = 0;foreverbegin#({$random}%100)d = ~d;end
endalways #10 clk = ~clk;timing uut_timing(.clk(clk),.d(d),.rst(rst),.q(q)
);
endmodule

带异步复位的D触发器的仿真输出结果如下图所示。
在这里插入图片描述
由上图输出结果可以看到,当复位信号有效时,输出q即刻置为0,尽管d不为0。
带异步复位的D触发器的RTL图如下。
在这里插入图片描述


带异步复位和同步置数的D触发器

带异步复位D触发器中的复位独立与时钟,同步置数则有别于异步复位,它同步于时钟信号,这里的同步置数可以置1、置0或置高阻状态等,根据电路的需要设定。
需要注意的是,同步操作不能把信号放到敏感列表里,也就是always语句后的括号里。
带异步复位和同步置数的D触发器的设计源代码如下。

module timing(clk,rst,set_num,d,q);
input clk;
input rst;
input set_num;
input d;
output reg q;always@(posedge clk or negedge rst)
begin if(!rst)q <= 0;else if(set_num)q <= 1'bz;elseq <= d;
end
endmodule

仿真测试源代码如下。

module sim_timing();
reg clk;
reg d;
reg rst;
reg set_num;
wire q;initial
beginrst = 0;set_num = 0;#300rst = 1;set_num = 1;#200set_num = 0;
endinitial
begin d = 0;clk = 0;foreverbegin#({$random}%100)d = ~d;end
endalways #10 clk = ~clk;timing uut_timing(.clk(clk),.d(d),.rst(rst),.set_num(set_num),.q(q)
);
endmodule

带异步复位和同步置数的D触发器的仿真输出结果如下图所示。
在这里插入图片描述
由上图可知,复位信号有效时,输出一直为0,在置数信号有效时,输出并不像异步复位那样即刻变化,而是在时钟上升沿到来后再变化。
带异步复位和同步置数的D触发器的RTL图如下。
在这里插入图片描述


移位寄存器

移位寄存器是指在每个时钟脉冲来临时,向左或向右移动一位,通过上述D触发器的例子可知其特性,数据输出同步于时钟边沿,故移位寄存器在每个时钟来临后,每个D触发器的输出q等于前一个D触发器的输出值,从而实现移位的功能。移位寄存器的代码中需要用到拼接运算符“{}”。
移位寄存器的设计源代码如下。

module timing(clk,rst,d,q);
input clk;
input rst;
input d;
output reg[7:0] q;always@(posedge clk or negedge rst)
begin if(!rst)q <= 0;elseq <= {q[6:0],d};  //后7位左移,最低位补输入值
//        q <= {d,q[7:1]};  //前7位右移,最高位补输入值
end
endmodule

仿真测试源代码如下。

module sim_timing();
reg clk;
reg d;
reg rst;
wire[7:0] q;initial
beginrst = 0;#200rst = 1;
endinitial
begin d = 0;clk = 0;foreverbegin#({$random}%100)d = ~d;end
endalways #10 clk = ~clk;timing uut_timing(.clk(clk),.d(d),.rst(rst),.q(q)
);
endmodule

移位寄存器向左移位的输出结果如下图所示。
在这里插入图片描述
由上面的输出结果可以看到,复位信号无效时,最低位在时钟上升沿到来后置为d,同时其余各位向左移动一位。
移位寄存器向右移位的输出结果如下图所示。
在这里插入图片描述
由上面的输出结果可以看到,复位信号无效时,最高位在时钟上升沿到来后置为d,同时其余各位向右移动一位。
移位寄存器的RTL图如下。
在这里插入图片描述


单口RAM

单口RAM的写地址与读地址共用一个地址,代码中将地址保留,延迟一周期之后将数据读出。
单口RAM的设计源代码如下。

module timing(input clk,input write,input [7:0] data,input [4:0] addr,output [7:0] q
);
reg[7:0] ram[31:0]; //定义32个8位宽度的数据
reg[4:0] addr_reg;always@(posedge clk)
begin if(write)ram[addr] <= data;  //write dataaddr_reg <= addr;  //memory address
endassign q = ram[addr_reg]; //read data
endmodule

仿真测试源代码如下。

module sim_timing();
reg clk;
reg write;
reg [7:0] data;
reg [5:0] addr; 
wire[7:0] q;initial
beginclk = 0;write = 1;data = 0;addr = 0;
endalways #10 clk = ~clk;always@(posedge clk)
begin data <= data + 1'b1;addr <= addr + 1'b1;
endtiming uut_timing(.clk(clk),.write(write),.data(data),.addr(addr),.q(q)
);
endmodule

单口RAM的输出结果如下图所示。
在这里插入图片描述
通过上面的输出结果可以看到,输出延迟一个周期后将数据读出。


伪双口RAM

伪双口RAM的读写地址是独立的,可以随机选择写或者读地址,同时进行读写操作。
伪双口RAM的设计源代码如下。

module timing(input clk,input write,input read,input [7:0] data,input [4:0] write_addr,input [4:0] read_addr,output reg[7:0] q
);
reg[7:0] ram[31:0]; //定义32个8位宽度的数据always@(posedge clk)
begin if(write)ram[write_addr] <= data;  //write dataif(read)q <= ram[read_addr];  //read data
end
endmodule

仿真测试源代码如下。

module sim_timing();
reg clk;
reg write;
reg read;
reg [7:0] data;
reg [5:0] write_addr; 
reg [5:0] read_addr; 
wire[7:0] q;initial
beginclk = 0;write = 0;read = 0;data = 0;write_addr = 0;read_addr = 0;#40 write = 1;#40 read = 1;
endalways #10 clk = ~clk;always@(posedge clk)
begin 
if(write)begindata <= data + 1'b1;write_addr <= write_addr + 1'b1;if(read)read_addr <= read_addr + 1'b1;end
endtiming uut_timing(.clk(clk),.write(write),.read(read),.data(data),.write_addr(write_addr),.read_addr(read_addr),.q(q)
);
endmodule

伪双口RAM的输出结果如下图所示。
在这里插入图片描述
通过上面的输出结果可以看到,在写信号有效时往RAM中写数据,在读信号有效时从RAM中读出数据,读写操作可以同时进行。


真双口RAM

真双口RAM有两套控制线,数据线,允许两个系统同时对其进行读写操作。
真双口RAM的设计源代码如下。

module timing(input clk,input write_a,write_b,input read_a,read_b,input [7:0] data_a,data_b,input [4:0] addr_a,addr_b,output reg[7:0] q_a,q_b
);
reg[7:0] ram[31:0]; //定义32个8位宽度的数据always@(posedge clk)
begin if(write_a)ram[addr_a] <= data_a;  //write dataif(read_a)q_a <= ram[addr_a];  //read data
endalways@(posedge clk)
begin if(write_b)ram[addr_b] <= data_b;  //write dataif(read_b)q_b <= ram[addr_b];  //read data
end
endmodule

仿真测试源代码如下。

module sim_timing();
reg clk;
reg write_a,write_b;
reg read_a,read_b;
reg [7:0] data_a,data_b;
reg [5:0] addr_a,addr_b; 
wire[7:0] q_a,q_b;initial
beginclk = 0;write_a = 0;write_b = 0;read_a = 0;read_b = 0;data_a = 0;data_b = 0;addr_a = 0;addr_b = 0;#40 write_a = 1;#40 read_b = 1;
endalways #10 clk = ~clk;always@(posedge clk)
begin 
if(write_a)begindata_a <= data_a + 1'b1;addr_a <= addr_a + 1'b1;end
endalways@(posedge clk)
begin 
if(read_b)addr_b <= addr_b + 1'b1;
endtiming uut_timing(.clk(clk),.write_a(write_a),.write_b(write_b),.read_a(read_a),.read_b(read_b),.data_a(data_a),.data_b(data_b),.addr_a(addr_a),.addr_b(addr_b),.q_a(q_a),.q_b(q_b)
);
endmodule

真双口RAM的输出结果如下图所示。
在这里插入图片描述
我们在代码里设置的是a往RAM里面写数据,而b从RAM中往出读数据,通过上面的输出结果可以看到,这与我们在代码中设置的相符。


单口ROM

ROM是用来存储数据的,下面是一个单口ROM的例子。
单口ROM的设计源代码如下。

module timing(input clk,input [2:0] addr,output reg[7:0] q
);always@(posedge clk)
begin case(addr)3'b000 : q <= 8'd1;3'b001 : q <= 8'd12;3'b010 : q <= 8'd23;3'b011 : q <= 8'd34;3'b100 : q <= 8'd45;3'b101 : q <= 8'd56;3'b110 : q <= 8'd67;3'b111 : q <= 8'd78;default : q <= 8'd0;endcase
end
endmodule

仿真测试源代码如下。

module sim_timing();
reg clk;
reg [2:0] addr;
wire[7:0] q;initial
beginclk = 0;addr = 0;
endalways #10 clk = ~clk;always@(posedge clk)
begin addr <= addr + 1'b1;
endtiming uut_timing(.clk(clk),.addr(addr),.q(q)
);
endmodule

单口ROM的输出结果如下图所示。
在这里插入图片描述通过上面的输出结果可以看到,输出结果q的值与我们在ROM中预设的值是一样的。


参考资料: ZYNQ 开发平台 FPGA 教程 AX7020

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

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

相关文章

单元测试方法-cmockery实践

目录 单元测试概念 引子 定义 内容 方法 单元测试模型 测试模型构建 单元测试工具简介 Cmockery使用介绍 简介 使用 VPBX实践 UT框架搭建 目录 编译&#xff1a; 实例demo 例1&#xff1a; 例2&#xff1a; 例3&#xff1a; 例4&#xff1a; 例5&#xff…

从0开始搭建vue3+vite+ts+pinia项目

目录 项目搭建选项 项目搭建步骤 本地开发环境 Vite脚手架构建项目 关联Git仓库 开发工具 安装pinia 安装Sass 安装Vant-UI 安装postcss-pxtorem&#xff08;移动端项目&#xff09; 安装axios 本地调试 环境变量 本地代理 全局UI组件 路由中间件 项目部署 n…

layui(2)----页面元素

水平导航栏 依赖加载模块&#xff1a;element <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport"…

AcWing 回转游戏 dfs IDA* 剪枝 统一操作 java

&#x1f351; 算法题解专栏 &#x1f351; 回转游戏 如下图所示&#xff0c;有一个 # 形的棋盘&#xff0c;上面有 1 , 2 , 3 1,2,3 1,2,3 三种数字各 8 8 8 个。 给定 8 8 8 种操作&#xff0c;分别为图中的 A s i m H A \\sim H AsimH。 这些操作会按照图中字母和箭头…

MCGS昆仑通态触摸屏导入博途自定义数据类型和DB块变量的具体方法演示

MCGS昆仑通态触摸屏导入博途自定义数据类型和DB块变量的具体方法演示 如下图所示,在博途中新建项目后,添加自己所需的数据类型,然后选中该数据类型,右击选择“从块生成源“—”仅所选块“, 如下图所示,设置文件名后点击保存, 如下图所示,选中需要导出的DB块,右击选…

vue 自定义el-table穿梭框功能

一、需求描述&#xff1a;前段时间接到一个需求是点击做一个类似穿梭框的表格点击选中功能&#xff0c;弹框的左边是全部数据展示&#xff0c;点击表格行数据可以选中自动增加到右边的已选框&#xff0c;并且可以手动删除、重置选中数据。点击确定后到展示到主页面&#xff0c;…

Java核心知识点常考面试题(持续更新中)

Java核心知识点常考面试题&#xff08;持续更新中&#xff09; 线程与线程池Java锁机制轻量级锁重量级锁 线程与线程池 一、线程 1、线程的状态 2、线程的创建方式 &#xff08;1&#xff09;继承 Thread 类&#xff1b; &#xff08;2&#xff09;实现 Runnable 接口&#…

IDEA2023.1配置Git

一、前言 在使用新设备整理git项目时&#xff0c;报了以下问题&#xff0c;在整理项目的同时&#xff0c;做下记录。 二、下载git 2.1.官网下载git 官网下载地址&#xff1a; git官网&#xff0c;如下图所示&#xff1a; 如果选方法二&#xff0c; 接下来会让选择系统&#…

【cocos精品】《三国之刃》:腾讯首款三国炫技格斗手游

基于cocos引擎开发的《三国之刃》是腾讯独家代理的三国题材的动作格斗手游。独创的自由组合战技系统&#xff0c;配合特色的兵器和灵兽技能&#xff0c;可搭配出上万种格斗套路&#xff0c;让您的战斗酣畅淋漓又变幻莫测。清爽灵活的操作&#xff0c;无锁定技术PK&#xff0c;更…

java开发街机三国志_入坑必看《街机三国志》游戏初期重点讲解

《街机三国志》为了让新手更好的了解游戏&#xff0c;设立里相关的新手指引&#xff0c;引导新入门的玩家完成各种任务与基础的系统教学。只凭新手教学是没办法在初期阶段积累足够的资源的。本次小编特意整理了一些新手教程中没有提及的重点&#xff0c;希望帮助玩家们更好的开…

搜索引擎三国鼎立:百度 vs 360 vs 搜狗

理论上说&#xff0c;搜索市场不存在平分秋色的可能&#xff0c;不管份额如何接近&#xff0c;最终必然是东风压倒西风&#xff0c;这一点在全球市场都未见过反例。雅虎在日本和台湾独占鳌头&#xff0c;Naver在韩国有压倒性优势&#xff0c;Yandex称霸俄罗斯。谷歌在全球大部分…

街机三国志隐藏人物刘备_隐藏的人物

街机三国志隐藏人物刘备 最初的程序员的故事将永远不为人知 背后没有外套的男人是梅尔凯&#xff08;Mel Kaye&#xff09;&#xff0c;埃德纳瑟&#xff08;Ed Nather&#xff09;为他写了他永恒的程序员绝版经典著作《故事》 。 那一年是1960年&#xff0c;尽管存在有关他编…

Java霸王的大陆梦幻版_三国志霸王的大陆,喜欢三国的进

三国是中国历史上英雄辈出的时代&#xff0c;《霸王的大陆》这款移植自Fc的战棋游戏更是中国手游java游戏的No.1!该游戏内容极其丰富&#xff0c;对玩家的要求很高&#xff0c;因此这完全是一款符合游戏高手要求的大型单机游戏。以下是这款游戏的核心攻略&#xff0c;只要稍加留…

无可用下载链接_经典大全合集500个街机游戏大全下载

经典大全合集500个街机游戏大全下载 WinKawaks1.45模拟器 游戏链接 链接:https://pan.baidu.com/s/1MZ3_Gv825dtswcGXr006zQ 提取码:zhrk 一、游戏介绍

linux模拟器玩三国战记,三国战纪风云再起街机版

三国战纪风云再起街机版带你回忆最初玩三国街机游戏的乐趣,多种对战玩法轻松上手,在三国战纪风云再起街机版手机游戏里面玩家可以随便选择一个角色进入战斗,强烈的打击感绝对让你爱不释手,在指尖畅享超酷的格斗盛宴。 三国战纪风云再起街机版介绍 三国战纪风云再起街机版是…

智勇三国

视频: http://you.video.sina.com.cn/a/4806164-1488862174.html 8M的客户端下载地址: 一,http://yule.hedanwang.cn/sanguozhi/sanguozhi_864.htm 二,QQ群:100410266 的群共享下载 智勇三国是单机游戏三国群英传2的简单化、网络化、智能化。简单化指的是保留精华&#xff0c…

小时候玩的10款经典街机游戏,如今我们都在玩什么?

很多的人的童年&#xff0c;都是伴随着游戏度过的。尤其是8090后。今天就列举10款经典的大型街机游戏&#xff0c;跟大家一起回忆一下童年时光&#xff0c;不信没有你玩过的&#xff01; 1、《拳皇》 小时候小编最喜欢的大型对战格斗型街机游戏之一&#xff0c;一阵猛如虎的操…

toFixed精度丢失问题

bug说明&#xff1a; 10.3950 * 3935.00 用toFixed&#xff08;2&#xff09; 得到的是40904.32 实际应该是40904.33 解决的方法&#xff1a; 第一种&#xff1a; 在main.js中直接复制下面代码即可 Number.prototype.toFixed function (n) {n n || 0let resNum Math.ro…

深浅拷贝及赋值区别理解

浅拷贝&#xff1a; 对象浅拷贝Object.assign() 数组的浅拷贝Array.prototype.slice()与Array.prototype.concat() 解构赋值 1.对于数组/对象中基本数据类型[123,234]&#xff0c;拷贝的是数值&#xff0c;所以修改拷贝后的这个值&#xff0c;原数据不会改变&#xff1b;2.对…

谷歌浏览器手动设置Cookie

1、Chrome中访问地址chrome://flags 2、搜索Partitioned cookies将设置项改为Enabled即可&#xff0c; 3、重启浏览器&#xff0c;手动添加cookie将会保留&#xff0c;且不会标红