You are on page 1of 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