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

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

相关文章:

Vivado下时序逻辑模块的仿真

文章目录 D触发器两级D触发器带异步复位的D触发器带异步复位和同步置数的D触发器移位寄存器单口RAM伪双口RAM真双口RAM单口ROM 组合逻辑电路在逻辑功能上特点是任意时刻的输出仅仅取决于当前时刻的输入&#xff0c;与电路原来的状态无关。 时序逻辑在逻辑功能上的特点是任意时刻…...

ThreadLocal的使用方式

1. ThreadLocal的使用方式 (1) 在关联数据类中创建private static ThreadLocal 在下面的类中&#xff0c;私有静态 ThreadLocal 实例&#xff08;serialNum&#xff09;为调用该类的静态 SerialNum.get() 方法的每个 线程维护了一个“序列号”&#xff0c;该方法将返回当前…...

全面理解:C++中的指针和迭代器,以及解引用操作符(*)和箭头操作符(->)的用法

指针与迭代器的基础概念 指针&#xff1a; 指针是一种变量&#xff0c;其值为另一种类型的对象在计算机内存中的地址。你可以使用指针来直接访问和操作它指向的对象。指针的使用非常强大&#xff0c;但也很危险&#xff0c;因为你有可能错误地操作内存&#xff0c;这可能会导致…...

Vite 使用学习指南

Vite 的基本概念和特点 Vite 是什么&#xff0c;它的主要特点是什么 Vite 是一个基于 ES modules 的前端构建工具&#xff0c;它的主要特点包括&#xff1a; 快速的冷启动&#xff1a;Vite 采用了基于浏览器原生 ES 模块的开发模式&#xff0c;可以在开发时快速启动应用&…...

【算法训练(day6)】双指针模板

一.双指针算法的由来和使用场景 通常情况下我们可能会遇到在某些可遍历的集合中寻找满足某种性质的字串或元素。这时候我们采取暴力的思路就会面临多重循环。我们可以利用题目中所给的集合并利用其性质将多重循环降成一重循环。光用语言描述可能不太好理解。接下来看几个双指针…...

免费常用的API接口大全

免费常用的API接口大全 OPEN AI &#xff1a; ChatGPT 能够模拟人类的语言行为&#xff0c;与用户进行自然的交互。ChatGPT 可以用于处理多种类型的对话&#xff0c;包括对话机器人、问答系统和客服机器人等。它还可以用于各种自然语言处理任务&#xff0c;比如文本摘要、情感分…...

【HTML】第 2 节 - HTML 标签

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、标题标签 3、段落标签 4、文本格式化标签 5、图像标签 5.1、基本作用 5.2、属性 6、超链接标签 7、音频标…...

MATLAB算法实战应用案例精讲-【数模应用】残差检验(附Java、python和MATLAB代码)

目录 几个高频面试题目 线性回归残差是否一定满足正态分布? 一般情况 特殊情况...

初学Qt(Day03)

今天概览 今天的目标是写一个动态的彩虹灯 一开始是有思路的。只是写的过程中有太多小bug了&#xff0c;真的是防不胜防 我的思路是&#xff1a; 主界面是一个开始界面&#xff0c;点击开始按钮之后&#xff0c;有一个子界面出现&#xff0c;显示出彩虹灯转动的效果。 内部的执…...

皮卡丘xss之htmlspecialchars、xss之href输出、xss之js输出

1.xss之htmlspecialchars htmlspecialchars()函数的功能如下&#xff1a; htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。 预定义的字符是&#xff1a; &#xff08;1&#xff09;& &#xff08;和号&#xff09;成为 &amp; &#xff08;2&#xff09;…...

ArrayList和LinkedList的区别

ArrayList和Vector使用了数组的实现&#xff0c;可以认为ArrayList或者Vector封装了对内部数组的操作&#xff0c;比如向数组中添加&#xff0c;删除&#xff0c;插入新的元素或者数据的扩展和重定向。 LinkedList使用了循环双向链表数据结构。与基于数组ArrayList相比&#xf…...

记录 vue3 webpack 使用 iframe 遇到的坑

需求 我尝试用Vue3写一个自己的主页&#xff0c;把常用的功能集中到主页中&#xff0c;如下图 后发现一个好玩的东西&#xff0c;js实现的在网页底部出现鱼和波浪&#xff0c;如下图&#xff0c;就像想也放到自己的主页中&#xff0c;搜索后发现可以在Vue中用iframe标签直接引…...

华为OD机试真题 Java 实现【去除多余空格】【2023Q1 100分】

一、题目描述 去除文本多余空格,但不去除配对单引号之间的多余空格。给出关键词的起始和结束下标,去除多余空格后刷新关键词的起始和结束下标。 条件约束: 不考虑关键词起始和结束位置为空格的场景;单词的的开始和结束下标保证涵盖一个完整的单词,即一个坐标对开始和结束…...

SAP-MM 条件类型字段解析

01、“定价类型”&#xff1a;定义此条件类型的代码和描述&#xff0c;代码不能重复&#xff0c;描述可更改&#xff0c;根据实际需要&#xff0c;条件类型可定制&#xff1b; 02、“存取顺序”&#xff1a;表示此条件类型在定价时&#xff0c;要到存取顺序号定义的条件表中读…...

C#,码海拾贝(28)——求解“对称正定方程组”的“平方根法”之C#源代码

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 求解线性方程组的类 LEquations /// 原作 周长发 /// 改编 深度混淆 /// </summary> public static partial class LEquations { /// <summary> /…...

碳纤维单丝外径测试中的纳米分辨率激光衍射法解决方案

摘要&#xff1a;碳纤维单丝热膨胀系数是碳纤维复合材料设计、生产与可靠性和寿命评估的重要参数&#xff0c;本文针对单丝径向高温热膨胀系数测试这一难题提出了相应的解决方案。解决方案的核心内容是基于激光衍射法和高温辐射加热&#xff0c;并采用衍射轮廓拟合技术以及相应…...

服务(第三十二篇)nginx做缓存服务器

nginx作为缓存服务配置语法 1、proxy_cache_path 配置语法&#xff08;即缓存路径配置语法&#xff09; Syntax&#xff1a;proxy_cache_path path [levelslevels] [use_temp_pathon|off] keys_zonename:size [inactivetime] [max_sizesize] [manager_filesnumber] [manager_s…...

Java 集合、数组、字符串的相互转换(关于list.toArray(new String[0])的源码分析)

在 Java 中&#xff0c;可以通过以下方式实现集合、数组和字符串之间的相互转换。 一、集合和数组的相互转化 ①、将集合转为数组&#xff1a;&#xff08;toArray 方法&#xff09; List<String> list new ArrayList<>(); list.add("apple"); lis…...

Redis的全局命令及相关误区

Redis中所说的数据结构是针对key-value中的value而言的。主要的结构包括String、哈希表、列表、集合等等在redis中存在16个库&#xff0c;涉及到后期的集群搭建只能使用0号库最为方便 查看所有键&#xff08;支持通配符&#xff09; keys * keys S*返回当前数据库中的键总数 …...

C++核心编程—类和对象,类的三大特性——封装、继承、多态

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 &#x1f4ac;文章目录 一.类和对象的概念①什么是对象&#xff1f;②抽象和类1.类的基本概念2.类的声明与定义&#xff1a;3.对象的创建与使用 二.类的封装①为什么有封…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...