龙芯LoongArch CPU设计——基于vivado中的ip核实现RAM和ROM及性能比较

2023-10-11 16:30

本文主要是介绍龙芯LoongArch CPU设计——基于vivado中的ip核实现RAM和ROM及性能比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

在计算机组成原理的课程学习中,很多同学(我也是)的RAM和ROM都是在代码中以数组的形式来表示。

例如:

reg [31:0] Ins[0:127];//定义一个名为Ins的reg类型数组,该数组有128个单元,每个单元32位

现在使用vivado中的ip核来对我们设计RAM和ROM进行改造,看看实例化之后的性能是否会发生变化。
 

ROM和RAM相关知识介绍

ROM 是只读存储器(Read Only Memory)的简称,是一种只能读出事先所存数据的固态半导体存储器。其特性是一旦储存数据就无法再将之改变或删除,且数据不会因为电源关闭而消失。而事实上在 FPGA 中通过 IP 核生成的 ROM 或 RAM 调用的都是 FPGA 内部的RAM 资源,掉电内容都会丢失(这也很容易解释,FPGA 芯片内部本来就没有掉电非易失存储器单元)。用 IP 核生成的 ROM 模块只是提前添加了数据文件(.coe 格式),在 FPGA 运行时通过数据文件给 ROM 模块初始化,才使得 ROM 模块像个“真正”的掉电非易失存储器;也正是这个原因,ROM 模块的内容必须提前在数据文件(.coe格式)中写好,并且无法在电路中修改。
 

RAM 是随机存取存储器(Random Access Memory)的简称,是一个易失性存储器。RAM 工作时可以随时从任何一个指定的地址写入或读出数据,同时我们还能修改其存储的数据,即写入新的数据,这是 ROM 所并不具备的功能。在 FPGA 中这也是其与 ROM 的最大区别。ROM 是只读存储器,而 RAM 是可写可读存储器,在我们 FPGA 中使用这两个存储器主要也是要区分这一点,因为这两个存储器使用的都是我们 FPGA 内部的 RAM 资源,不同的是 ROM 只用到了 RAM 资源的读数据端口,同时RAM也可以提前添加数据文件(.coe 格式)
 

IP核具体实现ROM

单击 IPCatalog,在右边窗口 Search 位置输入 ROMS,在 Memories & Storage Elements 下可以看到有两个与 RAM 创建的入口,一个是 Distributed Memory Generator(分布式),另一个是 Block Memory Generator(块式),两者最主要的差别是生成的 Core 所占用的 FPGA 资源不一样,从Distributed Memory Generator 生成的 ROM/RAM Core 占用的资源是 LUT(查找表,查找表本质就是一个小的 RAM),适用于所需存储空间较小的场景;从 Block Memory Generator 生成的 ROM/RAM Core 占用的资源是 Block Memory(嵌入式的硬件 RAM),适用于所需存储空间较大的场景。本人的ROM目前所需存储空间不大,为80×8bit,在此选择 Distributed Memory Generator。

由于LoongArch32采用的是按字节编址,所以Data Width设置为8,因为Depth的数值要求为2的次方,我的是80×8bit,所以Depth填128。Memory Type(存储器类型)选ROM即可。Component Name为自定义的名字,任取即可,我取的名字是dist。

用 IP 核生成的 ROM 模块需要提前添加数据文件,所以要配置Coefficients File,即添加.coe文件(提前写好),从而ROM实现了存储数据的功能。

 我的.coe文件如下

至此,用IP核配置ROM完成,若想使用该ROM,只需在设计文件中调用即可。要注意:.coe文件要和vivado中的设计文件配合好,不要犯逻辑上的错误。.coe文件中的数据是存在ROM中的。并且在.coe文件中,一个空格表示一个存储单元的结束,由于loongarch32的指令集为32位,按字节(8位)寻址,所以我在一个周期中,从基址开始,先得到在ROM中连续存储的四个8bit的存储单元,分别为data_out_instr1、data_out_instr2、data_out_instr3、data_out_instr4,由于采用小端模式(高字节存储在高地址,低字节存储在低地址),所以拼接成了一条32位的指令Instr。

Pc u0(offset,pc_inc,clk,rst,PCdata);
dist n1(.a(PCdata),.spo(data_out_instr1));
dist n2(.a(PCdata+1),.spo(data_out_instr2));
dist n3(.a(PCdata+2),.spo(data_out_instr3));
dist n4(.a(PCdata+3),.spo(data_out_instr4));
assign Instr={data_out_instr4,data_out_instr3,data_out_instr2,data_out_instr1};

IP核具体实现RAM

