[메모리]

6. SDRAM controller - 2

Neo Park 2012. 7. 20. 09:32

 

amba_define.v

AMBA 2.0에서 사용되는 신호 들에 대해 define을 해 놓은 것이다.

//---------------------------------------------------------------
// Copyright (c) 2009-2010 by Dynalith Systems Co., Ltd.
// All right reserved.
//
// http://www.dynalith.com
//---------------------------------------------------------------
// VERSION = 2010.02.01.
//---------------------------------------------------------------
// Macros:
//---------------------------------------------------------------
// Parameters:
//---------------------------------------------------------------
// Address map:
//---------------------------------------------------------------

// AHB
`define HTRANS_IDLE  2'b00
`define HTRANS_BUSY  2'b01
`define HTRANS_NONSEQ  2'b10
`define HTRANS_SEQ   2'b11

`define HBURST_SINGLE 3'b000
`define HBURST_INCR  3'b001
`define HBURST_WRAP4 3'b010
`define HBURST_INCR4 3'b011
`define HBURST_WRAP8 3'b100
`define HBURST_INCR8 3'b101
`define HBURST_WRAP16 3'b110
`define HBURST_INCR16 3'b111

`define HSIZE_8  3'b000 // byte
`define HSIZE_16 3'b001 // half word
`define HSIZE_32 3'b010 // word
`define HSIZE_64 3'b011 // double word
`define HSIZE_128 3'b100 // 4 word
`define HSIZE_256 3'b101 // 8 word
`define HSIZE_512 3'b110 // 16 word
`define HSIZE_1024 3'b111 // 32 word

`define HRESP_OKAY 2'b00
`define HRESP_ERROR 2'b01
`define HRESP_RETRY 2'b10
`define HRESP_SPLIT 2'b11

//---------------------------------------------------------------
// Notices: ... ...
//---------------------------------------------------------------
// Revision History
//
// 2010.03.01: Someting has chaned due to bla bla.. by HongGil Dong
// 2010.02.01.: Start by Zzz Xxx Yyyy (xyz@dynalith.com)
//--------------------------------------------------------------

 

 

 

 timescale.v

//---------------------------------------------------------------
// Copyright (c) 2009-2010 by Dynalith Systems Co., Ltd.
// All right reserved.
//
// http://www.dynalith.com
//---------------------------------------------------------------
// VERSION = 2010.02.01.
//---------------------------------------------------------------
// Macros:
//---------------------------------------------------------------
// Parameters:
//---------------------------------------------------------------
// Address map:
//---------------------------------------------------------------

// synthesis translate_off
`timescale 1ns/10ps
// synthesis translate_on

//---------------------------------------------------------------
// Notices: ... ...
//---------------------------------------------------------------
// Revision History
//
// 2010.03.01: Someting has chaned due to bla bla.. by HongGil Dong
// 2010.02.01.: Start by Zzz Xxx Yyyy (xyz@dynalith.com)
//--------------------------------------------------------------

timescale은 simulation에서만 사용되는 code이다. 그러므로 synthesis할 때 해당 문구가 해석되지 않게 하기 위해서 synthesis translate_off와 _on으로 capsulation 처리한다. 1ns/10ps는 기본적으로 verilog에서 사용되는 #1과 같은 unit delay가 1ns 단위가 되도록 한다. 10ps는 simulation에서의 최소 단위가 10ps 단위가 된다.

 

 

ahb_sdram_ctrl.v

//---------------------------------------------------------------
// Copyright (c) 2009-2010 by Dynalith Systems Co., Ltd.
// All right reserved.
//
// http://www.dynalith.com
//---------------------------------------------------------------
// VERSION = 2010.02.01.
//---------------------------------------------------------------
// Macros:
//---------------------------------------------------------------
// Parameters:
//---------------------------------------------------------------
// Address map:
//---------------------------------------------------------------

`include "timescale.v"

