一、RAM實(shí)驗(yàn)背景知識(shí)
RAM的定義
RAM的英文全稱是Random Access Memory,即隨機(jī)存取存儲(chǔ)器,它可以隨時(shí)把數(shù)據(jù)寫入任一指定地址的存儲(chǔ)單元,也可以隨時(shí)從任一指定地址中讀出數(shù)據(jù),其讀寫速度是由時(shí)鐘頻率決定的。RAM主要用來存放程序及程序執(zhí)行過程中產(chǎn)生的中間數(shù)據(jù)、運(yùn)算結(jié)果等。
RAM的分類
單端口:只有一個(gè)端口,讀寫數(shù)據(jù)不能同時(shí)進(jìn)行,共用數(shù)據(jù)通道。
偽雙端口:擁有兩個(gè)數(shù)據(jù)通道,一個(gè)用來寫一個(gè)用來讀。
真雙端口:擁有兩個(gè)數(shù)據(jù)通道,一個(gè)用來寫一個(gè)用來讀。
本次實(shí)驗(yàn)使用A7系列,是真雙端口
實(shí)驗(yàn)設(shè)計(jì)
- 當(dāng)我們想驅(qū)動(dòng)一個(gè)RAM的IP核時(shí),我們需要提供六個(gè)信號(hào):clk(時(shí)鐘)、rst(復(fù)位信號(hào))、wea(讀寫切換)、data(數(shù)據(jù)線)、addr(地址線)、en(ram的使能)
- 在本次代碼中,我們使用RAM這個(gè)IP核時(shí),需要一個(gè)讀寫模塊,里面有一個(gè)讀寫計(jì)數(shù)器(最大值64,0-31讀數(shù)據(jù),32-63寫數(shù)據(jù),在31時(shí)改變讀寫切換的值),數(shù)據(jù)計(jì)數(shù)器(0-31作為寫入數(shù)據(jù)),地址計(jì)數(shù)器(0-31)用這三個(gè)計(jì)數(shù)器來對(duì)應(yīng)上面六個(gè)輸入。
二、創(chuàng)建一個(gè)新的工程
不會(huì)新建工程的可以看一下我之前的博客,這里只展示一些簡(jiǎn)略的新建工程過程。將工程命名為ip_ram。
新建工程完成
三、創(chuàng)建RAM IP核
雙擊點(diǎn)開上圖3的位置
下面這個(gè)頁(yè)面是Vivado自動(dòng)生成的,不用改
最后一頁(yè)可以檢查一下自己的設(shè)置
看到下面的圖片,說明IP核已經(jīng)創(chuàng)建完成了
四、編寫代碼
創(chuàng)建ip_ram.v(設(shè)計(jì)文件)、ram_rw.v(讀寫模塊,為什么創(chuàng)建這個(gè)可以看上面的實(shí)驗(yàn)設(shè)計(jì))、ram_xdc.xdc(時(shí)序約束文件)
從.veo文件中可以把IP核的實(shí)例粘貼出來
ip_ram.v代碼如下所示(這里我放的是添加完ILA的完整代碼)
`timescale 1ns / 1ps
module ip_ram(
input sys_clk,
input sys_rst_n
);
wire ram_en ;
wire ram_wea ;
wire [4 : 0] ram_addr ;
wire [7 : 0] ram_wr_data ;
wire [7 : 0] ram_rd_data ;
ram_rw ram_rw_u(
.clk (sys_clk) ,
.rst_n (sys_rst_n) ,
.ram_en (ram_en) ,
.ram_wea (ram_wea) ,
.ram_addr (ram_addr) ,
.ram_wr_data (ram_wr_data) ,
.ram_rd_data (ram_rd_data)
);
blk_mem_gen_0 blk_mem_gen_0 (
.clka(sys_clk), // input wire clka
.rsta(sys_rst_n), // input wire rsta
.ena(ram_en), // input wire ena
.wea(ram_wea), // input wire [0 : 0] wea
.addra(ram_addr), // input wire [4 : 0] addra
.dina(ram_wr_data), // input wire [7 : 0] dina
.douta(ram_rd_data) // output wire [7 : 0] douta
// .rsta_busy() // output wire rsta_busy
);
endmodule
ram_rw代碼如下所示(這里我放的是添加完ILA的完整代碼)
`timescale 1ns / 1ps
module ram_rw(
input clk,
input rst_n,
output ram_en,
output ram_wea,
output reg [4 : 0] ram_addr,
output reg [7 : 0] ram_wr_data,
input [7 : 0] ram_rd_data
);
reg [5 : 0] rw_cnt;
assign ram_wea = (rw_cnt <= 6'd31 && ram_en) ? 1'b1:1'b0;
assign ram_en = rst_n;
always@(posedge clk or negedge rst_n) begin
if(!rst_n) rw_cnt <= 1'b0;
else if(rw_cnt == 6'd63) rw_cnt <= 6'b0;
else rw_cnt <= rw_cnt + 1'b1;
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) ram_wr_data <= 1'b0;
else if(rw_cnt <= 6'd31) ram_wr_data <= ram_wr_data +1'b1;
else ram_wr_data <= 1'b0;
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) ram_addr <= 1'b0;
else if(ram_addr <= 5'd31) ram_addr <= ram_addr +1'b1;
else ram_addr <= 1'b0;
end
ila_0 your_instance_name (
.clk(clk), // input wire clk
.probe0(ram_en), // input wire [0:0] probe0
.probe1(ram_wea), // input wire [0:0] probe1
.probe2(ram_addr), // input wire [4:0] probe2
.probe3(ram_wr_data), // input wire [7:0] probe3
.probe4(ram_rd_data) // input wire [7:0] probe4
);
endmodule
ram_xdc.xdc代碼如下所示(這里我放的是添加完ILA的完整代碼)
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS15} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U7 IOSTANDARD LVCMOS15} [get_ports sys_rst_n]
五、創(chuàng)建ILA IP核并生成比特流文件
這里實(shí)際上需要復(fù)制.veo的實(shí)例去更改代碼,完整代碼我貼到上一章了
點(diǎn)擊生成bit流文件
出現(xiàn)下面這個(gè)界面代表bit流生成成功,點(diǎn)擊取消就可以文章來源:http://www.zghlxwxcb.cn/news/detail-823888.html
六、將程序下入芯片,并通過ILA觀察波形
下載后ILA自動(dòng)打開,可以看到,讀寫時(shí)序以及讀寫數(shù)據(jù)都正確,實(shí)驗(yàn)成功文章來源地址http://www.zghlxwxcb.cn/news/detail-823888.html
到了這里,關(guān)于手把手教你在Vivado創(chuàng)建一個(gè)RAM的IP核并使用ILA工具驗(yàn)證的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!