有了IP核实现ROM的基础,实现RAM就显得简单许多,因为RAM是可读可写入,所以可以不使用.coe文件,和IP核实现ROM一样,选择Distributed Memory Generator。

 我配置的Component Name取名为dist_ram,Depth为1024(存储单元数为1024),Data_Width为32(数据宽度为32位),Memory Type选择为Single Port RAM(单端口RAM),就得到了名为dist_ram的1024×32bit的单端口RAM,小伙伴们要根据你们所设计的实际情况来配置哈。

配置完成后,在设计文件中使用该RAM,要特别注意,形参和实参要正确对应。

dist_ram u7(.clk(clk),.we(MemWrEn),.a(AddResult),.d(busB),.spo(data_out));

用IP核实例化前后的性能比较 

 

 可以看到,实例化后较实例化前,综合时间(synth_design Time)减少了,确实提高了速度,但同时可以观察到,存储空间(Memory)变大了,想到了数据结构课程中的经典思想:拿空间换时间。

 

 可以看到,不管是Post-Synthesis还是Post-Implementation,实例化后的利用率都比实例化前要高,性能明显提高了。

 总结

使用vivado中的ip核来对我们设计RAM和ROM进行改造后,发现所设计CPU电路的性能明显提高。设计CPU就像一张拼图,把之前学过的零碎东西拼凑在一起,融会贯通。只有自己摸索和思考,实践和实现,才能体会其中的奥秘和乐趣。最后,与大家共勉:天下难事必作于易,天下大事必作于细。

参考阅读:https://blog.csdn.net/yifantan/article/details/127492786?ops_request_misc=&request_id=&biz_id=102&utm_term=%E4%BD%BF%E7%94%A8vivado%20ip%E6%A0%B8ram&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-127492786.142^v92^chatsearchT3_1&spm=1018.2226.3001.4187

这篇关于龙芯LoongArch CPU设计——基于vivado中的ip核实现RAM和ROM及性能比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/189350

相关文章

Java实现将Markdown转换为纯文本

《Java实现将Markdown转换为纯文本》这篇文章主要为大家详细介绍了两种在Java中实现Markdown转纯文本的主流方法,文中的示例代码讲解详细,大家可以根据需求选择适合的方案... 目录方法一:使用正则表达式(轻量级方案)方法二:使用 Flexmark-Java 库(专业方案)1. 添加依赖(Ma

使用EasyExcel实现简单的Excel表格解析操作

《使用EasyExcel实现简单的Excel表格解析操作》:本文主要介绍如何使用EasyExcel完成简单的表格解析操作,同时实现了大量数据情况下数据的分次批量入库,并记录每条数据入库的状态,感兴... 目录前言固定模板及表数据格式的解析实现Excel模板内容对应的实体类实现AnalysisEventLis

Mybatis从3.4.0版本到3.5.7版本的迭代方法实现

《Mybatis从3.4.0版本到3.5.7版本的迭代方法实现》本文主要介绍了Mybatis从3.4.0版本到3.5.7版本的迭代方法实现,包括主要的功能增强、不兼容的更改和修复的错误,具有一定的参考... 目录一、3.4.01、主要的功能增强2、selectCursor example3、不兼容的更改二、

如何使用C#串口通讯实现数据的发送和接收

《如何使用C#串口通讯实现数据的发送和接收》本文详细介绍了如何使用C#实现基于串口通讯的数据发送和接收,通过SerialPort类,我们可以轻松实现串口通讯,并结合事件机制实现数据的传递和处理,感兴趣... 目录1. 概述2. 关键技术点2.1 SerialPort类2.2 异步接收数据2.3 数据解析2.

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

Qt把文件夹从A移动到B的实现示例

《Qt把文件夹从A移动到B的实现示例》本文主要介绍了Qt把文件夹从A移动到B的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录如何移动一个文件? 如何移动文件夹(包含里面的全部内容):如何删除文件夹:QT 文件复制,移动(

Flask 验证码自动生成的实现示例

《Flask验证码自动生成的实现示例》本文主要介绍了Flask验证码自动生成的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习... 目录生成图片以及结果处理验证码蓝图html页面展示想必验证码大家都有所了解,但是可以自己定义图片验证码

VSCode配置Anaconda Python环境的实现

《VSCode配置AnacondaPython环境的实现》VisualStudioCode中可以使用Anaconda环境进行Python开发,本文主要介绍了VSCode配置AnacondaPytho... 目录前言一、安装 Visual Studio Code 和 Anaconda二、创建或激活 conda

使用mvn deploy命令上传jar包的实现

《使用mvndeploy命令上传jar包的实现》本文介绍了使用mvndeploy:deploy-file命令将本地仓库中的JAR包重新发布到Maven私服,文中通过示例代码介绍的非常详细,对大家的学... 目录一、背景二、环境三、配置nexus上传账号四、执行deploy命令上传包1. 首先需要把本地仓中要

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操