?? command.v
字號:
// Issue the appropriate command if the sdram is not currently busy 如果SDRAM空閑,則發(fā)出適當?shù)膬?nèi)部命令
//包含一個用戶命令與刷新請求的仲裁器。如何仲裁請看本模塊開頭的介紹
if ((REF_REQ == 1 | REFRESH == 1) & command_done == 0 & do_refresh == 0 & rp_done == 0 // Refresh若隱藏的刷新請求信號有效或REFRESH命令有效,且SDRAM空閑,rp_done指示沒有正在進行的讀寫及刷新命令,當前沒有do_reada、do_writea內(nèi)部命令發(fā)出,同時do_refresh未發(fā)出,則發(fā)出do_refresh(賦1)
& do_reada == 0 & do_writea == 0)
do_refresh <= 1;
else
do_refresh <= 0; //否則為0
if ((READA == 1) & (command_done == 0) & (do_reada == 0) & (rp_done == 0) & (REF_REQ == 0)) // READA若READA命令有效,且SDRAM空閑,rp_done指示沒有正在進行的讀寫及刷新命令,刷新請求信號無效,同時do_reada未發(fā)出,則發(fā)出do_reada(賦1)。
do_reada <= 1;
else
do_reada <= 0; //否則為0
if ((WRITEA == 1) & (command_done == 0) & (do_writea == 0) & (rp_done == 0) & (REF_REQ == 0)) // WRITEA若WRITEA命令有效,且SDRAM空閑,rp_done指示沒有正在進行的讀寫及刷新命令,刷新請求信號無效,同時do_writea未發(fā)出,則發(fā)出do_writea(賦1),do_writea和do_writea1用在不同always塊中
begin
do_writea <= 1;
do_writea1 <= 1;
end
else
begin
do_writea <= 0;
do_writea1 <= 0; //否則為0
end
if ((PRECHARGE == 1) & (command_done == 0) & (do_precharge == 0)) // PRECHARGE若PRECHARGE命令有效,且SDRAM空閑,同時do_precharge未發(fā)出,則發(fā)出do_precharge,即do_precharge賦1,
do_precharge <= 1;
else
do_precharge <= 0; //否則為0
if ((LOAD_MODE == 1) & (command_done == 0) & (do_load_mode == 0)) // LOADMODE若LOAD_MODE命令有效,且SDRAM空閑,同時do_load_mode未發(fā)出,則發(fā)出do_load_mode,即do_load_mode賦1,
do_load_mode <= 1;
else
do_load_mode <= 0; //否則為0
// set command_delay shift register and command_done flag
// The command delay shift register is a timer that is used to ensure that
// the SDRAM devices have had sufficient time to finish the last command.
//設置命令延遲移位寄存器和SDRAM忙標志,命令延遲移位寄存器確保SDRAM有足夠時間完成上一個命令操作
//對讀寫及刷新命令,最大突發(fā)長度為8個字,因此需要8個時鐘周期完成讀寫操作,同時由于在讀寫命令之前,控制器首先要給出ACTIVATE命令,而ACTIVATE命令與讀寫命令之間延遲最大為3個時鐘周期,這樣就要求控制器至少在(8+1)+(3+2)=14個時鐘周期內(nèi)不能對用戶給出的新的讀寫刷新命令作出反應;但在9個時鐘周期后,控制器可對其他命令作出響應如precharge命令,從而可以終止讀寫操作。
//對其他命令設置為8+1=9個時鐘周期內(nèi)控制器不能響應新的命令。
if ((do_refresh == 1) | (do_reada == 1) | (do_writea == 1) | (do_precharge == 1)
| (do_load_mode)) //如果有任何一個內(nèi)部命令被發(fā)出,則command_delay賦全1,command_done置位(表示SDRAM忙),rw_flag賦值為do_reada(若do_reada為1即讀操作命令有效,則rw_flag賦1;否則若do_reada為0,則rw_flag賦0,表明不是讀操作命令)
begin
command_delay <= 8'b11111111;
command_done <= 1;
rw_flag <= do_reada;
end
else //否則,命令延遲移位寄存器進行向右移位操作,最低位移出給command_done,最高位補0。在移位期間只要命令延遲移位寄存器不為0,command_done就始終為1(可保持9個時鐘周期為1),因此不會有新的內(nèi)部命令被發(fā)出,保證SDRAM有足夠時間完成上一個命令操作
begin
command_done <= command_delay[0]; // the command_delay shift operation
command_delay[6:0] <= command_delay[7:1];
command_delay[7] <= 0;
end
// start additional timer that is used for the refresh, writea, reada commands
//用于refresh, writea, reada命令的附加的移位寄存器rp_shift,保證SDRAM有足夠時間完成上一次讀寫及刷新命令,因為這三個命令的執(zhí)行需要更多的時間,還須隱含執(zhí)行ACTIVATE命令
if (command_delay[0] == 0 & command_done == 1) //若命令延遲移位寄存器最低位為0且command_done == 1,則附加的移位寄存器rp_shift賦全1,rp_done 置位(表示讀寫忙)
begin
rp_shift <= 4'b1111;
rp_done <= 1;
end
else //否則,附加的移位寄存器rp_shift進行右移位操作,最低位移出給rp_done,最高位補0。在移位期間只要附加的移位寄存器不為0,rp_done就始終為1(可保持5個時鐘周期為1),因此不會有新的讀、寫、刷新內(nèi)部命令被發(fā)出(但別的內(nèi)部命令可以發(fā)出,比如do_precharge命令,這條命令可以終止正在進行的讀寫及刷新命令)
begin
rp_done <= rp_shift[0];
rp_shift[2:0] <= rp_shift[3:1];
rp_shift[3] <= 0;
end
end
end
// logic that generates the OE signal for the data path module該always塊產(chǎn)生輸出使能信號OE,輸出給data path module
// For normal burst write the duration of OE is dependent on the configured burst length.在正常的突發(fā)寫入操作中,OE的持續(xù)時間取決于配置的REG1的burst length位段
// For page mode accesses(SC_PM=1) the OE signal is turned on at the start of the write command在頁寫入訪問模式中,OE在write命令開始時有效并且保持到檢測到PRECHARGE命令
// and is left on until a PRECHARGE(page burst terminate) is detected.
//(時鐘信號CLK上升沿)
always @(posedge CLK or negedge RESET_N)
begin
if (RESET_N == 0) //復位,清除oe_shift、oe1、oe2、OE
begin
oe_shift <= 0;
oe1 <= 0;
oe2 <= 0;
OE <= 0;
end
else
begin
if (SC_PM == 0) //若SC_PM == 0,說明是正常的突發(fā)寫入操作,則
begin
if (do_writea1 == 1) //若do_writea1 == 1,即內(nèi)部寫命令有效(首先會執(zhí)行ACTIVATE命令),則
begin // Set the shift register to the appropriate value based on burst length.根據(jù)SC_BL(burst length)的值設置輸出移位寄存器oe_shift
if (SC_BL == 1) //若burst length==1(突發(fā)寫入長度為1個字),則oe_shift取值為0,進行一次移位操作后會使oe1清0,即輸出使能信號能持續(xù)一個時鐘周期
oe_shift <= 0;
else if (SC_BL == 2) //若burst length==2(突發(fā)寫入長度為2個字),則oe_shift取值為1,進行兩次移位操作后會使oe1清0,即輸出使能信號能持續(xù)兩個時鐘周期
oe_shift <= 1;
else if (SC_BL == 4) //若burst length==4(突發(fā)寫入長度為4個字),則oe_shift取值為7,進行四次移位操作后會使oe1清0,即輸出使能信號能持續(xù)四個時鐘周期
oe_shift <= 7;
else if (SC_BL == 8) //若burst length==8(突發(fā)寫入長度為8個字),則oe_shift取值為127,進行八次移位操作后會使oe1清0,即輸出使能信號能持續(xù)八個時鐘周期
oe_shift <= 127;
oe1 <= 1; //oe1置位
end
else //否則若do_writea1 != 1,即執(zhí)行完ACTIVATE命令,則
begin
oe_shift[6:0] <= oe_shift[7:1]; // Do the shift operation輸出移位寄存器oe_shift進行向右移位操作,最高位補0,最低位移進oe1,oe1移進oe2,oe2移進oe3,oe3移進oe4
oe_shift[7] <= 0;
oe1 <= oe_shift[0];
oe2 <= oe1;
oe3 <= oe2;
oe4 <= oe3;
if (SC_RC == 2) //若SC_RC == 2,即RAS to CAS Delay為2個時鐘周期,則oe3(oe1延遲2個時鐘周期的結果)賦給OE,否則必有SC_RC == 3(因為根據(jù)SDRAM資料,RAS to CAS Delay即tRCD只能取3CLKs或2CLKs),即RAS to CAS Delay為3個時鐘周期,則oe4(oe1延遲3個時鐘周期的結果)賦給OE
OE <= oe3;
else
OE <= oe4;
end
end
else //否則若SC_PM == 1,說明是頁寫入訪問模式,則
begin
if (do_writea1 == 1) // OE generation for page mode accesses 若do_writea1 == 1,即內(nèi)部寫命令有效,則oe4置位
oe4 <= 1;
else if (do_precharge == 1 | do_reada == 1 | do_refresh)// 否則若內(nèi)部寫命令無效,而內(nèi)部命令do_precharge或do_reada或do_refresh有效,則oe4清除
oe4 <= 0;
OE <= oe4; // oe4賦給OE
end
end
end
// This always block tracks the time between the activate command and the
// subsequent WRITEA or READA command, RC. The shift register is set using
// the configuration register setting SC_RC. The shift register is loaded with
// a single '1' with the position within the register dependent on SC_RC.
// When the '1' is shifted out of the register it sets so_rw which triggers
// a writea or reada command
//這個always塊監(jiān)測控制SDRAM執(zhí)行ACTIVATE命令和接下來的WRITEA or READA命令之間的時間間隔。當用戶輸入WRITEA or READA命令后,command module發(fā)出內(nèi)部命令do_reada == 1 | do_writea == 1,此時觸發(fā)SDRAM執(zhí)行ACTIVATE命令,然后等到do_rw==1時才觸發(fā)SDRAM執(zhí)行WRITEA or READA命令,等待的時間由SC_RC決定(必須保證CAS有效時才觸發(fā)SDRAM執(zhí)行WRITEA or READA命令),由本always塊監(jiān)測控制。
//讀寫移位寄存器用配置寄存器REG1中的SC_RC位段加載。讀寫移位寄存器中1加載的位置取決于SC_RC位段,當1移出讀寫移位寄存器時,do_rw被置位,該信號將觸發(fā)一個writea or reada命令
//(時鐘信號CLK上升沿)
always @(posedge CLK or negedge RESET_N)
begin
if (RESET_N == 0) //復位,清除rw_shift、do_rw
begin
rw_shift <= 0;
do_rw <= 0;
end
else
begin
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -