Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //define command
- //CKE - CS' - RAS' - CAS' - WE' - BA1 - BA0 - A10
- //{DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]}
- //parameter DESL = 8'b11xxxxxx;
- //parameter NOP = 8'b10111xxx;
- //parameter BST = 8'b10110xxx;
- //parameter READ = 8'b10101xx0; //BA0 e BA1 vanno settati di volta in volta
- //parameter REAU = 8'b10101xx1; //BA0 e BA1 vanno settati di volta in volta
- //parameter WRITE = 8'b10100xx0; //BA0 e BA1 vanno settati di volta in volta
- //parameter WRAU = 8'b10100xx1; //BA0 e BA1 vanno settati di volta in volta
- //parameter ACT = 8'b10011xxx; //BA0 BA1 e A10vanno settati di volta in volta
- //parameter PRE = 8'b10010XX0; //BA0 e BA1 vanno settati di volta in volta
- //parameter PALL = 8'b10010xx1;
- //parameter REF = 8'b10001XXX;
- //parameter SELF = 8'b10001xxx;
- //parameter MRS = 8'b10000000;
- parameter DESL = 8'b11000000;
- parameter NOP = 8'b10111000;
- parameter BST = 8'b10110000;
- parameter READ = 8'b10101000; //BA0 e BA1 vanno settati di volta in volta
- parameter REAU = 8'b10101001; //BA0 e BA1 vanno settati di volta in volta
- parameter WRITE = 8'b10100000; //BA0 e BA1 vanno settati di volta in volta
- parameter WRAU = 8'b10100001; //BA0 e BA1 vanno settati di volta in volta
- parameter ACT = 8'b10011000; //BA0 BA1 e A10vanno settati di volta in volta
- parameter PRE = 8'b10010000; //BA0 e BA1 vanno settati di volta in volta
- parameter PALL = 8'b10010001;
- parameter REF = 8'b10001000;
- parameter SELF = 8'b10001000;
- parameter MRS = 8'b10000000;
- //define STATE
- parameter INIT_STATE = 0;
- parameter NOP_STATE = 1;
- parameter IDLE_STATE = 2;
- parameter ACTIVE_STATE = 3; //alla fine di questo stato si deve controllare qual richiesta è avvenuta e si deve rimandare al proprio stato
- parameter READ_STATE = 4;
- parameter WRITE_STATE = 5;
- parameter READA_STATE = 6;
- parameter WRITEA_STATE = 7;
- parameter START_READ_STATE = 8;
- parameter START_WRITE_STATE = 9;
- parameter PRECHARGE_STATE = 10;
- parameter PRECHARGEALL_STATE = 11;
- parameter REFRESH_STATE = 12;
- parameter MRS_STATE = 13;
- //parametri MRS
- parameter burstLength = 3'b011; //(3bit)
- parameter burstType = 0; //(1bit) 0 = sequenziale, 1 = interlacciato
- parameter latency = 3; //(3bit) CAS latency
- parameter opMode = 0; //(2bit) normal operating mode;
- parameter writeBurst = 0; //(1bit) 0 = burstLenght, 1 = single location access
- //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)
- parameter clkTime = 10; //ns, periodo di clock
- parameter refreshTime = 6400000; //clock entro il quale devono essere esguiti 8192 refresh (=64ms/10ns)
- parameter averageRefreshTime = 760; //tempo medio fra un refresh e un altro. (=6400000/8192=781.25)
- 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)
- parameter tRCD = 3; //DELAY ACTIVE TO READ/WRITE //fra l'active e read o write deve passare questo tempo
- 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)
- parameter tRC = 10; //tempo minimo che deve passare tra ACTIVE consecutivi
- parameter tRAS = 7; //tempo minimo fra active e precharge dello stesso bank (stesso bank?)
- parameter tRP = 3; //tempo minimo fra precharge e successivo active sullo stesso bank
- parameter tRRD = 2; //tempo minimo fra ACTIVE di bank diversi
- parameter tDPL = 2; //tempo dopo il quale può essere esguito il precharge di un bank (e istante in cui avviene l'auto precharge)
- parameter tDAL = 5; //tempo minimo trascorso fra l'input dei dati e il successivo active/refresh
- parameter tMRD = 2; //tempo minimo che deve trascorrere fra l'invio della modalita MRS e l'invio del primo active
- //parametri ritardi
- module SDRAM_CONTROLLER(
- input rst_n,
- input holdClk,
- input ramClk,//il PLL viene implementato qui stesso (così come le FIFO)
- /////////////////////////////
- //read FIFO (tutti gli altri pin delle FIFo vengono definiti successivamente quando verranno inizializzate le FIFO)
- output isReadFIFOEmpty, //controlla se la FIFO di lettura è vuota
- output [15:0] OUTData [8], //da qui vengono prelevati i dati appena letti dalla RAM
- //fine read FIFO
- output readAvailable, //=1 se la lettura è stata eseguita e quindi dato disponibile in dataUT (??)
- input readRq, //=1 quando si vuole eseguire una lettura (una volta completata la lettura)
- input [1:0] rdBank, //seleziona il bank
- input [12:0] rdRow, //seleziona la linea
- input [9:0] rdColumn, //seleziona la colonna
- /////////////////////////////
- //write FIFO
- output isWriteFIFOFull, //controlla se la FIFO di scrittura è piena
- input [15:0] INData [8], //riceve i dati che verranno scritti in RAM
- //fine write FIFO
- // output writeBusy, //durante una scrittura viene posto a 1 e impedisce scritture "contemporanee"
- input writeRq, //=1 quando si vuole eseguire una scrittura
- input [1:0] wrBank, //seleziona il bank di partenza
- input [12:0] wrRow, //seleziona la linea di partenza
- input [9:0] wrColumn, //seleziona la colonna di partenza
- output reg busy,
- //////////// SDRAM //////////
- output reg [12:0] DRAM_ADDR,
- output reg [1:0] DRAM_BA,
- output reg DRAM_CAS_N,
- output reg DRAM_CKE,
- output DRAM_CLK,
- output reg DRAM_CS_N,
- inout reg [15:0] DRAM_DQ,
- output reg DRAM_LDQM,
- output reg DRAM_RAS_N,
- output reg DRAM_UDQM,
- output reg DRAM_WE_N,
- output isInit
- );
- //registri utilizzati per memorizzare il contenuto dei vari input/output della ram
- // reg [12:0] ADDR;
- // reg [1:0] BA;
- // reg CAS_N;
- // reg CKE;
- // reg CS_N;
- // reg [15:0] DQ;
- // reg LDQM;
- // reg RAS_N;
- // reg UDQM;
- // reg WE_N;
- assign DRAM_CLK = ramClk;
- reg [15:0] DRAM_DQ_reg;
- assign DRAM_DQ = DRAM_DQ_reg;
- //REG interni ----------------------------------------
- reg wasInit; //diventa 1 dopo il primo init
- reg initStarted;
- reg readAvailableReg;
- reg [7:0] currentState;
- reg [15:0] currentWait;
- // reg [7:0] nextState;
- //reg [7:0] typeReq; //(?) contiene il tipo di richiesta (READ, WRITEA, ecc) in modo da conoscere lo stato dopo l'activate
- //reg [31:0] wait_count; //contiene il numero di cicli da attendere. viene decrementato ciclo per ciclo
- reg [15:0] refreshCount;
- reg [31:0] elapsedRefreshTime;
- 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)
- reg busyReg;
- assign busy = busyReg | ~wasInit;
- assign isInit = wasInit;
- assign readAvailable = readAvailableReg;
- reg [4:0] readCount;
- reg test;
- //fine REG interni -----------------------------------
- // //inizio definizione FIFO---------------------------------------------------
- // reg readClear, writeClear; //clear asincrono fifo //potrebbe essere necessario inviarlo in qualche momento che in questo istante non mi ricordo
- //
- // reg [15:0] readINData, writeOUTData;
- // reg readWrReq; //conviene che questi siano reg in modo da poterli disattivare
- // reg writeRdReq; //conviene che questi siano reg in modo da poterli disattivare
- // wire writeEmpty; //read/write indicano la FIFO di appartenenza
- // wire readFull; //read/write indicano la FIFO di appartenenza
- // wire [2:0] readUsed, writeUsed;
- //
- // FIFO read(readClear, readINData[15:0], holdClk, extractReq, holdClk, readWrReq, OUTData[15:0], isReadFIFOEmpty, readUsed, readFull); //read si intende dalla ram
- // FIFO write(writeClear, INData[15:0], holdClk, writeRdReq, holdClk, insertReq, writeOUTData[15:0], writeEmpty, writeUsed, isWriteFIFOFull); //write si intende in ram
- // //fine dichiarazione FIFO---------------------------------------------------
- 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,
- //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};
- //inizio FIFO comandi
- 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,
- //NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
- //NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, INIT_STATE};
- reg [4:0] firstState;// = 31; //punta al primo comando da eseguire
- reg [4:0] lastState;// = 30; //punta all'ultimo posto in cui può essere inserito un comando
- wire emptyState = (lastState == firstState);
- wire fullState = ((lastState-2) == firstState);
- //fine FIFO comandi
- //inizio FIFO read
- reg [15:0] readQueue [8];
- reg [2:0] firstRead; //punta al primo comando da eseguire
- reg [2:0] lastRead; //punta all'ultimo posto in cui può essere inserito un comando
- wire emptyRead = lastRead == firstRead;
- wire fullRead = (lastRead-1) == firstRead;
- assign isReadFIFOEmpty = emptyRead;
- assign OUTData = readQueue; //verificare se OUTData viene effettivamente scritto
- //fine FIFO read
- //inizio FIFO read
- reg [15:0] writeQueue [8];// = INData;
- reg [2:0] firstWrite; //punta al primo comando da eseguire
- reg [2:0] lastWrite; //punta all'ultimo posto in cui può essere inserito un comando
- wire emptyWrite = lastWrite == firstWrite;
- wire fullWrite = (lastWrite-1) == firstWrite;
- assign isWriteFIFOFull = fullWrite;
- //fine FIFO read
- //tecnicamente il codice sotto dovrebbe impostare il nextState a REFRESH nel primo istante utile in cui viene il prossimo stato risulta di IDLE.
- //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
- integer i;
- initial
- begin
- wasInit = 0; //diventa 1 dopo il primo init
- initStarted = 1;
- 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,
- 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};
- stateQueue = '{NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
- NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
- NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, INIT_STATE};
- readCount = 0;
- refreshCount[15:0] = 16'b0;
- elapsedRefreshTime[31:0] = 32'b0;
- startReadRamClk = 0;
- readAvailableReg = 0;
- firstState[4:0] = 5'd31;
- lastState[4:0] = 5'd30;
- firstRead[2:0] = 0;
- lastRead[2:0] = 0;
- firstWrite[2:0] = 8;
- lastWrite[2:0] = 1;
- end
- always @(posedge holdClk)
- begin
- if (rst_n == 0)
- begin
- // initStarted = 0;
- // end
- //
- // if (initStarted == 0)
- // begin
- wasInit = 0; //diventa 1 dopo il primo init
- initStarted = 1;
- 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,
- 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};
- stateQueue = '{NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
- NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE,
- NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, NOP_STATE, INIT_STATE};
- readCount = 0;
- refreshCount[15:0] = 16'b0;
- elapsedRefreshTime[31:0] = 32'b0;
- startReadRamClk = 0;
- readAvailableReg = 0;
- firstState[4:0] = 5'd31;
- lastState[4:0] = 5'd30;
- firstRead[2:0] = 0;
- lastRead[2:0] = 0;
- firstWrite[2:0] = 8;
- lastWrite[2:0] = 1;
- end
- else
- begin
- if (elapsedRefreshTime < refreshTime)
- begin
- elapsedRefreshTime = elapsedRefreshTime + 1;
- end
- else
- begin
- refreshCount = 0;
- elapsedRefreshTime = 0;
- end
- //questo sotto forse da problemi (aggiunge sempre l'init)
- // if (wasInit == 0)
- // begin
- // stateQueue[lastState] = INIT_STATE;
- // lastState = lastState - 1;
- // end
- if (writeRq && busy == 0)
- begin
- stateQueue[lastState] = ACTIVE_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = NOP_STATE;
- waitQueue[lastState] = tRCD - 2;
- lastState = lastState - 1;
- stateQueue[lastState] = WRITEA_STATE; //in corrispondenza di questo mandare il primo dato
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_WRITE_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_WRITE_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_WRITE_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_WRITE_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_WRITE_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_WRITE_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_WRITE_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = NOP_STATE;
- waitQueue[lastState] = tRP;
- lastState = lastState - 1;
- for (i = 0; i<8; i=i+1)
- begin
- writeQueue[i][15:0] = INData[i][15:0];
- end
- end
- if (readRq && busy == 0)
- begin
- stateQueue[lastState] = ACTIVE_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = NOP_STATE;
- waitQueue[lastState] = tRCD - 2;
- lastState = lastState - 1;
- stateQueue[lastState] = READA_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = NOP_STATE;
- waitQueue[lastState] = tCAC - 2;
- lastState = lastState - 1;
- stateQueue[lastState] = START_READ_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_READ_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_READ_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_READ_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_READ_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_READ_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_READ_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = START_READ_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- end
- if (lastState == firstState) //coda vuota //è il posto giusto????
- begin //inserisco in coda un nuovo comando, quello di IDLE
- if(elapsedRefreshTime/(refreshCount + 1) > averageRefreshTime) //se vero serve refresh
- begin
- stateQueue[firstState] = PRECHARGEALL_STATE;
- waitQueue[firstState] = 0;
- stateQueue[firstState - 1] = NOP_STATE;
- waitQueue[firstState - 1] = tRP - 2;
- stateQueue[firstState - 2] = REFRESH_STATE; //sostituisco il corrente comando di IDLE con il comando di refresh
- waitQueue[firstState - 2] = 0;
- stateQueue[firstState - 3] = NOP_STATE;
- waitQueue[firstState - 3] = tRC - 2;
- lastState = lastState - 4;
- end
- else
- begin
- stateQueue[firstState] = IDLE_STATE;
- waitQueue[firstState] = 0;
- lastState = lastState - 1;
- end
- end
- currentWait = waitQueue[firstState + 1];
- if (waitQueue[firstState + 1] != 0)
- begin
- waitQueue[firstState + 1] = waitQueue[firstState + 1] - 1;
- end
- else
- begin
- currentState = stateQueue[firstState];
- //qui comincia la macchina a stati con la valutazione dei vari comandi
- /////////////////////////////////
- case (stateQueue[firstState])
- INIT_STATE: begin
- busyReg = 1;
- wasInit = 0;
- firstState = 31;
- lastState = 30;
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = NOP;
- //waitQueue[firstState] = 20000;
- DRAM_LDQM = 1'b1;
- DRAM_UDQM = 1'b1;
- stateQueue[lastState] = PRECHARGEALL_STATE;
- waitQueue[lastState] = tRP - 1; //giusto tRP - 1
- lastState = lastState - 1;
- for (i = 0; i < 8; i = i + 1)
- begin
- stateQueue[lastState] = REFRESH_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = NOP_STATE;
- waitQueue[lastState] = tRC - 2;
- lastState = lastState - 1;
- end
- //
- stateQueue[lastState] = MRS_STATE;
- waitQueue[lastState] = 0;
- lastState = lastState - 1;
- stateQueue[lastState] = NOP_STATE;
- waitQueue[lastState] = tMRD - 2;
- lastState = lastState - 1;
- end
- NOP_STATE: begin
- busyReg = 1;
- {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!
- end
- IDLE_STATE:
- begin
- {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!
- busyReg = 0;
- startReadRamClk = 0;
- end
- ACTIVE_STATE:
- begin
- busyReg = 1;
- case (stateQueue[firstState-2]) //il successivo � NOP e quello dopo ancora � quello che dobbiamo analizzare
- READ_STATE:
- begin
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = ACT;
- DRAM_ADDR[12:0] = rdRow[12:0];
- DRAM_BA[1:0] = rdBank[1:0];
- firstRead = 0;
- lastRead = 0;
- readCount = 0;
- readAvailableReg = 0;
- DRAM_DQ_reg = 16'bz;
- end
- WRITE_STATE:
- begin
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = ACT;
- DRAM_ADDR[12:0] = wrRow[12:0];
- DRAM_BA[1:0] = wrBank[1:0];
- firstWrite = 8;
- lastWrite = 1; //corrispondono a un full
- end
- READA_STATE:
- begin
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = ACT;
- DRAM_ADDR[12:0] = rdRow[12:0];
- DRAM_BA[1:0] = rdBank[1:0];
- firstRead = 0;
- lastRead = 0;
- readCount = 0;
- readAvailableReg = 0;
- DRAM_DQ_reg = 16'bz;
- end
- WRITEA_STATE:
- begin
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = ACT;
- DRAM_ADDR[12:0] = wrRow[12:0];
- DRAM_BA[1:0] = wrBank[1:0];
- firstWrite = 8;
- lastWrite = 1; //corrispondono a un full
- end
- endcase
- end
- READ_STATE: begin
- busyReg = 1;
- DRAM_LDQM = 1'b0;
- DRAM_UDQM = 1'b0;
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = READ;
- DRAM_ADDR[9:0] = rdColumn;
- DRAM_BA[1:0] = rdBank;
- end
- WRITE_STATE: begin
- busyReg = 1;
- DRAM_LDQM = 1'b0;
- DRAM_UDQM = 1'b0;
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = WRITE;
- DRAM_ADDR[9:0] = wrColumn;
- DRAM_BA[1:0] = wrBank;
- DRAM_DQ_reg = writeQueue[firstWrite];
- firstWrite = firstWrite - 1; //MSB - LSB
- //NOTA: usare il mascheramento per non sovrascrivere i dati che non si vuole modificare (in caso di lunghezzadi scrittura minore di 8)
- end
- READA_STATE: begin
- busyReg = 1;
- DRAM_LDQM = 1'b0;
- DRAM_UDQM = 1'b0;
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = REAU;
- DRAM_ADDR[9:0] = rdColumn;
- DRAM_BA[1:0] = rdBank;
- end
- WRITEA_STATE: begin
- busyReg = 1;
- DRAM_LDQM = 1'b0;
- DRAM_UDQM = 1'b0;
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = WRAU;
- DRAM_ADDR[9:0] = wrColumn;
- DRAM_BA[1:0] = wrBank;
- firstWrite = firstWrite - 1; //MSB - LSB
- DRAM_DQ_reg = writeQueue[firstWrite];
- end
- START_READ_STATE: begin
- busyReg = 1;
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = NOP;
- lastRead = lastRead - 1;
- DRAM_DQ_reg = 16'bz;
- if (readCount < 8)
- begin
- readCount = readCount + 1;
- startReadRamClk = 1;
- end
- else
- begin
- startReadRamClk = 0;
- readAvailableReg = 1;
- end
- end
- START_WRITE_STATE: begin
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = NOP;
- DRAM_LDQM = 1'b0;
- DRAM_UDQM = 1'b0;
- // if (firstWrite > 0)
- // begin
- DRAM_DQ_reg = writeQueue[firstWrite];
- firstWrite = firstWrite - 1; //MSB - LSB
- // end
- end
- PRECHARGE_STATE: begin
- busyReg = 1;
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = PRE;
- //wait_count = tRP;
- end
- PRECHARGEALL_STATE: begin
- busyReg = 1;
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = PALL;
- //wait_count = tRP;
- end
- REFRESH_STATE: begin
- busyReg = 1;
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = REF;
- refreshCount = refreshCount + 1;
- end
- MRS_STATE: begin
- busyReg = 1;
- {DRAM_CKE, DRAM_CS_N, DRAM_RAS_N, DRAM_CAS_N, DRAM_WE_N, DRAM_BA[1:0], DRAM_ADDR[10]} = MRS;
- DRAM_ADDR[2:0] = burstLength;
- DRAM_ADDR[3] = burstType;
- DRAM_ADDR[6:4] = latency;
- DRAM_ADDR[8:7] = opMode;
- DRAM_ADDR[9] = writeBurst;
- {DRAM_BA[1:0], DRAM_ADDR[12:10]} = 5'b0; //Per garantire compaitibilità con altre RAM
- refreshCount = 0;
- elapsedRefreshTime = 0;
- wasInit = 1;
- end
- default begin
- end
- endcase
- firstState = firstState - 1; //sono passato al comando successivo
- /////////////////////////////////
- end
- end
- end
- always @(posedge ramClk)
- begin
- if (startReadRamClk)
- begin
- test = ~test;
- readQueue[lastRead] = DRAM_DQ_reg[15:0];
- end
- end
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement