以下Verilog HDL代码符合wishbone总线B3标准协议,在Altera和Xilinx的开发工具上可以实现综合,自动推断并采用片上RAM资源,可以完成内存内容的初始化。
1 /* 2 ************************************************************************************************ 3 * File : ram_wb.v 4 * Module : ram_wb 5 * Author : Lyu Yang 6 * Data : 01,01,1970 7 * Description : wishbone generic ram 8 ************************************************************************************************ 9 */ 10 11 // synthesis translate_off 12 `timescale 1ns / 1ps 13 // synthesis translate_on 14 `timescale 1ns / 100ps 15 module ram_wb ( 16 clk_i, 17 rst_i, 18 cyc_i, 19 stb_i, 20 we_i, 21 sel_i, 22 adr_i, 23 dat_i, 24 dat_o, 25 cti_i, 26 ack_o 27 ); 28 29 parameter adr_width = 10; 30 parameter mem_size = 1024; 31 32 // clock 33 input clk_i; 34 // async reset 35 input rst_i; 36 37 // wishbone signals 38 input cyc_i; 39 input stb_i; 40 input we_i; 41 input [3:0] sel_i; 42 input [adr_width+1:0] adr_i; 43 input [31:0] dat_i; 44 output [31:0] dat_o; 45 input [2:0] cti_i; 46 output reg ack_o; 47 48 wire [31:0] wr_data; 49 50 // mux for data to ram 51 assign wr_data[31:24] = sel_i[3] ? dat_i[31:24] : dat_o[31:24]; 52 assign wr_data[23:16] = sel_i[2] ? dat_i[23:16] : dat_o[23:16]; 53 assign wr_data[15: 8] = sel_i[1] ? dat_i[15: 8] : dat_o[15: 8]; 54 assign wr_data[ 7: 0] = sel_i[0] ? dat_i[ 7: 0] : dat_o[ 7: 0]; 55 56 ram #( 57 .dat_width(32), 58 .adr_width(adr_width), 59 .mem_size(mem_size) 60 ) ram0 ( 61 .dat_i(wr_data), 62 .dat_o(dat_o), 63 .adr_i(adr_i[adr_width+1:2]), 64 .we_i(we_i & ack_o), 65 .clk(clk_i) 66 ); 67 68 // ack_o 69 always @ (posedge clk_i or posedge rst_i) 70 if (rst_i) 71 ack_o <= 1‘b0; 72 else if (!ack_o) 73 begin 74 if (cyc_i & stb_i) 75 ack_o <= 1‘b1; 76 end 77 else if ((sel_i != 4‘b1111) | (cti_i == 3‘b000) | (cti_i == 3‘b111)) 78 ack_o <= 1‘b0; 79 80 endmodule 81 82 ////////////////////////////////////////////////////////////////////////// 83 module ram 84 ( 85 clk, 86 we_i, 87 adr_i, 88 dat_i, 89 dat_o 90 ); 91 92 parameter adr_width = 10; 93 parameter dat_width = 32; 94 parameter mem_size = 1024; 95 96 input [dat_width-1:0] dat_i; 97 input [adr_width-1:0] adr_i; 98 input we_i; 99 output reg [dat_width-1:0] dat_o; 100 input clk; 101 102 reg [dat_width-1:0] ram [0:mem_size - 1]; 103 104 initial $readmemh("data.txt", ram); 105 106 always @ (posedge clk) 107 begin 108 dat_o <= ram[adr_i]; 109 if (we_i) 110 ram[adr_i] <= dat_i; 111 end 112 113 endmodule // ram 114
使用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)。
时间: 2024-10-24 03:20:02