0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Vivado:ROM和RAM的verilog代码实现

CHANBAEK 来源:FPGA入门到精通 作者:未可知摩尔 2023-05-16 16:57 次阅读

本文主要介绍ROMRAM实现的verilog代码版本,可以借鉴参考下。

一、ROM设计方法

Read-only memory(ROM)使用ROM_STYLE属性选择使用寄存器或块RAM资源来实现ROM,示例代码如下:

//使用块RAM资源实现ROM
module rams_sp_rom_1 (
    input clk, 
    input rd_en, 
    input [5:0] rd_addr, 
    output [19:0] dout
);

(*rom_style = "block" *) reg [19:0] data;

always @(posedge clk) begin
    if (rd_en)
        case(rd_addr)
        6'd0: data <= 20'h0200A; 
        6'd1: data <= 20'h00300;
        6'd2: data <= 20'h08101; 
        ......
        6'd32: data <= 20'h00301; 
        default: data <= 20'h00102;
        endcase
end

assign dout = data;

endmodule

二、RAM设计方式

RAM设计方式有很多,可以用BRAM、LUT、分布式RAM、URAM实现,可以使用RAM_STYLE属性强制规定使用的资料类型。

  • (*ram_style = "block" *)表示用Block RAM实现
  • (*ram_style = "reg" *)表示用寄存器实现
  • (*ram_style = "distributed" *)表示用分布式 RAM实现
  • (*ram_style = "uram" *)表示用uram实现

1、单端口RAM

端口RAM支持3种不同的读写同步模式,解决同时读写同一地址的情况,每一个读、写端口都可以配置为:

  • Write-First模式:新内容载入时可以马上被读取;
  • Read-First模式:新内容载入时,先读取旧的内容;
  • No-Change模式:新内容载入时,不读取该地址的内容(即维持之前的值不变);
// 数据输出可复位的单端块RAM,Read_first
module rams_sp_rf_rst (
    input clk, 
    input en, 
    input we, 
    input rst, 
    input [9:0]addr, 
    input [15:0]di, 
    output reg [15:0]dout
);

reg [15:0] ram [1023:0];

always @(posedge clk)
    if (en) begin //块RAM使能
        if (we) ram[addr] <= di; //写使能
        if (rst) dout <= 0;   //输出复位
        else dout <= ram[addr];
    end

endmodule


// 写优先模式的单端块RAM,Wrist_first
module rams_sp_wf (
    input clk, 
    input en, 
    input we, 
    input [9:0] addr, 
    input [15:0] di, 
    output reg [15:0] dout
);

reg [15:0] ram [1023:0];

always @(posedge clk)
    if (en) begin
        if (we) begin
            RAM[addr] <= di;
            dout <= di;
        end
        else dout <= RAM[addr];
    end

endmodule


// No-Change模式的单端块RAM
module rams_sp_wf (
    input clk, 
    input en, 
    input we, 
    input [9:0] addr, 
    input [15:0] di, 
    output reg [15:0] dout
);

reg [15:0] ram [1023:0];

always @(posedge clk)
    if (en) begin
        if (we) RAM[addr] <= di;
        else dout <= RAM[addr];
    end

endmodule

3、伪双端口RAM

// 单时钟控制,伪双端块RAM
module simple_dual_one_clock (
    input clk,
    input ena,
    input enb,
    input wea,
    input [9:0] addra,
    input [15:0] dia,
    input [9:0] addrb,
    output reg [15:0] dob
);

reg [15:0] ram [1023:0];

always @(posedge clk)  //写
    if (ena) 
        if (wea) ram[addra] <= dia;

always @(posedge clk) 
    if (enb) dob <= ram[addrb];  //读

endmodule


// 双时钟控制,伪双端块RAM
module simple_dual_two_clocks (
    input clk,
    input ena,
    input enb,
    input wea,
    input [9:0] addra,
    input [15:0] dia,
    input [9:0] addrb,
    output reg [15:0] dob
);

