您的位置:首页 > 其它

Wishbone B3总线Generic RAM写法

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

/*
************************************************************************************************
*    File   : ram_wb.v
*    Module : ram_wb
*    Author : Lyu Yang
*    Data   : 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
);

parameter adr_width = 10;
parameter mem_size  = 1024;

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

// wishbone signals
input                   cyc_i;
input                   stb_i;
input                   we_i;
input   [3:0]           sel_i;
input   [adr_width+1:0] adr_i;
input   [31:0]          dat_i;
output  [31:0]          dat_o;
input   [2:0]           cti_i;
output  reg             ack_o;

wire [31:0]          wr_data;

// mux for data to ram
assign wr_data[31:24] = sel_i[3] ? dat_i[31:24] : dat_o[31:24];
assign wr_data[23:16] = sel_i[2] ? dat_i[23:16] : dat_o[23:16];
assign wr_data[15: 8] = sel_i[1] ? dat_i[15: 8] : dat_o[15: 8];
assign wr_data[ 7: 0] = sel_i[0] ? dat_i[ 7: 0] : dat_o[ 7: 0];

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

// ack_o
always @ (posedge clk_i or posedge rst_i)
if (rst_i)
ack_o <= 1'b0;
else if (!ack_o)
begin
if (cyc_i & stb_i)
ack_o <= 1'b1;
end
else if ((sel_i != 4'b1111) | (cti_i == 3'b000) | (cti_i == 3'b111))
ack_o <= 1'b0;

endmodule

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

parameter adr_width = 10;
parameter dat_width = 32;
parameter mem_size  = 1024;

input [dat_width-1:0]      dat_i;
input [adr_width-1:0]      adr_i;
input                        we_i;
output reg [dat_width-1:0] dat_o;
input                      clk;

reg [dat_width-1:0] ram [0:mem_size - 1];

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)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: