11.1~11.2双端口RAM(报错复盘,一些理解(循环,阻塞非阻塞),三目运算符解决使能端)

news2024/11/22 16:33:07

双端口RAM

分别用于读写数据,同时进行

当读使能端有效时可以读出来数据

当写使能端有效时可以覆写数据

读写并行操作

报错

1.reg必须在always里

这个不能assign,因为reg型不能assign,单端口的那个可以assign是因为其定义为了wire型,就不在always里进行,而是在运算后输出时用的,所以可以assign

这里定义成了reg,那么赋值就一定要写在always里

2.多个else if的操作覆盖

这个不能得到正确输出是因为,一个if里只能执行一次,即即使有多个else if,且都满足,也只进行一个判别条件里的(靠近顶层的),就是说如果读写信号都有效,也只会进行写操作,而屏蔽掉读操作,所以就会出问题,导致一直读不出来

解决方式就是把读和写分在两个always里,保证不会因为else if只会执行一个,而使另一个被屏蔽掉

3.未知情况的完善缺陷

只是这样依然会得不到期望的输出,2的情况是一直读不出来,即输出信号一直是0

3的情况是,由于没有对读使能端情况的完善,即只在读为1时,才会对输出信号做出修改,但是却没有说读为0时该怎么做,就会导致,在读为0时,锁存上一个读为1时读到的信号,这样就会导致在不想读时,一直输出有信号的读信号,就会出错,得不到预期的波形

解决方法就是完善各种使能端的情况,当读使能端为0时,就要把读的输出信号置0

对于写使能,写的功能就是改变RAM内部数据值

当为1时,进行覆写;为0时,保持原状态(可写可不写,但必须明白这种情况的处理是这样的);

对于读使能,功能就是改变读信号,读出信号

当为1时,进行读;为0时,显然不希望之前的信号依然保存,所以要进行置0操作(这时就必须要额外写)

补充:对于2的另一种解决方法

还是在一个always里,只不过不用else if了,就用if,保证每次都会对if里的条件进行判断,简便,但是在互斥事件时,会浪费一定的不必要的判定时间,但是对独立的事件,就是必要的

其他

本例中的阻塞与非阻塞

这里面用阻塞赋值,即=可行,是因为状态的转移不涉及上一个状态,所以可以直接改变

而读写时,也是可以直接读出想写的内容,而不是之前写的内容,即读写和原来写的是什么无关

关于循环

要用循环,就要定义integer量,integer不能综合,只是用来循环,简化代码

这里的循环就是用来初始化,简化代码用的,无法综合,因为没有元件符合,只是用来简化代码长度而诞生的,初始化的本质逻辑还是逐个赋0,即

如果有128个寄存器,就需要128行,而循环无所谓深度多少

另一种实现思路

由于使能端只能是0或1,所以用三目运算符可以简单清晰,明了的表示出各种情况及方法,不重不漏。

读写分离always,两个三目运算符考虑两个使能端的各种情况

同步FIFO

就是说读使能时,返回队头;不读,则返回0;

写使能时,如果不满,就接着写,满了,就让队头出,写在队尾;不写,保持原态;

空信号,是读的时候空,对写没影响,即往后写,但是改变读的结果,为0;

满信号,是写的时候满,对读没影响,即一直读队头,但是改变写的模式;

但是注意,这里的读出,就是取出队列,即读一个取一个;

根据双口RAM实现FIFO

双端口实现

深度即寄存器数量,位宽为WIDTH

对组地址信号的位宽,为深度对2取对数,向上取整

电路功能

FIFO

空满状态的判断

统计队列内部数据数量的计数器CNT,并根据计数器的大小判断空满状况。

如果CNT==0,则空,如果CNT==深度,则满

读写同时进行时,计数器数值不变;写入时,CNT+1;读出时,CNT-1;

这里是声明读写地址,以及队列深度的计数(采用二进制)

关于位宽

常见的两种含义,第一种的位宽用于数据结构的定义,第二种用于数据结构内部数据特性、大小的定义

一是位宽代表个数

即有多少位宽,就意味有几个数据

队列定义,寄存器堆定义,数组定义,都是这个意思,即[n-1:0],从0拉到n-1,表示这个数据结构里有n个数据,一位就代表了一个数据单元

