Advertisement
godar_

SDRAM_CONTROLLER.v

Aug 8th, 2017
550
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //define command
  2. //CKE - CS' - RAS' - CAS' - WE' - BA1 - BA0 - A10
  3. //{DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}
  4. //parameter DESL  = 8'b11xxxxxx;
  5. //parameter NOP      = 8'b10111xxx;
  6. //parameter BST  = 8'b10110xxx;
  7. //parameter READ  = 8'b10101xx0; //BA0 e BA1 vanno settati di volta in volta
  8. //parameter REAU  = 8'b10101xx1; //BA0 e BA1 vanno settati di volta in volta
  9. //parameter WRITE = 8'b10100xx0; //BA0 e BA1 vanno settati di volta in volta
  10. //parameter WRAU     = 8'b10100xx1; //BA0 e BA1 vanno settati di volta in volta
  11. //parameter ACT  = 8'b10011xxx; //BA0 BA1 e A10vanno settati di volta in volta
  12. //parameter PRE  = 8'b10010XX0; //BA0 e BA1 vanno settati di volta in volta
  13. //parameter PALL     = 8'b10010xx1;
  14. //parameter REF  = 8'b10001XXX;
  15. //parameter SELF     = 8'b10001xxx;
  16. //parameter MRS  = 8'b10000000;
  17. parameter DESL  = 8'b11000000;
  18. parameter NOP    = 8'b10111000;
  19. parameter BST    = 8'b10110000;
  20. parameter READ  = 8'b10101000; //BA0 e BA1 vanno settati di volta in volta
  21. parameter REAU  = 8'b10101001; //BA0 e BA1 vanno settati di volta in volta
  22. parameter WRITE = 8'b10100000; //BA0 e BA1 vanno settati di volta in volta
  23. parameter WRAU   = 8'b10100001; //BA0 e BA1 vanno settati di volta in volta
  24. parameter ACT    = 8'b10011000; //BA0 BA1 e A10vanno settati di volta in volta
  25. parameter PRE    = 8'b10010000; //BA0 e BA1 vanno settati di volta in volta
  26. parameter PALL   = 8'b10010001;
  27. parameter REF    = 8'b10001000;
  28. parameter SELF   = 8'b10001000;
  29. parameter MRS    = 8'b10000000;
  30.  
  31. //define STATE
  32. parameter INIT_STATE = 0;
  33. parameter NOP_STATE = 1;
  34. parameter IDLE_STATE = 2;
  35. parameter ACTIVE_STATE = 3; //alla fine di questo stato si deve controllare qual richiesta è avvenuta e si deve rimandare al proprio stato
  36. parameter READ_STATE = 4;
  37. parameter WRITE_STATE = 5;
  38. parameter READA_STATE = 6;
  39. parameter WRITEA_STATE = 7;
  40. parameter START_READ_STATE = 8;
  41. parameter START_WRITE_STATE = 9;
  42. parameter PRECHARGE_STATE = 10;
  43. parameter PRECHARGEALL_STATE = 11;
  44. parameter REFRESH_STATE = 12;
  45. parameter MRS_STATE = 13;
  46.  
  47. //parametri MRS
  48. parameter burstLength = 3'b011; //(3bit)
  49. parameter burstType = 0;    //(1bit) 0 = sequenziale, 1 = interlacciato
  50. parameter latency = 3;      //(3bit) CAS latency
  51. parameter opMode = 0;       //(2bit) normal operating mode;
  52. parameter writeBurst = 0;   //(1bit) 0 = burstLenght, 1 = single location access
  53.  
  54. //parametri ritardi (in colpi di clock) (potremmo dover sottrarre 1 ai ritardi, dal momento che noi cominciamo a contare il ritardo a partire dal nop e non dal comando principale)
  55. parameter clkTime = 10; //ns, periodo di clock
  56. parameter refreshTime = 6400000; //clock entro il quale devono essere esguiti 8192 refresh (=64ms/10ns)
  57. parameter averageRefreshTime = 760; //tempo medio fra un refresh e un altro. (=6400000/8192=781.25)
  58. parameter tCAC = 3; //CAS LATENCY   //tempo che intercorre fra l'invio del comando read/write e la disponibilità del dato (o l'istante in cui deve essere inviato)
  59. parameter tRCD = 3; //DELAY ACTIVE TO READ/WRITE    //fra l'active e read o write deve passare questo tempo
  60. parameter tRAC = 6;//tRCD + tCAC;   //RAS LATENCY //tempo che intercorre fra l'invio del comando e la disponibilità del dato (o di scrittura del dato)
  61. parameter tRC = 10; //tempo minimo che deve passare tra ACTIVE consecutivi
  62. parameter tRAS = 7; //tempo minimo fra active e precharge dello stesso bank (stesso bank?)
  63. parameter tRP  = 3; //tempo minimo fra precharge e successivo active sullo stesso bank
  64. parameter tRRD = 2; //tempo minimo fra ACTIVE di bank diversi
  65. parameter tDPL = 2; //tempo dopo il quale può essere esguito il precharge di un bank (e istante in cui avviene l'auto precharge)
  66. parameter tDAL = 5; //tempo minimo trascorso fra l'input dei dati e il successivo active/refresh
  67. parameter tMRD = 2; //tempo minimo che deve trascorrere fra l'invio della modalita MRS e l'invio del primo active
  68.  
  69. //parametri ritardi
  70.  
  71.  
  72. module SDRAM_CONTROLLER(
  73.     input rst_n,
  74.     input holdClk,
  75.     input ramClk,//il PLL viene implementato qui stesso (così come le FIFO)
  76.    
  77.     /////////////////////////////
  78.    
  79.     //read FIFO (tutti gli altri pin delle FIFo vengono definiti successivamente quando verranno inizializzate le FIFO)
  80.    
  81.     output isReadFIFOEmpty,     //controlla se la FIFO di lettura è vuota
  82.     output [15:0] OUTData [8],      //da qui vengono prelevati i dati appena letti dalla RAM
  83.    
  84.     //fine read FIFO
  85.    
  86.     output readAvailable,       //=1 se la lettura è stata eseguita e quindi dato disponibile in dataUT (??)
  87.     input readRq,                   //=1 quando si vuole eseguire una lettura (una volta completata la lettura)
  88.     input [1:0] rdBank,             //seleziona il bank
  89.     input [12:0] rdRow,             //seleziona la linea
  90.     input [9:0] rdColumn,           //seleziona la colonna
  91.    
  92.     /////////////////////////////
  93.    
  94.     //write FIFO
  95.    
  96.     output isWriteFIFOFull,     //controlla se la FIFO di scrittura è piena
  97.     input [15:0] INData [8],    //riceve i dati che verranno scritti in RAM
  98.    
  99.     //fine write FIFO
  100.    
  101. //  output writeBusy,               //durante una scrittura viene posto a 1 e impedisce scritture "contemporanee"
  102.     input writeRq,                  //=1 quando si vuole eseguire una scrittura
  103.     input [1:0] wrBank,             //seleziona il bank di partenza
  104.     input [12:0] wrRow,             //seleziona la linea di partenza
  105.     input [9:0] wrColumn,           //seleziona la colonna di partenza
  106.    
  107.     output reg busy,
  108.        
  109.     //////////// SDRAM //////////
  110.     output reg          [12:0]      DRAM_ADDR,
  111.     output reg           [1:0]      DRAM_BA,
  112.     output reg                      DRAM_CAS_N,
  113.     output reg                      DRAM_CKE,
  114.     output                          DRAM_CLK,
  115.     output reg                      DRAM_CS_N,
  116.     inout reg           [15:0]      DRAM_DQ,
  117.     output reg                      DRAM_LDQM,
  118.     output reg                      DRAM_RAS_N,
  119.     output reg                      DRAM_UDQM,
  120.     output reg                      DRAM_WE_N,
  121.     output isInit
  122. );
  123.  
  124.  
  125.  
  126.  
  127.    
  128.    
  129.     //registri utilizzati per memorizzare il contenuto dei vari input/output della ram
  130. //  reg [12:0] ADDR;
  131. //  reg [1:0] BA;
  132. //  reg CAS_N;
  133. //  reg CKE;
  134. //  reg CS_N;
  135. //  reg [15:0] DQ;
  136. //  reg LDQM;
  137. //  reg RAS_N;
  138. //  reg UDQM;
  139. //  reg WE_N;
  140.    
  141.     assign DRAM_CLK = ramClk;
  142.     reg [15:0] DRAM_DQ_reg;
  143.     assign DRAM_DQ = DRAM_DQ_reg;
  144.  
  145.     //REG interni ----------------------------------------
  146.     reg wasInit; //diventa 1 dopo il primo init
  147.     reg initStarted;
  148.     reg readAvailableReg;
  149.     reg [7:0] currentState;
  150.     reg [15:0] currentWait;
  151. //  reg [7:0] nextState;
  152.  
  153.     //reg [7:0] typeReq; //(?) contiene il tipo di richiesta (READ, WRITEA, ecc) in modo da conoscere lo stato dopo l'activate
  154.     //reg [31:0] wait_count; //contiene il numero di cicli da attendere. viene decrementato ciclo per ciclo
  155.    
  156.     reg [15:0] refreshCount;   
  157.     reg [31:0] elapsedRefreshTime;
  158.     reg startReadRamClk;    //quando 1, in prossimità del posedge di ramClk, si possono leggere i dati dal bus d della ram e si possono immettere nella fifo di lettura (magari gli cambiamo nome poi)
  159.    
  160.     reg busyReg;
  161.     assign busy = busyReg | ~wasInit;
  162.     assign isInit = wasInit;
  163.     assign readAvailable = readAvailableReg;
  164.     reg [4:0] readCount;
  165.     reg test;
  166.     //fine REG interni -----------------------------------
  167.    
  168.    
  169. //  //inizio definizione FIFO---------------------------------------------------
  170. //  reg readClear, writeClear; //clear asincrono fifo //potrebbe essere necessario inviarlo in qualche momento che in questo istante non mi ricordo
  171. // 
  172. //  reg [15:0] readINData, writeOUTData;
  173. //  reg readWrReq; //conviene che questi siano reg in modo da poterli disattivare
  174. //  reg writeRdReq; //conviene che questi siano reg in modo da poterli disattivare
  175. //  wire writeEmpty; //read/write indicano la FIFO di appartenenza
  176. //  wire readFull;  //read/write indicano la FIFO di appartenenza
  177. //  wire [2:0] readUsed, writeUsed;
  178. //
  179. //  FIFO read(readClear, readINData[15:0], holdClk, extractReq, holdClk, readWrReq, OUTData[15:0], isReadFIFOEmpty, readUsed, readFull);                //read si intende dalla ram
  180. //  FIFO write(writeClear, INData[15:0], holdClk, writeRdReq, holdClk, insertReq, writeOUTData[15:0], writeEmpty, writeUsed, isWriteFIFOFull);  //write si intende in ram
  181. //  //fine dichiarazione FIFO---------------------------------------------------
  182.    
  183.     reg [15:0] waitQueue [32];// = '{16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0,
  184.                                             //16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'd24000};
  185.     //inizio FIFO comandi
  186.     reg [15:0] stateQueue [32];// = '{NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
  187.                                              //NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
  188.                                              //NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, INIT_STATE};
  189.     reg [4:0] firstState;// = 31; //punta al primo comando da eseguire
  190.     reg [4:0] lastState;// = 30; //punta all'ultimo posto in cui può essere inserito un comando
  191.     wire emptyState = (lastState == firstState);
  192.     wire fullState = ((lastState-2) == firstState);
  193.     //fine FIFO comandi
  194.    
  195.     //inizio FIFO read
  196.     reg [15:0] readQueue [8];
  197.     reg [2:0] firstRead; //punta al primo comando da eseguire
  198.     reg [2:0] lastRead; //punta all'ultimo posto in cui può essere inserito un comando
  199.     wire emptyRead = lastRead == firstRead;
  200.     wire fullRead = (lastRead-1) == firstRead;
  201.     assign isReadFIFOEmpty = emptyRead;
  202.     assign OUTData = readQueue; //verificare se OUTData viene effettivamente scritto
  203.     //fine FIFO read
  204.    
  205.     //inizio FIFO read
  206.     reg [15:0] writeQueue [8];// = INData;
  207.     reg [2:0] firstWrite; //punta al primo comando da eseguire
  208.     reg [2:0] lastWrite; //punta all'ultimo posto in cui può essere inserito un comando
  209.     wire emptyWrite = lastWrite == firstWrite;
  210.     wire fullWrite = (lastWrite-1) == firstWrite;
  211.     assign isWriteFIFOFull = fullWrite;
  212.     //fine FIFO read
  213.    
  214.    
  215.    
  216.     //tecnicamente il codice sotto dovrebbe impostare il nextState a REFRESH nel primo istante utile in cui viene il prossimo stato risulta di IDLE.
  217.     //ATTENZIONE: sarebbe più corretto inserire tanti refresh quanti sono i refresh "mancanti". servirebbe un ciclo for per fare questo perchè al momento non si ha la garanzia che vengano eseguiti 8192 refresh in 64ms
  218.  
  219.  
  220. integer i;
  221. initial
  222. begin
  223.         wasInit = 0; //diventa 1 dopo il primo init
  224.         initStarted = 1;
  225.            
  226.         waitQueue = '{16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0,
  227.                                  16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'd24000};
  228.                                      
  229.         stateQueue = '{NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
  230.                              NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
  231.                              NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, INIT_STATE};
  232.  
  233.         readCount = 0;
  234.         refreshCount[15:0] = 16'b0;
  235.         elapsedRefreshTime[31:0] = 32'b0;
  236.         startReadRamClk = 0;
  237.         readAvailableReg = 0;
  238.            
  239.         firstState[4:0] = 5'd31;
  240.         lastState[4:0] = 5'd30;
  241.            
  242.         firstRead[2:0] = 0;
  243.         lastRead[2:0] = 0;
  244.            
  245.         firstWrite[2:0] = 8;
  246.         lastWrite[2:0] = 1;
  247.            
  248. end
  249.  
  250. always @(posedge holdClk)
  251. begin
  252.     if (rst_n == 0)
  253.     begin
  254. //          initStarted = 0;
  255. //      end
  256. //     
  257. //      if (initStarted == 0)
  258. //      begin
  259.         wasInit  = 0; //diventa 1 dopo il primo init
  260.         initStarted  = 1;
  261.            
  262.         waitQueue  = '{16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0,
  263.                                  16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'b0, 16'd24000};
  264.                                      
  265.         stateQueue  = '{NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
  266.                              NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
  267.                              NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, INIT_STATE};
  268.  
  269.         readCount  = 0;
  270.         refreshCount[15:0]  = 16'b0;
  271.         elapsedRefreshTime[31:0]  = 32'b0;
  272.         startReadRamClk  = 0;
  273.         readAvailableReg  = 0;
  274.            
  275.         firstState[4:0]  = 5'd31;
  276.         lastState[4:0]  = 5'd30;
  277.            
  278.         firstRead[2:0]  = 0;
  279.         lastRead[2:0]  = 0;
  280.            
  281.         firstWrite[2:0]  = 8;
  282.         lastWrite[2:0]  = 1;
  283.            
  284.            
  285.     end
  286.     else
  287.     begin
  288.        
  289.         if (elapsedRefreshTime < refreshTime)
  290.         begin
  291.             elapsedRefreshTime  = elapsedRefreshTime + 1;
  292.         end
  293.         else
  294.         begin
  295.             refreshCount  = 0;
  296.             elapsedRefreshTime  = 0;
  297.         end
  298.    
  299.         //questo sotto forse da problemi (aggiunge sempre l'init)
  300.     //  if (wasInit == 0)
  301.     //  begin
  302.     //      stateQueue[lastState] = INIT_STATE;
  303.     //      lastState = lastState - 1;
  304.     //  end
  305.         if (writeRq && busy == 0)
  306.         begin
  307.             stateQueue[lastState] = ACTIVE_STATE;
  308.             waitQueue[lastState] = 0;
  309.             lastState = lastState - 1;
  310.            
  311.             stateQueue[lastState] = NOP_STATE;
  312.             waitQueue[lastState] = tRCD - 2;           
  313.             lastState = lastState - 1;
  314.            
  315.             stateQueue[lastState] = WRITEA_STATE; //in corrispondenza di questo mandare il primo dato
  316.             waitQueue[lastState] = 0;      
  317.             lastState = lastState - 1;
  318.            
  319.             stateQueue[lastState] = START_WRITE_STATE;
  320.             waitQueue[lastState] = 0;      
  321.             lastState = lastState - 1;
  322.            
  323.             stateQueue[lastState] = START_WRITE_STATE;
  324.             waitQueue[lastState] = 0;      
  325.             lastState = lastState - 1;
  326.            
  327.             stateQueue[lastState] = START_WRITE_STATE;
  328.             waitQueue[lastState] = 0;      
  329.             lastState = lastState - 1;         
  330.  
  331.             stateQueue[lastState] = START_WRITE_STATE;
  332.             waitQueue[lastState] = 0;      
  333.             lastState = lastState - 1;
  334.            
  335.             stateQueue[lastState] = START_WRITE_STATE;
  336.             waitQueue[lastState] = 0;      
  337.             lastState = lastState - 1;
  338.            
  339.             stateQueue[lastState] = START_WRITE_STATE;
  340.             waitQueue[lastState] = 0;      
  341.             lastState = lastState - 1;
  342.  
  343.             stateQueue[lastState] = START_WRITE_STATE;
  344.             waitQueue[lastState] = 0;      
  345.             lastState = lastState - 1;
  346.            
  347.             stateQueue[lastState] = NOP_STATE;
  348.             waitQueue[lastState] = tRP;    
  349.             lastState = lastState - 1;
  350.            
  351.             for (i = 0; i<8; i=i+1)
  352.             begin
  353.                 writeQueue[i][15:0] = INData[i][15:0];
  354.             end
  355.            
  356.         end
  357.  
  358.         if (readRq && busy == 0)
  359.         begin
  360.            
  361.             stateQueue[lastState] = ACTIVE_STATE;
  362.             waitQueue[lastState] = 0;
  363.             lastState = lastState - 1;
  364.            
  365.             stateQueue[lastState] = NOP_STATE;
  366.             waitQueue[lastState] = tRCD - 2;           
  367.             lastState = lastState - 1;
  368.            
  369.             stateQueue[lastState] = READA_STATE;
  370.             waitQueue[lastState] = 0;      
  371.             lastState = lastState - 1;
  372.            
  373.             stateQueue[lastState] = NOP_STATE;
  374.             waitQueue[lastState] = tCAC - 2;       
  375.             lastState = lastState - 1;
  376.            
  377.             stateQueue[lastState] = START_READ_STATE;
  378.             waitQueue[lastState] = 0;      
  379.             lastState = lastState - 1;
  380.            
  381.             stateQueue[lastState] = START_READ_STATE;
  382.             waitQueue[lastState] = 0;      
  383.             lastState = lastState - 1;
  384.            
  385.             stateQueue[lastState] = START_READ_STATE;
  386.             waitQueue[lastState] = 0;      
  387.             lastState = lastState - 1;
  388.            
  389.             stateQueue[lastState] = START_READ_STATE;
  390.             waitQueue[lastState] = 0;      
  391.             lastState = lastState - 1;
  392.            
  393.             stateQueue[lastState] = START_READ_STATE;
  394.             waitQueue[lastState] = 0;      
  395.             lastState = lastState - 1;
  396.            
  397.             stateQueue[lastState] = START_READ_STATE;
  398.             waitQueue[lastState] = 0;      
  399.             lastState = lastState - 1;
  400.            
  401.             stateQueue[lastState] = START_READ_STATE;
  402.             waitQueue[lastState] = 0;      
  403.             lastState = lastState - 1;
  404.            
  405.             stateQueue[lastState] = START_READ_STATE;
  406.             waitQueue[lastState] = 0;      
  407.             lastState = lastState - 1;
  408.         end
  409.  
  410.    
  411.         if (lastState == firstState) //coda vuota //è il posto giusto????
  412.         begin //inserisco in coda un nuovo comando, quello di IDLE
  413.             if(elapsedRefreshTime/(refreshCount + 1) > averageRefreshTime) //se vero serve refresh
  414.             begin
  415.                 stateQueue[firstState] = PRECHARGEALL_STATE;
  416.                 waitQueue[firstState] = 0;
  417.                
  418.                 stateQueue[firstState - 1] = NOP_STATE;
  419.                 waitQueue[firstState - 1] = tRP - 2;       
  420.                
  421.                 stateQueue[firstState - 2] = REFRESH_STATE; //sostituisco il corrente comando di IDLE con il comando di refresh
  422.                 waitQueue[firstState - 2] = 0;
  423.                
  424.                 stateQueue[firstState - 3] = NOP_STATE;
  425.                 waitQueue[firstState - 3] = tRC - 2;
  426.                 lastState = lastState - 4;
  427.  
  428.             end
  429.             else
  430.             begin
  431.                 stateQueue[firstState] = IDLE_STATE;
  432.                 waitQueue[firstState] = 0;
  433.                 lastState = lastState - 1;
  434.             end
  435.         end
  436.         currentWait = waitQueue[firstState + 1];
  437.         if (waitQueue[firstState + 1] != 0)
  438.         begin
  439.             waitQueue[firstState + 1]  = waitQueue[firstState + 1] - 1;
  440.         end
  441.         else   
  442.         begin
  443.            
  444.             currentState  = stateQueue[firstState];
  445.            
  446.             //qui comincia la macchina a stati con la valutazione dei vari comandi
  447.             /////////////////////////////////
  448.             case (stateQueue[firstState])
  449.                 INIT_STATE: begin
  450.                     busyReg  = 1;
  451.                     wasInit  = 0;
  452.                     firstState  = 31;
  453.                     lastState  = 30;
  454.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = NOP;
  455.                     //waitQueue[firstState]  = 20000;
  456.                     DRAM_LDQM  = 1'b1;
  457.                     DRAM_UDQM  = 1'b1;
  458.                    
  459.                     stateQueue[lastState] = PRECHARGEALL_STATE;
  460.                     waitQueue[lastState] = tRP - 1;     //giusto tRP - 1
  461.                     lastState = lastState - 1;
  462.                    
  463.                    
  464.                    
  465.                     for (i = 0; i < 8; i = i + 1)
  466.                     begin
  467.                         stateQueue[lastState] = REFRESH_STATE;
  468.                         waitQueue[lastState] = 0;      
  469.                         lastState = lastState - 1;
  470.                        
  471.                         stateQueue[lastState] = NOP_STATE;
  472.                         waitQueue[lastState] = tRC - 2;
  473.                         lastState = lastState - 1;
  474.                     end
  475.                    
  476.                     //
  477.                     stateQueue[lastState] = MRS_STATE;
  478.                     waitQueue[lastState] = 0;      
  479.                     lastState = lastState - 1; 
  480.  
  481.                     stateQueue[lastState] = NOP_STATE;
  482.                     waitQueue[lastState] = tMRD - 2;       
  483.                     lastState = lastState - 1;     
  484.                 end
  485.                 NOP_STATE: begin
  486.                     busyReg  = 1;
  487.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = NOP; //questo è un comando, non è uno stato!
  488.                     end
  489.                 IDLE_STATE:
  490.                     begin
  491.                         {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = NOP; //questo è un comando, non è uno stato!
  492.                         busyReg  = 0;
  493.                         startReadRamClk  = 0;
  494.                     end
  495.                 ACTIVE_STATE:
  496.                     begin
  497.                         busyReg  = 1;
  498.                         case (stateQueue[firstState-2]) //il successivo � NOP e quello dopo ancora � quello che dobbiamo analizzare
  499.                             READ_STATE:
  500.                             begin
  501.                                 {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = ACT;
  502.                                 DRAM_ADDR[12:0]  = rdRow[12:0];
  503.                                 DRAM_BA[1:0]  = rdBank[1:0];
  504.                                 firstRead  = 0;
  505.                                 lastRead  = 0;
  506.                                 readCount  = 0;
  507.                                 readAvailableReg  = 0;
  508.                                 DRAM_DQ_reg  = 16'bz;
  509.  
  510.                             end
  511.                             WRITE_STATE:
  512.                             begin
  513.                                 {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = ACT;
  514.                                 DRAM_ADDR[12:0]  = wrRow[12:0];
  515.                                 DRAM_BA[1:0]  = wrBank[1:0];
  516.                                 firstWrite  = 8;
  517.                                 lastWrite  = 1; //corrispondono a un full
  518.  
  519.                             end
  520.                             READA_STATE:
  521.                             begin
  522.                                 {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = ACT;
  523.                                 DRAM_ADDR[12:0]  = rdRow[12:0];
  524.                                 DRAM_BA[1:0]  = rdBank[1:0];
  525.                                 firstRead  = 0;
  526.                                 lastRead  = 0;
  527.                                 readCount  = 0;
  528.                                 readAvailableReg  = 0; 
  529.                                 DRAM_DQ_reg  = 16'bz;
  530.                             end
  531.                             WRITEA_STATE:
  532.                             begin
  533.                                 {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = ACT;
  534.                                 DRAM_ADDR[12:0]  = wrRow[12:0];
  535.                                 DRAM_BA[1:0]  = wrBank[1:0];
  536.                                 firstWrite  = 8;
  537.                                 lastWrite  = 1; //corrispondono a un full                              
  538.                             end
  539.                         endcase
  540.                     end
  541.                 READ_STATE: begin
  542.                     busyReg  = 1;
  543.                     DRAM_LDQM  = 1'b0;
  544.                     DRAM_UDQM  = 1'b0;
  545.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = READ;
  546.                     DRAM_ADDR[9:0]  = rdColumn;
  547.                     DRAM_BA[1:0]  = rdBank;
  548.                    
  549.                 end
  550.                 WRITE_STATE: begin
  551.                     busyReg  = 1;
  552.                     DRAM_LDQM  = 1'b0;
  553.                     DRAM_UDQM  = 1'b0;
  554.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = WRITE;
  555.                     DRAM_ADDR[9:0]  = wrColumn;
  556.                     DRAM_BA[1:0]  = wrBank;
  557.  
  558.                     DRAM_DQ_reg  = writeQueue[firstWrite];
  559.                     firstWrite  = firstWrite - 1; //MSB - LSB
  560.                     //NOTA: usare il mascheramento per non sovrascrivere i dati che non si vuole modificare (in caso di lunghezzadi scrittura minore di 8)
  561.  
  562.                
  563.                 end
  564.                 READA_STATE: begin
  565.                     busyReg  = 1;
  566.                     DRAM_LDQM  = 1'b0;
  567.                     DRAM_UDQM  = 1'b0;
  568.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = REAU;
  569.                     DRAM_ADDR[9:0]  = rdColumn;
  570.                     DRAM_BA[1:0]  = rdBank;            
  571.                    
  572.                 end
  573.                 WRITEA_STATE: begin
  574.                     busyReg  = 1;
  575.                     DRAM_LDQM  = 1'b0;
  576.                     DRAM_UDQM  = 1'b0;
  577.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = WRAU;
  578.                     DRAM_ADDR[9:0]  = wrColumn;
  579.                     DRAM_BA[1:0]  = wrBank;
  580.                    
  581.                     firstWrite  = firstWrite - 1; //MSB - LSB
  582.                     DRAM_DQ_reg  = writeQueue[firstWrite];
  583.                    
  584.                
  585.                 end
  586.                 START_READ_STATE: begin
  587.                     busyReg  = 1;
  588.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = NOP;
  589.                     lastRead  = lastRead - 1;
  590.                     DRAM_DQ_reg  = 16'bz;
  591.                     if (readCount < 8)
  592.                     begin
  593.                         readCount  = readCount + 1;
  594.                         startReadRamClk  = 1;                  
  595.                     end
  596.                     else
  597.                     begin
  598.                         startReadRamClk  = 0;
  599.                         readAvailableReg  = 1;
  600.                     end                
  601.                 end
  602.                 START_WRITE_STATE: begin
  603.                 {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = NOP;
  604.                 DRAM_LDQM  = 1'b0;
  605.                 DRAM_UDQM  = 1'b0;
  606. //                  if (firstWrite > 0)
  607. //                  begin
  608.                         DRAM_DQ_reg  = writeQueue[firstWrite];
  609.                         firstWrite  = firstWrite - 1; //MSB - LSB
  610. //                  end
  611.                 end
  612.                 PRECHARGE_STATE: begin
  613.                     busyReg  = 1;
  614.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = PRE;
  615.  
  616.                     //wait_count  = tRP;
  617.                 end
  618.                 PRECHARGEALL_STATE: begin
  619.                     busyReg  = 1;
  620.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = PALL;
  621.  
  622.                     //wait_count  = tRP;
  623.                 end
  624.                 REFRESH_STATE: begin
  625.                     busyReg  = 1;
  626.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = REF;
  627.                     refreshCount  = refreshCount + 1;
  628.                    
  629.                 end
  630.                 MRS_STATE: begin
  631.                     busyReg  = 1;
  632.                     {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}  = MRS;
  633.                     DRAM_ADDR[2:0]  = burstLength;
  634.                     DRAM_ADDR[3]  = burstType;
  635.  
  636.                     DRAM_ADDR[6:4]  = latency;
  637.                     DRAM_ADDR[8:7]  = opMode;
  638.                     DRAM_ADDR[9]  = writeBurst;
  639.                     {DRAM_BA[1:0], DRAM_ADDR[12:10]}  = 5'b0; //Per garantire compaitibilità con altre RAM
  640.                    
  641.                     refreshCount  = 0;
  642.                     elapsedRefreshTime  = 0;
  643.                     wasInit  = 1;
  644.                 end
  645.                 default begin
  646.  
  647.                
  648.                
  649.  
  650.                 end
  651.             endcase
  652.             firstState  = firstState - 1; //sono passato al comando successivo 
  653.             /////////////////////////////////
  654.         end
  655.     end
  656. end
  657.    
  658.    
  659.     always @(posedge ramClk)
  660.     begin
  661.  
  662.         if (startReadRamClk)
  663.         begin
  664.             test  = ~test;
  665.             readQueue[lastRead]  = DRAM_DQ_reg[15:0];
  666.         end        
  667.     end
  668.    
  669. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement