📄 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 + -