感谢邓堪文大佬
平台:
sdram_model_plus文件太大放在资源里去了,自行下载,敲完代码,伐木累。
给点支持吧
初始化sdram_init模块
module sdram_init(
//system singles
input sclk ,
input reset ,
//others
output reg [3:0] cmd_reg ,//输出
output wire[12:0] sdram_addr ,
output wire flag_init_end
);
//===============================================================
//*************Define parameter and Internal Singles*************
//===============================================================
localparam DELAY_200US = 10000 ;
//SDRAM Command
localparam NOP = 4'b0111;
localparam PRE = 4'b0010;
localparam AREF = 4'b0001;
localparam MSET = 4'b0000;
reg [13:0] cnt_200us ;
wire flag_200us ;
reg [3:0] cnt_cmd ;
//===============================================================
//**************** Main Code ***********
//===============================================================
//cnt_200us
always@(posedge sclk or negedge reset)begin
if(!reset)
cnt_200us <= 'd0;
else if(flag_200us == 1'b0)
cnt_200us <= cnt_200us + 1'b1;
end
//cnt_cmd
always@(posedge sclk or negedge reset)begin
if(!reset)
cnt_cmd <= 1'd0;
else if(flag_200us == 1'b1 && flag_init_end == 1'b0)
cnt_cmd <= cnt_cmd + 1'b1;
end
//cmd_reg
always@(posedge sclk or negedge reset)begin
if(!reset)
cmd_reg <= NOP;
else if(flag_200us == 1'b1)
case(cnt_cmd)
0: cmd_reg <= PRE;
1: cmd_reg <= AREF;
5: cmd_reg <= AREF;
9: cmd_reg <= MSET;
default:cmd_reg <= NOP;
endcase
end
//sdram_addr
assign flag_init_end = (cnt_cmd > 10)? 1'b1 : 1'b0;
assign sdram_addr = (cmd_reg == MSET)? 13'b0_0000_00011_0010 : 13'b0_0100_0000_0000;//代表4突发 3潜伏。。。
assign flag_200us = (cnt_200us >= DELAY_200US)? 1'b1 : 1'b0;
endmodule
sdram_aref
module sdram_aref(
//system signals
input sclk ,
input reset ,
//comunicat with ARBIT
input ref_en ,
output reg ref_req ,
output wire flag_ref_end ,
//others
output reg [3:0] aref_cmd ,
output wire [12:0] sdram_addr ,
input flag_init_end
);
//==============================================================================\
//*********************Define Parameter and Internal Signal ********************
//==============================================================================/
localparam DELAY_78us = 390 ;//理论上7.5us即可为了刷新完全,多花点时间
localparam CMD_AREF = 4'b0001 ;
localparam CMD_NOP = 4'b0111 ;
localparam CMD_PRE = 4'b0010 ;
reg [3:0] cmd_cnt ;
reg [8:0] ref_cnt ;
reg flag_ref ;//表示在刷新由top产生的使能信号激活,直到刷新结束才为0
//=============================================================================\
//********************** Main Code ***************************************
//=============================================================================/
always @(posedge sclk or negedge reset) begin
if(reset == 1'b0)
ref_cnt <= 9'd0;
else if(ref_cnt >= DELAY_78us)
ref_cnt <= 9'd0;
else if(flag_init_end == 1'b1)
ref_cnt <= ref_cnt +1'b1;
end
always @(posedge sclk or negedge reset) begin
if(reset == 1'b0)
flag_ref <= 1'b0;
else if(flag_ref_end == 1'b1)
flag_ref <= 1'b0;
else if(ref_en == 1'b1)
flag_ref <= 1'b1;
end
always @(posedge sclk or negedge reset ) begin
if(reset == 1'b0)
cmd_cnt <= 4'd0;
else if(flag_ref == 1'b1)
cmd_cnt <= cmd_cnt + 1'b1;
else
cmd_cnt <= 4'd0;
end
always @(posedge sclk or negedge reset) begin
if(reset == 1'b0)
aref_cmd <= CMD_NOP;
else if(cmd_cnt == 2)
aref_cmd <= CMD_AREF; //预充电 改为刷新时不需要预充电电
else
aref_cmd <= CMD_NOP;
end
//ref_req
always @(posedge sclk or negedge reset) begin
if(reset == 1'b0)
ref_req <= 0;
else if(ref_en == 1)
ref_req <= 0;
else if(ref_cnt >= DELAY_78us)
ref_req <= 1;
end
assign flag_ref_end = (cmd_cnt >= 4'd3) ? 1'b1 : 1'b0;
assign sdram_addr = 13'd0_0100_0000_0000;
endmodule
sdram_write
module sdram_write(
//system single
input sclk,
input reset,
//commucation with top
input wr_en,//现有请求在使能
output wire wr_req,
output reg flag_wr_end,
//others
input ref_req,//刷新请求信号
input wr_trig,//写触发
//write interface
output reg[3:0] wr_cmd,
output reg[12:0] wr_addr,
output wire[1:0] bank_addr,
output reg[15:0] wr_data
);
/
//
/
//状态
localparam S_IDLE = 5'b0_0001;
localparam S_REQ = 5'b0_0010;
localparam S_ACT = 5'b0_0100;//行激活
localparam S_WR = 5'b0_1000;
localparam S_PRE = 5'b1_0000;
//SDRAM Comand
localparam CMD_NOP = 4'b0111;
localparam CMD_PRE = 4'b0010;
localparam CMD_AREF = 4'b0001;
localparam CMD_ACT = 4'b0011;
localparam CMD_WR = 4'b0100;
reg flag_wr;//写进行中
reg[4:0] state; //5个状态
//*********************************************
reg flag_act_end; //4个数据一个act
reg flag_pre_end; //写完就激活下一行pre
reg sd_row_end; //写一行结束
reg[1:0] burst_cnt; //0 1 2 3
reg[1:0] burst_cnt_t; //延迟一拍
reg wr_data_end; //两行写完强制结束
//********************************************
reg[3:0] act_cnt; //
reg[3:0] break_cnt;
reg[7:0] col_cnt; //列地址计数
//********************************************
reg[12:0] row_addr;
wire[8:0] col_addr;
//flag_wr
always@(posedge sclk or negedge reset)begin
if(!reset)
flag_wr <= 1'b0;
else if(wr_trig == 1'b1 && flag_wr == 0)
flag_wr <= 1'b1;
else if(wr_data_end == 1'b1)
flag_wr <= 1'b0;
end
//burst_cnt 突发4计数
always@(posedge sclk or negedge reset)begin
if(!reset)
burst_cnt <= 0;
else if(state == S_WR)
burst_cnt <= burst_cnt + 1;
else
burst_cnt <= 0;
end
//burst_cnt_t
always@(posedge sclk or negedge reset)begin
burst_cnt_t <= burst_cnt;
end
//--------------------STATE-----------------------
always@(posedge sclk or negedge reset)begin
if(!reset)
state <= S_IDLE;
else case(state)
S_IDLE:
if(wr_trig == 1)
state <= S_REQ;
else
state <= S_IDLE;
S_REQ:
if(wr_en == 1)
state <= S_ACT;
else
state <= S_REQ;
S_ACT:
if(flag_act_end == 1)//一次突发写完为1
state <= S_WR;
else
state <= S_ACT;
S_WR://些状态跳到充电
if(wr_data_end == 1)
state <= S_PRE; //写完两行
else if(ref_req == 1 && burst_cnt_t == 'd2 && flag_wr == 1)
state <= S_PRE;//刷新到这里 准备 跳出,下几个时钟周期又回来
else if(sd_row_end == 1 && flag_wr == 1)//写完一行
state <= S_PRE;
S_PRE:
if(ref_req == 1 && flag_wr == 1)
state <= S_REQ;
else if(flag_pre_end == 1 && flag_wr == 1)
state <= S_ACT;
else if(wr_data_end == 1)
state <= S_IDLE;
default:
state <= S_IDLE;
endcase
end
//wr_cmd
always@(posedge sclk or negedge reset)begin
if(!reset)
wr_cmd <= CMD_NOP;
else case(state)
S_ACT:
if(act_cnt == 0)
wr_cmd <= CMD_ACT;
else
wr_cmd <= CMD_NOP;
S_WR:
if(burst_cnt == 0)
wr_cmd <= CMD_WR;
else
wr_cmd <= CMD_NOP;
S_PRE:
if(break_cnt == 0)
wr_cmd <= CMD_PRE;
else
wr_cmd <= CMD_NOP;
default:
wr_cmd <= CMD_NOP;
endcase
end
//wr_addr
always@(*)begin//组合逻辑不会延一拍
case(state)
S_ACT:
if(act_cnt == 0)
wr_addr <= row_addr;
S_WR:
wr_addr <= {4'b0000,col_addr}; //A10为1,,好像是0
S_PRE:
if(break_cnt == 0)
wr_addr <= {13'b0_0100_0000_0000};
endcase
end
//---------------------------------------------------
//flag_act_end
always@(posedge sclk or negedge reset)begin
if(!reset)
flag_act_end <= 0;
else if(act_cnt == 'd3)
flag_act_end <= 1;//相当于第4个别的模块调用已经是第五个了
else
flag_act_end <= 0;
end
//act_cnt
always@(posedge sclk or negedge reset)begin
if(!reset)
act_cnt <= 0;
else if(state == S_ACT)//激活需要4个周期包括 命令行地址 延迟3 列地址
act_cnt <= act_cnt + 1;
else
act_cnt <= 0;
end
//flag_pre_end //突发为4 结束
always@(posedge sclk or negedge reset)begin
if(!reset)
flag_pre_end <= 0;
else if(break_cnt == 'd3)//预充电也需要时间
flag_pre_end <= 1;
else
flag_pre_end <= 0;
end
//
always@(posedge sclk or negedge reset)begin
if(!reset)
flag_wr_end <= 0;
else if((state == S_PRE && ref_req == 1)
|| (state == S_PRE && wr_data_end == 1))//刷新计数
flag_wr_end <= 1;
else
flag_wr_end <= 0;
end
//break_cnt //预充电时间
always@(posedge sclk or negedge reset)begin
if(!reset)
break_cnt <= 0;
else if(state == S_PRE)
break_cnt <= break_cnt + 1;
else
break_cnt <= 0;
end
//wr_data_end
always@(posedge sclk or negedge reset)begin
if(!reset)
wr_data_end <= 0;
else if(row_addr == 2 && col_addr == 'd511)//自动累加9位 两行写结束//改为3行
wr_data_end <= 1;//
else
wr_data_end <= 0;
end
//col_cnt
always@(posedge sclk or negedge reset)begin
if(!reset)
col_cnt <= 0;
else if(col_addr == 511)
col_cnt <= 0;
else if(burst_cnt_t == 3)
col_cnt <= col_cnt + 1;
end
//row_addr
always@(posedge sclk or negedge reset)begin
if(!reset)
row_addr <= 0;
else if(sd_row_end == 1)
row_addr <= row_addr + 1;
end
//sd_row_end
always@(posedge sclk or negedge reset)begin
if(!reset)
sd_row_end <= 0;
else if(col_addr == 509)
sd_row_end <= 1;
else
sd_row_end <= 0;
end
//
always@(*)begin
case(burst_cnt_t)
0:wr_data <= 1;
1:wr_data <= 2;
2:wr_data <= 3;
3:wr_data <= 4;
default: wr_data <= 0;
endcase
end
assign col_addr = {col_cnt,burst_cnt_t};
assign bank_addr = 2'b00;//写操作代码
assign wr_req = state[1];
endmodule
sdram_read
module sdram_read(
//system single
input sclk,
input reset,
//commucation with top
input rd_en,//现有请求在使能
output wire rd_req,
output reg flag_rd_end,
//others
input ref_req,//刷新请求信号
input rd_trig,//写触发
//read interface
output reg[3:0] rd_cmd,
output reg[12:0] rd_addr,
output wire[1:0] bank_addr
//output reg[15:0] rd_data
);
/
//
/
//状态
localparam S_IDLE = 5'b0_0001;
localparam S_REQ = 5'b0_0010;
localparam S_ACT = 5'b0_0100;//行激活
localparam S_RD = 5'b0_1000;
localparam S_PRE = 5'b1_0000;
//SDRAM Comand
localparam CMD_NOP = 4'b0111;
localparam CMD_PRE = 4'b0010;
localparam CMD_AREF = 4'b0001;
localparam CMD_ACT = 4'b0011;
localparam CMD_RD = 4'b0101;
reg flag_rd;//写进行中
reg[4:0] state; //5个状态
//*********************************************
reg flag_act_end; //4个数据一个act
reg flag_pre_end; //写完就激活下一行pre
reg sd_row_end; //写一行结束
reg[1:0] burst_cnt; //0 1 2 3
reg[1:0] burst_cnt_t; //延迟一拍
reg rd_data_end; //两行写完强制结束
//********************************************
reg[3:0] act_cnt; //
reg[3:0] break_cnt;
reg[7:0] col_cnt; //列地址计数
//********************************************
reg[12:0] row_addr;
wire[8:0] col_addr;
//flag_rd
always@(posedge sclk or negedge reset)begin
if(!reset)
flag_rd <= 1'b0;
else if(rd_trig == 1'b1 && flag_rd == 0)
flag_rd <= 1'b1;
else if(rd_data_end == 1'b1)
flag_rd <= 1'b0;
end
//burst_cnt 突发4计数
always@(posedge sclk or negedge reset)begin
if(!reset)
burst_cnt <= 0;
else if(state == S_RD)
burst_cnt <= burst_cnt + 1;
else
burst_cnt <= 0;
end
//burst_cnt_t
always@(posedge sclk or negedge reset)begin
burst_cnt_t <= burst_cnt;
end
//--------------------STATE-----------------------
always@(posedge sclk or negedge reset)begin
if(!reset)
state <= S_IDLE;
else case(state)
S_IDLE:
if(rd_trig == 1)
state <= S_REQ;
else
state <= S_IDLE;
S_REQ:
if(rd_en == 1)
state <= S_ACT;
else
state <= S_REQ;
S_ACT:
if(flag_act_end == 1)//一次突发写完为1
state <= S_RD;
else
state <= S_ACT;
S_RD://些状态跳到充电
if(rd_data_end == 1)
state <= S_PRE; //写完两行
else if(ref_req == 1 && burst_cnt_t == 'd2 && flag_rd == 1)
state <= S_PRE;//刷新到这里 准备 跳出,下几个时钟周期又回来
else if(sd_row_end == 1 && flag_rd == 1)//写完一行
state <= S_PRE;
S_PRE:
if(ref_req == 1 && flag_rd == 1)
state <= S_REQ;
else if(flag_pre_end == 1 && flag_rd == 1)
state <= S_ACT;
else if(rd_data_end == 1)
state <= S_IDLE;
default:
state <= S_IDLE;
endcase
end
//rd_cmd
always@(posedge sclk or negedge reset)begin
if(!reset)
rd_cmd <= CMD_NOP;
else case(state)
S_ACT:
if(act_cnt == 0)
rd_cmd <= CMD_ACT;
else
rd_cmd <= CMD_NOP;
S_RD:
if(burst_cnt == 0)
rd_cmd <= CMD_RD;
else
rd_cmd <= CMD_NOP;
S_PRE:
if(break_cnt == 0)
rd_cmd <= CMD_PRE;
else
rd_cmd <= CMD_NOP;
default:
rd_cmd <= CMD_NOP;
endcase
end
//rd_addr
always@(*)begin//组合逻辑不会延一拍
case(state)
S_ACT:
if(act_cnt == 0)
rd_addr <= row_addr;
S_RD:
rd_addr <= {4'b0000,col_addr}; //A10为1,,好像是0
S_PRE:
if(break_cnt == 0)
rd_addr <= {13'b0_0100_0000_0000};
endcase
end
//---------------------------------------------------
//flag_act_end
always@(posedge sclk or negedge reset)begin
if(!reset)
flag_act_end <= 0;
else if(act_cnt == 'd3)
flag_act_end <= 1;//相当于第4个别的模块调用已经是第五个了
else
flag_act_end <= 0;
end
//act_cnt
always@(posedge sclk or negedge reset)begin
if(!reset)
act_cnt <= 0;
else if(state == S_ACT)//激活需要4个周期包括 命令行地址 延迟3 列地址
act_cnt <= act_cnt + 1;
else
act_cnt <= 0;
end
//flag_pre_end //突发为4 结束
always@(posedge sclk or negedge reset)begin
if(!reset)
flag_pre_end <= 0;
else if(break_cnt == 'd3)//预充电也需要时间
flag_pre_end <= 1;
else
flag_pre_end <= 0;
end
//
always@(posedge sclk or negedge reset)begin
if(!reset)
flag_rd_end <= 0;
else if((state == S_PRE && ref_req == 1)
|| (state == S_PRE && rd_data_end == 1))//刷新计数
flag_rd_end <= 1;
else
flag_rd_end <= 0;
end
//break_cnt //预充电时间
always@(posedge sclk or negedge reset)begin
if(!reset)
break_cnt <= 0;
else if(state == S_PRE)
break_cnt <= break_cnt + 1;
else
break_cnt <= 0;
end
//rd_data_end
always@(posedge sclk or negedge reset)begin
if(!reset)
rd_data_end <= 0;
else if(row_addr == 2 && col_addr == 'd511)//自动累加9位 两行写结束//改为3行
rd_data_end <= 1;//
else
rd_data_end <= 0;
end
//col_cnt
always@(posedge sclk or negedge reset)begin
if(!reset)
col_cnt <= 0;
else if(col_addr == 511)
col_cnt <= 0;
else if(burst_cnt_t == 3)
col_cnt <= col_cnt + 1;
end
//row_addr
always@(posedge sclk or negedge reset)begin
if(!reset)
row_addr <= 0;
else if(sd_row_end == 1)
row_addr <= row_addr + 1;
end
//sd_row_end
always@(posedge sclk or negedge reset)begin
if(!reset)
sd_row_end <= 0;
else if(col_addr == 509)
sd_row_end <= 1;
else
sd_row_end <= 0;
end
//
/*
always@(*)begin
case(burst_cnt_t)
0:wr_data <= 1;
1:wr_data <= 2;
2:wr_data <= 3;
3:wr_data <= 4;
default: wr_data <= 0;
endcase
end
*/
assign col_addr = {col_cnt,burst_cnt_t};
assign bank_addr = 2'b00;//写操作代码
assign rd_req = state[1];
endmodule
sdram_top
module sdram_top(
//system singles
input sclk ,
input reset ,
//SDRAM Interface
output wire sdram_clk ,
output wire sdram_cke ,
output wire sdram_cs_n ,
output wire sdram_ras_n ,
output wire sdram_cas_n ,
output wire sdram_we_n ,
output wire [1:0] sdram_bank ,
output reg [12:0] sdram_addr ,
output wire [1:0] sdram_dqm ,
inout wire [15:0] sdram_dq ,
output wire flag_init_end ,
//others
input wr_trig ,
input rd_trig
);
//===============================================================
//*************Define parameter and Internal Singles*************
//===============================================================
//仲裁状态机
localparam IDLE = 5'b0_0001 ;
localparam ARBIT = 5'b0_0010 ;
localparam AREF = 5'b0_0100 ;
localparam WRITE = 5'b0_1000 ;
localparam READ = 5'b1_0000 ;
reg[3:0] sd_cmd ;//各种命令组合起来
//init_main
wire [3:0] init_cmd ;
wire [12:0] init_addr ;
//状态机状态
reg [4:0] state ;
//refresh module
wire ref_req ;
wire flag_ref_end ;
reg ref_en ;//仲裁
wire [3:0] ref_cmd ;
wire [12:0] ref_addr ;
//write module
reg wr_en ;
wire wr_req ;
wire flag_wr_end ;
wire[3:0] wr_cmd ;
wire[12:0] wr_addr ;
wire[1:0] wr_bank_addr ;
wire[15:0] wr_data ;
//read module
reg rd_en ;
wire rd_req ;
wire flag_rd_end ;
// wire ref_req ; //已经有了刷新命令
// wire rd_trig ;
wire[3:0] rd_cmd ;
wire[11:0] rd_addr ;
wire[1:0] rd_bank_addr ;
always @(posedge sclk or negedge reset) begin
if(reset == 1'b0)
state <= IDLE;
else case(state)
IDLE:
if(flag_init_end == 1'b1)
state <= ARBIT;
else
state <= IDLE;
ARBIT://仲裁
if(ref_en == 1'b1)
state <= AREF;
else if(wr_en == 1)//写优于读模块
state <= WRITE;
else if(rd_en == 1)
state <= READ;
else
state <= ARBIT;
AREF:
if(flag_ref_end == 1'b1)
state <= ARBIT;
else
state <=AREF;
WRITE:
if(flag_wr_end == 1'b1)
state <= ARBIT;
else
state <=WRITE;
READ:
if(flag_rd_end == 1'b1)
state <= ARBIT;
else
state <=READ;
default:
state <= IDLE;
endcase
end
//ref_en
always @(posedge sclk or negedge reset) begin
if(reset == 1'b0)
ref_en <= 1'b0;
else if(state == ARBIT && ref_req == 1'b1)
ref_en <= 1'b1;
else
ref_en <= 1'b0;
end
//wr_en
always @(posedge sclk or negedge reset) begin
if(reset == 1'b0)
wr_en <= 1'b0;
else if(state == ARBIT && ref_req == 1'b0 && wr_req == 1)
wr_en <= 1'b1;
else
wr_en <= 1'b0;
end
//rd_en
always @(posedge sclk or negedge reset) begin
if(reset == 1'b0)
rd_en <= 1'b0;
else if(state == ARBIT && ref_req == 0 && wr_req == 0 && rd_req == 1)
rd_en <= 1'b1;
else
rd_en <= 1'b0;
end
//===============================================================
//**************** Main Code ***********
//===============================================================
//目前只有刷新和写才有的状态
always@(*)begin
case(state)
IDLE:begin
sd_cmd <= init_cmd;
sdram_addr <= init_addr;
end
AREF:begin
sd_cmd <= ref_cmd;
sdram_addr <= ref_addr;
end
WRITE:begin
sd_cmd <= wr_cmd;
sdram_addr <= wr_addr;
end
READ:begin
sd_cmd <= rd_cmd;
sdram_addr <= rd_addr;
end
default:begin
sd_cmd <= 4'b0111;//nop
sdram_addr <= 0;
end
endcase
end
assign sdram_cke = 1'b1;
//assign sdram_addr = (state == IDLE) ? init_addr : ref_addr;
//assign {sdram_cs_n,sdram_ras_n,sdram_cas_n,sdram_we_n} = (state == IDLE) ? init_cmd : ref_cmd;
assign {sdram_cs_n,sdram_ras_n,sdram_cas_n,sdram_we_n} = sd_cmd;
assign sdram_dqm = 2'b00;
assign sdram_clk = ~sclk;//方便sdram采样
assign sdram_dq = (state == WRITE)? wr_data : {16{1'bz}};
assign sdram_bank = (state == WRITE)? wr_bank_addr : rd_bank_addr;
sdram_init sdram_init_inst(
//system singles
.sclk (sclk ),
.reset (reset ),
//others
.cmd_reg (init_cmd ),
.sdram_addr (init_addr ),
.flag_init_end (flag_init_end )
);
sdram_aref sdram_aref_inst(
//system signals
.sclk (sclk ),
.reset (reset ),
//comunicat with ARBIT
.ref_en (ref_en ),
.ref_req (ref_req ),
.flag_ref_end (flag_ref_end ),
//others
.aref_cmd (ref_cmd ),
.sdram_addr (ref_addr ),
.flag_init_end (flag_init_end )
);
sdram_write sdram_write_inst(
//system single
.sclk (sclk ),
.reset (reset ),
.wr_en (wr_en ),//现有请求在使能
.wr_req (wr_req ),
.flag_wr_end (flag_wr_end ),
.ref_req (ref_req ),//刷新请求信号
.wr_trig (wr_trig ),//写触发
.wr_cmd (wr_cmd ),
.wr_addr (wr_addr ),
.bank_addr (wr_bank_addr ),
.wr_data (wr_data )
);
sdram_read sdram_read_inst(
//system single
.sclk (sclk ),
.reset (reset ),
.rd_en (rd_en ),//现有请求在使能
.rd_req (rd_req ),
.flag_rd_end (flag_rd_end ),
.ref_req (ref_req ),//刷新请求信号
.rd_trig (rd_trig ),//写触发
.rd_cmd (rd_cmd ),
.rd_addr (rd_addr ),
.bank_addr (rd_bank_addr )
);
endmodule
tb_sdram_top
`timescale 1ns/1ns
module tb_sdram_top;
reg sclk;
reg reset;
//--------------------------
wire sdram_clk ;
wire sdram_cke ;
wire sdram_cs_n ;
wire sdram_ras_n ;
wire sdram_cas_n ;
wire sdram_we_n ;
wire [1:0] sdram_bank ;
wire [12:0] sdram_addr ;
wire [1:0] sdram_dqm ;
wire [15:0] sdram_dq ;
wire flag_init_end ;
reg wr_trig ;
reg rd_trig ;
initial begin
wr_trig <= 0;
rd_trig <= 0;
#205000 //初始化之后才能触发
wr_trig <= 1;
#20 //产生触发脉冲
wr_trig <= 0;
#126500
rd_trig <= 1;
#20
rd_trig <= 0;
end
initial begin
sclk <= 1'b1;
reset <= 1'b0;
#100
reset <= 1'b1;
end
always #10 sclk = ~sclk;
//从定义
defparam sdram_model_plus_inst.addr_bits = 13; //行地址
defparam sdram_model_plus_inst.data_bits = 16;
defparam sdram_model_plus_inst.col_bits = 9; //列地址
defparam sdram_model_plus_inst.mem_sizes = 4*1024*1024;//4M
sdram_top sdram_top_inst(
//system singles
.sclk (sclk ),
.reset (reset ),
//SDRAM Interface
.sdram_clk (sdram_clk ),
.sdram_cke (sdram_cke ),
.sdram_cs_n (sdram_cs_n ),
.sdram_cas_n (sdram_cas_n ),
.sdram_ras_n (sdram_ras_n ),
.sdram_we_n (sdram_we_n ),
.sdram_bank (sdram_bank ),
.sdram_addr (sdram_addr ),
.sdram_dqm (sdram_dqm ),
.sdram_dq (sdram_dq ),
.flag_init_end (flag_init_end ),
.wr_trig (wr_trig ),
.rd_trig (rd_trig )
);
sdram_model_plus sdram_model_plus_inst(
.Dq (sdram_dq ),
.Addr (sdram_addr ),
.Ba (sdram_bank ),
.Clk (sdram_clk ),
.Cke (sdram_cke ),
.Cs_n (sdram_cs_n ),
.Ras_n (sdram_ras_n ),
.Cas_n (sdram_cas_n ),
.We_n (sdram_we_n ),
.Dqm (sdram_dqm ),
.Debug (1'b1 )
);
endmodule