`include "amba_define.v"

module ahb_sdram_ctrl(
 // AHB Interface
 HRESETn,
 HCLK,
 HSEL,
 HREADYIN,
 HTRANS,
 HSIZE,
 HWRITE,
 HWDATA,
 HRDATA,
 HADDR,
 HREADYOUT,
 HRESP,

 // SDRAM Interface
 SDC_CLK,
 SDC_CS_N,
 SDC_CKE,
 SDC_BA,
 SDC_A,
 SDC_RAS_N,
 SDC_CAS_N,
 SDC_WE_N,
 SDC_DQM,
 // SDC_DQ
 SDC_DQ_I,
 SDC_DQ_O,
 SDC_DQ_T
);

input   HRESETn;
input   HCLK;

input   HSEL;
input   HREADYIN;
input [1:0] HTRANS;
input [2:0] HSIZE;
input   HWRITE;
input [31:0] HWDATA;
input [31:0] HADDR;

output [31:0] HRDATA;
output   HREADYOUT;
output [1:0] HRESP;

output   SDC_CLK;
output   SDC_CS_N;
output   SDC_CKE;
output [1:0] SDC_BA;
output [10:0] SDC_A;
output   SDC_RAS_N;
output   SDC_CAS_N;
output   SDC_WE_N;
output [3:0] SDC_DQM;
// inout [31:0] SDC_DQ;
input [31:0] SDC_DQ_I;
output [31:0] SDC_DQ_O;
output   SDC_DQ_T; // low active signal

wire [31:0] HRDATA;
wire   HREADYOUT;
wire [1:0] HRESP;

wire   SDC_CLK;
wire   SDC_CS_N;
wire   SDC_CKE;
wire [1:0] SDC_BA;
wire [10:0] SDC_A;
wire   SDC_RAS_N;
wire   SDC_CAS_N;
wire   SDC_WE_N;
wire [3:0] SDC_DQM;
// wire [31:0] SDC_DQ;
wire [31:0] SDC_DQ_I;
wire [31:0] SDC_DQ_O;
wire   SDC_DQ_T;

wire [31-2:0] MEM_ADDR;
wire [31:0] MEM_RDATA;
wire [31:0] MEM_WDATA;
wire   MEM_BUSY;
wire   MEM_CS;
wire [3:0] MEM_BE;
reg  [3:0] c1oBE;

assign HRDATA = MEM_RDATA;
assign HREADYOUT = !MEM_BUSY;
assign MEM_CS = HSEL & HTRANS[1] & HREADYIN;
assign MEM_WE = HWRITE;
assign MEM_ADDR = HADDR[31:2];
assign MEM_BE = c1oBE;
always @(posedge HCLK) begin
 if(HSIZE == `HSIZE_8) begin
  case(HADDR[1:0])
   2'b00: c1oBE = 4'b0001;
   2'b01: c1oBE = 4'b0010;
   2'b10: c1oBE = 4'b0100;
   2'b11: c1oBE = 4'b1000;
  endcase
 end else if(HSIZE == `HSIZE_16) begin
  case(HADDR[1])
   1'b0: c1oBE = 4'b0011;
   1'b1: c1oBE = 4'b1100;
  endcase
 end else begin
  c1oBE = 4'b1111;
 end
end

assign MEM_WDATA = HWDATA;
assign HRESP = 0;

sdramctrl sdramctrl(
 // memory interface
 .MRST_N(HRESETn),
 .MCLK(HCLK),
 .MCS(MEM_CS),
 .MADDR(MEM_ADDR),
 .MWE(MEM_WE),
 .MWDATA(MEM_WDATA),
 .MBE(MEM_BE),
 .MRDATA(MEM_RDATA),
 .MBUSY(MEM_BUSY),

 // sdram interface
 .SCLK(SDC_CLK),
 .SCS_N(SDC_CS_N),
 .SCKE(SDC_CKE),
 .SA(SDC_A),
 .SBA(SDC_BA),
 .SRAS_N(SDC_RAS_N),
 .SCAS_N(SDC_CAS_N),
 .SWE_N(SDC_WE_N),
 .SDQM(SDC_DQM),
 // .SDQ(SDC_DQ)
 .SDQ_I(SDC_DQ_I),
 .SDQ_O(SDC_DQ_O),
 .SDQ_T(SDC_DQ_T)
);

endmodule

//---------------------------------------------------------------
// Notices: ... ...
//---------------------------------------------------------------
// Revision History
//
// 2010.03.01: Someting has chaned due to bla bla.. by HongGil Dong
// 2010.02.01.: Start by Zzz Xxx Yyyy (xyz@dynalith.com)
//--------------------------------------------------------------

AHB interface와 sdram controller 실제 controller와 연결 해 주는 block이다. 간단하게 AHB를 memory interface와 연결하기 위한 block이다.

 

 

sdramctrl.v

//---------------------------------------------------------------
// Copyright (c) 2009-2010 by Dynalith Systems Co., Ltd.
// All right reserved.
//
// http://www.dynalith.com
//---------------------------------------------------------------
// VERSION = 2010.02.01.
//---------------------------------------------------------------
// Macros:
//---------------------------------------------------------------
// Parameters:
//---------------------------------------------------------------
// Address map:
//---------------------------------------------------------------

//**********************************************************
// Copyright (c) 2010 by Dynalith Systems Co., Ltd.
// All right reserved.
//
// No part of this publication or designs may be reproduced or used
// in any form or by any means including graphic, electronic, or mechanical,
// or by photocopying, recording, taping, or information storage and
// retrieval systems, without written permission of Dynalith Systems Co., Ltd.
//
// TITLE: SDRAM Controller
// FILE: sdramctrl.v
// Author: Dynalith Systems
// DESCRIPTION: SDRAM Controller
// ORGANIZATION: R&D Center
//               Dynalith Systems Co., Ltd
//               373-1 Kusong-dong, Yusong-gu, Daejon, Korea
//               E-mail: info@Dynalith.com
//               URL: http://www.Dynalith.com
// CREATED: Apr. 2010
//
// VERSION: 0.1
//   DATE:  Apr.  22, 2010 (Create)
//   AUTHOR: Sang-Young Ye
//   COMMENT:  self power on sequence
//      self auto refresh
//      single read/write support
//
// NOTICE:
//
//**********************************************************

// K4S643232H
// speed grade -70: lowest speed model
// CAS Latency 3
`define tCAS 3  // CAS latency

`define tRRD 2  // Row active to row active delay - 2 CLK(min)
`define tRCD 3  // RAS_N to CAS_N delay - 3 CLK(min)
`define tRP  3  // Row precharge time - 3 CLK(min)
`define tRAS 7  // Row active time - 7 CLK(min), 100 us(max)
`define tRC  10  // Row cycle time - 10 CLK(min)
`define tRDL 2  // Last data in to row precharge - 2 CLK(min)
`define tCDL 1  // Last data in to new col.address delay - 1 CLK(min)
`define tBDL 1  // Last data in to burst stop - 1 CLK(min)
`define tCCD 1  // Col. address to col. address delay - 1 CLK(min)
`define tMRS 2  // Mode Register Set cycle time - 2 CLK(min)
`define tCC  7  // CLK cycle time - 7 ns(min), 1000 ns(max)
`define tSAC 5.5  // CLK to valid output delay - 5.5 ns(max)
`define tOH  2  // Output data hold time - 2 ns(min)
`define tCH  3  // CLK high pulse width - 3 ns(min)
`define tCL  3  // CLK low pulse width - 3 ns(min)
`define tSS  1.75 // Input setup time - 1.75 ns(min), 2.5 ns(max)
`define tSH  1  // Input hold time - 1 ns(min)
`define tSLZ 1  // CLK to output in Low-Z - 1 ns(min)
`define tSHZ 5.5  // CLK to output in Hi-Z - 5.5 ns(max)

`define tRFC `tRC // tRC = tRFC, refresh cycle time
`define tWR  `tRDL // tRDL = tWR

// sdram mode register set value
`define pWBL 1'b0 // A[9] - Write Burst Length
`define pTM  2'b00 // A[8:7] - TestMode
`define pCAS 3'b011 // A[6:4] - CAS Latency
`define pBT  1'b0 // A[3] - Burst Type
`define pBL  3'b000 // A[2:0] - Burst Length

// synthesis translate_off
`define DELAY
// synthesis translate_on

`include "timescale.v"

// insert an unit delay for simulation
`ifdef DELAY
 `define UNIT_DELAY #1
`else
 `define UNIT_DELAY
`endif

module sdramctrl(
 // memory interface
 input   MRST_N,
 input   MCLK,
 input   MCS,
 input [31-2:0] MADDR,
 input   MWE,
 input [31:0] MWDATA,
 input [3:0] MBE,
 output [31:0] MRDATA,
 output   MBUSY,

 // sdram interface
 output   SCLK,
 output   SCS_N,
 output   SCKE,
 output [10:0] SA,
 output [1:0] SBA,
 output   SRAS_N,
 output   SCAS_N,
 output   SWE_N,
 output [3:0] SDQM,
 // inout [31:0] SDQ
 input [31:0] SDQ_I,
 output [31:0] SDQ_O,
 output   SDQ_T
);

// main state
localparam MST_POS  = 5'b0_0001, // Power on Sequence
   MST_IDLE  = 5'b0_0010, // Idle
   MST_MW  = 5'b0_0100, // Memory Write
   MST_MR  = 5'b0_1000, // Memory Read
   MST_AR  = 5'b1_0000; // Auto Refresh

reg  [4:0]  mstate;

wire   c1ePOS, c1ePOSComplete;
wire   c1eWrite, c1eWriteComplete;
wire   c1eRead, c1eReadComplete;
wire   c1eAR, c1eARComplete;
wire   c1eBusy;

always @(posedge MCLK or negedge MRST_N) begin
 if(!MRST_N)
  mstate <= MST_POS;
 else begin
  case(mstate)
   MST_POS:
    if(c1ePOSComplete)
     mstate <= MST_IDLE;
   MST_IDLE:
    if(c1eWrite)
     mstate <= MST_MW;
    else if(c1eRead)
     mstate <= MST_MR;
    else if(c1eAR)
     mstate <= MST_AR;
   MST_MW:
    if(c1eWriteComplete & !c1eWrite)
     mstate <= MST_IDLE;
   MST_MR:
    if(c1eReadComplete & !c1eRead)
     mstate <= MST_IDLE;
   MST_AR:
    if(c1eARComplete)
     mstate <= MST_IDLE;
   default:
    mstate <= MST_IDLE;
  endcase
 end
end

// Power on Sequence
 // 1. Apply power and start clock. Must maintain CKE="H", DQM="H" and the
 //    other pins are NOP condtion at this inputs.
 // 2. Maintain stable power, stable clock and NOP input condition for
 //    a minimum of 200us.
 // 3. Issue precharge commands for all banks of the devices.
 // 4. Issue 2 or more auto-refresh commands.
 //    wait tRC(Row cycle time) to re-issue auto refresh command again.
 //    tRC(min) is 10 CLK for -70 version
 // 5. Issue a mode register set command to initialize the mode register.

localparam  PST_IDLE = 6'b00_0001, // Idle
   PST_PC  = 6'b00_0010, // Precharge
   PST_tRP  = 6'b00_0100, // tRP
   PST_AR  = 6'b00_1000, // Auto Refresh
   PST_ARW  = 6'b01_0000, // Auto Refresh wait
   PST_MRS  = 6'b10_0000; // Mode Register Set

reg  [5:0] pstate;

wire   c1eClkStable;
wire   c1eWaitRP;
wire   c1eWaitRC;
wire   c1eARAgain;

always @(posedge MCLK or negedge MRST_N) begin
 if(!MRST_N)
  pstate <= PST_IDLE;
 else begin
  case(pstate)
   PST_IDLE:
    if(c1eClkStable & c1ePOS)
     pstate <= PST_PC;
   PST_PC:
    pstate <= PST_tRP;
   PST_tRP:
    if(!c1eWaitRP)
     pstate <= PST_AR;
   PST_AR:
    pstate <= PST_ARW;
   PST_ARW:
    if(!c1eWaitRC & c1eARAgain)
     pstate <= PST_AR;
    else if(!c1eWaitRC)
     pstate <= PST_MRS;
   PST_MRS:
    pstate <= PST_IDLE;
   default:
    pstate <= PST_IDLE;
  endcase
 end
end

assign c1ePOS = (mstate == MST_POS);
assign c1ePOSComplete = (pstate == PST_MRS);

// write state
localparam  WST_IDLE  = 6'b00_0001, // Idle
   WST_MWR  = 6'b00_0010, // Row Active
   WST_tRCD = 6'b00_0100, // tRCD
   WST_MWC  = 6'b00_1000, // Colum Address & Write
   WST_tAP  = 6'b01_0000, // Auto Precharge Starts
   WST_tRP  = 6'b10_0000; // tRP

reg  [5:0] wstate;

// wire c1eWrite;
reg   d1oMWE;
reg   d1oMCS;

assign c1eWrite = ((MCS & MWE) | (d1oMCS & d1oMWE));

wire c1eWaitRCD;
wire c1eWaitAP;
// wire c1eWaitRP;

always @(posedge MCLK or negedge MRST_N) begin
 if(!MRST_N)
  wstate <= WST_IDLE;
 else begin
  case(wstate)
   WST_IDLE:
    if (c1eWrite & !c1eBusy)
     wstate <= WST_MWR;
   WST_MWR:
    wstate <= WST_tRCD;
   WST_tRCD:
    if(!c1eWaitRCD)
     wstate <= WST_MWC;
   WST_MWC:
    wstate <= WST_tAP;
   WST_tAP:
    if(!c1eWaitAP)
     wstate <= WST_tRP;
   WST_tRP:
    if(!c1eWaitRP) begin
     if(c1eWrite)
      wstate <= WST_MWR;
     else
      wstate <= WST_IDLE;
    end
   default:
    wstate <= WST_IDLE;
  endcase
 end
end

assign c1eWriteComplete = (wstate == WST_tRP) & !c1eWaitRP;

// read state
localparam  RST_IDLE = 6'b00_0001, // Idle
   RST_MRR  = 6'b00_0010, // Row Active
   RST_tRCD = 6'b00_0100, // tRCD
   RST_MRC  = 6'b00_1000, // Colum Address
   RST_CAS  = 6'b01_0000, // CAS latency
   RST_MRD  = 6'b10_0000; // Memory Read

reg  [5:0] rstate;

// wire c1eRead;
assign c1eRead = ((MCS & !MWE) | (d1oMCS & !d1oMWE));

// wire c1eWaitRCD;
wire c1eWaitCAS;

always @(posedge MCLK or negedge MRST_N) begin
 if(!MRST_N)
  rstate <= RST_IDLE;
 else begin
  case(rstate)
   RST_IDLE:
    if(c1eRead & !c1eBusy)
     rstate <= RST_MRR;
   RST_MRR:
    rstate <= RST_tRCD;
   RST_tRCD:
    if(!c1eWaitRCD)
     rstate <= RST_MRC;
   RST_MRC:
    rstate <= RST_CAS;
   RST_CAS:
    if(!c1eWaitCAS)
     rstate <= RST_MRD;
   RST_MRD:
    if(c1eRead)
     rstate <= RST_MRR;
    else
     rstate <= RST_IDLE;
   default:
    rstate <= RST_IDLE;
  endcase
 end
end

assign c1eReadComplete = (rstate == RST_MRD);

// Auto Refresh
localparam AST_IDLE = 3'b001,
   AST_AR  = 3'b010, // Auto refresh
   AST_ARW  = 3'b100;

reg  [2:0] astate;

// wire   c1eAR;

always @(posedge MCLK or negedge MRST_N) begin
 if(!MRST_N)
  astate <= AST_IDLE;
 else begin
  case(astate)
   AST_IDLE:
    if(c1eAR)
     astate <= AST_AR;
   AST_AR:
    astate <= AST_ARW;
   AST_ARW:
    if(!c1eWaitRC)
     astate <= AST_IDLE;
   default:
    astate <= AST_IDLE;
  endcase
 end
end

assign c1eARComplete = (astate == AST_ARW) & !c1eWaitRC;

// auto refresh counter
reg  [7:0] d1oRefCnt;

always @(posedge MCLK or negedge MRST_N) begin
 if(!MRST_N)
  d1oRefCnt <= 0;
 else begin
  if(astate == AST_AR)
   d1oRefCnt <= 0;
  else if(!d1oRefCnt[7])
   d1oRefCnt <= d1oRefCnt + 1;
 end
end

// auto refresh
 // 15.6us / 100ns (10MHz) = 156 (max)
assign c1eAR = (mstate == MST_IDLE) & !c1eWrite & !c1eRead & d1oRefCnt[7];


// stable clock counter
 // 200us / 100ns (10MHz) = 2000 cycles (min)
reg  [10:0] d1oClkCnt;

always @(posedge MCLK or negedge MRST_N) begin
 if(!MRST_N)
  d1oClkCnt <= 0;
 else begin
  if (!c1eClkStable)
   d1oClkCnt <= d1oClkCnt + 1;
 end
end

assign c1eClkStable = &(d1oClkCnt);

reg  [3:0] d1oRCCnt;

always @(posedge MCLK) begin
 if((pstate == PST_ARW) | (astate == AST_ARW))
  d1oRCCnt <= d1oRCCnt + 1;
 else
  d1oRCCnt <= 1;
end

assign c1eWaitRC = (d1oRCCnt != `tRC - 1);

