ISE14.7 True Dual-port RAM 仿真学习

正文

学习使用Xilinx FPGA的双端口RAM,其框图如图所示。
在这里插入图片描述

IP核的配置

BRAM的配置按照寻求配置即可,唯一需要注意的地方就是输出寄存器的配置,这里,A端口都不选择,B端口都选择,对比查看两者的区别。

在这里插入图片描述

整体信息如下图所示

  • A端口具有使能信号,输入数据位宽为8位
  • B端口一直有使能信号,数据位宽为16位
  • A端口的读取Latency为1个时钟,B端口的读取Latency为3个时钟,原因在于B端口多了两个输出寄存器。

在这里插入图片描述

仿真验证

仿真需要验证一下几个问题:

  1. 读写时序如何
  2. 使能对读写的影响
  3. 不同位宽之间如何转换

数据写入

其写入时序可参考数据手册

在这里插入图片描述

写入ram的数据来源于提前生成的txt文件,先将该文件读取到一个内存中,在将其写入BRAM

integer index;

reg [7:0] data_in_int[0:511];


initial begin
    index = 0;
    $readmemh("../verilog/sim/data_in.txt",data_in_int);
    $stop;
end

读写RAM通过一个task完成

task wr_memory;
    input [8:0] start_addr;//写起始地址
    input [8:0] len;//写数据长度
    input wr_en;//1-->write,0-->read
    input [8:0] en_nclk;//N*clk