用来统筹管理数据的记录情况

二是代表实际大小

即用于实际计数,内部存储超过2的数据,表示数据,存储大的数据都是这种方式,位宽越大,表示这个数据越大,就代表一个实际的、实在的数据,采用的二进制计数,位宽就是用的几位二进制来记录

地址信号的定义,队列长度计数,分频器信号的计数,都是这个意思,其都是代表的一个数据

读写地址的确定

写功能,得到写的地址,

首先要写使能为1,接着判断是否满了,如果满了,地址就不动了,即指向队尾;不满,就让地址往后+1

读功能,得到读取元素的地址

首先要读使能为1,接着判断是不是为空,为空,则输出'0,即当前队列没有元素可以读出来;不为空,则地址往后+1,表示当前这个地址已经读出来了

注意,这里就是一定要用非阻塞赋值了,即等到这个电路功能都实现了再变化

因为此时后续的操作,都需要当前指针(即此时的waddr,raddr)所指向的地址,如果这时候更新,就访问不到了,所以需要在都结束后再更新

当前队列长度的确定

这个就是只取一个else if,即同一状态向后的不同分支,只取一个

当又读又写的时候,长度不变

读的时候,长度减1;写的时候,长度+1;

未知情况,保持不变

满空判断

实例化,以双端RAM实现FIFO

需要注意,如果能写而且还没满,就可以实际接着往下写,但是如果能写但是已经满了,就不接着往后写了;读也是这样

想的是,先一直写,然后读,这时候队列长度就减小了,还可以接着往里面写,但是写指针却没有动,所以就会导致越界

一种可能的思路是,它要读就一直读,直到读到空;要写就一直写,直到写到满;

主要就是读的时候,如果读,就一直读,全部读完,而不是读一部分,使其有剩余

那么FIFO的使用方式就是
`timescale 1ns/1ns
/**********************************RAM************************************/
module dual_port_RAM #(parameter DEPTH = 16,
					   parameter WIDTH = 8)(
	 input wclk
	,input wenc
	,input [$clog2(DEPTH)-1:0] waddr  //深度对2取对数,得到地址的位宽。
	,input [WIDTH-1:0] wdata      	//数据写入
	,input rclk
	,input renc
	,input [$clog2(DEPTH)-1:0] raddr  //深度对2取对数,得到地址的位宽。
	,output reg [WIDTH-1:0] rdata 		//数据输出
);

reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];

always @(posedge wclk) begin
	if(wenc)
		RAM_MEM[waddr] <= wdata;
end 

always @(posedge rclk) begin
	if(renc)
		rdata <= RAM_MEM[raddr];
end 

endmodule  

/**********************************SFIFO************************************/
module sfifo#(
	parameter	WIDTH = 8,
	parameter 	DEPTH = 16
)(
	input 					clk		, 
	input 					rst_n	,
	input 					winc	,
	input 			 		rinc	,
	input 		[WIDTH-1:0]	wdata	,

	output reg				wfull	,
	output reg				rempty	,
	output wire [WIDTH-1:0]	rdata
);
    wire                    wenc;
    reg [$clog2(DEPTH) : 0] waddr;
    reg [$clog2(DEPTH) : 0] raddr;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            wfull <= 'd0;
            rempty <= 'd0;
        end
        else begin
            wfull <= waddr == raddr + DEPTH;
            rempty <= waddr == raddr;
        end
    end
    
    assign wenc = winc && !wfull;
    assign renc = rinc && !rempty;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) 
            waddr <= 'd0;
        else if (wenc)
            waddr <= waddr + 'd1;
    end
    
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) 
            raddr <= 'd0;
        else if (renc)
            raddr <= raddr + 'd1;
    end
    
    
    dual_port_RAM #(.DEPTH (DEPTH),
                    .WIDTH (WIDTH))
    dual_port_RAM (
        .wclk  (clk  ),
        .wenc  (wenc ),
        .waddr (waddr),
        .wdata (wdata),
        .rclk  (clk  ),
        .renc  (renc ),
        .raddr (raddr),
        .rdata (rdata)
    );

endmodule

输入信号里有时钟信号,复位信号,读写使能信号,输入信号,

输出信号里有满信号,空信号,输出的队头信号

输入的时候,就写使能打开,然后

同步FIFO是说读写的时钟是一致的

异步FIFO

第一部分是双口RAM,用于数据的存储

第二部分是数据写入控制器

第三部分是数据读取控制器

第四部分是读指针同步器

使用写时钟的两级触发器采集读指针,输出到数据写入控制其

第五部分是写指针同步器

比较空满,采用格雷码的比较来产生

格雷码是循环编码,

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

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

相关文章

【LeetCode刷题-链表】--1290.二进制链表转整数

1290.二进制链表转整数 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next; }*…

JavaScript 基础 - 第2天

理解什么是流程控制&#xff0c;知道条件控制的种类并掌握其对应的语法规则&#xff0c;具备利用循环编写简易ATM取款机程序能力 运算符语句综合案例 运算符 算术运算符 数字是用来计算的&#xff0c;比如&#xff1a;乘法 * 、除法 / 、加法 、减法 - 等等&#xff0c;所以经…

【window系统】win10家庭版没有hyper-V的选项 问题解决办法

目录 事件起因环境和工具操作过程参考内容结束语 事件起因 在给我的新电脑安装docker和对应的Linux环境时 在 控制面版-程序-启用该或关闭Windows功能 时 没有找到对应网上那种教程里的Hyper-V的功能的选项&#xff0c;查找了一下&#xff0c;说是win10家庭版没有这个功能 专…

NEFU数字图像处理(5)图像压缩编码

一、概述 1.1简介 图像压缩编码的过程是在图像存储或传输之前进行&#xff0c;然后再由压缩后的图像数据&#xff08;编码数据&#xff09;恢复出原始图像或者是原始图像的近似图像 无损压缩&#xff1a;在压缩过程中没有信息损失&#xff0c;可由编码数据完全恢复出原始图像有…

动态路由协议OSPF项目部署(二)

1. 静态和动态路由的区别&#xff1b; 2. OSPF协议通信过程与部署&#xff1b; 3. OSPF协议在项目上的应用场景 - OSPF - 开放式最短路径优先 - 一个动态路由协议 - 路由器转发数据 - 路由器需要一张地图 - 路由表 - 路由表如何构建的&#xff1f; - 依靠手动 或…

selenium自动化测试入门 —— 浏览器多窗口切换!

有时web应用会打开多个浏览器窗口&#xff0c;当我们要定位新窗口中的元素时&#xff0c;我们需要将webDriver的handle&#xff08;句柄&#xff09;指定到新窗口。 什么意思&#xff1f; 假设我们打开web应用&#xff0c;在系统运行过程中重新打开一个新窗口&#xff08;可以…

短视频平台Roposo入驻印尼,会成为下一个Tiktok吗

Roposo是一个印度本土的短视频平台&#xff0c;功能和风格都和Tiktok很相似。 早在2020年7月&#xff0c;印度下令封禁了多个app&#xff0c;其中就包括了TikTok。在那之前&#xff0c;TikTok已经在印度累计了约2亿的用户&#xff0c;基数已经非常的大&#xff0c;那么被封禁之…

ESP32网络开发实例-Web服务器显示BMP180传感器数据

Web服务器显示BMP180传感器数据 文章目录 Web服务器显示BMP180传感器数据1、BMP180介绍2、软件准备3、硬件准备4、代码实现本文将介绍如何在ESP32的Web服务器显示BMP180数据。BMP180传感器可用于测量温度、压力和高度。 我们还可以使用此传感器测量海平面和实际高度的压力。 1、…

荒野大镖客emp.dll文件丢失的怎么办,快速修复游戏dll问题

在玩荒野大镖客这款游戏的过程中&#xff0c;我遇到了一个令人困扰的问题——emp.dll文件丢失。emp.dll是荒野大镖客游戏中的一个动态链接库文件&#xff0c;它负责管理游戏中的一些功能模块。当这个文件丢失时&#xff0c;游戏可能无法正常运行&#xff0c;导致一些功能无法使…

Python武器库开发-常用模块之configparser模块(十六)

configparser模块(十六) ConfigParser模块在python3中修改为configparser.这个模块定义了一个ConfigParser类&#xff0c;该模块的作用就是用来读取配置文件的&#xff0c;使用模块中的RawConfigParser()、ConfigParser()、 SafeConfigParser()这三个方法&#xff0c;创建一个…

Linux实现简易shell

文章目录 &#x1f984;0. shell&#x1f42e;1. 交互及获取命令行&#x1f437;2. 解析命令行&#x1f42f;3. 执行命令行&#x1f405;3.1 普通命令&#x1f405;3.2 内建命令 &#x1f981;4. 主函数逻辑及演示 本章代码gitee仓库&#xff1a;简易shell &#x1f984;0. she…

Python自动化测试如何自动生成测试用例?

传统的测试用例需要测试或者开发人员将用户的操作用代码表示出来&#xff0c;通过断言判断是否和预期一致&#xff0c;写测试用例也占用了部分时间&#xff0c;加上版本迭代测试用例的维护成本也较高&#xff0c;于是基于无埋点的需求相结合自动化测试来检测埋点&#xff0c;及…

行情分析——加密货币市场大盘走势(11.3)

大饼昨日与今日目前都是下跌态势&#xff0c;近期依然要保持逢低做多的策略。现在下跌&#xff0c;可以继续等待&#xff0c;也可以入场一部分仓位的多单&#xff0c;回调才是给机会上车。MACD日线来看&#xff0c;会继续回调&#xff0c;因此这个位置还是可以在等等。 以太昨日…

实践笔记-docker-compose安装

docker-compose 1.在线安装2.离线安装 1.在线安装 # github下载&#xff08;太慢了或者直接下载不了&#xff09; curl -L https://github.com/docker/compose/releases/download/1.25.4/docker-compose-uname -s-uname -m -o /usr/local/bin/docker-compose # daocloud下载 c…

【MySQL】015-MySQL索引

【MySQL】015-MySQL索引 文章目录 【MySQL】015-MySQL索引一、MySQL索引是什么1、概述2、好处3、缺点4、索引的使用场景5、常用命令查看数据表上建的索引 二、索引的分类1、三大类2、为什么使用B树作为索引在疑问为什么使用B树这种数据结构之前&#xff0c;先想想什么样的数据结…

网络编程——以太网协议

一&#xff0c;以太网格式 1.1目的地址 这个地址不是IP地址&#xff0c;而是网络中的另一套地址体系&#xff0c;mac 地址&#xff08;物理地址&#xff09;&#xff0c;这个地址的作用与IP地址有一定的重合。因为网络层协议与应用层协议是各自独立被开发的&#xff0c;所以地…

黄仁勋:英伟达预言 2 年内行业将面目全非 一个词形容AI:Unbelievable

本心、输入输出、结果 文章目录 黄仁勋&#xff1a;英伟达预言 2 年内行业将面目全非 一个词形容AI&#xff1a;Unbelievable前言【访谈内容】一个词形容AI&#xff1a;Unbelievable创立英伟达“比想象中难一百万倍”相关图片传送门弘扬爱国精神 黄仁勋&#xff1a;英伟达预言 …

贷款行业极难获客,怎么获取实时客户数据?

我们能想象当客户有贷款需求时会发生什么吗&#xff1f; 客户可能会打开手机搜索“如何借款”、“哪笔贷款利息低”、“最多能借多少钱”、“贷款需要什么条件”等关键词&#xff0c;然后&#xff0c;客户点击进入第一个链接&#xff0c;然后填写他们的姓名和电话号码来测试他…

浅谈无源供电无线测温在线监测系统应用方案

安科瑞 崔丽洁 摘要&#xff1a;无源供电无线测温在线监测系统是一种基于声表面波技术的测温技术&#xff0c;在变电站监测方面得到了很好的技术实践应用。本文对无源供电无线测温在线监测系统研究应用进行分析研究。 关键词&#xff1a;设备检测&#xff1b;无线测温。 引言 在…

vcruntime140.dll无法继续执行代码修复教程

在计算机的世界里&#xff0c;我们经常会遇到各种各样的问题&#xff0c;其中之一就是“vcruntime140.dll缺失”。这个问题可能会影响到我们的正常使用&#xff0c;但是别担心&#xff0c;今天我就来给大家分享一下关于vcruntime140.dll缺失的4种修复方案。 首先&#xff0c;我…