reg [15:0] ram [1023:0];

always @(posedge clka)  //写
    if (ena)
        if (wea) ram[addra] <= dia;

always @(posedge clkb)
    if (enb) dob <= ram[addrb];  //读

endmodule

4、真双端口RAM

// 带有两个写端口的双端块RAM
module rams_tdp_rf_rf (
    input clka,
    input clkb,
    input ena,
    input enb,
    input wea,
    input web,
    input [9:0] addra,
    input [9:0] addrb,
    input [15:0] dia,
    input [15:0] dib,
    output reg [15:0] doa,
    output reg [15:0] dob
);

reg [15:0] ram [1023:0];

always @(posedge clka)      //端口1
    if (ena) begin
        if (wea) ram[addra] <= dia;
        doa <= ram[addra];
    end

always @(posedge clkb)      //端口2
    if (enb) begin
        if (web) ram[addrb] <= dib;
        dob <= ram[addrb];
    end

endmodule


// 带有可选输出寄存器的块RAM
module rams_pipeline (
    input clk1, 
    input clk2, 
    input we, 
    input en1, 
    input en2, 
    input [9:0] addr1, 
    input [9:0] addr2, 
    input [15:0] di, 
    output reg [15:0] res1, 
    output reg [15:0] res2
);

reg [15:0] RAM [1023:0];
reg [15:0] do1;
reg [15:0] do2;