// auto refresh repeat counter
reg  [1:0] d1oARRptCnt;

always @(posedge MCLK or negedge MRST_N) begin
 if(!MRST_N)
  d1oARRptCnt <= 0;
 else begin
  if(pstate == PST_AR)
   d1oARRptCnt <= d1oARRptCnt + 1;
 end
end

assign c1eARAgain = !d1oARRptCnt[1];

// tRCD counter: start from 1
reg  [1:0] d1oRCDCnt;

always @(posedge MCLK) begin
 if((wstate == WST_tRCD) | (rstate == RST_tRCD))
  d1oRCDCnt <= d1oRCDCnt + 1;
 else
  d1oRCDCnt <= 1;
end

assign c1eWaitRCD = ((wstate == WST_tRCD) | (rstate == RST_tRCD)) & (d1oRCDCnt != `tRCD);

// auto precharge start
reg  [1:0] d1oAPCnt;

always @(posedge MCLK) begin
 if(wstate == WST_tAP)
  d1oAPCnt <= d1oAPCnt + 1;
 else
  d1oAPCnt <= 1;
end

// 2 cycles after last data
assign c1eWaitAP = (wstate == WST_tAP) & (d1oAPCnt != 2);

// row precharge counter
reg  [1:0] d1oRPCnt;

always @(posedge MCLK) begin
 if((wstate == WST_tRP) | (pstate == PST_tRP))
  d1oRPCnt <= d1oRPCnt + 1;
 else
  d1oRPCnt <= 1;
end

assign c1eWaitRP = (d1oRPCnt != `tRP - 1);

