本(běn)文(wén)为(wèi)明(míng)德揚原創及(jí)录(lù)用(yòng)文(wén)章(zhāng),轉(zhuǎn)载請注明(míng)出(chū)处!
SDRAM控制器設計(jì)的(de)主(zhǔ)要(yào)功能(néng)是(shì)能(néng)对(duì)SDRAM進(jìn)行读(dú)写操作,本(běn)工程实現(xiàn)了(le)SDRAM的(de)初始化(huà)、自(zì)動(dòng)刷新、读(dú)、写等功能(néng)。
初始化(huà)功能(néng)和(hé)刷新功能(néng)在(zài)前(qián)一(yī)章(zhāng)的(de)分(fēn)享中(zhōng)已經(jīng)進(jìn)行了(le)比較詳细(xì)的(de)描述,感(gǎn)興趣的(de)同(tóng)学可(kě)以(yǐ)搜索学習下(xià),这(zhè)里(lǐ)不(bù)再贅述。今天(tiān)我(wǒ)们(men)主(zhǔ)要(yào)讨論SDRAM读(dú)写的(de)功能(néng)以(yǐ)及(jí)实現(xiàn)。
一(yī)、原理功能(néng)
1、读(dú)写突發(fà)模式
在(zài)初始化(huà)里(lǐ)的(de)模式寄存器配置中(zhōng)我(wǒ)们(men)将读(dú)写的(de)突發(fà)长度(dù)(BL)設置为(wèi)4,列選通(tòng)潛伏期(qī)(CL)設为(wèi)3,突發(fà)類(lèi)型为(wèi)順序模式(每一(yī)次(cì)突發(fà)只(zhī)給(gěi)出(chū)起始地(dì)址即可(kě))。对(duì)于(yú)預充電(diàn)選擇(Auto Precharge)自(zì)動(dòng)預充電(diàn),即外(wài)部(bù)不(bù)需要(yào)發(fà)送預充電(diàn)命令
2、读(dú)、写时(shí)序图(tú)
图(tú)表(biǎo)1写时(shí)序图(tú)
图(tú)表(biǎo)2读(dú)时(shí)序图(tú)
由(yóu)时(shí)序图(tú)可(kě)知,读(dú)写模块(kuài)采用(yòng)線(xiàn)性(xìng)序列機(jī)設計(jì)比較簡單。在(zài)每次(cì)读(dú)写突發(fà)之前(qián)都需要(yào)發(fà)送ACTIVE命令,同(tóng)时(shí)給(gěi)出(chū)bank地(dì)址和(hé)row地(dì)址,2拍後(hòu)發(fà)出(chū)读(dú)或(huò)写命令,同(tóng)时(shí)将A10拉高(gāo)并給(gěi)出(chū)col地(dì)址。对(duì)于(yú)写操作沒(méi)有(yǒu)潛伏期(qī),由(yóu)于(yú)DQ是(shì)双(shuāng)向(xiàng)端口(kǒu),所(suǒ)以(yǐ)需要(yào)一(yī)个(gè)三(sān)态門(mén)控制DQ總(zǒng)線(xiàn)方(fāng)向(xiàng),當写操作时(shí)为(wèi)輸出(chū)方(fāng)向(xiàng),读(dú)操作时(shí)为(wèi)輸入(rù)方(fāng)向(xiàng)。对(duì)于(yú)读(dú)操作,發(fà)出(chū)读(dú)命令後(hòu)会(huì)有(yǒu)CL拍的(de)潛伏期(qī),本(běn)实验(yàn)里(lǐ)CL=3,即發(fà)出(chū)读(dú)命令後(hòu)3拍,數據(jù)才会(huì)出(chū)現(xiàn)在(zài)DQ總(zǒng)線(xiàn)上(shàng)。
二(èr)、FPGA实現(xiàn)
1、模块(kuài)架構
注:信(xìn)号(hào)方(fāng)向(xiàng)請看(kàn)箭头(tóu)
2、模块(kuài)架構解(jiě)读(dú)
要(yào)完整实現(xiàn)SDRAM控制器必須要(yào)完成(chéng)初始化(huà),刷新,读(dú)写这(zhè)四(sì)部(bù)分(fēn)功能(néng)。所(suǒ)以(yǐ)模块(kuài)劃(huà)分(fēn)大體(tǐ)依照次(cì)为(wèi)指導。由(yóu)于(yú)SDRAM控制器工作时(shí)鐘(zhōng)为(wèi)100MHz,且要(yào)輸出(chū)一(yī)个(gè)頻率相同(tóng)相位相差180°的(de)时(shí)鐘(zhōng)給(gěi)SDRAM,所(suǒ)以(yǐ)要(yào)有(yǒu)一(yī)个(gè)鎖相环(huán)模块(kuài)。刷新需要(yào)計(jì)时(shí)刷新間(jiān)隔,所(suǒ)以(yǐ)要(yào)加入(rù)一(yī)个(gè)刷新定(dìng)时(shí)器模块(kuài),由(yóu)于(yú)初始化(huà),刷新,读(dú),写等模块(kuài)都要(yào)輸出(chū)sdr_cke,sdr_cs_n,sdr_cas_n,sdr_ras_n,sdr_we_n,sdr_ba,sdr_a等信(xìn)号(hào)到(dào)SDRAM,所(suǒ)以(yǐ)需要(yào)一(yī)个(gè)選擇模块(kuài)。将sdr_cke,sdr_cs_n,sdr_cas_n,sdr_ras_n,sdr_we_n,sdr_ba,sdr_a等信(xìn)号(hào)組合成(chéng)bus信(xìn)号(hào)輸入(rù)到(dào)選擇模块(kuài)。
新加入(rù)的(de)信(xìn)号(hào)说(shuō)明(míng),其他(tā)信(xìn)号(hào)在(zài)前(qián)两(liǎng)篇(piān)中(zhōng)已經(jīng)詳细(xì)说(shuō)明(míng),读(dú)者(zhě)可(kě)以(yǐ)參考。
|
信(xìn)号(hào) |
功能(néng) |
说(shuō)明(míng) |
|
頂层 |
|
|
|
local_data |
写突發(fà)數據(jù)輸入(rù) |
外(wài)部(bù)輸入(rù) |
|
local_addr |
地(dì)址總(zǒng)線(xiàn) |
外(wài)部(bù)輸入(rù) |
|
local_q |
读(dú)突發(fà)數據(jù)輸出(chū) |
輸出(chū) |
|
local_wrreq |
写請求 |
外(wài)部(bù)輸入(rù) |
|
local_rdreq |
读(dú)請求 |
外(wài)部(bù)輸入(rù) |
|
local_reday |
可(kě)以(yǐ)進(jìn)行读(dú)写操作信(xìn)号(hào) |
輸出(chū) |
|
local_rdata_vaild |
輸出(chū)數據(jù)有(yǒu)效信(xìn)号(hào) |
輸出(chū) |
|
写模块(kuài) |
|
|
|
wr_en |
写使能(néng) |
仲裁模块(kuài)輸出(chū)到(dào)写模块(kuài) |
|
wr_done |
写完成(chéng) |
写模块(kuài)輸出(chū)到(dào)仲裁模块(kuài) |
|
wr_bus |
写操作總(zǒng)線(xiàn) |
写模块(kuài)輸出(chū)到(dào)選擇模块(kuài) |
|
sdr_dq |
SDRAM數據(jù)總(zǒng)線(xiàn) |
双(shuāng)向(xiàng)端口(kǒu),对(duì)于(yú)写模块(kuài)是(shì)輸出(chū),读(dú)模块(kuài)是(shì)輸入(rù) |
|
读(dú)模块(kuài) |
|
|
|
rd_bus |
读(dú)操作總(zǒng)線(xiàn) |
读(dú)模块(kuài)輸出(chū)到(dào)選擇模块(kuài) |
|
rd_en |
读(dú)使能(néng) |
仲裁模块(kuài)輸出(chū)到(dào)读(dú)模块(kuài) |
|
rd_done |
读(dú)完成(chéng) |
读(dú)模块(kuài)輸出(chū)到(dào)仲裁模块(kuài) |
新加入(rù)了(le)写模块(kuài)和(hé)读(dú)模块(kuài)。
写模块(kuài)主(zhǔ)要(yào)是(shì)完成(chéng)一(yī)次(cì)写突發(fà)操作,将local_data信(xìn)号(hào)写入(rù)到(dào)SDRAM中(zhōng)的(de)指定(dìng)地(dì)址local_addr中(zhōng)。local_addr主(zhǔ)要(yào)由(yóu)bank地(dì)址,行地(dì)址和(hé)列地(dì)址組合而(ér)成(chéng)。在(zài)读(dú)和(hé)写模块(kuài)代(dài)碼中(zhōng)均有(yǒu)體(tǐ)現(xiàn),可(kě)以(yǐ)參考。
读(dú)模块(kuài)主(zhǔ)要(yào)完成(chéng)一(yī)次(cì)读(dú)突發(fà)操作,将SDRAM中(zhōng)指定(dìng)的(de)地(dì)址中(zhōng)的(de)數據(jù)读(dú)出(chū)来(lái),并賦值給(gěi)local_q信(xìn)号(hào)。
由(yóu)于(yú)加入(rù)了(le)写模块(kuài)和(hé)读(dú)模块(kuài),所(suǒ)以(yǐ)仲裁模块(kuài)也(yě)要(yào)做出(chū)相應(yìng)的(de)修改,當收(shōu)到(dào)刷新請求时(shí),即rt_flag信(xìn)号(hào)後(hòu),在(zài)結束(shù)本(běn)次(cì)读(dú)突發(fà)或(huò)者(zhě)写突發(fà)後(hòu),拉高(gāo)刷新使能(néng)(ref_en)信(xìn)号(hào),當收(shōu)到(dào)写請求且沒(méi)有(yǒu)刷新請求时(shí),拉高(gāo)写使能(néng)(wr_en)信(xìn)号(hào),當收(shōu)到(dào)读(dú)請求且沒(méi)有(yǒu)刷新請求和(hé)写請求时(shí),拉高(gāo)读(dú)使能(néng)(rd_en)信(xìn)号(hào)。
3、頂层模块(kuài)參考代(dài)碼
|
module sdram_top( clk , sys_rst_n , //其他(tā)信(xìn)号(hào),舉例dout local_addr, local_data, local_q, local_rdreq, local_wrreq, local_ready, local_rdata_valid, init_done, sdr_cke, sdr_cs_n, sdr_ras_n, sdr_cas_n, sdr_we_n, sdr_ba, sdr_a, sdr_dq, sdr_dqm, sdr_clk );
input clk; input sys_rst_n; input [24:0] local_addr; input [63:0] local_data; output [63:0] local_q; input local_rdreq; input local_wrreq; output local_ready; output local_rdata_valid; output init_done; output sdr_cke; output sdr_cs_n; output sdr_ras_n; output sdr_cas_n; output sdr_we_n; output [1:0] sdr_ba; output [12:0] sdr_a; inout [15:0] sdr_dq; output [1:0] sdr_dqm; output sdr_clk;
wire phy_clk; wire rst_n; wire rt_flag; wire rt_clear; wire rt_en; wire ref_en; wire ref_done; wire wr_done; wire wr_en; wire rd_en; wire rd_done; wire [1:0] sel_sm; wire [19:0] sdr_bus; wire [19:0] init_bus; wire [19:0] ref_bus; wire [19:0] wr_bus; wire [19:0] rd_bus;
assign {sdr_cke, sdr_cs_n, sdr_ras_n, sdr_cas_n, sdr_we_n, sdr_ba, sdr_a} = sdr_bus; assign sdr_dqm = 2'b00;
sdram_init sdram_init_inst( .clk (phy_clk) , .rst_n (rst_n) , //其他(tā)信(xìn)号(hào),舉例dout .init_done (init_done) , .init_bus (init_bus) );
arbitrate arbitrate_inst( .clk(phy_clk), .rst_n(rst_n), .rt_flag(rt_flag), .rt_en(rt_en), .rt_clear(rt_clear), .ref_done(ref_done), .ref_en(ref_en), .init_done(init_done), .sel_sm(sel_sm), .local_rdata_valid(local_rdata_valid), .local_ready(local_ready), .local_wrreq(local_wrreq), .local_rdreq(local_rdreq), .wr_done(wr_done), .wr_en(wr_en), .rd_en(rd_en), .rd_done(rd_done) );
ref_timer ref_timer_inst( .clk(phy_clk), .rst_n(rst_n), .rt_en(rt_en), .rt_clear(rt_clear), .rt_flag(rt_flag) );
sdram_ref sdram_ref_inst( .clk(phy_clk), .rst_n(rst_n), .ref_en(ref_en), .ref_done(ref_done), .ref_bus(ref_bus) );
sdram_write sdram_write_inst( .clk(phy_clk), .rst_n(rst_n), .wr_en(wr_en), .wr_done(wr_done), .wr_bus(wr_bus), .sdr_dq(sdr_dq), .local_data(local_data), .local_addr(local_addr) );
sdram_read sdram_read_inst( .clk(phy_clk), .rst_n(rst_n), .rd_en(rd_en), .rd_done(rd_done), .rd_bus(rd_bus), .sdr_dq(sdr_dq), .local_q(local_q), .local_addr(local_addr) );
sdram_mux sdram_mux_inst( .clk(phy_clk), .rst_n(rst_n), .init_bus(init_bus), .ref_bus(ref_bus), .wr_bus(wr_bus), .rd_bus(rd_bus), .sdr_bus(sdr_bus), .sel_sm(sel_sm) );
my_pll PLL( .areset (~sys_rst_n) , .inclk0 (clk) , .c0 (phy_clk) , .c1 (sdr_clk) , .locked (rst_n) );
endmodule |
4、模块(kuài)功能(néng)
PLL模块(kuài),初始化(huà)模块(kuài),刷新模块(kuài)在(zài)前(qián)面(miàn)两(liǎng)篇(piān)文(wén)章(zhāng)中(zhōng)已經(jīng)讨論过(guò),这(zhè)里(lǐ)不(bù)再描述。
(1)写模块(kuài)
主(zhǔ)要(yào)完成(chéng)写突發(fà),采用(yòng)線(xiàn)性(xìng)序列機(jī)設計(jì),當檢测到(dào)wr_en为(wèi)高(gāo)電(diàn)平时(shí),計(jì)數器開(kāi)始計(jì)时(shí),并發(fà)出(chū)開(kāi)ACT命令,并将row地(dì)址賦值給(gěi)sdr_a。两(liǎng)拍之後(hòu),發(fà)出(chū)写命令,并将A10拉高(gāo),然後(hòu)開(kāi)始将數據(jù)賦值給(gěi)sdr_dq信(xìn)号(hào)。然後(hòu)計(jì)數到(dào)8-1时(shí)将写完成(chéng)信(xìn)号(hào)wr_done拉高(gāo)。
可(kě)以(yǐ)对(duì)照时(shí)序图(tú)閱读(dú)代(dài)碼,其代(dài)碼如(rú)下(xià):
|
module sdram_write(clk, rst_n, wr_en, wr_done, wr_bus, sdr_dq, local_data, local_addr);
input clk; input rst_n; input wr_en; output reg wr_done; output [19:0] wr_bus; inout [15:0] sdr_dq; input [63:0] local_data; input [24:0] local_addr;
parameter CNT_MAX = 8; parameter NOP = 4'b0111; parameter ACT = 4'b0011; parameter WR = 4'b0100;
reg [3:0] cnt; reg [3:0] sdr_cmd; reg [1:0] sdr_ba; reg [12:0] sdr_a; reg [15:0] temp; reg out_en;
wire [9:0] col; wire [12:0] row; wire [1:0] ba; wire sdr_cke; wire add_cnt; wire end_cnt;
assign {ba, row, col} = local_addr; assign sdr_dq = out_en ? temp : 16'dz; assign sdr_cke = 1'b1; assign wr_bus = {sdr_cke, sdr_cmd, sdr_ba, sdr_a};
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt <= 0; end else if(add_cnt)begin if(end_cnt) cnt <= 0; else cnt <= cnt + 1; end end
assign add_cnt = wr_en; assign end_cnt = add_cnt && cnt==CNT_MAX - 1 ;
always @ (posedge clk or negedge rst_n)begin if(!rst_n)begin sdr_cmd <= NOP; end else if(add_cnt && cnt == 1 - 1)begin sdr_cmd <= ACT; end else if(add_cnt && cnt == 3 - 1)begin sdr_cmd <= WR; end else begin sdr_cmd <= NOP; end end
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin sdr_ba <= 2'd0; end else begin sdr_ba <= ba; end end
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin sdr_a <= 13'd0; end else if(add_cnt && cnt == 1 - 1)begin sdr_a <= row; end else if(add_cnt && cnt == 3 - 1)begin sdr_a <= {2'd0, 1'b1, col}; end else begin sdr_a <= 13'd0; end end
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin temp <= 16'd0; end else if(add_cnt && cnt == 4 - 1)begin temp <= local_data[15:0]; end else if(add_cnt && cnt == 5 - 1)begin temp <= local_data[31:16]; end else if(add_cnt && cnt == 6 - 1)begin temp <= local_data[47:32]; end else if(add_cnt && cnt == 7 - 1)begin temp <= local_data[63:48]; end else begin temp <= 16'd0; end end
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin out_en <= 1'b0; end else if(add_cnt && cnt == 4 - 1)begin out_en <= 1'b1; end else if(add_cnt && cnt == 8 - 1)begin out_en <= 1'b0; end else begin out_en <= out_en; end end
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin wr_done <= 1'b0; end else if(add_cnt && cnt == 1 - 1)begin wr_done <= 1'b0; end else if(add_cnt && cnt == 8 - 1)begin wr_done <= 1'b1; end else begin wr_done <= wr_done; end end
endmodule |
(2)读(dú)模块(kuài)
读(dú)模块(kuài)主(zhǔ)要(yào)完成(chéng)读(dú)突發(fà),对(duì)于(yú)读(dú)模块(kuài)来(lái)说(shuō),sdr_dq信(xìn)号(hào)是(shì)輸入(rù)信(xìn)号(hào),且不(bù)是(shì)同(tóng)一(yī)时(shí)鐘(zhōng)域信(xìn)号(hào),所(suǒ)以(yǐ)要(yào)加两(liǎng)級同(tóng)步寄存器。當檢测到(dào)读(dú)使能(néng)rd_en为(wèi)高(gāo)时(shí),計(jì)數器開(kāi)始計(jì)數,并發(fà)出(chū)ACT命令,同(tóng)时(shí)給(gěi)出(chū)row地(dì)址,两(liǎng)拍之後(hòu)發(fà)出(chū)读(dú)命令,并将A10拉高(gāo),由(yóu)于(yú)加入(rù)了(le)两(liǎng)級同(tóng)步寄存器且读(dú)潛伏期(qī)为(wèi)3,所(suǒ)以(yǐ)5拍之後(hòu)才可(kě)以(yǐ)采集數據(jù),即計(jì)數到(dào)9-1时(shí)采集數據(jù),4拍之後(hòu)數據(jù)采集完成(chéng),下(xià)一(yī)拍将读(dú)完成(chéng)信(xìn)号(hào)rd_done拉高(gāo)。
可(kě)以(yǐ)对(duì)照时(shí)序图(tú)閱读(dú)代(dài)碼,代(dài)碼如(rú)下(xià)
|
module sdram_read(clk, rst_n, rd_en, rd_done, rd_bus, sdr_dq, local_q, local_addr);
input clk; input rst_n; input rd_en; output reg rd_done; output [19:0] rd_bus; input [15:0] sdr_dq; output reg [63:0] local_q; input [24:0] local_addr;
parameter CNT_MAX = 14; parameter NOP = 4'b0111; parameter ACT = 4'b0011; parameter RD = 4'b0101;
reg [3:0] cnt; reg [3:0] sdr_cmd; reg [1:0] sdr_ba; reg [12:0] sdr_a; reg [15:0] temp0, temp1;
wire [9:0] col; wire [12:0] row; wire [1:0] ba; wire sdr_cke; wire add_cnt; wire end_cnt;
assign {ba, row, col} = local_addr; assign sdr_cke = 1'b1; assign rd_bus = {sdr_cke, sdr_cmd, sdr_ba, sdr_a};
always @(posedge clk)begin temp0 <= sdr_dq; temp1 <= temp0; end
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt <= 0; end else if(add_cnt)begin if(end_cnt) cnt <= 0; else cnt <= cnt + 1; end end
assign add_cnt = rd_en; assign end_cnt = add_cnt && cnt==CNT_MAX - 1 ;
always @ (posedge clk or negedge rst_n)begin if(!rst_n)begin sdr_cmd <= NOP; end else if(add_cnt && cnt == 1 - 1)begin sdr_cmd <= ACT; end else if(add_cnt && cnt == 3 - 1)begin sdr_cmd <= RD; end else begin sdr_cmd <= NOP; end end
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin sdr_ba <= 2'd0; end else begin sdr_ba <= ba; end end
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin sdr_a <= 13'd0; end else if(add_cnt && cnt == 1 - 1)begin sdr_a <= row; end else if(add_cnt && cnt == 3 - 1)begin sdr_a <= {2'd0, 1'b1, col}; end else begin sdr_a <= 13'd0; end end
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin local_q <= 64'd0; end else if(add_cnt && cnt == 9 - 1)begin local_q[15:0] <= temp1; end else if(add_cnt && cnt == 10 - 1)begin local_q[31:16] <= temp1; end else if(add_cnt && cnt == 11 - 1)begin local_q[47:32] <= temp1; end else if(add_cnt && cnt == 12 - 1)begin local_q[63:48] <= temp1; end else begin local_q <= local_q; end end
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin rd_done <= 1'b0; end else if(add_cnt && cnt == 1 - 1)begin rd_done <= 1'b0; end else if(add_cnt && cnt == 13 - 1)begin rd_done <= 1'b1; end else begin rd_done <= rd_done; end end
endmodule |
(3)仲裁模块(kuài)
由(yóu)于(yú)加入(rù)了(le)写模块(kuài)和(hé)读(dú)模块(kuài),所(suǒ)以(yǐ)仲裁模块(kuài)也(yě)要(yào)做出(chū)相應(yìng)的(de)修改,當收(shōu)到(dào)刷新請求时(shí),即rt_flag信(xìn)号(hào)後(hòu),在(zài)結束(shù)本(běn)次(cì)读(dú)突發(fà)或(huò)者(zhě)写突發(fà)後(hòu),拉高(gāo)刷新使能(néng)(ref_en)信(xìn)号(hào),當收(shōu)到(dào)写請求且沒(méi)有(yǒu)刷新請求时(shí),拉高(gāo)写使能(néng)(wr_en)信(xìn)号(hào),當收(shōu)到(dào)读(dú)請求且沒(méi)有(yǒu)刷新請求和(hé)写請求时(shí),拉高(gāo)读(dú)使能(néng)(rd_en)信(xìn)号(hào)。
主(zhǔ)要(yào)代(dài)碼如(rú)下(xià):
|
module arbitrate(clk, rst_n, rt_flag, rt_en, rt_clear, ref_done,ref_en, init_done, sel_sm, local_rdata_valid, local_ready,local_wrreq, local_rdreq, wr_done, wr_en, rd_en, rd_done);
input clk, rst_n; input rt_flag; output reg rt_en,rt_clear; input ref_done; output reg ref_en; input init_done; output reg [1:0]sel_sm; output reglocal_rdata_valid; output reglocal_ready; input local_wrreq,local_rdreq; input wr_done; output reg wr_en; output reg rd_en; input rd_done;
localparam SM_INIT =2'd0; localparam SM_REF = 2'd1; localparam SM_WR = 2'd2; localparam SM_RD = 2'd3;
always @(posedge clkor negedge rst_n)begin if(!rst_n)begin rt_en<= 0; end elseif(init_done)begin rt_en<= 1; end else begin rt_en<= rt_en; end end
always @(posedge clkor negedge rst_n)begin if(!rst_n)begin rt_clear<= 0; end elseif(ref_en)begin rt_clear<= 1; end elseif(ref_done)begin rt_clear<= 0; end else begin rt_clear<= rt_clear; end end
always @(posedge clkor negedge rst_n)begin if(!rst_n)begin ref_en<= 0; end elseif(rt_flag)begin ref_en<= 1; end elseif(ref_done)begin ref_en<= 0; end else begin ref_en<= ref_en; end end
always @(posedge clkor negedge rst_n)begin if(!rst_n)begin sel_sm<= SM_INIT; end elseif(!init_done)begin sel_sm<= SM_INIT; end elseif(rt_flag)begin sel_sm<= SM_REF; end elseif(local_wrreq && !rt_flag)begin sel_sm<= SM_WR; end elseif(local_rdreq && !rt_flag)begin sel_sm<= SM_RD; end else begin sel_sm<= sel_sm; end end
always @(posedge clkor negedge rst_n)begin if(!rst_n)begin wr_en<= 0; end elseif(local_wrreq && !rt_flag)begin wr_en<= 1; end elseif(wr_done)begin wr_en<= 0; end else begin wr_en<= wr_en; end end
always @(posedge clkor negedge rst_n)begin if(!rst_n)begin rd_en<= 0; end elseif(local_rdreq && !local_wrreq && !rt_flag)begin rd_en<= 1; end elseif(rd_done)begin rd_en<= 0; end else begin rd_en<= rd_en; end end
always @(posedge clkor negedge rst_n)begin if(!rst_n)begin local_ready<= 1; end elseif(wr_en || rd_en)begin local_ready<= 0; end else begin local_ready<= 1; end end
always @(posedge clkor negedge rst_n)begin if(!rst_n)begin local_rdata_valid<= 0; end elseif(rd_done)begin local_rdata_valid<= 1; end else begin local_rdata_valid<= 0; end end endmodule |
(5)仿真(zhēn)验(yàn)證
向(xiàng)SDRAM中(zhōng)写入(rù)64’h1122334455667788,然後(hòu)读(dú)出(chū)来(lái)。由(yóu)图(tú)可(kě)知SDRAM正(zhèng)确读(dú)出(chū)了(le)數據(jù)。(波(bō)形顯示的(de)是(shì)十(shí)六(liù)進(jìn)制,報告是(shì)十(shí)進(jìn)制)















