verilog 二维的memory数据存储和读取

这篇具有很好参考价值的文章主要介绍了verilog 二维的memory数据存储和读取。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        在做有关矩阵运算时,需要我们将数据保存为二维数据的形式,如下

reg   [width:0]   mem [depth1:0] [depth2:0];

        这里的二维是对标matlab中的数据保存习惯,因为matlab中二维数组中的每个元素并不需要考虑位宽的问题,但是在verilog中需要考虑这一点。

        下面为将2048个数据保存为128*16的数据的例程,程序中memory定义的是128*128的大小,并不影响保存128*16的数据,程序分为数据存储和读取两部分,读取的部分在testbench中给出的激励是   读取第二行的128个数据。

        该行的数据,前两个为'hfaed18c8、'h07df180a     后两个数据为'hea71f2c2、'h07dfe7f5

`timescale 1ns / 1ps
//该模块实现多符号数据存储  并将每个符号读取进去FFT模块进行调制
module data_in_memory #(
    parameter NC_NUMBER              =    128,             //子载波数量
    parameter NS_NUMBER              =    128,              //符号数量
    parameter DATA_IMAGANDREAL_WIDTH =    32                //实数和虚数的总体位宽
)
(
    input sys_clk,
    input rst_n,
    //write
    input data_in_valid,                          //因为输入的特殊性,写使能信号一直有效 
                                                  //1024*128个长周期
    input [DATA_IMAGANDREAL_WIDTH-1:0] data_in,
    
    //read
    input        read_en,   //fft输出的valid信号    需要等到fft运算结束之后给出读使能信号
    input [$clog2(NC_NUMBER)-1:0] addr,            //读数据地址 fft输出的user信号
    input [$clog2(NC_NUMBER)-1:0] Ns_or_Nc_count,  //Ns_or_Nc_count 计数模块的输出
    
    output reg data_out_valid,                         //读出的数据有效标记
    output reg [DATA_IMAGANDREAL_WIDTH-1:0] data_out   //读出的数据
);

reg [$clog2(NS_NUMBER)-1:0] count_sys;                  //这是ram的地址索引和符号计数和子载 
                                                        //波计数有关联
reg [$clog2(NC_NUMBER)-1:0] count_carr;                 //子载波计数


//写入数据
//三维寄存器复位
reg [DATA_IMAGANDREAL_WIDTH-1:0] mem [NC_NUMBER-1:0][NS_NUMBER-1:0]; //二维还是三维??
integer i;                                           //子载波计数
integer j;                                           //符号计数
always@(posedge sys_clk or negedge rst_n) begin
    if(!rst_n) begin
        for (i=0;i<NC_NUMBER;i=i+1) begin            //赋初值
            for (j=0;j<NS_NUMBER;j=j+1) begin
                mem[i][j]<='d0;
            end
        end
    end
    else if(data_in_valid) begin
        mem[count_carr][count_sys]<=data_in;         //将每个接收数据存储
    end
end
//子载波计数count_carr
always@(posedge sys_clk or negedge rst_n) begin
    if(!rst_n)
        count_carr<='d0;
    else if(data_in_valid)
        count_carr<=count_carr+1'b1;              //子载波一直计数
    else
        count_carr<='d0;
end
//count_sys 符号计数
always@(posedge sys_clk or negedge rst_n) begin
    if(!rst_n)
        count_sys<='d0;
    else if(count_carr==NC_NUMBER-1)
        count_sys<=count_sys+1'b1;
    else if(!data_in_valid)                           
        count_sys<='d0;
    else
        count_sys<=count_sys;                  //子载波计数期间一直保存符号数的计数值 
end
///读出数据
always@(posedge sys_clk or negedge rst_n) begin
    if(!rst_n) begin
        data_out_valid<='d0;
        data_out<='d0;
    end
    else if(read_en) begin
        data_out_valid<=1'b1;
        data_out<=mem[addr][Ns_or_Nc_count];
    end
    else begin
        data_out_valid<='d0;
        data_out<='d0;
    end
end
endmodule

testbench

`timescale 1ns / 1ps
module test_data_in_memory();

