fpga实操训练(ip ram和ip fifo)

news2024/9/27 12:17:09

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        所有的fpga ip当中,用的最多的ip一般有pll、rom、ram和fifo。前面,我们讨论过了rom,rom相比较ram和fifo而言,多一个mif文件的配置。而ram、fifo则不需要这样的操作。今天可以继续学习下ram和fifo,这样在后面的开发中就会显得游刃有余。

1、ip ram配置

a)创建ip ram的方法

        要创建ip ram,首先需要打开ip catalog,输入ram,选择双端口输入,

         接下来,系统会提示输入文件名,不妨命名为ip_ram.v。完成命名之后,就可以开始ip的配置了。这里面有几个重要的对话框需要注意下,首先是设置好bit宽度和word数量,

        确认是否共享时钟,

         确认是否需要晚一节拍输出数据,

         其他部分的页面采用默认的配置就可以了。

b)准备测试代码

        有了ip ram核之后,下面就是需要把它实例化,并且添加必要的测试代码。内容如下所示,

module top(clk, rst);

input clk;
input rst;

wire clk;
wire rst;


reg[4:0] read_address;
reg[4:0] write_address;
reg[7:0] write_data;
reg write_en;

wire[7:0] read_data;


always@(posedge clk or negedge rst)
	if(!rst)
		read_address <= 5'd0;
	else
		read_address <= read_address + 1'b1;

always@(posedge clk or negedge rst)
	if(!rst) begin
		write_en <= 1'b0;
		write_address <=5'd0;
		write_data <= 8'd0;
	end else begin
		if(write_address != 5'd31) begin
			write_en <= 1'b1;
			write_address <= write_address + 1'b1;
			write_data <= write_data + 8'd2 ;
		end else begin
			write_en <= 1'b0;
			write_address <=5'd0;
			write_data <= 8'd0;
		end
	end

ip_ram ip_ram0(
	.clock(clk),
	.data(write_data),
	.rdaddress(read_address),
	.wraddress(write_address),
	.wren(write_en),
	.q(read_data)
	);


endmodule

         测试的代码逻辑并不复杂。首先,在fpga复位之后,先对ram进行赋值操作。等所有的地址都写上数据之后,下面就是不停循环读出这些数据。为了验证这些数据是否真的被写入到ram空间,可以通过SignalTap的方法,通过jtag读一下这些数据,观察之前的写操作究竟有没有生效。

c)准备SignalTap,并且开始测试

        SignalTap的配置方法前面提过多次,这里直接给出配置的截图即可,

         经过输入F6和Esc之后,就可以看到截取的地址和数据了,

         前面编写测试代码的时候,写入的数据都是address*2。假设输入的地址是0,那么读取的数据应该是0;如果输入的地址是1,那么读取的数据应该是2,依次类推。通过截图,我们发现当read_address是0x12h的时候,q需要等一个时钟才能输出0x24h。这说明,ram和rom其实是一样的,两者都是等一个时钟才能输出数据的。

2、ip fifo配置

a)和ram一样,首先还是从ip catalog中寻找fifo,

        同样,这里需要用户自己输入文件名。不妨命名为ip_fifo.v,接着就可以开始配置。配置的内容很多,最关键的有这么几处。首先,输入write bit长度、read bit长度、总长度。这个非常有用,

         确定主要的输出信号,

         确认rdreq的用法,

         完成主要的这些操作之后,再加上自身的默认配置,就可以完成ip fifo的基本设定了。

b)准备测试代码

module top(clk, rst);

input clk;
input rst;

wire clk;
wire rst;

reg[7:0] write_data;
wire[31:0] read_data;
wire write_full;
wire read_empty;

reg write_req;
reg read_req;

// write state and next_write_state
reg[1:0] write_state;
reg[1:0] next_write_state;

always@(posedge clk or negedge rst)
	if(!rst)
		write_state <= 2'b00;
	else 
		write_state <= next_write_state;
		
always@(*)
	if(!rst)
		next_write_state <= 2'b00;
	else begin
		case (write_state)
			2'b00:
				if(!write_full)
					next_write_state <= 2'b01;
				else
					next_write_state <= 2'b00;
			
			2'b01:
				if(write_full)
					next_write_state <= 2'b00;
				else
					next_write_state <= 2'b01;
					
			default:
				next_write_state <= 2'b00;
		endcase
	end

always @(posedge clk or negedge rst)
	if(!rst) 
		write_req <= 1'b0;
	else if(next_write_state == 2'b01)
		write_req <= 1'b1;	
	else
		write_req <= 1'b0;


always @(posedge clk or negedge rst)
	if(!rst) 
		write_data <= 8'd0;
	else if(next_write_state == 2'b01)
		write_data <= write_data + 1'b1;	
	
// read_state and next_read_state		
reg[1:0] read_state;
reg[1:0] next_read_state;

always@(posedge clk or negedge rst)
	if(!rst)
		read_state <= 2'b00;
	else 
		read_state <= next_read_state;
		
always@(*)
	if(!rst)
		next_read_state <= 2'b00;
	else begin
		case (read_state)
			2'b00:
				if(!read_empty)
					next_read_state <= 2'b01;
				else
					next_read_state <= 2'b00;
			
			2'b01:
				if(read_empty)
					next_read_state <= 2'b00;
				else
					next_read_state <= 2'b01;
					
			default:
				next_read_state <= 2'b00;
		endcase
	end

always @(posedge clk or negedge rst)
	if(!rst) 
		read_req <= 1'b0;
	else if(next_read_state == 2'b01)
		read_req <= 1'b1;	
	else
		read_req <= 1'b0;	

// invoke ip ip_fifo

wire[7:0] rdusedw;
wire[7:0] wrusedw;

ip_fifo ip_fifo0(
	.data(write_data),
	.rdclk(clk),
	.rdreq(read_req),
	.wrclk(clk),
	.wrreq(write_req),
	.q(read_data),
	.rdempty(read_empty),
	.rdusedw(rdusedw),
	.wrfull(write_full),
	.wrusedw(wrusedw));

endmodule

         测试代码的内容不复杂,主要的工作就是把流程切分成write_state和read_state。对于write_state而言,一旦发现fifo不满,就开始写入数据。而对于read_state而言,每当发现fifo非空,就不停读取数据。这样,一写一读,就构成了fifo的基本操作。如果两者速率不匹配,或者字节长度不同,fifo还可以充当临时buffer的角色。当然,为了验证我们的测试是否正确,最终还得借助于SignalTap这个工具。

c)SignalTap配置和测试

        SignalTap中主要检查写入和读取的数据,

        烧入sof文件之后,经过F6和Esc之后,就可以看到相关的波形数据了,

 

补充1:

        之前测试的时候一直没有注意时序约束。事实上,在 fpga开发过程中最好做到0 error,0 warning。这是比较合适的。所以,项目中最好添加必要的时序约束文件,告知quartus软件当前fpga希望以什么样的时钟运行,

# Clock constraints

create_clock -name "clk" -period 20.000ns [get_ports {clk}]


# Automatically constrain PLL and other generated clocks
derive_pll_clocks -create_base_clocks

# Automatically calculate clock uncertainty to jitter and other effects.
derive_clock_uncertainty

# tsu/th constraints

# tco constraints

# tpd constraints

补充2:

        另外,如果引脚比较多,pin bind也是一个体力活。这部分可以借助于tcl脚本来完成。编写完tcl之后,就可以通过"Tools"->"Tcl Scripts"运行脚本即可,

package require ::quartus::project

set_location_assignment PIN_E1 -to clk
set_location_assignment PIN_N13 -to rst
set_location_assignment PIN_D9 -to led[3]
set_location_assignment PIN_C9 -to led[2]
set_location_assignment PIN_F9 -to led[1]
set_location_assignment PIN_E10 -to led[0]

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

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

相关文章

弹性盒子(flex)

一、什么是弹性盒子 弹性盒子是一种用于按行或按列布局元素的一维布局方法。元素可以膨胀以填充额外的空间&#xff0c;收缩以适应更小的空间。 二、flex 模型说明 主轴&#xff08;main axis&#xff09;&#xff1a; 是沿着 flex 元素放置的方向延伸的轴&#xff08;比如页…

【vue】关于vuex的一点补充

1.vuex的基本和下载 1.vuex是一种集中管理模式&#xff0c;举个详细一点的例子就是公共的数据&#xff0c;函数和计算属性&#xff0c;允许任何组件来使用&#xff0c;修改这里面的数据&#xff0c;vuex也可以成为store处理模式&#xff0c;其中一个store示例有state&#xff…

hadoop大数据入门HDFS、MapReduce、YARN的个人通俗理解

大数据时代,在数据量,计算量,计算时间上都是单机无法胜任的&#xff0c;通过简单的增强单机已经无法解决。普遍的解决方案为将多个单机组合起来进行存储和计算的分布式集群来处理。 Hadoop支持使用普通机器组成可拓展的分布式主从集群实现了对大数据的分布式存储&#xff08;HD…

SpringCloud之Hystrix服务熔断

Hystrix服务熔断1. 服务雪崩2. Hystrix 的概念3. Hystrix 的作用4. 服务熔断4.1 概念4.2 服务熔断解决哪些问题&#xff1f;4.3 案例5. 服务降级5.1 概念5.2 案例6. 服务熔断和降级的区别7. Dashboard 流监控分布式系统面临的问题复杂分布式体系结构中的应用程序有数十个依赖关…

At and Cron and Scheduling task

1.at 一次性任务 一次性使用&#xff0c;执行某条命令或者脚本&#xff0c;守护进程atd,默认安装以及开机启动。在输入完命令的时候&#xff0c;按CtrlD结束 now 5min 现在过后5分钟 teatime tomorrow 明天的下午茶时间-4点 noon 中午 5pm august 3 2016 2016年八月3号的下午5点…

linux平台下node cnpm的安装方法

linux node cnpm的安装方法&#xff1a;1、下载linux版的node&#xff0c;并放在“/home/node/”目录下 &#xff1b;2、打开linux解压缩下gz&#xff1b;3、回到根目录&#xff0c;建立软连接&#xff1b;4、通过“npm install -g cnpm --registryhttps://registry.npm.taobao…

4、MYSQL常用函数(日期和时间函数)

目录 curdate&#xff08;&#xff09;&#xff1a;返回当前日期 curtime&#xff08;&#xff09;&#xff1a;返回当前时间 now&#xff08;&#xff09;&#xff1a;返回当前日期和时间 unix_timestamp&#xff08;date&#xff09;&#xff1a;返回date的unix时间函数 fro…

再学C语言18:循环控制语句——while循环

3种基本的程序流&#xff1a;顺序、循环、分支 3种循环程序流&#xff1a;while、do while、for 伪代码&#xff08;pseudocode&#xff09;&#xff1a;一种用简单的英语表示程序的方法&#xff0c;与计算机语言的形式相对应&#xff1b;伪代码有助于设计程序的逻辑 while循…

Python语言快速入门下2

目录 一、前言 二、字符串 【字符串】 【字符串格式化】 【字符串常用方法】 1&#xff09;去掉空格和特殊字符 3&#xff09;字符串的测试和替换函数 4&#xff09;字符串的分割 5&#xff09;连接字符串 6&#xff09;截取字符串&#xff08;切片&#xff09; 7&a…

2022年「博客之星」,花落谁家? 大家来竞猜吧

一年一度的「博客之星」大赛如火如荼地进行着&#xff0c;大家都忙着评分、发帖、回帖.....今天发现我在分组的排名只有40多名&#xff0c;基本上算是放弃了。但是&#xff0c;看到本文的朋友&#xff0c;还是可以帮我拉拉票的&#xff01;请点开链接给个五星评分&#xff1a; …

Linux下安装Fastdfs

一、前期准备工作 1、需要提前下载的安装包&#xff1a; &#xff08;1&#xff09;libfatscommon-1.0.43&#xff1a;FastDFS分离出的一些公用函数包 &#xff08;2&#xff09;fastdfs-6.06&#xff1a;FastDFS本体包 &#xff08;3&#xff09;nginx&#xff1a;nginx-1.2…

服装行业进销存软件哪个好?

好用的进销存软件有以下评判标准&#xff1a; 1. 能否为企业带来效益。理清自身在进销存管理中的难点以及进销存软件需要具备的功能。 2. 是否简单实用&#xff0c;人员是否上手容易。选购软件不易太复杂&#xff0c;会给前期软件使用造成人力、物力等压力。 3. 进销存软件的…

【SpringBoot应用篇】SpringBoot集成AntiSamy防御XSS(跨站脚本攻击)--过滤器实现

【SpringBoot应用篇】SpringBoot集成AntiSamy防御XSS&#xff08;跨站脚本攻击&#xff09;--过滤器实现XSS介绍AntiSamy介绍AntiSamy使用pomUserUserControllerXssFilterXssRequestWrapper配置类XSS介绍 XSS&#xff1a;跨站脚本攻击(Cross Site Scripting)&#xff0c;为不和…

4、MYSQL常用函数(字符串)

目录 abs&#xff08;x&#xff09;&#xff1a;返回x的绝对值 ceil&#xff08;x&#xff09;&#xff1a;返回大于x的最小整数 floor&#xff08;x&#xff09;&#xff1a;返回小于x的最大整数 mod&#xff08;x,y&#xff09;&#xff1a;返回x/y的模 Rand&#xff08;&a…

分析激光焊接机焊接不牢固的原因

激光焊接机在焊接时为什么会出现焊接不牢固呢&#xff1f;是不是激光焊接设备出现问题了&#xff1f;当激光焊接机进行焊接加工时&#xff0c;出现材料之间的焊接不牢固这会影响整体质量。这时&#xff0c;用户不可避免地会质疑激光焊接机的效果我们也是可以理解的。实质出现激…

javaEE初阶---多线程(初阶)

一 : 学习目标 认识多线程掌握多线程程序的编写掌握多线程的状态掌握什么是线程不安全及解决思路掌握synchronized、volatile关键字 二 : 初识线程 2.1 线程概念 线程&#xff08;thread&#xff09;是操作系统能够进行运算调度的最小单位.它被包含在进程之中&#xff0c;是进…

django使用二——restful框架使用

背景 前言&#xff1a; 前篇django使用一&#xff0c;已将基本的项目、应用创建并运行&#xff1b;见&#xff1a;django使用一——规范化创建 本篇则针对ViewSet及rest_framework初使用做介绍&#xff1b; 闲笔&#xff1a; 两束平行宇宙射线射入黑盒&#xff0c;在人们充满…

《计算机网络》——第六章知识点

第六章思维导图如下&#xff1a; 应用层对应用程序的通信提供服务。 域名解析:根据域名找IP地址 域名结构 FTP是基于客户/服务器(C/S)的协议。 用户通过一个客户机程序连接至在远程计算机上运行的服务器程序。依照FTP协议提供服务&#xff0c;进行文件传送的计算机就是FTP服…

对象类型的设计(简答题)

在实际项目开发中需要进行对象类型的设计&#xff0c;给你的问题是&#xff0c;在学生信息系统中需要你设计班级Classes类型和学生Student类型&#xff0c;为了便于数据的查询&#xff0c;需要建立对象之间的联系&#xff0c;比如一个班级有多个学生&#xff0c;每个学生属于一…

看完这篇,我不允许你还不会用Allegro显示PCB的3D模式

看完这篇,我不允许你还不会用Allegro显示PCB的3D模式 Allegro可以显示PCB的3D效果,利于查看和检查,如下图 具体操作如下 选择Set-up-user preferences选择Display