begin
    //a 端口 使能
    ena = 1; 
    for(index=start_addr;index<(len + start_addr) ;index=index+1'b1)begin
        if(index-start_addr > en_nclk)
            ena = 0;

        @(posedge clka);

        addra = index;
        wea   = wr_en;
        if(wr_en == 1)
            dina  = data_in_int[index][7:0];
        else
            dina = 8'hff;
    end
    @(posedge clka);
    wea = 0;
end
endtask
   //从0地址开始写16个字节数据,使能持续16个clk,虽然使能持续17个,但是数据长度只有16个
   wr_memory(0,16,1,17);

写入16个字节完成后,通过modesim仿真,可查看写入内存的数据,和txt中的数据完全一致

在这里插入图片描述

读取数据

读取数据和写入数据一样,只是将写使能信号wea拉低即可。

//从8地址开始读4个字节数据
wr_memory(8,4,0,4);

读取数据仿真如下图所示,可以看到,在给出地址时,数据并非立马出现,而是相对于地址晚了一个时钟,这便是读取Latency,这里A端口为1个CLK。

在这里插入图片描述

使能信号

再看一下使能信号对写入数据的影响

wr_memory(16,8,1,4);
#(PERIOD*10);
wr_memory(2,4,0,2);

仿真中,向16地址写入8个字节数据,其中,使能信号持续8个时钟,写使能信号持续4个时钟。

可以看到,从地址16(0x10)开始,只写入了四个数据。

在这里插入图片描述

读取时序如下图所示,使能信号持续2个时钟。

可以看到,两个时钟后,使能为低,地址改变,数据也不会变化

在这里插入图片描述

对于使能信号,数据手册中这么解释。

在这里插入图片描述

也就是说,使能的优先级最高,如果没给使能信号,那么读、写、复位都将不会生效。

位宽转换

  • 本仿真中,A端口数据位宽为8位,B端口位宽为16位,那么8位到16位的字节序是怎样转换的?

需要注意一点的是,对于A端口来说,其写入20个数据,相应的地址从0~19

但是对于B端口来说,其位宽是A的两倍,因此对B来说,只有10个数据,那么其地址范围为0~9

这也是为什么B端口的地址位宽比A少一位的原因。

task random_read_b;
    input   [8:0]   start_addr;
    input   [8:0]   end_addr;
    input   [8:0]   rcnt;

    for(index = 0;index < rcnt ; index = index + 1'b1) begin
        @(posedge clkb);
        addrb = {$random} % (end_addr - start_addr);
    end

endtask
   //一共写入20个字节数据,换算成16位只有10个
    random_read_b(0,9,4);

仿真中,随机变换B端口地址,从时序中可以得到以下信息:

  1. 读取数据相对于地址延迟3个CLK,符合IP核中的Latency为3个时钟。

  2. 读取数据时,低字节在低地址,高字节在高地址,典型的小端模式。

  3. B端口的地址,可以等效为 A端口地址右移一位。以仿真为例,B端口读取地址为0x08,其对于数据为A端口的0x10的数据。

    具体关系如下伪代码:

    wire [7:0] addra;
    wire [6:0] addrb;
    
    addra = addrb << 1;
    addrb = addra >>1;
    
    //或者
    addra = {addrb[6:0],1'b0};
    addrb = addra[7:1];
    

在这里插入图片描述

关于地址映射关系,在手册中也有体现。

总结一句话就是,低字节在低地址。

在这里插入图片描述

附录

软件版本

modelsim 使用10.4版本。

ISE为14.7版本。

在这里插入图片描述

参考资料

PG058 - LogiCORE IP Block Memory Generator

仿真代码

module tb_dpram;

// mem Parameters
parameter PERIOD  = 10;


// mem Inputs
reg             clka                        = 0 ;
reg             ena                         = 0 ;
reg   [0 : 0]   wea                         = 0 ;
reg   [11 : 0]  addra                       = 0 ;
reg   [7 : 0]   dina                        = 0 ;
reg   			clkb                        = 0 ;
reg   [0 : 0]   web                         = 0 ;
reg   [10 : 0]  addrb                       = 0 ;
reg   [15 : 0]  dinb                        = 0 ;

// mem Outputs
wire  [7 : 0]   douta                           ;
wire  [15 : 0]  doutb                           ;


reg             rst_n                       = 0 ;

initial
begin
    forever #(PERIOD)  clka=~clka;
end

initial
begin
    #(PERIOD/2);
    forever #(PERIOD/2)  clkb=~clkb;
end

initial
begin
    #(PERIOD*20) rst_n  =  1;
end

//a port write adn read
//b port only read
mem  u_mem (
    .clka                    ( clka            ),
    .ena                     ( ena             ),
    .wea                     ( wea    [0 : 0]  ),
    .addra                   ( addra  [11 : 0] ),
    .dina                    ( dina   [7 : 0]  ),
    .clkb                    ( clkb            ),
    .web                     ( 'b0             ),
    .addrb                   ( addrb  [10 : 0] ),
    .dinb                    ( 'd0             ),

    .douta                   ( douta  [7 : 0]  ),
    .doutb                   ( doutb  [15 : 0] )
);


integer index;

reg [7:0] data_in_int[0:511];


initial begin
    index = 0;
    $readmemh("../verilog/sim/data_in.txt",data_in_int);
    $stop;
end

task wr_memory;
    input [8:0] start_addr;//写起始地址
    input [8:0] len;//写数据长度
    input wr_en;//1-->write,0-->read
    input [8:0] en_nclk;//N*clk
begin
    //a 端口 使能
    ena = 1; 
    for(index=start_addr;index<(len + start_addr) ;index=index+1'b1)begin
        if(index-start_addr > en_nclk)
            ena = 0;

        @(posedge clka);

        addra = index;
        wea   = wr_en;
        if(wr_en == 1)
            dina  = data_in_int[index][7:0];
        else
            dina = 8'hff;
    end
    @(posedge clka);
    wea = 0;
end
endtask

task random_read_b;
    input   [8:0]   start_addr;
    input   [8:0]   end_addr;
    input   [8:0]   rcnt;

    for(index = 0;index < rcnt ; index = index + 1'b1) begin
        @(posedge clkb);
        addrb = {$random} % (end_addr - start_addr);
    end

endtask

initial
begin

    @(posedge rst_n);
    #(PERIOD*10);



    //从0地址开始写16个字节数据,使能持续16个clk,虽然使能持续17个,但是数据长度只有16个
    wr_memory(0,16,1,17);

    //从8地址开始读4个字节数据
    wr_memory(8,4,0,4);

    wr_memory(16,8,1,4);
    #(PERIOD*10);
    wr_memory(2,4,0,2);

    #(PERIOD*10);

    //一共写入20个字节数据,换算成16位只有10个
    random_read_b(0,9,4);

    #(PERIOD*10);
    $stop;
end


endmodule
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ISE14.7和ModelSim可以联合仿真,具体步骤如下: 1. 在ISE中打开设计工程,点击"Generate Programming File"生成bit文件。 2. 在ISE中点击"Generate Simulation"生成仿真文件。 3. 在ModelSim中打开仿真文件,添加ISE生成的bit文件。 4. 在ModelSim中进行仿真,可以查看仿真结果。 需要注意的是,ISE和ModelSim的版本需要兼容,否则可能会出现兼容性问题。同时,需要确保仿真文件中包含了所有需要仿真的模块和信号。 ### 回答2: ISE(Integrated Software Environment)和ModelSim都是常用的数字电路设计工具,ISE主要用于开发基于FPGA的硬件系统,而ModelSim则是专门用于模拟数字电路的软件。这两种工具可以联合使用进行电路仿真,可以从不同角度完整地验证设计的正确性和性能。 关于ISE14.7和ModelSim的联合仿真,有以下几个方面需要注意: 1.仿真文件格式 ISE和ModelSim之间需要进行文件格式的转换。ISE生成的仿真文件为VHDL或Verilog格式,而ModelSim则需要将这些文件转换成VHDL库或Verilog库文件(.vlib或.v库文件)和测试文件(.vhd或.v文件)。在ISE中,需要将仿真代码添加到ISE工程中,并在设备视图中为仿真添加仿真文件。 2.仿真引擎集成 ModelSim和ISE之前的仿真引擎需要进行集成设置。在ISE工程设置中,需要选择ModelSim仿真引擎作为仿真工具,该引擎与ModelSim相同。在仿真之前,需要将ISE的设计文件从ISE到ModelSim,可以在ISE仿真对话框中进行设置。 3.仿真过程 在仿真过程中,可以用ISE和ModelSim联合仿真。首先,ISE将设计代码编译成可进行仿真的文件,并将其传输到ModelSim。然后,在ModelSim中,可以创建仿真波形来查看仿真结果。这样可以确保电路设计正确,并且可以通过查看波形来进行性能分析和调试。 总体来说,ISE和ModelSim的联合仿真能够有效提高数字电路设计的效率和精度。它使得设计人员能够从不同的角度了解其设计,并检查其设计的正确性和性能。此外,在仿真过程中,可以使用ISE和ModelSim提供的丰富的工具来帮助完成各种分析和调试任务,为设计人员提供更多的便利和支持。 ### 回答3: ISE14.7是Xilinx公司针对FPGA设计开发的一款综合工具,而ModelSim是一款常用的仿真工具,它们可以联合使用,帮助我们更加全面地验证FPGA设计的正确性。 ISE14.7支持将设计RTL代码和测试用例转换为VHDL或Verilog语言的模拟模型,并通过仿真模拟检测它们的逻辑正确性。ModelSim可以读入ISE14.7生成的仿真文件,进行波形仿真和代码调试,在仿真过程中,可以查看信号的变化,同时输出仿真结果。 ISE14.7和ModelSim联合仿真的优势在于可以在Xilinx工具链中完成FPGA设计的整个流程。在仿真过程中,我们可以通过三种方法进行联合仿真。 第一种方法是通过ISE GUI进行联合仿真设置。从ISE软件中启动ModelSim,ModelSim将自动读取ISE工程文件,并映射到ModelSim项目中。此外,ModelSim将执行VHDL代码仿真。在这种情况下,在ModelSim中打开一个CO模拟文件即可进行波形仿真。 第二种方法是通过ISE GUI设置仿真选项。通过ISE GUI,我们可以选择仿真选项来执行联合仿真,同时可以配置ModelSim仿真软件。通过配置ModelSim仿真软件,可以选择VHDL仿真/Verilog仿真,从而在仿真过程中匹配ModelSim仿真软件所需的仿真语法。 第三种方法是通过命令行设置仿真选项。通过-xise指定ISE工程文件和-xsimlib指定ModelSim仿真模式,即可完成仿真过程。 总之,ISE14.7和ModelSim联合仿真可以在FPGA设计的整个流程中发挥重要作用,它们可以提高FPGA设计的正确性,并在仿真过程中有效验证电路的正确性,同时也可以提高FPGA设计的工作效率和设计质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值