⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 command.v

📁 SDRAM控制器Verilog员代码
💻 V
📖 第 1 页 / 共 3 页
字号:
                
                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 + -