0% found this document useful (0 votes)
83 views

Mini Project Code

This document contains code for a controller module and data path module for a DDR memory controller. The controller module code defines state machines for initialization and command states to control the DDR memory. It also generates refresh requests and latches address inputs. The data path module code defines registers and logic to handle read and write data paths between the system and DDR memory. It contains registers for synchronizing and registering DQ inputs and generating DQ, DQS, and DQM outputs.

Uploaded by

SkMujeebullah
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
83 views

Mini Project Code

This document contains code for a controller module and data path module for a DDR memory controller. The controller module code defines state machines for initialization and command states to control the DDR memory. It also generates refresh requests and latches address inputs. The data path module code defines registers and logic to handle read and write data paths between the system and DDR memory. It contains registers for synchronizing and registering DQ inputs and generating DQ, DQS, and DQM outputs.

Uploaded by

SkMujeebullah
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 28

CODE FOR MINI PROJECT

CODE FOR CONTROLER MODULE :


`timescale 1ns / 1ps
module ddr_ctrl(clk,reset_n,sys_r_wn,sys_add,sys_adsn,sys_dly_200us,sys_init_done,istate,
cstate, wren,addr);
`include "ddr_par.v"
inputclk;reset_n;sys_r_wn;sys_adsn;sys_dly_200us;
input [RA_MSB:CA_LSB]

sys_add;

outputsys_init_done;
output [3:0]

istate;

output [3:0]

cstate;

output

wren;

output [RA_MSB:CA_LSB]

addr;

regsys_init_done; // indicates sdr initialization is done


reg [3:0]

istate;

// INIT_FSM state variables

reg [3:0]

cstate;

// CMD_FSM state variables

reg [3:0]

cs_clkcnt;

reg [3:0]

i_clkcnt;

regi_syncResetClkCNT; // reset i_clkcnt to 0


regcs_syncResetClkCNT; // reset cs_clkcnt to 0
regload_mrs_done; // Load mode register done during intilaization
regload_mrs_af;
regrd_wr_req_during_ref_req;
reg [RA_MSB:CA_LSB]
reg
reg [10:0]

addr;

wren;
q;
1

regref_req_c;
regref_req;
reglatch_ref_req;
regref_ack;
regsys_adsn_r;
reg [RA_MSB:CA_LSB]

sys_add_r ;

regsys_r_wn_r;
// local definitions
`defineendOf_tRP_ii_clkcnt == NUM_CLK_tRP
`defineendOf_tRFC_ii_clkcnt == NUM_CLK_tRFC
`defineendOf_tMRD_ii_clkcnt == NUM_CLK_tMRD

`defineendOf_tRPcs_clkcnt == NUM_CLK_tRP
`defineendOf_tRFCcs_clkcnt == NUM_CLK_tRFC
`defineendOf_tMRDcs_clkcnt == NUM_CLK_tMRD
`defineendOf_tRCDcs_clkcnt == NUM_CLK_tRCD
`defineendOf_Cas_Latencycs_clkcnt == NUM_CLK_CL
`defineendOf_Read_Burstcs_clkcnt == NUM_CLK_READ - 1
`defineendOf_Write_Burstcs_clkcnt == NUM_CLK_WRITE - 1
`defineendOf_tDALcs_clkcnt == NUM_CLK_WAIT
// INIT_FSM state machine
always @(posedgeclk or negedgereset_n) begin
if (reset_n == 1'b0) begin
istate<= i_IDLE;
load_mrs_done<= 1'b0;
load_mrs_af<= 1'b0;
end else
2

case (istate)
i_IDLE: begin

// wait for 200 us delay by checking sys_dly_200us

if (sys_dly_200us) istate<= i_NOP;


end
i_NOP: begin

// After 200us delay apply NOP and then do precharge all

istate<= i_PRE;
end
i_PRE: begin

// precharge all

istate<= (NUM_CLK_tRP == 0) ? (load_mrs_done ? i_AR1 : i_EMRS): i_tRP;


end
i_tRP: begin

// wait until tRP satisfied

if (`endOf_tRP_i)
istate<= load_mrs_done ? i_AR1 :i_EMRS;
end
i_EMRS: begin //Enable DLL in Extended Mode Reg
istate<= (NUM_CLK_tMRD == 0) ? i_MRS :i_tMRD;
end
i_tMRD: begin // wait until tMRD satisfied
if (`endOf_tMRD_i)
istate<= load_mrs_done ? (load_mrs_af ?i_ready : i_PRE) : i_MRS;
end
i_MRS: begin

//Reset DLL in load Mode Reg

load_mrs_done<= 1'b1;
istate<= (NUM_CLK_tMRD == 0) ? (load_mrs_af ?i_ready : i_PRE) : i_tMRD;
end
i_AR1: begin

// auto referesh

istate<= (NUM_CLK_tRFC == 0) ? i_AR2 : i_tRFC1;


3

end
i_tRFC1: begin // wait until tRFC satisfied
if (`endOf_tRFC_i) istate<= i_AR2;
end
i_AR2: begin

