首页 > 其他分享 >IP核学习之自定义ram:参照IP核xilinx_dist_sdpram_0oregs_32x12

IP核学习之自定义ram:参照IP核xilinx_dist_sdpram_0oregs_32x12

时间:2024-09-14 15:21:13浏览次数:13  
标签:std dist 自定义 -- IP sdpram downto LOGIC logic

一、Distributed Memory Generator有什么用?

Distributed Memory Generator是Vivado中的IP核,即分布式存储器。
它可以生成只读存储器 (ROM),单端口、简单双端口和双端口随机存取存储器 (RAM),
且生成的存储器支持16-65536字的数据深度,和1-1024位的数据宽度。

xilinx_dist_sdpram_0oregs_32x12 似乎是指一个双端口的分布式存储器(SDPRAM),它具有32个地址和每个地址可以存储12位数据。在Xilinx FPGA中,分布式RAM(Distributed RAM)是利用查找表(LUTs)中的额外逻辑来实现的小型RAM,通常用于实现小规模的存储需求。

在Xilinx FPGA架构中,分布式RAM可以在SLICEM中的查找表(LUTs)实现,而SLICEL则不支持此功能。每个SLICEM可以配置为不同形式的RAM,例如单端口RAM、双端口RAM、简单双端口RAM或四端口RAM。对于简单双端口RAM,一个SLICEM可以提供最多256位的存储空间,即4个LUTs,每个LUT提供64位的存储能力。

二、端口说明

本次选择的设置是简单双端口,接口调用如下:

分布式ram代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity dist_sdpram is
    Port (
        a : in STD_LOGIC_VECTOR(4 downto 0); -- 5-bit address
        d : in STD_LOGIC_VECTOR(11 downto 0); -- 12-bit data input
        dpra : in STD_LOGIC_VECTOR(4 downto 0); -- 5-bit address for read
        clk : in STD_LOGIC; -- Clock input
        we : in STD_LOGIC; -- Write enable
        qdpo_ce : in STD_LOGIC; -- Output register clock enable
        qdpo : out STD_LOGIC_VECTOR(11 downto 0) -- 12-bit data output
    );
end dist_sdpram;

architecture Behavioral of dist_sdpram is
    type ram_type is array (0 to 31) of STD_LOGIC_VECTOR(11 downto 0);
    signal ram : ram_type := (others => (others => '0')); -- Initialize RAM
begin
    process(clk)
    begin
        if rising_edge(clk) then
            if we = '1' then
                ram(conv_integer(a)) <= d; -- Write operation
            end if;
        end if;
    end process;

    -- Read operation
    process(clk)
    begin
        if rising_edge(clk) then
            if qdpo_ce = '1' then
                qdpo <= ram(conv_integer(dpra)); -- Read operation
            end if;
        end if;
    end process;
end Behavioral;

调用两次封装为更大的sdpram_32x24_0oregs_wrapper

​
entity sdpram_32x24_0oregs_wrapper is
        waddr : in STD_LOGIC_VECTOR(4 downto 0); -- 5-bit address
        wdata : in STD_LOGIC_VECTOR(11 downto 0); -- 12-bit data input
        raddr : in STD_LOGIC_VECTOR(4 downto 0); -- 5-bit address for read
        clk : in STD_LOGIC; -- Clock input
        wen : in STD_LOGIC; -- Write enable
        ren : in STD_LOGIC; -- Output register clock enable
        q : out STD_LOGIC_VECTOR(11 downto 0) -- 12-bit data output
end sdpram_32x24_0oregs_wrapper;