// CAS delay counter
reg  [1:0] d1oCASCnt;

always @(posedge MCLK) begin
 if(rstate == RST_CAS)
  d1oCASCnt <= d1oCASCnt + 1;
 else
  d1oCASCnt <= 1;
end

assign c1eWaitCAS = (d1oCASCnt != `tCAS - 1);

// busy condition
// 1. Power on Sequence
// 2. during write data
// 3. during read data
// 4. Auto Refresh
// wire c1eBusy;
assign c1eBusy = (mstate == MST_POS) |
     ((wstate != WST_IDLE) & (wstate != WST_MWR)) |
     ((rstate != RST_IDLE) & (rstate != RST_MRD)) |
     ((astate != AST_IDLE));


reg [31-2:0] d1oMADDR;
// reg   d1oMWE;
// reg   d1oMCS;
always @(posedge MCLK or negedge MRST_N) begin
 if(!MRST_N) begin
  d1oMADDR <= 0;
  d1oMWE <= 0;
  d1oMCS <= 0;
 end else begin
  if(!c1eBusy) begin
   d1oMADDR <= MADDR;
   d1oMWE <= MWE;
   d1oMCS <= MCS;
  end
 end
end


wire  [1:0] d1oBankAddr;
assign d1oBankAddr = d1oMADDR[20:19];
wire  [10:0] d1oRowAddr;
assign d1oRowAddr = d1oMADDR[18:8];

reg  [7:0] d1oColAddr;

always @(posedge MCLK) begin
 if((wstate == WST_MWR) | (rstate == RST_MRR)) begin
  d1oColAddr <= d1oMADDR[7:0];
 end
end

wire p1eCS_N;
assign p1eCS_N = !((pstate == PST_PC) | (pstate == PST_AR) | (pstate == PST_MRS) |
       (wstate == WST_MWR) | (wstate == WST_MWC) |
       (rstate == RST_MRR) | (rstate == RST_MRC) |
          (astate == AST_AR));

wire p1eRAS_N;
assign p1eRAS_N = !((pstate == PST_PC) | (pstate == PST_AR) | (pstate == PST_MRS) |
     (wstate == WST_MWR) | (rstate == RST_MRR) |
     (astate == AST_AR));

wire p1eCAS_N;
assign p1eCAS_N = !((pstate == PST_AR) | (pstate == PST_MRS) |
     (wstate == WST_MWC) | (rstate == RST_MRC) |
     (astate == AST_AR));

wire p1eWE_N;
assign p1eWE_N = !((pstate == PST_PC) | (pstate == PST_MRS) | (wstate == WST_MWC));

// A[10]: Auto Precharge
reg  [10:0] p1eSA;
always @(pstate or wstate or rstate or d1oRowAddr or d1oColAddr) begin
 if(pstate == PST_PC)
  p1eSA = {1'b1, 10'b0};
 else if(pstate == PST_MRS)
  p1eSA = {1'b0, `pWBL, `pTM, `pCAS, `pBT, `pBL};
 else if((wstate == WST_MWR) | (rstate == RST_MRR))
  p1eSA = d1oRowAddr;
 else
  p1eSA = {1'b1, 2'b0, d1oColAddr};
