?? command.v
字號:
if ((do_reada == 1) | (do_writea == 1)) //若內部讀命令do_reada或內部寫命令do_writea有效(此時將首先發出ACTIVATE命令),則
begin
if (SC_RC == 1) // Set the shift register,根據SC_RC的值設置讀寫移位寄存器。若SC_RC == 1,則do_rw置位,即在內部命令do_reada或do_writea有效后(即發出ACTIVATE命令后)1個時鐘周期可觸發讀寫操作
do_rw <= 1;
else if (SC_RC == 2) //若SC_RC == 2,則讀寫移位寄存器rw_shift賦初值為1,只有進行一次右移操作,do_rw才會置位,因此在內部命令do_reada或do_writea有效后(即發出ACTIVATE命令后)2個時鐘周期才會觸發讀寫操作
rw_shift <= 1;
else if (SC_RC == 3) //若SC_RC == 3,則讀寫移位寄存器rw_shift賦初值為2,只有進行兩次右移操作,do_rw才會置位,因此在內部命令do_reada或do_writea有效后(即發出ACTIVATE命令后)3個時鐘周期才會觸發讀寫操作
rw_shift <= 2;
end
else //否則內部讀寫命令都無效,則對讀寫移位寄存器rw_shift進行向右移位操作,最高位補0,最低位進入do_rw
begin
rw_shift[2:0] <= rw_shift[3:1]; // perform the shift operation
rw_shift[3] <= 0;
do_rw <= rw_shift[0];
end
end
end
// This always block generates the command acknowledge, CM_ACK, signal.
// It also generates the acknowledge signal, REF_ACK, that acknowledges
// a refresh request that was generated by the internal refresh timer circuit.
//這個always塊產生命令確認信號CM_ACK,也產生刷新請求確認信號REF_ACK(該刷新請求由內部刷新定時器電路產生),輸出給control_interface模塊。
//(時鐘信號CLK上升沿)
always @(posedge CLK or negedge RESET_N)
begin
if (RESET_N == 0)
begin
CM_ACK <= 0;
REF_ACK <= 0;
end
else
begin
if (do_refresh == 1 & REF_REQ == 1) // Internal refresh timer refresh request 若內部命令do_refresh且內部刷新請求有效,則刷新請求確認信號REF_ACK置位
REF_ACK <= 1;
else if ((do_refresh == 1) | (do_reada == 1) | (do_writea == 1) | (do_precharge == 1) // externa commands否則若其他一些內部命令有效,則命令確認信號CM_ACK置位
| (do_load_mode))
CM_ACK <= 1;
else //否則若沒有任何內部命令和內部刷新請求有效,則這兩個確認信號清除
begin
REF_ACK <= 0;
CM_ACK <= 0;
end
end
end
// This always block generates the address, cs, cke, and command signals(ras,cas,wen)
// 這個always塊產生控制SDRAM需要的一些信號address, cs, cke, and command signals(ras,cas,wen),輸出給頂層模塊sdr_sdram,用來控制SDRAM
//(時鐘信號CLK上升沿)
always @(posedge CLK ) begin
if (RESET_N==0) begin //復位將這些控制信號全部清除
SA <= 0;
BA <= 0;
CS_N <= 1;
RAS_N <= 1;
CAS_N <= 1;
WE_N <= 1;
CKE <= 0;
end
else begin //否則,
CKE <= 1; //CKE置位,以使能SDRAM的時鐘信號
// Generate SA 產生SA、BA、CS_N
if (do_writea == 1 | do_reada == 1) // ACTIVATE command is being issued, so present the row address 若內部ACTIVATE命令有效,則將行地址送SA
SA <= rowaddr;
else
SA <= coladdr; // else alway present column address否則總是列地址送SA
if ((do_rw==1) | (do_precharge)) //若讀寫觸發信號有效或內部命令do_precharge有效,則將SC_PM取反賦給SA[10]。若SC_PM==0(即正常模式),則SA[10]取1;對讀寫命令而言,自動precharge有效;對precharge命令而言,所有bank都執行precharge。若SC_PM==1(即頁寫入訪問模式),則SA[10]取0;對讀寫命令而言,自動precharge無效,若要讀SDRAM中的不同行,需由用戶發出precharge命令來關閉相應bank,之后再讀;對precharge命令而言,只有被BA選中的bank才執行precharge命令。
SA[10] <= !SC_PM; // set SA[10] for autoprecharge read/write or for a precharge all command
// don't set it if the controller is in page mode.
if (do_precharge==1 | do_load_mode==1)
BA <= 0; // Set BA=0 if performing a precharge or load_mode command 若內部命令do_precharge 或do_load_mode有效,則bank選擇地址賦0(根據手冊,BA1/BA0 must be issued 0/0 in the mode register set)。而對precharge命令而言,若SC_PM==1,BA取0將設置bank0執行precharge命令;若SC_PM==0,BA的設置不起作用,所有bank都執行precharge命令。
else
BA <= bankaddr[1:0]; // else set it with the appropriate address bits 否則bank選擇地址bankaddr[1:0]賦給BA
if (do_refresh==1 | do_precharge==1 | do_load_mode==1)
CS_N <= 0; // Select both chip selects if performing
else // refresh, precharge(all) or load_mode 若內部命令do_refresh、do_precharge、do_load_mode有效,則片選信號位都有效,即兩個SDRAM都選中
begin
CS_N[0] <= SADDR[`ASIZE-1]; // else set the chip selects based off of the
CS_N[1] <= ~SADDR[`ASIZE-1]; // msb address bit 否則CS_N[0]取地址線最高位,CS_N[1]取地址線最高位的反,即地址線最高位用作SDRAM片選信號線
end
//Generate the appropriate logic levels on RAS_N, CAS_N, and WE_N
//depending on the issued command.
//根據執行的命令產生合適的RAS_N, CAS_N, and WE_N信號,輸出給頂層模塊sdr_sdram,用來控制SDRAM,參看SDRAM手冊
if (do_refresh==1) begin // Refresh(刷新,包括隱藏的刷新請求和刷新命令): S=00, RAS=0, CAS=0, WE=1
RAS_N <= 0;
CAS_N <= 0;
WE_N <= 1;
end
else if ((do_precharge==1) & ((oe4 == 1) | (rw_flag == 1))) begin // burst terminate if write is active突發終止操作
RAS_N <= 1; // 若在oe4有效(即輸出已經使能,已經開始寫操作)或rw_flag標志為讀(已經發出讀內部命令)時,do_precharge內部命令有效,則執行突發終止操作??(Burst Termination命令不是只能終止讀操作么?如果是終止讀寫操作就應該用precharge命令呀?)
CAS_N <= 1;
WE_N <= 0;
end
else if (do_precharge==1) begin // Precharge All(Precharge命令): S=00, RAS=0, CAS=1, WE=0
RAS_N <= 0;
CAS_N <= 1;
WE_N <= 0;
end
else if (do_load_mode==1) begin // Mode Write(載入模式命令load_mode): S=00, RAS=0, CAS=0, WE=0
RAS_N <= 0;
CAS_N <= 0;
WE_N <= 0;
end
else if (do_reada == 1 | do_writea == 1) begin // Activate(激活命令): S=01 or 10, RAS=0, CAS=1, WE=1
RAS_N <= 0;
CAS_N <= 1;
WE_N <= 1;
end
else if (do_rw == 1) begin // Read/Write(讀寫命令): S=01 or 10, RAS=1, CAS=0, WE=0 or 1
RAS_N <= 1;
CAS_N <= 0;
WE_N <= rw_flag;
end
else begin // No Operation(空操作命令): RAS=1, CAS=1, WE=1 沒有以上內部命令時,給出空操作命令
RAS_N <= 1;
CAS_N <= 1;
WE_N <= 1;
end
end
end
endmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -