|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2013-8-1 11:55:55
|
显示全部楼层
代码如下:
sdram控制
//-----------------------------------------------------------------------------
module Sdram_Control
(
clk,rst_n,sd_init_ok,fifo_wruseDW,fifo_wr_reg,out_data,Sdram_data,
ramCK,ramDQM,ramBS,ramADR,ramCS,ramRAS,ramCAS,ramWE,ramDAT,
FillRow,FillCol,DispBS,FillBS,dat_in_resp,dat_in_act
);
input clk;
input rst_n;
input [2:0] fifo_wruseDW;
input [11:0]FillRow;
input [7:0]FillCol;
input [1:0]DispBS;
input [1:0]FillBS;
input [15:0]Sdram_data;
input dat_in_act;
output sd_init_ok;
output fifo_wr_reg;
output ramCK,ramCS,ramRAS,ramCAS,ramWE;
output [1:0]ramDQM,ramBS;
output [11:0]ramADR;
output [15:0] out_data;
inout [15:0] ramDAT;
output dat_in_resp;
//-----------------------------------------------------------------------------
reg sd_init_ok ; // System run enable
reg dat_in_resp;
reg [3:0] clk_cnt;
reg [2:0] loop_cnt; // Nop loop cnt
reg [11:0] DispRow;
reg [7:0] DispCol; // for 32Pages
reg [3:0]Refresh_cnt;
reg fifo_wr_reg;
//-----------------------------------------------------------------------------
reg refresh_en;
reg ramOE; // if "1",writer data to ram
reg ramRAS,ramCAS,ramWE;
reg [13:0] init_cnt;
reg [3:0] state_mode;
reg [3:0] next_state;
reg [11:0] ramADR;
reg [1:0] ramBS;
//-----------------------------------------------------------------------------
// wire [15:0] out_data;
//-----------------------------------------------------------------------------
assign ramCK = clk; // Ram Clock
assign ramDQM = 2'b00; // DQM is not used
assign ramCS = 1'b0;
assign ramDAT = ramOE ? Sdram_data: 16'hzzzz;
assign out_data = ramDAT;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
always @(negedge clk or negedge rst_n)
if(!rst_n) begin
sd_init_ok <= 1'b0;
state_mode <= 4'd0;
ramADR <= 12'hfff;
ramRAS <= 1'b1;
ramCAS <= 1'b1;
ramWE <= 1'b1;
ramOE <= 1'b0;
init_cnt <= 14'h3fff;
Refresh_cnt <= 4'd0;
DispRow <= 12'd0;
DispCol <= 8'd0;
fifo_wr_reg <= 1'b0;
dat_in_resp <= 1'b0;
ramBS <= 2'b11;
loop_cnt <= 3'd0;
//rec_end <= 1'b0;
end
else if(sd_init_ok)begin
case(state_mode) //sdram read or writer or Auto-precharge
4'd0:
begin
ramRAS <= 1'b1;
ramCAS <= 1'b1;
ramWE <= 1'b1;
state_mode <= next_state;
end
4'd1:begin
// From init entry,Row Active
if(fifo_wruseDW<3'd4)
begin
ramRAS <= 1'b0;
ramCAS <= 1'b1;
ramWE <= 1'b1;
ramBS <= DispBS;
ramADR <= DispRow;
state_mode <= 4'd0;
next_state <= 4'd2;
end
else if(dat_in_act != dat_in_resp)begin
dat_in_resp <= !dat_in_resp;
state_mode <= 4'd5;
end
else state_mode <= 4'd1;
end
4'd2:
begin
ramRAS <= 1'b1;
ramCAS <= 1'b0;
ramWE <= 1'b1;
//loop_cnt <= 3'd1;
ramADR <= {4'b0100,DispCol};
if(DispRow[0] == 1'b0) begin
if(DispCol[7:2] == 6'h3f)begin
DispCol <= 8'd0;
DispRow <= DispRow + 1'b1;
end
else
DispCol[7:2] <= DispCol[7:2] + 1'b1;
end
else begin
if(DispCol == 8'd220) begin
DispCol <= 8'd0;
if(DispRow ==12'd543)
DispRow <= 12'd0;
else
DispRow <= DispRow + 1'b1;
refresh_en <= 1'b1;
end
else
DispCol[7:2] <= DispCol[7:2] + 1'b1;
end
state_mode <= 4'd0;//10;
next_state <= 4'd3; // Goto get data
end
4'd3:
begin
fifo_wr_reg <= 1'b1;
state_mode <= 4'd10;
loop_cnt <= 2; // 6 nop loops
next_state <= 4'd4; // Goto
end
4'd4:
begin
fifo_wr_reg <= 1'b0;
//loop_cnt <= 3;
state_mode <= 4'd0;//2
next_state <= 4'd8;
end
4'd5: // Bank Active for write
begin
ramRAS <= 0;
ramCAS <= 1;
ramWE <= 1;
ramOE <= 1;
ramBS <= FillBS;
ramADR <= FillRow;
state_mode <= 4'd0;
next_state <= 4'd6; // Goto write
end
4'd6: // Write with Auto-precharge
begin
ramRAS <= 1;
ramCAS <= 0;
ramWE <= 0;
ramADR <={4'b0100,FillCol};
state_mode <= 4'd7;
loop_cnt <= 3'd3; // 5 nop loops
next_state <= 4'd1; // Goto detect next state
end
4'd7: // Nop Loop cnt
begin
ramRAS <= 1;
ramCAS <= 1;
ramWE <= 1;
if(loop_cnt)
loop_cnt <= loop_cnt - 3'h1;
else begin
state_mode <= next_state;
ramOE <= 0;
end
end
4'd8:
begin
if(refresh_en)
begin
refresh_en <= 0;
state_mode <= 4'd9; // Next state is Auto Refresh
end
else
state_mode <= 4'd1; // Next state is read
end
4'd9: // Auto Refresh
begin
ramRAS <= 1'b0;
ramCAS <= 1'b0;
ramWE <= 1'b1;
loop_cnt <= 3'd2;
state_mode <= 4'd10;
next_state <= 4'd1; // Goto detect write or not
end
4'd10: // Nop for no write
begin
ramRAS <= 1;
ramCAS <= 1;
ramWE <= 1;
if(loop_cnt)
loop_cnt <= loop_cnt - 3'h1;
else
state_mode <= next_state;
end
endcase
end
else
begin
case(state_mode) //sdram init
4'd0: // Wait for 200us
begin
init_cnt <= init_cnt -1'b1;
ramRAS <= 1'b1;
ramCAS <= 1'b1;
ramWE <= 1'b1;
ramADR <= 12'hfff;
if(init_cnt == 14'd0)
state_mode <= 4'd2;
end
4'd1: // idle
begin
init_cnt <= init_cnt - 1'b1;
ramRAS <= 1'b1;
ramCAS <= 1'b1;
ramWE <= 1'b1;
ramBS <= 2'b11;
ramADR <= 12'hfff;
if(init_cnt == 14'd0)begin
if(Refresh_cnt> 4'd7) begin
state_mode <= 4'd4;
Refresh_cnt <= 4'd0;
end
else state_mode <= next_state;
end
end
4'd2: // Precharge All
begin
ramRAS <= 1'b0;
ramCAS <= 1'b1;
ramWE <= 1'b0;
//ramADR[10] <= 1'b1;//对所有行预充电
state_mode <= 4'd1;
next_state <= 4'd3;
init_cnt <= 14'd3;
end
4'd3: // Auto Refresh
begin
Refresh_cnt <= Refresh_cnt + 1'b1;
ramRAS <= 1'b0;
ramCAS <= 1'b0;
ramWE <= 1'b1;
init_cnt <= 14'd5;
state_mode <= 4'd1; // Goto idle
next_state <= 4'd3;
end
4'd4: // Mode Register Set
begin
ramRAS <= 1'b0;
ramCAS <= 1'b0;
ramWE <= 1'b0;
ramBS <= 2'b00;
ramADR <= 12'b0010_0010_0010; // CL=3,BL=4
state_mode <= 4'd1; // Goto idle
next_state <= 4'd5;
init_cnt <= 14'd8;
end
4'd5:
begin
ramRAS <= 1'b1;
ramCAS <= 1'b1;
ramWE <= 1'b1;
sd_init_ok <= 1'b1;
state_mode <= 4'd1;
end
endcase
end
endmodule
|
|