// auto referesh

istate<= (NUM_CLK_tRFC == 0) ? i_MRS : i_tRFC2;


end
i_tRFC2: begin // wait until tRFC satisfied
load_mrs_af<= 1'b1; // Load mode register after refresh
if (`endOf_tRFC_i) istate<= i_MRS;
end
i_ready: begin

// stay at this state for normal operation

istate<= i_ready;
end
default: begin
istate<= i_NOP;
end
endcase
end
// sys_init_done generation
always @(posedgeclk or negedgereset_n) begin
if (reset_n == 1'b0) begin
sys_init_done<= 0;
end else begin
case (istate)
i_ready: sys_init_done<= 1;
default: sys_init_done<= 0;
4

endcase
end
end
// Latching the address and looking at
// READ or Write request during Refresh and address latching
always @(posedgeclk or negedgereset_n) begin
if (reset_n == 1'b0) begin
rd_wr_req_during_ref_req<= 1'b0;
addr<= {RA_MSB {1'b0}};
sys_adsn_r<= 1'b0;
sys_add_r<= {RA_MSB {1'b0}};
sys_r_wn_r<= 1'b0;
end else begin
sys_adsn_r<= sys_adsn;
sys_add_r<= sys_add;
sys_r_wn_r<= sys_r_wn;
// Store the address whenever there is address strobe
if (!sys_adsn_r&&sys_init_done)
addr<= sys_add_r;
// New (rd or wr) during refresh command getting serviced
case (cstate)
c_idle: begin
if (!rd_wr_req_during_ref_req)
if (!sys_adsn_r&&latch_ref_req)
rd_wr_req_during_ref_req<= 1'b1;
else
rd_wr_req_during_ref_req<= 1'b0;
5

end
// After completing write (c_tDAL)
// Durinfc_tDAL, system can make a request and
// refresh can be pending.
c_tRFC,
c_tDAL,
c_AR: begin
if (!sys_adsn_r)
rd_wr_req_during_ref_req<= sys_init_done;
end
default: begin
rd_wr_req_during_ref_req<= 1'b0;
end
endcase
end
end
// CMD_FSM state machine
always @(posedgeclk or negedgereset_n) begin
if (reset_n == 1'b0) begin
cstate<= c_idle;
wren<= 1'b0;
end else begin
case (cstate)
c_idle: // wait until refresh request or addr strobe asserted
if (latch_ref_req&&sys_init_done)
cstate<= c_AR;
else if ((!sys_adsn_r&&sys_init_done) || rd_wr_req_during_ref_req)
6

cstate<= c_ACTIVE;
c_ACTIVE: // assert row/bank addr
if (NUM_CLK_tRCD == 0)
cstate<= (sys_r_wn_r) ? c_READA :c_WRITEA;
else
cstate<= c_tRCD;
c_tRCD: // wait until tRCD satisfied
if (`endOf_tRCD)
cstate<= (sys_r_wn_r) ? c_READA :c_WRITEA;
c_READA: // assert col/bank addr for read with auto-precharge
cstate<= c_cl;
c_cl:

