后仿中搞定ROM Overlay

我们知道在一些特殊的调试场合,我们可能需要进行综合后,或者布局布线后的仿真。这个具体的仿真步骤我们在前面的文章中已经做过介绍,这里就不再赘述。

今天我们要研究的问题是后仿中的ROM Overlay,ROM Overlay其实就是对运行的ROM程序进行修改,前面文章中我们也专门介绍了如何对生成的FPGA bit进行Overlay操作。这里我们来看看在后仿中如何进行如何进行ROM Overlay操作,之所以要进行这种仿真,主要是有以下一些实际情况:

  1. 碰到一个更改了ROM Overlay之后程序运行不正常,甚至CORE行为不正常的情况
  2. 生成bit测试的时候,原来固化的ROM程序并不能满足要求,需要用修改之后的程序进行仿真

针对上面两种情况,仿真ROM Overlay可以省略重新PR的时间,有效的提升开发的效率。

其实仿真得好好处就是各种东西都可以随意的修改,ROM Overlay也不例外,基本的实现思路就是在我们的testbench中重新做一个ROM,这个ROM直接通过mem数组实现,mem内容可以通过hex文件导入。这个ROM加到testbench之后,通过hierarchy导入时钟地址信号,并将输出数据force到原有的ROM输出端就可以了。

wire [31:0] rom_q;
initial begin
    force  testbench.u_chip.rom_256k.mem.rom_mem_rom_q = rom_q;
end
rom_overlay #(
    .SIZE(65536),
    .ADDR_WIDTH(16),
    .DATA_WIDTH(32),
    .INIT_FILE("/path/to/fpga_rom.hex")
) u_rom_overlay (
    .clk(testbench.u_chip.rom_256k.mem.clk_12MHz_i),
    .a(testbench.u_chip.rom_256k.mem.A_muxed),
    .q(rom_q)
);

相应的ROM模型:

module rom_overlay(clk, a, q);
    parameter SIZE = 512;
    parameter ADDR_WIDTH = 9;
    parameter DATA_WIDTH = 31;
    parameter INIT_FILE = "";

    input clk;
    input [ADDR_WIDTH-1 : 0] a;
    output [DATA_WIDTH-1 : 0] q;

    reg [DATA_WIDTH-1 : 0] q;

    reg [DATA_WIDTH-1 : 0] mem [0:SIZE-1];

    initial begin
        // $readmemb(INIT_FILE, mem); // for mif file
        $readmemh(INIT_FILE, mem); // for hex file
    end

    always @(posedge clk)
    begin
        q <= mem[a];
    end
endmodule

上面这种方法实际上是比较简单的testbench搭建方法。

另外我们在后仿文件中可能看到一些有.mif的一些路径和文件信息,需要说明的是这些路径和文件信息是没有用的,所以对这些文件修改并不能对仿真数据进行干预。

相关文章

发表新评论