end

wire [1:0] p1eBA;
assign p1eBA = d1oBankAddr;

reg  [3:0] d1oBE;
always @(posedge MCLK) begin
 if((wstate == WST_MWR) | (rstate == RST_MRR))
  d1oBE <=  MBE[3:0];
end

// Read DQM out
// DQM to Data-out Mask = 2
reg  c1oRdMaskOut;
always @(posedge MCLK)
 c1oRdMaskOut <= (rstate == RST_MRC);

reg  [3:0] p1eDQM;
always @(mstate or wstate or c1oRdMaskOut or d1oBE) begin
 if((mstate == MST_MW) & (wstate == WST_MWC))
  p1eDQM = ~d1oBE;
 else if(c1oRdMaskOut)
  p1eDQM = ~d1oBE;
 else
  p1eDQM = 4'hf;
end

reg  [31:0] d1oWDATA;
always @(posedge MCLK) begin
 if(wstate == WST_MWR)
  d1oWDATA <= MWDATA;
end

// wire [31:0] p1eDQ_I;
reg  [31:0] p1eDQ_I;
wire [31:0] p1eDQ_O;
wire   p1eDQ_T_N;

assign p1eDQ_O = d1oWDATA;
// assign p1eDQ_I = SDQ;
// assign p1eDQ_I = SDQ_I;
always @(negedge MCLK)
 p1eDQ_I = SDQ_I;
