コード(トップモジュールRTL)
/* **************************** MODULE PREAMBLE ********************************
Copyright (c) 2012, ArchiTek
This document constitutes confidential and proprietary information
of ArchiTek. All rights reserved.
// このモジュールはsdcCntl, sdcRd, sdcWr, sdcTermをまとめるだけ
// 余りコメントはしない
*/
// ***************************** MODULE HEADER *********************************
module sdc (
iReq, iGnt, iRxw, iAddr,
iWrAck, iWrData, iWrMask,
iRdAck, iRdData,
pReq, pGnt, pAddr,
cs_n, ras_n, cas_n, we_n, addr, ba,
wdvld, wdvldd, wd, wdqm, rdvld, rd,
reg_pCOM,
reg_pACCW, reg_pACCR,
reg_pFAW, reg_pRRD,
reg_dTWR, reg_dTRW,
reg_dWL, reg_dRL,
clk, clk_n,
reset_n
);
// ************************* PARAMETER DECLARATIONS ****************************
// Rowアドレスのスタートを定める(上位モジュールで設定)
parameter ROWS = 5'h00; // Row Address Start Bit
// *************************** I/O DECLARATIONS ********************************
// Normal Master
// 通常アクセスのRequest信号グループ(ハンドシェークを実施)
input iReq;
output iGnt;
input iRxw;
input [31:0] iAddr;
output iWrAck;
input [15:0] iWrData;
input [1:0] iWrMask;
output iRdAck;
output [15:0] iRdData;
// Interrupt Master
// 割り込みアクセスのRequest信号グループ(ハンドシェークを実施)
input pReq;
output pGnt;
input [31:0] pAddr;
// PHYに接続するDDR信号、簡易版なのでCKEやODTは除かれている
// SDRAM Interface
output cs_n;
output ras_n;
output cas_n;
output we_n;
output [15:0] addr;
output [2:0] ba;
output wdvld; // PHY用のWriteタイミング信号
output wdvldd; // sdcTermでPHY固有のカスタマイズ
output [15:0] wd;
output [1:0] wdqm;
output rdvld; // PHY用のWriteタイミング信号
input [15:0] rd;
// Register Interface
input [7:0] reg_pACCW;
input [7:0] reg_pACCR;
input [7:0] reg_pCOM;
input [4:0] reg_pFAW;
input [4:0] reg_pRRD;
input [4:0] reg_dTWR;
input [4:0] reg_dTRW;
input [4:0] reg_dWL;
input [4:0] reg_dRL;
// 単一クロック制御(逆相は必要)
// Utility
input clk;
input clk_n;
input reset_n;
// ************************** LOCAL DECLARATIONS *******************************
// sdcCntlからsdcRdとsdcWrにR/Wコマンド発行タイミングを通知
wire [4:0] rdWL, rdRL;
wire cntlWrPush, cntlRdPush;
// sdcRdとsdcWrからsdcTermにデータタイミングを通知(出力信号と紛らわしいので注意)
wire wrdvld, rddvld;
wire [15:0] wrd;
wire [1:0] wrdqm;
// sdcTermで叩き直したReadデータ
wire [15:0] rdd;
// ****************************** MODULE BODY **********************************
// -----------------------------------------------------------------------------
// Controller
sdcCntl #(ROWS) cntl_0 (
.iReq (iReq),
.iGnt (iGnt),
.iRxw (iRxw),
.iAddr (iAddr),
.pReq (pReq),
.pGnt (pGnt),
.pAddr (pAddr),
.wrPush (cntlWrPush),
.rdPush (cntlRdPush),
.cs_n (cs_n),
.ras_n (ras_n),
.cas_n (cas_n),
.we_n (we_n),
.addr (addr),
.ba (ba),
.reg_pACCW (reg_pACCW),
.reg_pACCR (reg_pACCR),
.reg_pCOM (reg_pCOM),
.reg_pFAW (reg_pFAW),
.reg_pRRD (reg_pRRD),
.reg_dTWR (reg_dTWR),
.reg_dTRW (reg_dTRW),
.reg_dWL (reg_dWL),
.reg_dRL (reg_dRL),
.rdWL (rdWL),
.rdRL (rdRL),
.clk (clk),
.reset_n (reset_n)
);
// -----------------------------------------------------------------------------
// Write Path
sdcWr wr_0 (
.iAck (iWrAck),
.iData (iWrData),
.iMask (iWrMask),
.iPush (cntlWrPush),
.vld (wrdvld),
.data (wrd),
.dqm (wrdqm),
.rdWL (rdWL),
.clk (clk),
.reset_n (reset_n)
);
// -----------------------------------------------------------------------------
// Read Path
sdcRd rd_0 (
.iAck (iRdAck),
.iData (iRdData),
.iPush (cntlRdPush),
.vld (rddvld),
.data (rdd),
.rdRL (rdRL),
.clk (clk),
.reset_n (reset_n)
);
// -----------------------------------------------------------------------------
// Terminal
sdcTerm term_0 (
.iwdvld (wrdvld),
.iwd (wrd),
.iwdqm (wrdqm),
.irdvld (rddvld),
.ird (rdd),
.owdvld (wdvld),
.owdvldd (wdvldd),
.owd (wd),
.owdqm (wdqm),
.ordvld (rdvld),
.ord (rd),
.clk (clk),
.clk_n (clk_n),
.reset_n (reset_n)
);
// ************************** FUNCTIONS and TASKS ******************************
endmodule
// *****************************************************************************
コード(sdcRd RTL)
/* **************************** MODULE PREAMBLE ********************************
Copyright (c) 2012, ArchiTek
This document constitutes confidential and proprietary information
of ArchiTek. All rights reserved.
// 入出力信号はトップモジュールを参照のこと
*/
// ***************************** MODULE HEADER *********************************
module sdcRd (
iAck, iData, iPush,
vld, data,
rdRL,
clk, reset_n
);
// *************************** I/O DECLARATIONS ********************************
output iAck;
output [15:0] iData;
input iPush;
output vld;
input [15:0] data;
input [4:0] rdRL;
input clk;
input reset_n;
// ************************** LOCAL DECLARATIONS *******************************
reg [31:0] delayChain; // 遅延カウンター
wire [31:0] delayChainD;
reg burstInc; // バーストインクリメントフラグ
wire burstIncD;
reg [1:0] burstCnt; // バーストカウンター、4固定
wire [1:0] burstCntD;
reg [31:0] insertCom;
reg iAck, dvld;
// ****************************** MODULE BODY **********************************
// -----------------------------------------------------------------------------
// Delay Chain
// 特殊なカウンターを参照
// 32サイクルまでの遅延調整が可能
always @(posedge clk or negedge reset_n)
if (!reset_n)
delayChain <= #1 32'h00000000;
else
delayChain <= #1 delayChainD;
// 遅延位置に'1'を立てるため手続き的代入文を使用
always @(
iPush or
rdRL
) begin
insertCom = 32'h00000000;
insertCom[rdRL] = iPush;
end
// ここで上記のCheck inを遅延カウンターに統合
assign delayChainD = {1'b0, delayChain[31:1]} | insertCom;
// -----------------------------------------------------------------------------
// Burst Count
// 遅延カウンターのLSB(RL遅延したコマンド発行タイミング)で4を数えるカウンターを起動
// コマンド発行タイミングの原理から、起動フラグは4サイクル以内に2つは存在しない
// burstIncはFF間の論理段数削減のためFF化(遅延の移動参照)
always @(posedge clk or negedge reset_n)
if (!reset_n) begin
burstInc <= #1 1'b0;
burstCnt <= #1 2'h0;
end
else begin
burstInc <= #1 burstIncD;
burstCnt <= #1 burstCntD;
end
assign burstIncD = |burstCntD;
assign burstCntD = delayChain[0]
? 2'h1
: burstCnt + {1'b0, burstInc};
// -----------------------------------------------------------------------------
// Acknowledge
// マスターとPHY用のAcknowlegeを生成、iAckはdvldに比べ1サイクル遅延するだけ
always @(posedge clk or negedge reset_n)
if (!reset_n) begin
dvld <= #1 1'b0;
iAck <= #1 1'b0;
end
else begin
dvld <= #1 delayChain[0] | burstInc;
iAck <= #1 dvld;
end
assign vld = (|delayChainD[1:0])
| (|burstCntD);
// -----------------------------------------------------------------------------
// Through out
// データはラッチせずマスターに返す
// ラッチする場合、iAckも1サイクルずらすため再度ラッチする(dvldは操作しない)
assign iData = data;
// ************************** FUNCTIONS and TASKS ******************************
endmodule
// *****************************************************************************
コード(sdcWr RTL)
/* **************************** MODULE PREAMBLE ********************************
Copyright (c) 2012, ArchiTek
This document constitutes confidential and proprietary information
of ArchiTek. All rights reserved.
// タイミング等はsdcRdと同じため、差分のみコメント
*/
// ***************************** MODULE HEADER *********************************
module sdcWr (
iAck, iData, iMask, iPush,
vld, data, dqm, rdWL,
clk, reset_n
);
// *************************** I/O DECLARATIONS ********************************
output iAck;
input [15:0] iData;
input [1:0] iMask;
input iPush;
output vld;
output [15:0] data;
output [1:0] dqm;
input [4:0] rdWL;
input clk;
input reset_n;
// ************************** LOCAL DECLARATIONS *******************************
reg [31:0] delayChain;
wire [31:0] delayChainD;
reg burstInc;
wire burstIncD;
reg [1:0] burstCnt;
wire [1:0] burstCntD;
reg [31:0] insertCom;
reg iAck;
reg [15:0] data;
reg [1:0] dqm;
// ****************************** MODULE BODY **********************************
// -----------------------------------------------------------------------------
// Delay Chain
always @(posedge clk or negedge reset_n)
if (!reset_n)
delayChain <= #1 32'h00000000;
else
delayChain <= #1 delayChainD;
always @(
iPush or
rdWL
) begin
insertCom = 32'h00000000;
insertCom[rdWL] = iPush;
end
assign delayChainD = {1'b0, delayChain[31:1]} | insertCom;
// -----------------------------------------------------------------------------
// Burst Count
always @(posedge clk or negedge reset_n)
if (!reset_n) begin
burstInc <= #1 1'b0;
burstCnt <= #1 2'h0;
end
else begin
burstInc <= #1 burstIncD;
burstCnt <= #1 burstCntD;
end
assign burstIncD = |burstCntD;
assign burstCntD = delayChain[0]
? 2'h1
: burstCnt + {1'b0, burstInc};
// -----------------------------------------------------------------------------
// Acknowledge
// マスターとPHY用のAcknowlegeを生成、iAckとvldは同じサイクル
always @(posedge clk or negedge reset_n)
if (!reset_n)
iAck <= #1 1'b0;
else
iAck <= #1 delayChain[0] | burstInc;
assign vld = iAck;
// -----------------------------------------------------------------------------
// Data Latch
// データとマスクはラッチする、非Write時はHi-Z制御なのでリセットによるクリアは不要
always @(posedge clk)
begin
data <= #1 iData;
dqm <= #1 iMask;
end
// ************************** FUNCTIONS and TASKS ******************************
endmodule
// *****************************************************************************
コード(sdcTerm RTL)
/* **************************** MODULE PREAMBLE ********************************
Copyright (c) 2012, ArchiTek
This document constitutes confidential and proprietary information
of ArchiTek. All rights reserved.
*/
// ***************************** MODULE HEADER *********************************
module sdcTerm (
iwdvld, iwd, iwdqm,
irdvld, ird,
owdvld, owdvldd, owd, owdqm,
ordvld, ord,
clk, clk_n,
reset_n
);
// *************************** I/O DECLARATIONS ********************************
input iwdvld;
input [15:0] iwd;
input [1:0] iwdqm;
input irdvld;
output [15:0] ird;
output owdvld;
output owdvldd;
output [15:0] owd;
output [1:0] owdqm;
output ordvld;
input [15:0] ord;
input clk;
input clk_n;
input reset_n;
// ************************** LOCAL DECLARATIONS *******************************
reg owdvldd;
reg ordvld;
reg [15:0] ird, trd;
// ****************************** MODULE BODY **********************************
// -----------------------------------------------------------------------------
// Write Data
// sdcWrで生成したWriteタイミングの遅延信号を作るだけ(PHYに依存)
assign owd = iwd;
assign owdqm = iwdqm;
assign owdvld = iwdvld;
always @(posedge clk or negedge reset_n)
if (!reset_n)
owdvldd <= #1 1'b0;
else
owdvldd <= #1 iwdvld;
// -----------------------------------------------------------------------------
// Read Data
// 逆エッジと正エッジのサンプリングで同期
// 逆エッジでサンプルするデータのSetup, Hold条件はPHYによって保証しておかなければならない
always @(posedge clk_n)
trd <= #1 ord;
always @(posedge clk)
ird <= #1 trd;
// ReadタイミングはPHYに合わせてラッチ
always @(posedge clk_n or negedge reset_n)
if (!reset_n)
ordvld <= #1 1'b0;
else
ordvld <= #1 irdvld;
// ************************** FUNCTIONS and TASKS ******************************
endmodule
// *****************************************************************************
回路デザイン > 設計例 [DDR制御(論理)] > コーディング2 次のページ(テスト) このページのTOP ▲