// CASn latency

if (`endOf_Cas_Latency) cstate<= c_rdata;


c_rdata: // read cycle data phase
if (`endOf_Read_Burst) cstate<= c_idle;
c_WRITEA: begin // assert col/bank addr for write with auto-precharge
cstate<= c_wdata;
wren<= 1'b1;
end
c_wdata: begin // write cycle data phase
if (`endOf_Write_Burst) begin
cstate<= c_tDAL;
wren<= 1'b0;
end
end
c_tDAL: // wait until (tWR + tRP) satisfied before issuing next
// SDRAM ACTIVE command
7

if (`endOf_tDAL) cstate<= c_idle;


c_AR:

// auto-refresh

cstate<= (NUM_CLK_tRFC == 0) ? c_idle :c_tRFC;


c_tRFC: // wait until tRFC satisfied
if (`endOf_tRFC) cstate<= c_idle;
default: begin
cstate<= c_idle;
wren<= 1'b0;
end
endcase
end
end
// Refresh request, generation using LFSR counters
// for better frequency and resource utilisation
always @(posedgeclk or negedgereset_n) begin
if (reset_n == 1'b0) begin
q

<= 0;

ref_req<= 1'b0;
end else begin
q[0]

<= ~(q[10]^q[8]^ref_req_c);

q[10:1] <= q[9:0];


ref_req<= ref_req_c;
end
end
always @ (q) begin
if (REF_INTERVAL == REF_INT_128MBIT_100MHZ)
/*477*/ref_req_c = q[10]&~q[9]&~q[8]&~q[7]&q[6]&q[5]&q[4]&~q[3]&q[2]&q[1]&q[0];
8

if (REF_INTERVAL == REF_INT_NON128MBIT_100MHZ)
/*605*/ref_req_c =
q[10]&q[9]&~q[8]&~q[7]&~q[6]&~q[5]&~q[4]&~q[3]&q[2]&~q[1]&q[0];
if (REF_INTERVAL == REF_INT_128MBIT_133MHZ)
/*300*/ref_req_c =
~q[10]&q[9]&q[8]&~q[7]&~q[6]&~q[5]&~q[4]&~q[3]&~q[2]&~q[1]&~q[0];
if (REF_INTERVAL == REF_INT_NON128MBIT_133MHZ)
/*350*/ref_req_c =
~q[10]&q[9]&q[8]&~q[7]&q[6]&~q[5]&q[4]&~q[3]&~q[2]&~q[1]&~q[0];
end
always @(posedgeclk or negedgereset_n) begin
if (reset_n == 1'b0) begin
ref_ack<= 0;
latch_ref_req<= 1'b0;
end else begin
if (ref_req)
latch_ref_req<= 1'b1;
else if (ref_ack)
latch_ref_req<= 1'b0;
case (cstate)
c_idle:
ref_ack<= sys_init_done&&latch_ref_req;
default:
ref_ack<= 1'b0;
endcase
end
end
// Clock Counter

always @(posedgeclk or negedgereset_n) begin


if (reset_n == 1'b0) begin
cs_clkcnt<= 4'b0;
end else begin
if (cs_syncResetClkCNT)
cs_clkcnt<= 4'b0;
else
cs_clkcnt<= cs_clkcnt + 1'b1;
end
end
always @(posedgeclk or negedgereset_n) begin
if (reset_n == 1'b0) begin
i_clkcnt<= 4'b0;
end else begin
i_clkcnt<= 4'b0;
else
i_clkcnt<= i_clkcnt + 1'b1;
end
end
// istatesyncResetClkCNT generation
always @(istate or i_clkcnt) begin
case (istate)
i_PRE:
i_syncResetClkCNT= (NUM_CLK_tRP == 0) ? 1 : 0;
i_AR1,
i_AR2:
i_syncResetClkCNT= (NUM_CLK_tRFC == 0) ? 1 : 0;
10

i_tRP:
i_syncResetClkCNT= (`endOf_tRP_i) ? 1 : 0;
i_tMRD:
i_syncResetClkCNT= (`endOf_tMRD_i) ? 1 : 0;
i_tRFC1,
i_tRFC2:
i_syncResetClkCNT= (`endOf_tRFC_i) ? 1 : 0;
default:
i_syncResetClkCNT= 1;
endcase
end
// cstatesyncResetClkCNT generation
always @(cstate or cs_clkcnt) begin
case (cstate)
c_idle:
cs_syncResetClkCNT= 1;
c_ACTIVE:
cs_syncResetClkCNT= (NUM_CLK_tRCD == 0) ? 1 : 0;
c_tRCD:
cs_syncResetClkCNT= (`endOf_tRCD) ? 1 : 0;
c_tRFC:
cs_syncResetClkCNT= (`endOf_tRFC) ? 1 : 0;
c_cl:
cs_syncResetClkCNT= (`endOf_Cas_Latency) ? 1 : 0;
c_rdata:
cs_syncResetClkCNT= (cs_clkcnt == NUM_CLK_READ) ? 1 : 0;
c_wdata:
11

cs_syncResetClkCNT= (`endOf_Write_Burst) ? 1 : 0;
c_tDAL:
cs_syncResetClkCNT= (`endOf_tDAL) ? 1 : 0;
default:
cs_syncResetClkCNT= 1;
endcase // case(cstate)
end
endmodule

//DATA PATH
`timescale 1ns / 1ps
module ddr_data( clk, clk2x, reset_n, sys_dataout, sys_dataout_en, sys_datain, sys_dmsel,cstate
wren, sys_rdyn, dqin, dqout, dqout_en, dqsout, dqsout_en, dqm_out );
`include "ddr_par.v"
input

clk;clk2x; reset_n; wren;

input[3:0]

cstate;

input [DSIZE-1:0]

sys_datain;

// System data in

input [DSIZE/8-1:0]

sys_dmsel;

// System data mask select.

input [DSIZE/2-1:0]

dqin;

output [DSIZE/2-1:0]

dqout_en;

output [DSIZE/2-1:0]

dqout;

// DDR data in (read data)


// DDR output enables
// DDR output (write data)

output [DSIZE/16-1:0]

dqsout_en;

output [DSIZE/16-1:0]

dqsout;

// DDR output enables


// DDR output strobe

output

sys_rdyn;

// Ready signal to the system

output [DSIZE-1:0]

sys_dataout

/*synthesis dout="" */ ;
12

output [DSIZE-1:0]

sys_dataout_en /*synthesis syn_preserve=1 */ /*synthesis dout="" */ ;

output [DSIZE/16-1:0]

dqm_out;

// Data mask output to DDR

reg [DSIZE/2-1:0]

dqout_en

/*synthesis syn_preserve=1 */ /*synthesis dout="" */ ;

reg [DSIZE/2-1:0]

dqout

reg [DSIZE/16-1:0]

dqsout_en

reg [DSIZE/16-1:0]

dqsout

reg

sys_rdyn;

reg [DSIZE-1:0]

sys_dataout_en /*synthesis syn_preserve=1 */ /*synthesis dout="" */;

reg [DSIZE/16-1:0]
signals

dqm_out

/*synthesis dout="" */ ;
/*synthesis syn_preserve=1 */ /*synthesis dout="" */ ;
/*synthesis dout="" */ ;

/*synthesis dout="" */ ; // DDR SDRAM Data Mask

//--- Internal Registers


reg [DSIZE/2-1:0]

dqin_2x_sync_reg /*synthesis din="" */;

reg [DSIZE/2-1:0]

dqin_x_reg;

reg [DSIZE/2-1:0]

dqin_xn_reg;

reg [DSIZE/2-1:0]

dqin_xnx_reg;

reg [DSIZE/2-1:0]

dqin_reg_l /*synthesis dout="" */ ;

reg [DSIZE/2-1:0]

dqin_reg_h /*synthesis dout="" */ ;

// Write path registers


reg [DSIZE/2+DSIZE/16-1:0] dqout_and_dqsout_en /*synthesis syn_preserve=1 */;
reg [DSIZE/2-1:0]

dqout_reg;

reg [DSIZE/16-1:0]

dqm_outreg;

reg [DSIZE/2-1:0]

datain_regl /*synthesis din="" */;

reg [DSIZE/16-1:0]

dmsel_regl /*synthesis din="" */;

reg [DSIZE-1:0]

datain_nx ;

reg [DSIZE/8-1:0]

dmsel_nx ;

13

reg

dqsout_reg;

reg

select_lower_half;

reg

write_rdy_d1;

reg

write_rdy_d2;

reg

write_rdy_d3;

reg

read_rdy;

reg

read_rdy_d;

reg

write_rdy;

reg

wren_d2x;

reg

wren_dx;

reg [DSIZE/16-1:0]

dqsout_en_nx;

//--- WIRES
wire [DSIZE-1:0]

sys_dataout;

// Read Cycle Data Path


// Latching the incoming DDR data
always @(posedge clk2x or negedge reset_n)begin
if (reset_n == 1'b0)
dqin_2x_sync_reg <= {DSIZE/2{1'b0}};
else
dqin_2x_sync_reg <= dqin;
end
// +ve edge clk
always @(posedge clk or negedge reset_n) begin
if (reset_n == 1'b0) begin
dqin_x_reg

<= {DSIZE/2{1'b0}};
14

dqin_xnx_reg

<= {DSIZE/2{1'b0}};

end
else begin
dqin_x_reg

<= dqin_2x_sync_reg;

// dqin_xnx_reg will be used only for


// CAS latency = 2.5.
if (MR_CAS_Latency == Latency_25)
dqin_xnx_reg <= dqin_xn_reg;
end
end
// -ve edge clk
always @(negedge clk or negedge reset_n) begin
if (reset_n == 1'b0)
dqin_xn_reg <= {DSIZE/2{1'b0}};
else
dqin_xn_reg <= dqin_2x_sync_reg;
end
// Tranfering the data +ve clk
always @(posedge clk or negedge reset_n) begin
if (reset_n == 1'b0) begin
dqin_reg_l <= {DSIZE/2{1'b0}};
dqin_reg_h <= {DSIZE/2{1'b0}};
end else begin
if (MR_CAS_Latency == Latency_25) begin
dqin_reg_h <= dqin_x_reg;
15

dqin_reg_l <= dqin_xnx_reg;


end else begin
dqin_reg_h <= dqin_xn_reg;
dqin_reg_l <= dqin_x_reg;
end
end
end
assign sys_dataout = {dqin_reg_h, dqin_reg_l};
// Write Cycle Data Path
// Generation of dqout_en and dqsout_en for DDRRAM
// Assert the DDR output and DDR strobe output enables during
// the c_WRITEA, c_wdata and c_tDAL states
always @(posedge clk or negedge reset_n) begin
if (reset_n == 1'b0) begin
dqout_and_dqsout_en <= {DSIZE/2+DSIZE/16 {1'b0}};
end else begin
case (cstate)
c_WRITEA,c_wdata,c_tDAL : begin
// For XPGA
// dqout_and_dqsout_en <= {DSIZE/2+DSIZE/16 {1'b1}};
// For ORCA
dqout_and_dqsout_en <= {DSIZE/2+DSIZE/16 {1'b0}};
end
default: begin
// For XPGA
16

// dqout_and_dqsout_en <= {DSIZE/2+DSIZE/16 {1'b0}};

// For ORCA
dqout_and_dqsout_en <= {DSIZE/2+DSIZE/16 {1'b1}};
end
endcase
end
end
// Both dq_out, and dqout_en should be clocked by the
// same clock and the same edge (+ve clk2x). This is required
// otherwise PAR tool will not place output flops in PIC.
always @(posedge clk2x or negedge reset_n) begin
if (reset_n == 1'b0) begin
dqout_en

<= {DSIZE/2 {1'b0}};

end else begin


dqout_en

<= dqout_and_dqsout_en[DSIZE/2-1:0];

end
end
always @(negedge clk or negedge reset_n) begin
if (reset_n == 1'b0) begin
dqsout_en_nx

<= {DSIZE/16 {1'b0}};

end else begin


dqsout_en_nx

<= dqout_and_dqsout_en[DSIZE/2+DSIZE/16-1: DSIZE/2];

end
end
17

always @(negedge clk2x or negedge reset_n) begin


if (reset_n == 1'b0) begin
dqsout_en

<= {DSIZE/16 {1'b0}};

end else begin


dqsout_en

<= dqsout_en_nx;

end
end
// Generation of dqsout
always @(posedge clk2x or negedge reset_n) begin
if (reset_n == 1'b0) begin
wren_dx <= 1'b0;
end else begin
wren_dx <= wren_d2x ? ~wren_dx : 1'b0;
end
end
// Note that dqsout and dqsout_en are clocked
// with the same clock and the same edge (-ve clk2x)
always @(negedge clk2x or negedge reset_n) begin
if (reset_n == 1'b0) begin
dqsout_reg
dqsout

<= 1'b0;
<= {DSIZE/16{1'b0}};

end else begin


dqsout_reg
dqsout

<= wren_dx;
<= dqsout_reg;

end
18

end
// Generation of dqout
// Latch the system data on +ve clk
always @(negedge clk or negedge reset_n) begin
if (reset_n == 1'b0) begin
datain_nx <= {DSIZE{1'b0}};
dmsel_nx <= {DSIZE/8{1'b0}};
end else begin
datain_nx <= sys_datain[DSIZE-1:0];
dmsel_nx <= sys_dmsel[DSIZE/8-1:0];
end
end
// dqout_reg has two clocks (of clk2x) from sys_datain and datain_nx.
// Similarly for dqm_out.
// This is essential to meet the desired frequency.
always @(posedge clk2x or negedge reset_n) begin
if (reset_n == 1'b0) begin
wren_d2x

<= 1'b0;

select_lower_half
dqout_reg
dqm_outreg
dqout
dqm_out

<= 1'b0;

<= {DSIZE/2 {1'b0}};


<= {DSIZE/16 {1'b0}};
<= {DSIZE/2 {1'b0}};
<= {DSIZE/16{1'b0}};

end else begin


wren_d2x

<= wren;
19

select_lower_half

<= wren_d2x ? ~select_lower_half : 1'b0;

dqout_reg
<= select_lower_half ? datain_nx[DSIZE-1:DSIZE/2] :
sys_datain[DSIZE/2-1:0];
dqm_outreg
<= select_lower_half ? dmsel_nx[DSIZE/8-1:DSIZE/16]:
sys_dmsel[DSIZE/16-1:0];
dqout
dqm_out

<= dqout_reg;
<= dqm_outreg;

end
end
// Generation of sys_rdyn. When sys_rdyn goes low
// data transfer takes place. Applies to read and write
always @(posedge clk or negedge reset_n) begin
if (reset_n == 1'b0) begin
sys_rdyn

<= 1'b1;

write_rdy_d1

<= 1'b0;

write_rdy_d2

<= 1'b0;

write_rdy_d3

<= 1'b0;

read_rdy
read_rdy_d

<= 1'b0;
<= 1'b0;

end else begin


// Generate for read and write cycles, during data transfer
// This will be useful to directly attach to processors
// Also during refresh time, if master requests read/write cycles.
write_rdy_d1

<= write_rdy;

write_rdy_d2

<= write_rdy_d1;

write_rdy_d3

<= write_rdy_d2;
20

read_rdy
read_rdy_d

<= (cstate == c_rdata) ? 1'b1 : 1'b0;


<= (read_rdy || (cstate == c_rdata) ) ? 1'b1: 1'b0;

if (NUM_CLK_WRITE == 1)
sys_rdyn

<= !(write_rdy | read_rdy);

if (NUM_CLK_WRITE == 2)
sys_rdyn

// For burst length 4

<= !(write_rdy | write_rdy_d1 | read_rdy);

if (NUM_CLK_WRITE == 4)
sys_rdyn

// For burst length 2

// For burst length 8

<= !(write_rdy | write_rdy_d1 | write_rdy_d2 | write_rdy_d3 | read_rdy);

end
end
// Generation of sys_dataout_en
always @(negedge clk or negedge reset_n) begin
if (reset_n == 1'b0) begin
sys_dataout_en <= {DSIZE{1'b0}};
end else begin
sys_dataout_en <= read_rdy_d ? {DSIZE {1'b0}} : {DSIZE {1'b1}};
end
end

// Generation of write_rdy (combinational signal)


always @ (cstate ) begin
case (cstate)
c_WRITEA: begin
write_rdy = 1'b1;
end
21

default: begin
write_rdy = 1'b0;
end
endcase
end
endmodule

TOP MODULE

`timescale 1ns / 1ps


moduleddr_top ( ddr_dq, ddr_dqs, sysd, sys_rdyn, sys_init_done, ddr_dqm, ddr_wen, ddr_rasn,
ddr_csn, ddr_cke, ddr_casn, ddr_ba, ddr_add, ddr_clk, ddr_clkn, sys_r_wn,
sys_dmsel, sys_dly_200us, sys_adsn, sys_add, reset_n, clk);
`include "ddr_par.v"
inputclk; reset_n,sys_adsn,sys_dly_200us,sys_r_wn;
input [RA_MSB:CA_LSB] sys_add;
input [DSIZE/8-1:0]

sys_dmsel;

// System address
// System data mask select during DDR write

output [DDR_A_WIDTH-1:0]ddr_add;

// DDR address

output [DDR_BA_WIDTH-1:0]ddr_ba;

// DDR bank address

outputddr_casnddr_cke,ddr_csn,ddr_rasn,ddr_wen,sys_init_done,sys_rdyn,ddr_clk,
ddr_clkn;
output [DSIZE/16-1:0] ddr_dqm;
inout [DSIZE/2-1:0]

ddr_dq;

inout [DSIZE/16-1:0]

ddr_dqs;

// DDR data mask signal


// DDR data in/out
// DDR data strobe
22

inout [DSIZE-1:0]

sysd;

reg [DSIZE/2-1:0]

ddr_dq_i;

reg [DSIZE/16-1:0]

ddr_dqs_i;

reg [DSIZE-1:0]

sysd_i;

wire [RA_MSB:CA_LSB]
wire [3:0]

cstate;

wire [3:0]

istate;

wire

// System data in/out

addr;

wren;

wire [DSIZE-1:0]

sys_datain;

wire [DSIZE/2-1:0]

dqout;

wire [DSIZE/2-1:0]

dqout_en;

wire [DSIZE/16-1:0]

dqsout;

wire [DSIZE/2-1:0]

dqin;

wire [DSIZE/16-1:0]

dqsout_en;

wire [DSIZE-1:0]

sys_dataout;

wire [DSIZE-1:0]

sys_dataout_en;

wire

pll_mclk_sp;

integeri,j,m;
ddr_ctrl u1_ddr_ctrl (
/*AUTOINST*/
// Outputs
.sys_init_done

(sys_init_done),

.istate

(istate[3:0]),

.cstate

(cstate[3:0]),

.wren

(wren),
23

.addr

(addr[RA_MSB:CA_LSB]),

// Inputs
.clk
.reset_n

(pll_mclk),
(reset_n),

.sys_r_wn

(sys_r_wn),

.sys_adsn

(sys_adsn),

.sys_dly_200us
.sys_add

(sys_dly_200us),

(sys_add[RA_MSB:CA_LSB]));

ddr_data u1_ddr_data (
/*AUTOINST*/
// Outputs
.dqout_en
.dqout
.dqsout_en
.dqsout
.sys_rdyn
.sys_dataout

(dqout_en[DSIZE/2-1:0]),
(dqout[DSIZE/2-1:0]),
(dqsout_en[DSIZE/16-1:0]),
(dqsout[DSIZE/16-1:0]),
(sys_rdyn),
(sys_dataout[DSIZE-1:0]),

.sys_dataout_en (sys_dataout_en[DSIZE-1:0]),
.dqm_out

(ddr_dqm[DSIZE/16-1:0]),

// Inputs
.clk

(pll_mclk),

.clk2x

(pll_nclk),

.reset_n

(reset_n),

.cstate

(cstate[3:0]),

.wren

(wren),
24

.sys_datain

(sys_datain[DSIZE-1:0]),

.sys_dmsel

(sys_dmsel[DSIZE/8-1:0]),

.dqin

(dqin[DSIZE/2-1:0]));

ddr_sig u1_ddr_sig (
/*AUTOINST*/
// Outputs
.ddr_cke

(ddr_cke),

.ddr_csn

(ddr_csn),

.ddr_rasn

(ddr_rasn),

.ddr_casn

(ddr_casn),

.ddr_wen

(ddr_wen),

.ddr_ba

(ddr_ba[DDR_BA_WIDTH-1:0]),

.ddr_add

(ddr_add[DDR_A_WIDTH-1:0]),

// Inputs
.clk

(pll_mclk),

.reset_n

(reset_n),

.addr

(addr[RA_MSB:CA_LSB]),

.istate

(istate[3:0]),

.cstate

(cstate[3:0]));

assignddr_clk = pll_mclk;
assignddr_clkn = !pll_mclk;

assignddr_clk = pll_mclk_sp;
assignddr_clkn = !pll_mclk_sp;
ddr_pll_orca u1_ddr_pll_orca(
25

.clk

(clk),

.mclk (pll_mclk),
.nclk (pll_nclk),
.lock (lock)
);
ddr_pll_orca_sp u2_ddr_pll_orca(
.clk

(clk),

.mclk (pll_mclk_sp),
.nclk (),
.lock ()
);
// DDR interface (READ & WRITE
// Read data
assign dqin[DSIZE/2-1:0]

= ddr_dq;

// Write data
always @ (dqout_en or dqout) begin
for (i=0; i<(DSIZE/2); i=i+1)
// For ORCA
ddr_dq_i[i]

= dqout_en[i] ?1'bz :dqout[i] ;

// FOr XPGA
// ddr_dq_i[i]

= dqout_en[i] ?dqout[i] : 1'bz ;

end
assign #(0.9) ddr_dq = ddr_dq_i;
always @ (dqsout_en or dqsout) begin
26

for (j=0; j<(DSIZE/16); j=j+1)


// For ORCA
ddr_dqs_i[j]

= dqsout_en[j] ?1'bz :dqsout[j];

//For XPGA
//ddr_dqs_i[j]

= dqsout_en[j] ?dqsout[j] : 1'bz;

end
assign #(0.9) ddr_dqs = ddr_dqs_i;
// System side interface
// Write (system write)
assign sys_datain[DSIZE-1:0]

= sysd;

// System Read
always @ (sys_dataout_en or sys_dataout) begin
for (m=0; m<DSIZE; m=m+1)
// For ORCA
sysd_i[m]

= sys_dataout_en[m] ?1'bz :sys_dataout[m] ;

// For XPGA
// sysd_i[m]

= sys_dataout_en[m] ?sys_dataout[m] : 1'bz ;

end
assign #(0.9) sysd = sysd_i;
endmodule

27

28

You might also like