assign p1eDQ_T_N = !(wstate == WST_MWC);

assign MBUSY = c1eBusy;
assign MRDATA = p1eDQ_I;

assign SCKE = 1'b1;
assign SCLK = MCLK;
assign `UNIT_DELAY SCS_N = p1eCS_N;
assign `UNIT_DELAY SA = p1eSA;
assign `UNIT_DELAY SBA = p1eBA;
assign `UNIT_DELAY SRAS_N = p1eRAS_N;
assign `UNIT_DELAY SCAS_N = p1eCAS_N;
assign `UNIT_DELAY SWE_N = p1eWE_N;
assign `UNIT_DELAY SDQM = p1eDQM;
// assign `UNIT_DELAY SDQ = p1eDQ_T_N ? 32'bz : p1eDQ_O;
assign `UNIT_DELAY SDQ_O = p1eDQ_O;
assign `UNIT_DELAY SDQ_T = p1eDQ_T_N;

endmodule

//---------------------------------------------------------------
// Notices: ... ...
//---------------------------------------------------------------
// Revision History
//
// 2010.03.01: Someting has chaned due to bla bla.. by HongGil Dong
// 2010.02.01.: Start by Zzz Xxx Yyyy (xyz@dynalith.com)
//--------------------------------------------------------------

 

 

 

참조 : http://ye4006.springnote.com/pages/6309137

 

 

 


 

'[메모리]' 카테고리의 다른 글

SRAM과 DRAM의 차이  (0) 2012.08.24
7. SDRAM Controller Test  (0) 2012.07.20
5. SDRAM controller - 1  (0) 2012.07.16
4. SDRAM 동작테스트  (1) 2012.07.16
3. SDRAM 동작원리  (0) 2012.07.16