Vivado -RAM

ip_ram

定义了一个名为ip_ram的模块,该模块具有以下端口:

sys_clk:系统时钟输入。

sys_rst_n:系统复位输入。

cpp 复制代码
module ip_ram(
input sys_clk,
input sys_rst_n
    );

wire       ram_en                    ;
wire       ram_wea                   ;
wire [4:0] ram_addr                  ;
wire [7:0] ram_wr_data               ;
wire [7:0] ram_rd_data               ;

ram_rw模块包含了RAM的读写逻辑,其输入输出信号如下:

clk:时钟输入。

rst:复位输入。

ram_en:RAM使能信号。

ram_wea:RAM写使能信号。

ram_addr:RAM地址信号。

ram_wr_data:RAM写入数据信号。

ram_rd_data:RAM读出数据信号。

cpp 复制代码
ram_rw ram_rw_u(
.clk        (sys_clk),
.rst        (sys_rst_n),                
.ram_en     (ram_en),    
.ram_wea    (ram_wea),   
.ram_addr   (ram_addr),  
.ram_wr_data(ram_wr_data),
.ram_rd_data(ram_rd_data)
);

blk_mem_gen_0模块则是一个具有标准接口的内存生成器模块,其端口包括:

clka:时钟输入。

ena:内存使能信号。

wea:内存写使能信号。

addra:内存地址信号。

dina:写入内存的数据信号。

douta:从内存读出的数据信号。

cpp 复制代码
blk_mem_gen_0 your_instance_name (
  .clka(sys_clk),    // input wire clka
  .ena(ram_en),      // input wire ena
  .wea(ram_wea),      // input wire [0 : 0] wea
  .addra(ram_addr),  // input wire [4 : 0] addra
  .dina(ram_wr_data),    // input wire [7 : 0] dina
  .douta(ram_rd_data)  // output wire [7 : 0] douta
); 

ram_rw

下面Verilog代码定义了一个名为ram_rw的模块,实现了RAM的读写控制逻辑。该模块具有以下端口:

clk:时钟输入。

rst:复位输入。

ram_en:RAM使能输出。

ram_wea:RAM写使能输出。

ram_addr:RAM地址输出。

ram_wr_data:RAM写入数据输出。

ram_rd_data:RAM读出数据输入。

ram_wea信号在rw_cnt小于或等于31且ram_en为高电平时置为逻辑1,表示RAM写入使能。否则,置为逻辑0。

ram_en信号直接由复位信号控制,在复位信号为高电平时为逻辑0,表示RAM未使能。这意味着RAM在复位时处于禁用状态。

ram_wr_data是一个8位寄存器,用于存储RAM的写入数据。在每个时钟周期的上升沿或复位信号的下降沿触发时递增。当复位信号为低电平时,将ram_wr_data清零;当ram_wr_data小于或等于31时,递增;否则,将其清零。

ram_addr是一个5位寄存器,用于存储RAM的地址。其工作原理与ram_wr_data寄存器相似。

cpp 复制代码
module ram_rw(
input               clk,
input               rst,

output              ram_en,
output              ram_wea,
output reg[4:0]     ram_addr,
output reg[7:0]     ram_wr_data,

input [7:0]         ram_rd_data
    );

rw_cnt是一个6位寄存器,用于计数器功能。它在每个时钟周期上升沿或复位信号的下降沿触发时递增。当复位信号为低电平时,rw_cnt被清零。当rw_cnt达到63时,它会被重置为0。

cpp 复制代码
reg [5:0] rw_cnt;  

这两行assign语句的功能是将RAM的写使能信号ram_wea和RAM的使能信号ram_en赋值。

  1. ram_wea的赋值逻辑为:如果rw_cnt小于或等于31(即计数器rw_cnt的值在0到31之间),并且RAM使能信号ram_en为高电平(1),则ram_wea被赋值为1(逻辑真);否则,被赋值为0(逻辑假)。这意味着只有在RAM使能且计数器值小于等于31时,才会使RAM的写入操作有效。

  2. ram_en的赋值逻辑为:直接将ram_en赋值为复位信号rst。当复位信号为高电平时,RAM使能信号也被置为高电平,即RAM被使能;当复位信号为低电平时,RAM使能信号被置为低电平,即RAM被禁用。

这两行assign语句定义了RAM使能信号和RAM写使能信号的逻辑,使得RAM的写入操作在特定条件下有效,并且可以通过复位信号控制整个RAM的使能状态。

cpp 复制代码
assign ram_wea=(rw_cnt<=31&&ram_en)?1'b1:1'b0;
assign ram_en=rst;

模块内部逻辑包括三个always块:

第一个always块用于递增计数器rw_cnt,在时钟上升沿或复位信号下降沿触发。当复位信号为低电平时,计数器被清零;当计数器值达到63时,也将其清零;否则,计数器递增1。

cpp 复制代码
always@(posedge clk or negedge rst) begin
    if(!rst)
        rw_cnt<=1'b0;
    else if(rw_cnt==6'd63)
        rw_cnt<=1'b0;
    else
        rw_cnt<=rw_cnt+1'b1;
    end

第二个always块用于生成RAM写入数据信号ram_wr_data。当复位信号为低电平时,将写入数据清零;当写入数据小于或等于31时,递增写入数据;否则,将其清零。

cpp 复制代码
   
always@(posedge clk or negedge rst) begin 
    if(!rst)
        ram_wr_data<=0;
    else if(ram_wr_data<=6'd31)
        ram_wr_data<=ram_wr_data+1'b1;
    else
        ram_wr_data<=0;
    end

第三个always块用于生成RAM地址信号ram_addr。其逻辑与第二个always块类似,但递增的是RAM地址。

cpp 复制代码
always@(posedge clk or negedge rst) begin 
    if(!rst)
        ram_addr<=0;
    else if(ram_addr<=6'd31)
        ram_addr<=ram_addr+1'b1;
    else
        ram_addr<=0;
    end

此外,模块中还包含了一个名为ila_0的实例,ILA(Integrated Logic Analyzer)用于调试,以便在FPGA中观察信号的值

相关推荐
浩子智控6 小时前
电子设备DevOps
fpga开发
cycf18 小时前
CRC校验
fpga开发
landyjzlai19 小时前
AMBA总线(15)关于AXI-stream(sg模式)
arm开发·fpga开发·amba
白狐_79819 小时前
Quartus Prime 新手完全使用指南
fpga开发
Aaron15881 天前
三种主流接收机架构(超外差、零中频、射频直采)对比及发展趋势浅析
c语言·人工智能·算法·fpga开发·架构·硬件架构·信号处理
博览鸿蒙1 天前
一颗数字系统是如何在 FPGA 上“跑起来”的?
fpga开发
雨洛lhw1 天前
FPGA JTAG接口设计全解析
fpga开发·jtag
minglie12 天前
iverilog 配合 Makefile 搭建 Verilog 仿真工程
fpga开发
芒果树技术2 天前
MangoTree案例分享:基于AtomRIO FPGA平台,客户实现自适应主动减振
测试工具·fpga开发·模块测试
雨洛lhw2 天前
按键电路设计的细节
fpga开发