以下Verilog HDL代码符合wishbone总线B3标准协议,在Altera和Xilinx的开发工具上可以实现综合,自动推断并采用片上RAM资源,可以完成内存内容的初始化。

 /*
 ************************************************************************************************
 *    File   : ram_wb.v
 *    Module : ram_wb
 *    Author : Lyu Yang
 *    Date   : 01,01,1970
 *    Description : wishbone generic ram
 ************************************************************************************************
 */

 // synthesis translate_off
 `timescale 1ns / 1ps
 // synthesis translate_on
 `timescale 1ns / 100ps
 module ram_wb (
     clk_i,
     rst_i,
     cyc_i,
     stb_i,
     we_i,
     sel_i,
     adr_i,
     dat_i,
     dat_o,
     cti_i,
     ack_o
 );

 ;
 ;

 // clock
 input                   clk_i;
 // async reset
 input                   rst_i;

 // wishbone signals
 input                   cyc_i;
 input                   stb_i;
 input                   we_i;
 :]           sel_i;
 :] adr_i;
 :]          dat_i;
 :]          dat_o;
 :]           cti_i;
 output  reg             ack_o;

 :]          wr_data;

 // mux for data to ram
 :] = sel_i[] ? dat_i[:] : dat_o[:];
 :] = sel_i[] ? dat_i[:] : dat_o[:];
 : ] = sel_i[] ? dat_i[: ] : dat_o[: ];
 : ] = sel_i[] ? dat_i[ : ] : dat_o[ : ];

 ram #(
     .dat_width(),
     .adr_width(adr_width),
     .mem_size(mem_size)
 ) ram0 (
     .dat_i(wr_data),
     .dat_o(dat_o),
     .adr_i(adr_i[adr_width+:]),
     .we_i(we_i & ack_o),
     .clk(clk_i)
 );

 // ack_o
 always @ (posedge clk_i or posedge rst_i)
 if (rst_i)
     ack_o <= 'b0;
 else if (!ack_o)
     begin
         if (cyc_i & stb_i)
             ack_o <= 'b1;
     end
 'b111))
     ack_o <= 'b0;

 endmodule

 //////////////////////////////////////////////////////////////////////////
 module ram
 (
     clk,
     we_i,
     adr_i,
     dat_i,
     dat_o
 );

 ;
 ;
 ;

 :]      dat_i;
 :]      adr_i;
 input                        we_i;
 :] dat_o;
 input                      clk;

 :] ram [:mem_size - ];

 initial $readmemh("data.txt", ram);

 always @ (posedge clk)
 begin
     dat_o <= ram[adr_i];
     if (we_i)
         ram[adr_i] <= dat_i;
 end

 endmodule // ram
      

  使用Verilog中的$readmemh(filepath, data)或者$readmemb(filepath, data)功能,不仅在仿真中可以实现内存内容的初始化,现在的综合工具可以分析并得出适合各家工具的初始化文件并完成综合。

  另外,data.txt中数据内容的描述格式为:@十六进制地址[空白间隔 Tab Space \n]十六进制数据。例如,笔者在写Nios II处理器bootloader时候,片上存储bootloader程序的初始化文件部分为:

@00000000
00808014
@00000001
1001483a
@00000002
10bff804
@00000003
00bffd16
@00000004
00400034kljdaklj

  需要注意的是,地址可以不写,如果不写的话工具读取的时候认为地址从0开始连续分布。如果内容少于所需,那么剩余部分填充内容不确定(一般为0)。

05-24 23:45