10.31同步异步清零,阻塞与非阻塞例子,ROM,RAM,边沿检测实现

news2024/11/27 15:44:15

同步与异步清零

就是当复位信号发生变化,从1到0时立刻进行复位,negedge触发模块,即可工作;但如果到0后一直没有发生变化,即保持为0,那么就是在不断的时钟上升沿触发电路,但是都会因为复位信号为0,使进行!rst_n的初始化操作,而不会进行正常工作。只有当复位信号重新变为1时,才会停止对电路的不断复位,进行电路的正常工作,直到复位信号再次从1到0,触发电路的复位

阻塞赋值与非阻塞

按先后顺序执行赋值语句,上面赋完值后下面再用就是新的值,而always里就是上面赋值,下面在赋值时,如果涉及到上面的值,是原值,而不是赋的新值进行操作,等到都结束了,才会统一都赋值

还有就是注意如果一个模块里有多个always,那么都是电路中的一部分,是电路中的不同部分,非阻塞赋值是要这个模块都结束后才赋值,而不是当前always结束后赋值,只有这个文件、板块里都结束了,才会把模块里的运算结果赋值给锁存器。

(那么前驱的定义在前在后其实是没有关系的,在采用非阻塞的情况下,因为前驱的更新是在当下前驱、参数都用完后才更新的)

例一

阻塞情况

 非阻塞情况

例二

阻塞,直接=的情况

用的都是现在的x1,x2,所以就可以直接由x1,x2连到各自的输出门上

<=的情况

此时g要用的是之前的x1,x2,所以如果f在g上,就需要用<=,来让之前的f传给g

要不就让g在f上,让g先变,再让f变,

可以发现,如果是=,各个输出信号就是直接出去的,没有再回来的

如果是<=,有输出信号是回来的,连回去的 

只能用非阻塞赋值描述时序电路,但是当 always 块中后面的赋值语句依赖于前面赋值 语句的结果时,非阻塞赋值会产生无意义的电路

例三

always块中对同一变量多次赋值,只保留最后一次赋值结果;意思不是说只执行最后一个非阻塞赋值,而是说自上而下,都执行,但是不断覆盖 ,注意用的值都是上一状态的,而不是在此时赋值阶段产生的值,即使自上而下过程中,某些量的值发生了变化,用的也还是之前的量,新产生的量再目前是不可见的

 ROM实现

深度为8就是说有8个地址,可以存储8个数,然后初始化为0~14,就是每个地址的初始值

这就是声明一个寄存器,可以保持数据锁存

首先要声明数据的存储空间,名称之前的表示每个数据有多少位,指位宽;之后的表示需要多少个数据,指深度.就是一共有8个寄存器,每个寄存器可以存储宽度为4的数据

 reg [3:0] rom_data [7:0];

//保持ROM中的数据不变

       always @(posedge clk or negedge rst_n)

              if (!rst_n)                                          //对ROM中的数据进行初始化

                     begin

                            rom_data[0] <= 4'd0;

                            rom_data[1] <= 4'd2;

                            rom_data[2] <= 4'd4;

                            rom_data[3] <= 4'd6;         

                            rom_data[4] <= 4'd8;

                            rom_data[5] <= 4'd10;

                            rom_data[6] <= 4'd12;

                            rom_data[7] <= 4'd14;

                     end

              else

                     begin                                               //保持ROM中的数据不变

                            rom_data[0] <= 4'd0;

                            rom_data[1] <= 4'd2;

                            rom_data[2] <= 4'd4;

                            rom_data[3] <= 4'd6;         

                            rom_data[4] <= 4'd8;

                            rom_data[5] <= 4'd10;

                            rom_data[6] <= 4'd12;

                            rom_data[7] <= 4'd14;

                     end

 初始化完后为 

   always @(posedge clk or negedge rst_n)

              if (!rst_n)

                     data <= 4'd0;

              else

                     data <= rom_data[addr];

之前理解的是模块声明与调用完后,所调用的内存与元件就都被销毁了,和函数一样,

但实际上模块和语言里的函数是不同的,是电路组装的,模块调用不会终止,只要电路工作就会一直存在,在语句里声明的reg,wire都会一直存在,一直工作,而不是函数里那种自上而下,用完即销毁的。 保持工作状态,就是看时钟沿

