在通過編寫Verilog代碼實現ram功能時,需要自己先計算寄存器的位數和深度再編寫代碼。
而如果需要在編寫的ram中預置值的話,就需要使用Verilog語言編寫程序讀寫文件,來將相應的數據賦給寄存器。
這里給出Verilog實現ram的代碼:
module dpram( rclk, raddr, dout, wclk, we, waddr, din ); parameter aw = 16; //address widtth parameter dw = 12; //data address input rclk; //read clock input [aw-1:0] raddr; //read address output [dw-1:0] dout; //data output input wclk; //write clock input we; //write enable input [aw-1:0] waddr; //write address input [dw-1:0] din; //data input reg [dw-1:0] mem[(1<<aw)-1:0]; //block-ram reg [aw-1:0] ra; //register read address always @(posedge rclk) begin ra <= #1 raddr; end assign dout = mem[ra]; always @(posedge wclk) begin if(we) mem[waddr] <= #1 din; end //讀取mem文件存取程序中的mem寄存器 initial $readmemh("bmp_64K.mem",mem); endmodule
下面的程序定義了ram中寄存器的位數和深度,決定了ram的大小:
reg [dw-1:0] mem[(1<<aw)-1:0]; //block-ram
整段程序不是很復雜,其他部分主要是用於實現ram的讀寫控制功能,這里不做贅述。
Verilog實現讀寫文件功能的部分代碼如下:
//讀取mem文件存取程序中的mem寄存器 initial $readmemh("bmp_64K.mem",mem);
這段程序的功能是從文件名是“bmp_64K.mem”的文件中讀取其中的數據並置入前面定義的mem寄存器,即將數據置入ram中。
$readmemh("file_name.xxx",data)
就是將file_name.xxx中的數據讀入到data數組中。
使用格式有6種:
1) $readmemb("<數據文件名>",<存貯器名>); 2) $readmemb("<數據文件名>",<存貯器名>,<起始地址>); 3) $readmemb("<數據文件名>",<存貯器名>,<起始地址>,<結束地址>); 4) $readmemh("<數據文件名>",<存貯器名>); 5) $readmemh("<數據文件名>",<存貯器名>,<起始地址>); 6) $readmemh("<數據文件名>",<存貯器名>,<起始地址>,<結束地址>);
$readmemb要求數據格式必須是二進制形式,$readmemh則要求數據格式必須是16進制格式。
下面一些用法格式:(摘自https://wenku.baidu.com/view/81075c1f964bcf84b9d57b57.html)
1,打開文件
integer file_id; file_id = fopen("file_path/file_name");
2,寫入文件
//$fmonitor只要有變化就一直記錄 $fmonitor(file_id, "%format_char", parameter); eg:$fmonitor(file_id, "%m: %t in1=%d o1=%h", $time, in1, o1);
//$fwrite需要觸發條件才記錄 $fwrite(file_id, "%format_char", parameter);
//$fdisplay需要觸發條件才記錄 $fdisplay(file_id, "%format_char", parameter); $fstrobe();
3,讀取文件
integer file_id; file_id = $fread("file_path/file_name", "r");
4,關閉文件
$fclose(fjile_id);
5,由文件設定存儲器初值
$readmemh("file_name", memory_name"); //初始化數據為十六進制 $readmemb("file_name", memory_name"); //初始化數據為二進制