龙芯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

相关文章

C#实现将Excel表格转换为图片(JPG/ PNG)

《C#实现将Excel表格转换为图片(JPG/PNG)》Excel表格可能会因为不同设备或字体缺失等问题,导致格式错乱或数据显示异常,转换为图片后,能确保数据的排版等保持一致,下面我们看看如何使用C... 目录通过C# 转换Excel工作表到图片通过C# 转换指定单元格区域到图片知识扩展C# 将 Excel

基于Java实现回调监听工具类

《基于Java实现回调监听工具类》这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录监听接口类 Listenable实际用法打印结果首先,会用到 函数式接口 Consumer, 通过这个可以解耦回调方法,下面先写一个

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法

《springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法》:本文主要介绍springboot整合阿里云百炼DeepSeek实现sse流式打印,本文给大家介绍的非常详细,对大... 目录1.开通阿里云百炼,获取到key2.新建SpringBoot项目3.工具类4.启动类5.测试类6.测

pytorch自动求梯度autograd的实现

《pytorch自动求梯度autograd的实现》autograd是一个自动微分引擎,它可以自动计算张量的梯度,本文主要介绍了pytorch自动求梯度autograd的实现,具有一定的参考价值,感兴趣... autograd是pytorch构建神经网络的核心。在 PyTorch 中,结合以下代码例子,当你

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各