在每次使用完后,寄存器里的数据也会进行保持,而不是被销毁,就是声明和定义只有一次,但是赋值是不断进行的,即每次电路功能是从assign与always开始的,而不是从模板下的定义开始的

也可以理解成只是声明,声明有这么一个东西和信号,后面要用到,而不是说在这里去定义出来

定义和赋值是相关的,用到哪些,最后电路就生成哪些,而不是看声明的

`timescale 1ns/1ns
module rom(
	input clk,
	input rst_n,
	input [7:0]addr,
	
	output [3:0]data
);
	reg [3:0] rom_data [7:0];
	
	assign data = rom_data[addr];
//保持ROM中的数据不变	
	always @(posedge clk or negedge rst_n)
		if (!rst_n) 
			begin
				rom_data[0] <= 4'd0;
				rom_data[1] <= 4'd2;
				rom_data[2] <= 4'd4;
				rom_data[3] <= 4'd6;		
				rom_data[4] <= 4'd8;
				rom_data[5] <= 4'd10;
				rom_data[6] <= 4'd12;
				rom_data[7] <= 4'd14;
			end
		else 
			begin
				rom_data[0] <= rom_data[0];
				rom_data[1] <= rom_data[1];
				rom_data[2] <= rom_data[2];
				rom_data[3] <= rom_data[3];		
				rom_data[4] <= rom_data[4];
				rom_data[5] <= rom_data[5];
				rom_data[6] <= rom_data[6];
				rom_data[7] <= rom_data[7];
			end
endmodule

核心就是声明一个锁存器,然后根据输入的地址信号,从锁存器里取出来锁存的信号,用assign语句,always里主要就是复位以及对锁存状态的一个保持(这个可有可无) 。

只读不写

信号边沿检测

目的是为了检测目标信号发生变化时,是上升还是下降

检测信号a的边沿需要缓存信号前一时刻的值,例如记为a_tem。当前一时刻为0,这一时刻为1,说明信号出现上升沿,即 a&&!a_tem = 1; 当前一时刻为1,这一时刻为0,说明信号出现下降沿,即 !a&&a_tem = 1;

即如果下降沿,那么前一个前状态一定是1,现在状态一定是0;上升沿,前一定是0,现在一定是1;0的取反,然后和1的与出来就是1

前驱a的初始化与赋值

在每个时钟上升沿工作

声明为锁存,一方面是always的必须要求,另一方面是说,如果是wire就直接输出不做保存了,但是前驱a需要时刻保存上一个时钟上升沿(电路工作)时a的值,而不是任意时刻a的值,所以声明为reg,而不是wire

主体电路的判断

在每个时钟上升沿工作

输出信号的初始化,置零

主体的判断逻辑

电路对未知情况的完善

`timescale 1ns/1ns
module edge_detect(
	input clk,
	input rst_n,
	input a,
	
	output reg rise,
	output reg down
);
	
	reg a_tem;

//缓存a的数值	
	always @(posedge clk or negedge rst_n)
		if (!rst_n)
			a_tem <= 1'b0;
		else
			a_tem <= a;
			
//检测边沿,给出相应的信号
	always @(posedge clk or negedge rst_n)
		if (!rst_n)	
			begin 
				rise <= 1'b0;
				down <= 1'b0;
			end
		else if (!a_tem && a)   		//当前一时刻a=0,当前时刻a=1,表示a出现一次上升沿
			begin
				rise <= 1'b1;
				down <= 1'b0;
			end
		else if	(a_tem && !a)			//当前一时刻a=1,当前时刻a=0,表示a出现一次下降沿
			begin
				down <= 1'b1;
				rise <= 1'b0;
			end
		else 
			begin
				down <= 1'b0;
				rise <= 1'b0;
			end
endmodule

单端口RAM实现

enb是读写模式的信号,addr是要读取或者覆写的地址信号,w_data是要写时写入的信号

在clk时工作,由于深度为128,所以用7位二进制数去表示地址,然后每位都是4位长

这个是声明128个寄存器,即深度为128,然后每个寄存器可以存储宽度为7的数

循环的时候,要声明一个循环量,integer i,

复位的时候让128每个寄存器都为0,都遍历到

正常工作就是让对应地址(二进制转化的实际意义)上的数为输入的数据

最后的输出,如果enb是1,就是写,那么就不输出;是0,就是读,就输出

数据操作与赋值时,不用管位宽,它就是用来衡量数据的大小,和int是一个意思,如果不具体声明宽度中的某一位时,它操作时就是按照其实际意义来运算的。