architecture testbench of sdpram_32x24_tb is
    
    component dist_sdpram_32x12
        port (
            clk : in std_logic;
            we : in std_logic;
            a : in std_logic_vector(4 downto 0);
            d : in std_logic_vector(11 downto 0);
            dpra : in std_logic_vector(4 downto 0);
            qdpo_ce : in std_logic;
            qdpo : out std_logic_vector(11 downto 0)
        );
    end component;
    
    -- 测试平台内部连接RAM实体
    begin
        sdpram_L_inst: dist_sdpram_32x12
        port map (
            clk => clk,
            we => wen,
            a => waddr,
            d => wdata (11 downto 0),
            dpra => raddr,
            qdpo_ce => ren,
            qdpo => q (11 downto 0)
        );
        sdpram_H_inst: dist_sdpram_32x12
        port map (
            clk => clk,
            we => wen,
            a => waddr,
            d => wdata (23 downto 12),
            dpra => raddr,
            qdpo_ce => ren,
            qdpo => q (23 downto 12)
        );

​

tb:

entity sdpram_32x24_tb is
-- 测试平台不需要端口
end sdpram_32x24_tb;

architecture testbench of sdpram_32x24_tb is
    signal clk : std_logic := '0';
    signal we : std_logic := '0';
    signal a : std_logic_vector(4 downto 0) := (others => '0'); -- 写/读地址
    signal d : std_logic_vector(23 downto 0) := (others => '0'); -- 数据输入
    signal dpra : std_logic_vector(4 downto 0) := (others => '0'); -- 读地址
    signal qdpo_ce : std_logic := '0'; -- 输出寄存器时钟使能
    signal qdpo : std_logic_vector(23 downto 0); -- 数据输出

    component sdpram_32x24
        port (
            clk : in std_logic;
            we : in std_logic;
            a : in std_logic_vector(4 downto 0);
            d : in std_logic_vector(23 downto 0);
            dpra : in std_logic_vector(4 downto 0);
            qdpo_ce : in std_logic;
            qdpo : out std_logic_vector(23 downto 0)
        );
    end component;

