FPGA-学会使用vivado中的存储器资源RAM(IP核)

问题

信号源(例如ADC)以1us一个的速率产生12位的数据现要求获得连续1ms内的数据,通过串口以115200的波特率发到电脑。

分析

· 数据量是1000个

· 数据速率不匹配

· 数据内容未知

· 数据总数据量有限

· 数据的使用速度低于数据的产生速度

· 数据生产和消耗的位宽

· 数据量相对较大,数据要求能够重复使用,而且要求能够被更改

RAM:随机存储器(随机获取的存储器,可读可写的存储器)--random access memory

它可以随时把数据写入到任何一指定地址的存储单元。也可以随时从任一指定地址读出数据,其读写速度有时钟频率决定,主要用来存放程序以及程序执行过程中产生的数据,运算结果等

rom的预先存储  ram的实时写入

接下来 我们在Vivado中如何实现RAM IP核。

创建工程,进入Vivado界面

创建RAM IP 核

设置端口A(port A)

设置端口B(port B)

然后编写RAM测试文件

代码如下

`timescale 1ns / 1ps
module ram_test_tb;
    reg clka;
    reg ena;
    reg wea;
    reg [15:0]addra;
    reg [15:0]dina;
    reg clkb;
    reg enb;
    reg [15:0]addrb;
    wire [15:0]doutb;
    ram ram (
      .clka(clka),    // input wire clka
      .ena(ena),      // input wire ena
      .wea(wea),      // input wire [0 : 0] wea
      .addra(addra),  // input wire [15 : 0] addra
      .dina(dina),    // input wire [15 : 0] dina
      .clkb(clkb),    // input wire clkb
      .enb(enb),      // input wire enb
      .addrb(addrb),  // input wire [15 : 0] addrb
      .doutb(doutb)  // output wire [15 : 0] doutb
    );
    
    initial clka = 1; always #10 clka = ~clka;
    initial clkb = 1; always #15 clkb = ~clkb;
    
    initial begin
       ena = 0;
       wea = 0;
       addra = 0;
       dina = 0;
       addrb = 0;
       enb = 0;
       //写入写满
       #201;
       repeat(65536) begin
        ena = 1;
        wea = 1;
        #20;
        addra = addra + 1;
        dina = dina + 1;
       end 
       ena = 0;
       wea = 0;
       #20000;
       //读出;
       addrb = 65535;
       #300;
       repeat(65536)begin
        enb = 1;
        #30;
        addrb = addrb - 1;
       end
       #2000;
       $stop;
    end
    
endmodule

仿真波形

写入数据时波形

读出数据时波形(读使能到数据输出2个时钟周期)

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
异步RAM是一种基本的RAM类型,它的读写时序与时钟信号无关。在FPGA设计,通常使用异步RAM来实现数据的速率同步。下面是使用Vivado的异步RAM IP核来实现数据的速率同步的步骤和Verilog代码。 步骤: 1. 打开Vivado,创建新工程,并在工程添加一个新的RTL模块。 2. 在工程面板右键单击设计文件,并选择“Add Sources”。 3. 在“Add Sources”对话框选择“IP Catalog”选项卡,然后在搜索框输入“Block Memory Generator”以查找异步RAM IP。 4. 选择所需的异步RAM IP核并单击“Create”按钮将其添加到工程。 5. 配置异步RAM IP核的参数,如数据位宽、地址位宽、深度等。 6. 在RTL模块实例化异步RAM IP核,并将其连接到需要进行速率同步的信号上。 Verilog代码: 以下是一个使用异步RAM IP核实现数据速率同步的简单Verilog代码示例。假设我们有两个时钟域CLK1和CLK2,CLK1的频率为100MHz,CLK2的频率为50MHz,需要将一个16位数据从CLK1域传输到CLK2域。 ``` module async_ram_sync ( input wire clk1, // 100MHz时钟域 input wire clk2, // 50MHz时钟域 input wire rst, // 同步复位信号 input wire [15:0] din, // 输入数据 output reg [15:0] dout // 输出数据 ); // 实例化异步RAM IP核 async_ram #( .ADDR_WIDTH(8), // 地址位宽 .DATA_WIDTH(16), // 数据位宽 .DEPTH(256), // 深度 .MEMORY_TYPE("RAM"), // 存储器类型 .READ_LATENCY(1) // 读延迟 ) ram_inst ( .clk(clk1), // 时钟信号 .addr(din[7:0]), // RAM地址 .dout(dout), // 读出数据 .din(din), // 写入数据 .we(1'b1), // 写使能信号 .re(1'b0) // 读使能信号 ); reg [7:0] addr; always @(posedge clk2) begin if (rst) begin addr <= 8'h00; dout <= 16'h0000; end else begin addr <= addr + 1; dout <= ram_inst.dout; ram_inst.addr <= addr; ram_inst.we <= 0; ram_inst.re <= 1; end end endmodule ``` 在上述代码,我们实例化了一个异步RAM IP核,并将其时钟连接到CLK1时钟域。我们还使用一个计数器addr来生成RAM地址,并在CLK2时钟域读取异步RAM的数据。我们将异步RAM的读使能信号设置为1,并将其写使能信号设置为0,以确保数据不被写入RAM。在同步复位信号rst为高时,我们将计数器addr和输出数据dout重置为0。这个模块将数据从CLK1域同步到CLK2域,并且数据的速率会被降低到CLK2时钟域的速率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值