`timescale 1ns/1ns

module RAM_1port(
    input clk,
    input rst,
    input enb,
    input [6:0]addr,
    input [3:0]w_data,
    output wire [3:0]r_data
);
reg[3:0] ram[127:0];
integer i;
always@(posedge clk,negedge rst)begin
    if(!rst)begin
        for(i=0;i<127;i=i+1)begin
            ram[i]='b0;
        end
    end
    else if(enb)begin
        ram[addr]=w_data;
    end
end
assign r_data=(!enb)?ram[addr]:'b0;

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

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

相关文章

学习c++的第二天

目录 数据类型 基本数据类型 typedef 声明 枚举类型 类型转换 变量类型 变量定义 变量声明 左值&#xff08;Lvalues&#xff09;和右值&#xff08;Rvalues&#xff09; 变量作用域 数据类型 基本数据类型 C 为程序员提供了种类丰富的内置数据类型和用户自定义的数…

影视企业有哪些方式将视频文件快速海外跨国传输国内?

影视行业是一个高度国际化的行业&#xff0c;影视企业在跨国合作、制作、发行等方面有着强烈的需求。然而&#xff0c;影视企业在跨国文件传输方面也面临着诸多的问题和难题。视频文件通常具有较大的文件大小、多样的文件格式、高要求的文件质量等特点&#xff0c;这些特点使得…

WSL安装Ubuntu

先安装wsl2 安装Ubuntu 打开windows商店&#xff0c;搜索对应版本的Ubuntu&#xff0c;点击获取进度跑完后&#xff0c;点击打开&#xff0c;就可以完成安装 删除Ubuntu版本 wsl --unregister Ubuntu-18.04安装位置迁移 正常情况下Ubuntu是被安装在C盘&#xff0c;我们需要…

Java架构师数学与经济管理

目录 1 导学2 最小生成树3 最短路径4 网络与最大流量5 线性规划6 动态规划6.1 伏格尔法7 博弈论7.1 状态转移矩阵7.2 排队论8 决策论8.1 决策树9 数学建模想学习架构师构建流程请跳转:Java架构师系统架构设计 1 导学

如何选择合适的进口跨境商城源码?揭秘电商平台的成功之道

了解进口跨境电商平台源码的重要性 在进口跨境电商行业的兴起中&#xff0c;选择合适的商城源码是创业者成功的关键之一。进口跨境商城源码可提供网站架构、功能模块、支付系统、物流管理等基础构建&#xff0c;帮助企业快速搭建属于自己的商城平台。然而&#xff0c;在众多商城…

C语言实现 1.在一个二维数组中形成 n 阶矩阵,2.去掉靠边元素,生成新的 n-2 阶矩阵;3.求矩阵主对角线下元素之和:4.以方阵形式输出数组。

矩阵形式&#xff1a; 1 1 1 1 1 2 1 1 1 1 3 2 1 1 1 4 3 2 1 1 5 4 3 2 1 完整代码&#xff1a; /*编写以下函数 1&#xff0e;在一个二维数组中形成如以下形式的 n 阶矩阵&#xff1a; 1 1 1 1 1 2 1 1 1 1 3 2 1 1 1 4 3 2 1 1 5 4 3 2 1 2&#xff0e;去掉…

选择绿色壁炉:环保温暖你的家

壁炉的绿色选择是我们现代生活中越来越重要的话题。不仅为了保暖&#xff0c;还要考虑对环境的影响。在选择壁炉时&#xff0c;有一些绿色、环保的选项可以考虑&#xff0c;而且它们也能提供温馨的家居氛围。 嵌入式酒精壁炉&#xff1a;生物乙醇是一种环保的燃料&#xff0c;它…

什么是自动化测试框架?常用的自动化测试框架有哪些?

无论是在自动化测试实践&#xff0c;还是日常交流中&#xff0c;经常听到一个词&#xff1a;框架。之前学习自动化测试的过程中&#xff0c;一直对“框架”这个词知其然不知其所以然。 最近看了很多自动化相关的资料&#xff0c;加上自己的一些实践&#xff0c;算是对“框架”…

【C++】 常对象与常函数

常函数&#xff1a; 成员函数后加const后我们称为这个函数为常函数常函数内不可以修改成员属性成员属性声明时加关键字mutable后&#xff0c;在常函数中依然可以修改 常对象&#xff1a; 声明对象前加const称该对象为常对象常对象只能调用常函数 一、this指针本质 this指针…

Vscode使用国内镜像源下载,秒下

镜像源 国内镜像地址&#xff1a;https://vscode.cdn.azure.cn 使用方法&#xff1a;很简单&#xff0c;只需要在官网选择自己需要的版本&#xff0c;点击下载&#xff0c;在下载的路径中将我们的镜像源替换上去即可 1.81.1版本下载链接 https://vscode.cdn.azure.cn/stable/…

【SpringMVC篇】5种类型参数传递json数据传参

&#x1f38a;专栏【SpringMVC】 &#x1f354;喜欢的诗句&#xff1a;天行健&#xff0c;君子以自强不息。 &#x1f386;音乐分享【如愿】 &#x1f384;欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f33a;普通参数&#x1f33a;POJO参数&#x1f33a;嵌套…

Elemen table布局错乱解决方案

示例 解决方案 方案一 <el-table ref"mainTable"></el-table>、、、// 接口请求触发重新布局方法this.$nextTick(() > {this.$refs.mainTable.doLayout();});方案二 <el-tablestyle"width: 100%;max-height:400px;overflow-y: auto;"&g…

麒麟操作系统安装oracle 19c报错问题汇总

麒麟操作系统版本: [roothis-dsg lib64]# uname -a Linux his-dsg 4.19.90-24.4.v2101.ky10.x86_64 #1 SMP Mon May 24 12:14:55 CST 2021 x86_64 x86_64 x86_64 GNU/Linux 安装之前,建议先配置好ORACLE的环境变量,再执行一下bash_profile环境变量 1.xstart无法打开报错x11拒…

使用ant design pro出现面包屑导航和标题消失的问题

前端时间&#xff0c;我用ant design pro搭建了一个后台权限管理的项目模板&#xff0c;里面用到了PageContainer组件&#xff0c;默认会显示面包屑导航和标题&#xff0c;如图所示 后来&#xff0c;我把这个项目模板用于另外一个项目的前端页面&#xff0c;把整个项目的文件夹…

【java】命令行,包

文件夹情况&#xff1a; HelloWorld.java package com.demo; public class HelloWorld{public static void print(){System.out.println("HelloWorld!");}public static void main(String[] args){print();} } import.java import com.demo.HelloWorld; public cla…

Selenium三种等待方式的使用!

UI自动化测试&#xff0c;大多都是通过定位页面元素来模拟实际的生产场景操作。但在编写自动化测试脚本中&#xff0c;经常出现元素定位不到的情况&#xff0c;究其原因&#xff0c;无非两种情况&#xff1a;1、有frame&#xff1b;2、没有设置等待。 因为代码运行速度和浏览器…

【Linux】常见的Linux命令

目录 一、与目录有关的操作 二、与文件有关的操作 三、针对目录的操作 三、在linux上搭建环境 一、与目录有关的操作 1.ls 显示目录内容列表 ls / 这里的 / 表示根目录&#xff0c;相当于windows中的此电脑&#xff0c;linux中没有盘符。 ls -l / 显示详细信息 可以…

【EI会议征稿】第四届生物信息学与智能计算国际学术研讨会(BIC 2024)

第四届生物信息学与智能计算国际学术研讨会&#xff08;BIC 2024&#xff09; 2024 4th International Conference on Bioinformatics and Intelligent Computing 2024年第四届生物信息学与智能计算国际学术研讨会 &#xff08;BIC 2024&#xff09;将定于2024年1月26-28日在…

SOLIDWORKS® 2024 新功能 - PDM

SOLIDWORKS 2024 新功能 - PDM 1、改进的视觉内容 • 通过装配体可视化功能&#xff0c;在 SOLIDWORKS 中以图形方式查看零部件数据&#xff0c;如工作流程状态。 • 使用特定图标迅速识别焊件切割清单零部件。 优点 重要数据和系统信息一目了然。 2、增强的数据保护和跟踪功…

Controllable Guide-Space for Generalizable Face Forgery Detection

一、研究背景 以往工作专注于提取伪造特征的共同特性和真假域鉴别性信息&#xff0c;以提升特征泛化性。 但在训练过程中&#xff0c;这些方法只区分真假域&#xff0c;并将不同的伪造域看作一类而不加以区分。 这会导致伪造样本进一步以伪造不相关特征&#xff08;如&#xff…