begin
    uut: sdpram_32x24
    port map (
        clk => clk,
        we => we,
        a => a,
        d => d,
        dpra => dpra,
        qdpo_ce => qdpo_ce,
        qdpo => qdpo
    );

    clock: process
    begin
        clk <= '0';
        wait for 10 ns;
        clk <= '1';
        wait for 10 ns;
    end process;

    test_proc: process
    begin
        -- 初始化
        we <= '0';
        wait for 40 ns;

        -- 写入24个数据到低位地址
        we <= '1';
        for i in 0 to 23 loop
            a <= std_logic_vector(to_unsigned(i, a'length));
            d <= std_logic_vector(to_unsigned(i, d'length)); -- 写入数据i
            wait for 20 ns;
        end loop;
        we <= '0'; -- 确保写完后禁用写使能

        -- 写入冲突数据
        we <= '1';
        a <= (others => '0'); -- 选择一个低位地址进行写入
        d <= "1111111111111111111111111"; -- 写入新的数据
        wait for 20 ns;
        we <= '0'; -- 禁用写使能

        -- 验证数据是否正确存储在低位
        qdpo_ce <= '1';
        for i in 0 to 23 loop
            dpra <= std_logic_vector(to_unsigned(i, dpra'length));
            wait for 20 ns;
            if i = 0 then
                assert qdpo = "1111111111111111111111111"
                report "测试失败:地址0处读出的数据不正确,存在冲突"
                severity error;
            else
                assert qdpo = std_logic_vector(to_unsigned(i, qdpo'length))
                report "测试失败:地址 " & integer'image(i) & " 处读出的数据不正确"    
                severity error;
            end if;
        end loop;

        -- 验证数据是否正确移位到高位
        for i in 0 to 11 loop
            dpra <= std_logic_vector(to_unsigned(23 - i, dpra'length));
            wait for 20 ns;
            assert qdpo = std_logic_vector(to_unsigned(23 - i, qdpo'length))
            report "测试失败:地址 " & integer'image(23 - i) & " 处读出的数据不正确"
            severity error;
        end loop;

        wait;
    end process test_proc;
end testbench;

功能列表省略

标签:std,dist,自定义,--,IP,sdpram,downto,LOGIC,logic
From: https://blog.csdn.net/weixin_60610210/article/details/142181993

相关文章

  • IP核学习之判断自定义ram与xilinx_sdpram_00reg_64x36IP核的功能是否一致
    xilinx_sdpram_00reg_64x36IP核是一个简单的64个地址,每个地址存36位数据且没有输出寄存器的双端口ram,以下是自定义ram的代码,接口与该IP核的接口设定一致:libraryIEEE;useIEEE.STD_LOGIC_1164.ALL;useIEEE.NUMERIC_STD.ALL;entitysdpram_64x36_testisPort(......
  • codesys将自定义的功能块或者函数保存到本地库
    将通过ST代码实现的自定义功能保存到codesys的本地库,其他project可以直接实现调用。提高灵活性和效率。1、创建库工程 这里可能会提示涉及个别库没有安装或版本更新,根据提示安装对应库或更新即可。2、添加功能块和函数3、编写功能块和函数的参数定义及逻辑实现    ......
  • 【Unity】创建动态的Tooltip
    需求说明文字内容动态变化;根据文字的内容自适应宽高;跟随鼠标移动;可以隐藏和展示;鼠标到达窗口边缘,tooltip停靠边缘可见;成果展示Scene部分查看UI相机和Canvas的设置注意将文字放在最左下角脚本部分TooltipScreenSpaceUI脚本绑定至TooltipScreenSpaceUI物体public......
  • 安全:modsecurity加ip白名单
    一,创建目录和文件,并添加规则1,创建目录和文件[root@blogmodsecurity]#mkdircustom_rules[root@blogmodsecurity]#cdcustom_rules/[root@blogcustom_rules]#viipwhitelist.conf命令的内容:[root@blogcustom_rules]#moreipwhitelist.confSecRuleREMOTE_ADDR"@......
  • Qt自定义插件plugin的开发和调用
    1.需求描述设备管理组件保存了设备信息和通道信息到sqlite数据库,其他组件也想要访问这个数据库中的内容;需要开发一个自定义插件,用于提供接口给其他组件访问数据库; 开发环境vs2015+Qt5.9.62.插件介绍插件主要面向接口编程,通过接口实现功能的扩展,而不需要访问.lib文件。插件在......
  • PbootCMS留言自定义表单怎么调用
    在PBootCMS中,你可以通过自定义表单和标签来实现留言功能。以下是详细的步骤和示例代码,帮助你在全站任意地方使用留言表单和留言记录列表。1.留言提交表单示例代码<formaction="{pboot:msgaction}"method="post">联系人:<inputtype="text"name="contacts"require......
  • Redis之pipeline与事务
    前言    Redis使用的是单reactor网络模型,也就是io多路复用+非阻塞io的异步处理流程(注册事件,在事件循环callback处理事件)。我们可以将每个连接抽象看成一个pipe,哪个pipe中的数据先满就先处理。注意,单reactor指的是acceptor只有一个,而工作线程在6.0版本之前只有一个,也就......
  • 什么是IP地址SSL证书?
    IP地址SSL证书,也被称为IPSSL证书,是一种特殊的SSL证书,它与传统域名验证(DV)证书的主要区别在于验证机制。传统的SSL证书通常通过验证域名来确保安全连接,而IP地址SSL证书则是通过验证公网IP地址来确保安全连接。这种证书用于保护IP地址,并在安装后起到加密作用,确保通过该IP地址进行......
  • 自定义穿梭框封装
      后面有时间再来慢慢搞吧,暂且先这样,有需要的可以把代码考过去继续弄<template><divid="app"><divclass="f-transferflex"><!--left--><divclass="f-left"><divclass="f-topflexflex-jus......
  • 自定义WPF滑块样式-Slider
    在Windows应用程序开发中,滑块(Slider)是一个非常常见且有用的控件。它可以让用户通过拖动滑块来选择一个范围内的值。然而,WPF或UWP应用程序中的默认滑块样式可能并不总是符合我们的设计需求。因此,我们需要自定义滑块的样式。在本文中,我将向你展示如何使用XAML(ExtensibleApplicat......