parameter NC_NUMBER=128;
parameter NS_NUMBER=128;
parameter DATA_IMAGANDREAL_WIDTH=32;

reg sys_clk;
reg rst_n;

reg data_in_valid;
reg [31:0] data_in;

reg read_en;
reg [9:0] addr;
reg [9:0] Ns_or_Nc_count;

wire data_out_valid;
wire [31:0] data_out;

reg [31:0] echo_mem [2047:0];
initial begin
sys_clk='d0;
rst_n='d0;
$readmemb("D:/FPGA_one/rad_1024_128_Ranging_and_speed_v1/ranging_speed_echo.txt",echo_mem);
//这里的.txt文件保存了128*128长度的数据,为方便你测试,可以在matlab中生成,关于该文件的生成
//我将在后续中写出
#1000;
rst_n='b1;


#400000;
$stop;
end

always #10 sys_clk=~sys_clk;

data_in_memory #(
    .NC_NUMBER(NC_NUMBER),
    .NS_NUMBER(NS_NUMBER),
    .DATA_IMAGANDREAL_WIDTH(DATA_IMAGANDREAL_WIDTH)
)
u0 (
    .sys_clk(sys_clk),
    .rst_n(rst_n),
    
    .data_in_valid(data_in_valid),
    .data_in(data_in),
    
    .read_en(read_en),
    .addr(addr),
    .Ns_or_Nc_count(Ns_or_Nc_count),
    
    .data_out_valid(data_out_valid),
    .data_out(data_out)
);
reg [12:0] count;           //2^13 128*128
always@(posedge sys_clk or negedge rst_n) begin
    if(!rst_n)
        count<='d0;
    else if(count>='d2048)
        count<='dz;
    else
        count<=count+1'b1;
end
//valid
always@(posedge sys_clk or negedge rst_n) begin
    if(!rst_n) begin
        data_in<='d0;
        data_in_valid<='d0;
    end
    else if(count<=2047) begin
        data_in<=echo_mem[count]; //当前的count为0,但是输出数据与count=1对齐,需要注意,可 
                                  //通过将count打一拍来将count=0对齐输出数据
        data_in_valid<='d1;
    end
    else if(count==2048) begin     //因为只是测试,只取前16个128数据串即可
        data_in<=echo_mem[count];
        data_in_valid<='d0;
    end
    else begin
        data_in_valid<=data_in_valid;   //数据有效位,其实理解为数据使能也可以
        data_in<='d0;
    end
end
//read_en   Ns_or_Nc_count  addr
always@(posedge sys_clk or negedge rst_n) begin
    if(!rst_n) begin
        read_en<='d0;
        Ns_or_Nc_count<='d0;
        addr<='d0;
    end
    else if(count=='d255) begin  //取第二行的128个数据  在255计数处取值,输出数据在256处对齐
        read_en<='d1;
        Ns_or_Nc_count<='d1;     //0为第一行,1为第二行
        addr<=count-'d255;
    end
    else if(count=='d383) begin
        read_en<='d0;
        Ns_or_Nc_count<='d0;
        addr<='d0;
    end
    else begin
        read_en<=read_en;
        Ns_or_Nc_count<=Ns_or_Nc_count;
        addr<=addr+1'b1;
    end
end

endmodule

仿真结果如下:

接收数据存储到缓存verilog,fpga开发,matlab,开发语言

         验证数据存入对不对,查看读取的数据对不对即可,于是放大读取的数据,查看前两个数据和后两个数据,data_out为输出数据:

接收数据存储到缓存verilog,fpga开发,matlab,开发语言

接收数据存储到缓存verilog,fpga开发,matlab,开发语言

         读取出的数据是正确的。

 文章来源地址https://www.toymoban.com/news/detail-606355.html

到了这里,关于verilog 二维的memory数据存储和读取的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Verilog实现FPGA可编程电路中的RAM存储器

    Verilog实现FPGA可编程电路中的RAM存储器 在FPGA可编程电路的设计中,RAM存储器通常被广泛使用。而手写RAM存储器则可以提供更加灵活、高效的设计方案。本文将介绍如何使用Verilog语言来手写FPGA中的RAM存储器。 首先,我们需要确定RAM存储器的大小和宽度。假设我们需要实现一个

    2024年02月04日
    浏览(40)
  • 【【IIC模块Verilog实现---用IIC协议从FPGA端读取E2PROM】】

    下面是 design 设计 下面是testbench 下面是注意事项 因为时钟的不同 我们先设计出本次时钟所需要的dri_clk 在配置完dri_clk 之后 我们需要做的是对整个I2C结构 进行状态机的 书写 建议 写成经典的三段状态机的形式 同步时序描述状态转移 组合逻辑判断状态转移条件 时序电路描述

    2024年02月03日
    浏览(45)
  • MEMORY存储引擎:MEMORY存储引擎是一个新的存储引擎,它的特点是数据全部存放在内存中,速度快,但是安全

    作者:禅与计算机程序设计艺术 MEMORY(Memory Oriented Database)存储引擎,中文名“内存式数据库”,是一种新型的存储引擎,其设计目标是能够在内存中快速访问和处理海量数据。该存储引擎是基于键值对存储的,其中值可以是任意类型的数据,包括字符串、整数、浮点数等。

    2024年02月04日
    浏览(34)
  • 基于verilog的CNN搭建缓存图片数据浅析

    在编写基于verilog的的卷积神经网络实现时,需要定义一个滑窗,并与对应位置的图像像素值相乘再相加,实现单点的卷积运算,具体的操作如图1所示。 图1 卷积的实现过程 我们采用FPGA的RAM的进行图片(假设图片为5×5,滤波器的大小为3×3)数据缓存,由于图像的数据是按行

    2023年04月08日
    浏览(18)
  • java_web接收前端传的excel文件读取数据

    #本次做一个将患者数据导入到某个模块的功能,前期集成的代码时不时出现异常,本次进行修改记录 前端代码

    2024年02月04日
    浏览(41)
  • FPGA接收串口数据并通过LCD1602显示

    一、前言 在学习《FPGA设计与Verilog HDL实现》第九章内容Verilog驱动常用I/O外设时,书中有一个驱动LCD1602的例程,但其是通过状态机显示固定的几个字符。本着动手实践的原则,决定利用手头的硬件实现FPGA接收串口数据并在LCD1602上显示,下面记录项目开始的过程。因为刚接触

    2024年02月06日
    浏览(33)
  • FPGA_数码管显示UART串口接收的数据

          实验目标 :通过电脑调试助手向FPGA的UART串口接收模块发送数据,然后数据可以稳定显示 在数码管上。       实验目的 : 练习UART串口模块和数码管的使用。之前已经有文章详细讲解了串口和数码管的开发,故这里直接提供设计思路供大家参考。 (串口文章链接)ht

    2024年02月13日
    浏览(40)
  • FPGA串口接收解帧、并逐帧发送有效数据-2

    工程实现的功能:FPGA串口接收到串口调试助手发来的数据,将其数据解帧。判断到正确的帧头和帧尾之后,将有效数据存入rx_data中;另一方面发送端将有效数据逐帧发送出去。 参考:正点原子官方FPGA串口通信实验 模块构成: 在原子哥的基础上改的代码。 添加了接收状态机

    2024年02月05日
    浏览(27)
  • FPGA串口接收解帧、并逐帧发送有效数据——1

    工程实现的功能:FPGA串口接收到串口调试助手发来的数据,将其数据解帧。判断到正确的帧头和帧尾之后,将有效数据存入rx_data中;另一方面发送端将有效数据逐帧发送出去。 参考:正点原子官方FPGA串口通信实验 模块构成: 在原子哥的基础上改的代码。 添加了接收状态机

    2024年02月05日
    浏览(30)
  • 【FPGA学习记录3-1】Verilog语法之Verilog的数据类型

    写在前面 本科时学过FPGA的相关课程,因此对于Verilog相关语法的学习重在回顾。 1.Verilog的数据类型 Verilog 最常用的 2 种数据类型就是 线(wire)与寄存器(reg) ,其余类型可以理解为这两种数据类型的扩展或辅助。 1.1wire类型 wire 类型表示硬件单元之间的物理连线,由其连接

    2024年02月02日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包