Vitis HLS 学习笔记--static RAM/ROM

news2024/11/16 19:31:23

目录

1. 简介

2. static RAM

2.1 无 reset 的情形

2.2 含 reset 的情形

3. static ROM

4. 总结


1. 简介

本文仍然是讨论阵列的初始化与复位问题,区别于《Vitis HLS 学习笔记--global_array_RAM初始化及复位-CSDN博客》,本文讨论的对象是静态阵列,RAM和ROM。

静态阵列可以映射到BRAM/URAM/LUTRAM,本文并展示了它们如何初始化以及如何重置。

2. static RAM

2.1 无 reset 的情形

无 reset,意味着静态变量存储器的值不会受到 reset 信号的影响。

#include <ap_int.h>

int example(int i) {
    static ap_int<10> A[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
#pragma HLS BIND_STORAGE variable = A type = RAM_2P impl = BRAM
    static ap_int<10> B[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
#pragma HLS BIND_STORAGE variable = B type = RAM_2P impl = LUTRAM
    static ap_int<10> C[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
#pragma HLS BIND_STORAGE variable = C type = RAM_2P impl = URAM
    A[i] += B[i] + C[i];
    B[i] += 5;
    C[i] += 10;

    int result = (A[i] + B[i] + C[i]).to_int();
    return result;
}

查看存储绑定信息:

================================================================
== Bind Storage Report
================================================================
+-----------+------+------+--------+----------+---------+--------+---------+
| Name      | BRAM | URAM | Pragma | Variable | Storage | Impl   | Latency |
+-----------+------+------+--------+----------+---------+--------+---------+
| + example | 1    | 1    |        |          |         |        |         |
|   B_V_U   | -    | -    | pragma | B_V      | ram_2p  | lutram | 1       |
|   C_V_U   | -    | 1    | pragma | C_V      | ram_2p  | uram   | 1       |
|   A_V_U   | 1    | -    | pragma | A_V      | ram_2p  | bram   | 1       |
+-----------+------+------+--------+----------+---------+--------+---------+

与 global_array_RAM 不同的是,static RAM 是支持使用 URAM 来实现的,我们使用下列指令绑定资源。

#pragma HLS BIND_STORAGE variable = C type = RAM_2P impl = URAM

从报告中我们也可以观察到,变量C已被分配为uram资源。

Verilog 代码结构:

以变量C为例,其实现的Verilog代码如下:

module example_C_V_RAM_2P_URAM_1R1W (address0, ce0, q0, address1, ce1, d1, we1,  reset,clk);

parameter DataWidth = 10;
parameter AddressWidth = 4;
parameter AddressRange = 10;

input[AddressWidth-1:0] address0;
input ce0;
output reg[DataWidth-1:0] q0;
input[AddressWidth-1:0] address1;
input ce1;
input[DataWidth-1:0] d1;
input we1;
input reset;
input clk;

(* ram_style = "hls_ultra", cascade_height = 1 *)reg [DataWidth-1:0] ram[0:AddressRange-1];

initial begin
    $readmemh("./example_C_V_RAM_2P_URAM_1R1W.dat", ram);
end


always @(posedge clk)  
begin 
    if (ce0) begin
        q0 <= ram[address0];
    end
end

always @(posedge clk)  
begin 
    if (ce1) begin
        if (we1) 
            ram[address1] <= d1; 
    end
end

endmodule

2.2 含 reset 的情形

含 reset,意味着静态变量存储器的值在 reset 信号有效时,会恢复到初始状态。

需要在源代码中添加如下指令:

#pragma HLS reset variable=A
#pragma HLS reset variable=B
#pragma HLS reset variable=C

 Verilog 代码结构:

以变量C为例,其实现的Verilog代码如下:

module example_C_V_RAM_2P_URAM_1R1W
#(parameter
    DataWidth    = 10,
    AddressWidth = 4,
    AddressRange = 10
)(
    input  wire                    clk,
    input  wire                    reset,
    input  wire [AddressWidth-1:0] address0,
    input  wire                    ce0,
    output wire [DataWidth-1:0]    q0,
    input  wire [AddressWidth-1:0] address1,
    input  wire                    ce1,
    input  wire                    we1,
    input  wire [DataWidth-1:0]    d1
);
//------------------------Local signal-------------------
reg  [AddressRange-1:0] written = {AddressRange{1'b0}};
wire [DataWidth-1:0]    q0_ram;
wire [DataWidth-1:0]    q0_rom;
wire                    q0_sel;
reg  [0:0]              sel0_sr;
//------------------------Instantiation------------------
example_C_V_RAM_2P_URAM_1R1W_ram #(
    .DataWidth(DataWidth),
    .AddressWidth(AddressWidth),
    .AddressRange(AddressRange))
example_C_V_RAM_2P_URAM_1R1W_ram_u(
    .clk      ( clk ),
    .reset    ( reset ),
    .ce0      ( ce0 ),
    .address0 ( address0 ),
    .q0       ( q0_ram ),
    .ce1      ( ce1 ),
    .address1 ( address1 ),
    .we1      ( we1 ),
    .d1       ( d1 )
);

example_C_V_RAM_2P_URAM_1R1W_rom #(
    .DataWidth(DataWidth),
    .AddressWidth(AddressWidth),
    .AddressRange(AddressRange))
example_C_V_RAM_2P_URAM_1R1W_rom_u(
    .clk      ( clk ),
    .ce0      ( ce0 ),
    .address0 ( address0 ),
    .q0       ( q0_rom )
);
//------------------------Body---------------------------
assign q0     = q0_sel? q0_ram : q0_rom;
assign q0_sel = sel0_sr[0];

always @(posedge clk) begin
    if (reset)
        written <= 1'b0;
    else begin
        if (ce1 & we1) begin
            written[address1] <= 1'b1;
        end
    end
end

always @(posedge clk) begin
    if (ce0) begin
        sel0_sr[0] <= written[address0];
    end
end

endmodule

这部分内容可以参见《Vitis HLS 学习笔记--global_array_RAM初始化及复位-CSDN博客》。

3. static ROM

#include <ap_int.h>

int example(int i) {
    static const ap_int<10> A[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
#pragma HLS BIND_STORAGE variable = A type = ROM_1P impl = BRAM
    static const ap_int<10> B[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
#pragma HLS BIND_STORAGE variable = B type = ROM_1P impl = LUTRAM

    return A[i] + B[i];
}

由于 ROM 是只读的,所以使用 ROM_1P 来实现,即只有一个读取口。

ROM 存储器实现不可由 URAM 来实现。

查看存储器绑定报告: 

================================================================
== Bind Storage Report
================================================================
+-----------+------+------+--------+----------+---------+--------+---------+
| Name      | BRAM | URAM | Pragma | Variable | Storage | Impl   | Latency |
+-----------+------+------+--------+----------+---------+--------+---------+
| + example | 1    | 0    |        |          |         |        |         |
|   A_V_U   | 1    | -    | pragma | A_V      | rom_1p  | bram   | 1       |
|   B_V_U   | -    | -    | pragma | B_V      | rom_1p  | lutram | 1       |
+-----------+------+------+--------+----------+---------+--------+---------+

可以看到 ROM 也是通过 bram/lutram 来实现的,不过不影响,没有对外暴露写端口。

Verilog 代码结构:

 

 以变量A为例,其实现的Verilog代码如下:

(* rom_style = "block" *) module example_A_V_ROM_1P_BRAM_1R (
address0, ce0, q0, reset,clk);

parameter DataWidth = 4;
parameter AddressWidth = 4;
parameter AddressRange = 10;

input[AddressWidth-1:0] address0;
input ce0;
output reg[DataWidth-1:0] q0;
input reset;
input clk;

(* ram_style = "block" *)reg [DataWidth-1:0] ram[0:AddressRange-1];

initial begin
    $readmemh("./example_A_V_ROM_1P_BRAM_1R.dat", ram);
end

always @(posedge clk)  
begin 
    if (ce0) 
    begin
        q0 <= ram[address0];
    end
end

endmodule

4. 总结

在本文中,我们探讨了静态阵列在Vitis HLS中的初始化和复位问题,特别是与全局阵列RAM相比,静态RAM的不同之处。我们了解到静态阵列可以映射到BRAM、URAM或LUTRAM,并且可以通过特定的HLS指令进行初始化和重置。在无reset情形下,静态变量存储器的值不受reset信号影响,而在含reset情形下,存储器的值会在reset信号有效时恢复到初始状态。此外,我们还讨论了静态ROM的实现,它是只读的,通常使用BRAM或LUTRAM实现,但不能使用URAM。通过这些讨论,我们可以更好地理解如何在硬件设计中有效地使用这些存储结构,以及如何通过Vitis HLS工具来优化它们的实现。总的来说,这些知识对于那些希望在FPGA编程中实现高效存储和数据访问的开发者来说是非常宝贵的。

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

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

相关文章

微服务第一轮

课程文档 目录 一、业务流程 1、登录 Controller中的接口&#xff1a; Service中的实现impl&#xff1a; Service中的实现impl所继承的接口IService&#xff08;各种方法&#xff09;&#xff1a; VO&#xff1a; DTO&#xff1a; 2、搜索商品 ​Controller中的接口&a…

期望24K,商汤科技golang开发 社招一二三 + hr 面

商汤科技对数据库和中间件相关的东西问的比其他的大厂要少很多&#xff0c;可能他们更多是和算法相关&#xff0c;没有什么高并发的场景。总体感觉对技术的要求不是特别高。当时问了他们主管&#xff0c;我面试的部门的工作是主要去实现他们算法部门研究的算法&#xff0c;感觉…

CSS函数:fit-content与matrix的使用

网格函数 fit-content()属于网格函数&#xff0c;除此之外的网格函数还有&#xff1a;CSS函数&#xff1a; 实现数据限阈的数字函数。顾名思义&#xff0c;这三个函数只能在网格布局中使用。fit-content()函数主要是用于给定布局可用大小&#xff0c;适应内容&#xff0c;其功…

【微信小程序】页面导航

声明式导航 导航到 tabbar 页 tabBar页面指的是被配置为tabBar的页面。 在使用<navigator>组件跳转到指定的tabBar页面时&#xff0c;需要指定url属性和open-type属性&#xff0c;其中&#xff1a; url 表示要跳转的页面的地址&#xff0c;必须以/开头open-type表示跳…

【Vue】路由介绍

一、引入 思考 单页面应用程序&#xff0c;之所以开发效率高&#xff0c;性能好&#xff0c;用户体验好 最大的原因就是&#xff1a;页面按需更新 比如当点击【发现音乐】和【关注】时&#xff0c;只是更新下面部分内容&#xff0c;对于头部是不更新的 要按需更新&#xff…

企业微信hook接口协议,ipad协议http,内部联系人备注修改

内部联系人备注修改 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信 请求示例 {"uuid":"1688855749266556","vid":1688856554448765,"remark":"备注啦啦啦22222","des&quo…

Pycharm SSH远程连接时出现报错,测试 SFTP 连接,连接到 ‘connect.westb.seetacloud.com‘ 失败

问题由来 很离谱&#xff01;今天本来打算租借AutoDL的显卡完成一项深度学习的任务&#xff0c;很离谱的是同步文件夹的时候报了标题说的错。 就很莫名奇妙&#xff0c;一天都在网上找解决办法&#xff0c;结果都不对头。 其他报错 最后摸索着&#xff0c;在使用pycharm远程登…

[数据集][目标检测]手枪检测数据集VOC+YOLO格式3000张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3000 标注数量(xml文件个数)&#xff1a;3000 标注数量(txt文件个数)&#xff1a;3000 标注…

数据流通与智能家居的未来

在科技飞速发展的今天&#xff0c;智能家居逐渐融入我们的日常生活&#xff0c;改变了传统的居住方式。智能生态网络&#xff08;IEN&#xff09;作为智能家居的核心&#xff0c;集成了家庭内的各种智能设备和传感器&#xff0c;实现了对家庭环境的智能化管理。而数据要素流通则…

SpringCloud 服务调用 spring-cloud-starter-openfeign

spring-cloud-starter-openfeign 是 Spring Cloud 中的一个组件&#xff0c;用于在微服务架构中声明式地调用其他服务。它基于 Netflix 的 Feign 客户端进行了封装和增强&#xff0c;使其与 Spring Cloud 生态更好地集成。 1. Feign Feign 是一个声明式的 Web Service 客户端…

绿联Nas docker 中 redis 老访问失败的排查

部署了一些服务&#xff0c;老隔3-5 天其他服务就联不上 redis 了&#xff0c;未确定具体原因&#xff0c;只记录观察到的现象 宿主机访问 只有 ipv6 绑定了&#xff0c;ipv4 绑定挂掉了 其他容器访问 也无法访问成功 当重启容器后&#xff1a; 一切又恢复正常。 可能的解…

使用 Django 和 MQTT 构建实时数据传输应用

文章目录 什么是 MQTT&#xff1f;Django 中的 MQTT结论 在现代的 Web 应用程序开发中&#xff0c;实时数据传输变得越来越重要。MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅消息传输协议&#xff0c;而 Django 是一个流行的 Pyt…

【最新鸿蒙应用开发】——Want信息载体

信息传递载体Want 1、概述 上一章节我们学习了UIAbility组件 【最新鸿蒙应用开发】——一篇搞懂什么是UIAbility-CSDN博客 &#xff0c;其中组件间的交互传递信息的媒介就是Want&#xff0c;本章节我们来更加深入学习Want的相关知识。 Want是一种对象&#xff0c;用于在应用组…

实践记录-docker-step1~5/10-参考docker官网步骤操作记录

参考来源&#xff1a; &#xff08;应用的容器化实践&#xff09;docker官方入门指南 https://docs.docker.com/get-started/ 本指南包含有关如何开始使用 Docker 的分步说明。本指南介绍如何&#xff1a; 将映像作为容器生成并运行。 使用 Docker Hub 共享映像。 使用带有数据…

OpenCv之简单的人脸识别项目(属性判断页面)

人脸识别 准备十二、属性判断页面1.导入所需的包2.设置窗口2.1定义窗口外观和大小2.2设置窗口背景2.2.1设置背景图片2.2.2创建label控件 3.定义预测性别脚本4.定义预测年龄脚本5.定义关闭窗口的函数6.按钮设计6.1预测性别按钮6.2预测年龄按钮6.3返回按钮 7.定义关键函数8.属性判…

python-opencv图像分割

文章目录 二值化图像骨骼连通域分割 二值化 所谓图像分割&#xff0c;就是将图像的目标和背景分离开来&#xff0c;更直观一点&#xff0c;就是把目标涂成白色&#xff0c;背景涂成黑色&#xff0c;言尽于此&#xff0c;是不是恍然大悟&#xff1a;这不就是二值化么&#xff1…

农业四情监测系统

TH-Q1农业&#xff0c;作为支撑国民经济建设与发展的基础产业&#xff0c;其稳定与高效的发展对于国家乃至全球的经济稳定具有举足轻重的意义。然而&#xff0c;农业的发展并非一帆风顺&#xff0c;它面临着诸如气候变化、病虫害、土壤质量等多种因素的挑战。在这一背景下&…

AJAX 跨域

这里写目录标题 同源策略JSONPJSONP 是怎么工作的JSONP 的使用原生JSONP实践CORS 同源策略 同源&#xff1a; 协议、域名、端口号 必须完全相同、 当然网页的URL和AJAX请求的目标资源的URL两者之间的协议、域名、端口号必须完全相同。 AJAX是默认遵循同源策略的&#xff0c;不…

yolov8摔倒检测(包含数据集+训练好的模型)

基于先进的YOLOv8模型&#xff0c;实现了一套高效可靠的人体摔倒检测系统。YOLOv8作为YOLO系列的最新成员&#xff0c;以其卓越的检测速度和准确性&#xff0c;在计算机视觉领域尤其是目标检测任务中表现出色。本系统不仅能够实时处理视频流或监控画面&#xff0c;还能对静态图…

Termux安装SSH服务与内网穿透工具实现远程SFTP传输文件

文章目录 前言1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问4. 配置固定远程连接地址 前言 本教程主要介绍如何在安卓 Termux 系统中使用 SFTP 文件传输并结合[cpolar内网穿透工具](cpolar - 安全的内网穿透工具)轻松实现无公网IP远程传输&#xff0c;无需购…