always @(posedge clk1) begin  //端口1可读可写
    if (we == 1'b1) RAM[addr1] <= di;
    do1 <= RAM[addr1];
end

always @(posedge clk2)      //端口2只用于读
    do2 <= RAM[addr2];

always @(posedge clk1)
    if (en1 == 1'b1) res1 <= do1;

always @(posedge clk2)
    if (en2 == 1'b1) res2 <= do2;

endmodule

5、初始化RAM内容

初始化RAM可以在HDL源代码中进行,也可以利用外部数据文件设置。

//Verilog初始化为一个值
reg [DATA_WIDTH-1:0] ram [DEPTH-1:0];
integer i;
initial for (i=0; i < DEPTH; i=i+1) ram[i] = 0;

//读取二进制形式存储文件
reg [31:0] ram [0:3];
initial begin
    $readmemb("ram.data", ram, 0, 3);
end

//读取16进制形式存储文件
reg [31:0] ram [0:3];
initial begin
    $readmemh("ram.data", ram, 0, 3);
end

三、总结

本文介绍了如何使用Verilog HDL实现ROM和RAM,以及一些常见的设计方法和示例代码。对于不同类型的存储器,我们介绍了不同的实现方式,包括分布式RAM、单端口RAM和伪双端口RAM等。在任何情况下,都要格外注意存储器的读写一致性和正确性,确保系统的稳定性和正确性。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ROM
    ROM
    +关注

    关注

    4

    文章

    525

    浏览量

    84824
  • RAM
    RAM
    +关注

    关注

    7

    文章

    1322

    浏览量

    113708
  • Verilog
    +关注

    关注

    28

    文章

    1327

    浏览量

    109311
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66807
  • Vivado
    +关注

    关注

    18

    文章

    790

    浏览量

    65107
收藏 人收藏

    评论

    相关推荐

    RAMROM、FLASH 有什么不同?

    存放指令代码和一些固定数值,程序运行后不可改动;RAM用于程序运行中数据的随机存取,掉电后数据消失..code就是指将数据定义在ROM区域,具只读属性,例如一些LED显示的表头数据就可以定义成code
    发表于 10-19 10:48

    micrlaze RAM/ROM分配问题

    如果您正在使用微型光纤处理器并编译软件代码并且整个图像适合FPGA RAM ...则成为ROM。这是否意味着您每次要进行软件更改时都必须重新编译FPGA并获取新的.bit文件?有更简单的方法吗?此外
    发表于 05-20 06:37

    Vivado的多种RAM编写方式

    过多介绍。下面给出几个各种实现方式的Verilog示例代码。分布式RAM下面给出一个异步读模式的双口分布式RAM的示例:module ram
    发表于 09-29 09:40

    Vivado中进行HDL代码设计

    代码中初始化RAM组件更容易;支持package;自定义类型;枚举类型;没有reg和wire之间的混淆。Verilog语言的优势有:与C语言类似的语法;代码结构更紧凑;支持块注释(老
    发表于 09-29 10:08

    Vivado Synthesis中如何为Verilog代码中的“include file”设置路径?

    Verilog代码开发时,我们可以把经常会用到的公共变量和参数,单独放在一个cfg.v文件中,然后在别的文件中include这个文件,这样便于代码的组织管理,可以使得代码结构更加清晰
    发表于 11-10 14:49 9164次阅读

    ROMRAM、DRAM、SRAM和FLASH的区别

    常见存储器概念辨析:RAM、SRAM、SDRAM、ROM、EPROM、EEPROM、Flash存储器可以分为很多种类,其中根据掉电数据是否丢失可以分为RAM(随机存取存储器)和ROM
    发表于 12-04 14:23 1927次阅读

    ramrom的区别之处

    存储器是数字系统中用以存储大量信息的设备或部件,是计算机和数字设备中的重要组成部分。存储器可分为随机存取存储器(ram)和只读存储器(rom)两大类。要说它俩有什么区别,下面就由英尚微电子为大家解惑
    发表于 05-10 10:28 2897次阅读

    关于ROMRAM有哪些常见问题

    关于ROMRAM的常见问题分析。
    的头像 发表于 11-19 15:51 2453次阅读

    采用IEEE745格式的浮点+ROM RAM的方式成功实现FFT的设计

    采用IEEE745格式的浮点+ROM RAM的方式成功实现FFT的设计(嵌入式开发要学什么知乎)-采用IEEE745格式的浮点+ROM RAM
    发表于 07-30 16:21 9次下载
    采用IEEE745格式的浮点+<b class='flag-5'>ROM</b> <b class='flag-5'>RAM</b>的方式成功<b class='flag-5'>实现</b>FFT的设计

    浅谈单片机romram代码的关系,以及为什么要加上拉电阻

    ROM,RAM以及code,dataram掉电丢失rom掉电不丢失因为单片机RAM很有限,所以将不变的保存到ROM中CODE关键字的作用就是
    发表于 11-25 18:36 8次下载
    浅谈单片机<b class='flag-5'>rom</b>和<b class='flag-5'>ram</b>与<b class='flag-5'>代码</b>的关系,以及为什么要加上拉电阻

    一个单片机软件需要多少ROMRAM

    :Total ROM size: 即所需实际ROM最小值,包括代码code, 只读数据RO Data,还需包括初始化的读写数据,因为断电后这部分数据需存储于ROM中,上电后装载到
    发表于 12-20 19:14 0次下载
    一个单片机软件需要多少<b class='flag-5'>ROM</b>和<b class='flag-5'>RAM</b>

    stm32出现ramrom不够用,调试方法

    手里有一块stm32f103r8ct的板子,想移植ucosii+lwip,使用原子mini的源代码提示ramrom不够用,一直很纠结,感觉应该是malloc的问题,但又不知道怎么改
    发表于 12-20 19:15 3次下载
    stm32出现<b class='flag-5'>ram</b>、<b class='flag-5'>rom</b>不够用,调试方法

    手机上的ROMRAM技术原理

    ROMRAM的区别是什么?ROMRAM都是一种存储技术,只是两者原理不同,RAM为随机存储,掉电不会保存数据,而
    的头像 发表于 03-30 14:53 2026次阅读

    单片机中的RAM vs ROM

    单片机中的RAM vs ROM
    的头像 发表于 09-28 17:57 698次阅读

    巧言单片机RAMROM

    巧言单片机RAMROM
    的头像 发表于 10-17 15:45 497次阅读