📄 datacnl.v
字号:
module datacnl(
clk,
rst,
r_ram_rdb,
r_ram_rab,
r_req,
r_ack,
s_ram_wdb,
s_ram_wab,
s_ram_wen,
s_req,
s_ack,
cmd,
cmdack,
addr,
datain,
dataout,
start_send,
start_read,
vsync, //每帧同步一次,高有效
vsync_vga //vga的帧同步信号,每帧取一次同步,高有效
);
//--------------------ports--------------------
input clk,rst;
input [31:0] r_ram_rdb;
input cmdack;
input [31:0] dataout;
input r_req,s_req;
input start_read,vsync,vsync_vga;
output r_ack;
output [8:0] r_ram_rab;
output s_ram_wen;
output [8:0] s_ram_wab;
output [2:0] cmd;
output [20:0] addr;
output [31:0] datain,s_ram_wdb;
output start_send;
output s_ack;
//---------port variables declaration-----------
wire clk,rst;
wire cmdack;
wire [31:0] dataout;
reg [2:0] cmd;
reg [20:0] addr;
wire s_ram_wen;
reg start_send;
// State parameters used in MAIN STATE MACHINE
parameter
IDLE =21'b0_0000_0000_0000_0000_0001, //0
PRECHARGE =21'b0_0000_0000_0000_0000_0010, //1
PRECHARGE_ACK =21'b0_0000_0000_0000_0000_0100, //2
LOAD_MR =21'b0_0000_0000_0000_0000_1000, //3
LOAD_MR_ACK =21'b0_0000_0000_0000_0001_0000, //4
LOAD_R2 =21'b0_0000_0000_0000_0010_0000, //5
LOAD_R2_ACK =21'b0_0000_0000_0000_0100_0000, //6
LOAD_R1 =21'b0_0000_0000_0000_1000_0000, //7
IDLE_WR =21'b0_0000_0000_0001_0000_0000, //8
PAGE_WRITE =21'b0_0000_0000_0010_0000_0000, //9
BURST_WRITE =21'b0_0000_0000_0100_0000_0000, //10
BT_W =21'b0_0000_0000_1000_0000_0000, //11
WAIT_ACK_W_T =21'b0_0000_0001_0000_0000_0000, //12
PAGE_READ =21'b0_0000_0010_0000_0000_0000, //13
BURST_READ =21'b0_0000_0100_0000_0000_0000, //14
BT =21'b0_0000_1000_0000_0000_0000, //15
LAST_DATA =21'b0_0001_0000_0000_0000_0000, //16
CLOSE_PAGE_W =21'b0_0010_0000_0000_0000_0000, //17
REFRESH_W =21'b0_0100_0000_0000_0000_0000, //18
CLOSE_PAGE_R =21'b0_1000_0000_0000_0000_0000, //19
REFRESH_R =21'b1_0000_0000_0000_0000_0000; //20
parameter RCD='D3,CL='D3,BL='d180;//H_PIXELS>>2;
reg s_enable,s_enable_dly;
reg [20:0] STATE;
reg s_req_dly,r_req_dly;
reg vsync_dly,vsync_vga_dly;
reg vsync_dly1,vsync_vga_dly1;
always @ (posedge clk)
begin
s_req_dly <= s_req;
r_req_dly <= r_req;
vsync_dly <= vsync;
vsync_dly1 <= vsync_dly;
vsync_vga_dly <= vsync_vga;
vsync_vga_dly1 <= vsync_vga_dly;
end
reg [8*10:0] cmd_name;
always @ cmd
case (cmd)
3'b000: cmd_name="NOP";
3'b001: cmd_name="READA";
3'b010: cmd_name="WRITEA";
3'b011: cmd_name="REFRESH";
3'b100: cmd_name="PRECHARGE";
3'b101: cmd_name="LOAD_MODE";
3'b110: cmd_name="LOAD_REG1";
3'b111: cmd_name="LOAD_REG2";
endcase
reg [8*12:0] state_name;
always @ STATE
case(STATE)
PRECHARGE: state_name="PRECHARGE";
PRECHARGE_ACK: state_name="PRECHARGEACK";
LOAD_MR: state_name="LOAD_MR";
LOAD_MR_ACK: state_name="LOAD_MR_ACK";
LOAD_R2: state_name="LOAD_R2";
LOAD_R2_ACK: state_name="LOAD_R2_ACK";
LOAD_R1: state_name="LOAD_R1";
IDLE_WR: state_name="IDLE_WR";
PAGE_WRITE: state_name="PAGE_WRITE";
BURST_WRITE: state_name="BURST_WRITE";
BT_W: state_name="BT_W";
CLOSE_PAGE_W: state_name="CLOSE_PAGE_W";
CLOSE_PAGE_R: state_name="CLOSE_PAGE_R";
PAGE_READ: state_name="PAGE_READ";
BURST_READ: state_name="BURST_READ";
BT: state_name="BT";
LAST_DATA: state_name="LAST_DATA";
REFRESH_R: state_name="REFRESH_R";
REFRESH_W: state_name="REFRESH_W";
default: state_name="default";
endcase
//transfer the data bus
reg [31:0] s_ram_wdb;
always @ (posedge clk) begin
s_ram_wdb <= dataout;
end
wire [31:0] datain = r_ram_rdb;
reg STATE12_reg,STATE16_reg,STATE8_reg,STATE19_reg;
always @ (posedge clk) begin
STATE12_reg <= STATE[12];
STATE16_reg <= STATE[16];
STATE8_reg <= STATE[8];
STATE19_reg <= STATE[19];
end
reg [7:0] r_ram_rab_reg;
always @ (posedge clk or negedge rst)
if(!rst)
r_ram_rab_reg <= 1'b0;
else if((STATE[9]&cmdack)|STATE[10])
r_ram_rab_reg <= r_ram_rab_reg + 1'b1;
else if(STATE[12])
r_ram_rab_reg <= 1'b0;
reg r_ram_rab_hbit;
always @ (posedge clk or negedge rst)
if(!rst)
r_ram_rab_hbit <= 0;
else if(STATE[12])
r_ram_rab_hbit <= ~r_ram_rab_hbit;
else if(vsync_dly & STATE[8])
r_ram_rab_hbit <= 1'b0;
wire [8:0] r_ram_rab = {r_ram_rab_hbit,r_ram_rab_reg};
//generate the write address bus data
reg [7:0] s_ram_wab_reg;
always @ (posedge clk or negedge rst)
if(!rst) begin
s_ram_wab_reg <= 1'b0;
end
else begin
if(s_enable)
s_ram_wab_reg<=s_ram_wab_reg + 1'b1;
else
s_ram_wab_reg <= 1'b0;
end
reg s_ram_wab_hbit;
always @ (posedge clk or negedge rst)
if(!rst)
s_ram_wab_hbit <= 1'b0;
else if(!s_enable & s_enable_dly)
s_ram_wab_hbit <= ~s_ram_wab_hbit;
else if(vsync_vga_dly & STATE[8])
s_ram_wab_hbit <= 1'b0;
wire [8:0] s_ram_wab = {s_ram_wab_hbit,s_ram_wab_reg};
//generate the send wen signal
assign s_ram_wen = s_enable;
parameter NOP =3'b000,
READA =3'b001,
WRITEA =3'b010,
ARF =3'b011,
PRECHRG =3'b100,
LOAD_MODE =3'b101,
LOAD_REG1 =3'b110,
LOAD_REG2 =3'b111;
//generate the cmd to the sdr_sdram_controller
always @ (STATE)
case(STATE)
PRECHARGE: cmd = PRECHRG;
LOAD_MR: cmd = LOAD_MODE;
LOAD_R2: cmd = LOAD_REG2;
LOAD_R1: cmd = LOAD_REG1;
PAGE_WRITE: cmd = WRITEA;
BT_W: cmd = PRECHRG;
CLOSE_PAGE_W: cmd = PRECHRG;
CLOSE_PAGE_R: cmd = PRECHRG;
PAGE_READ: cmd = READA;
BT: cmd = PRECHRG;
REFRESH_W: cmd = ARF;
REFRESH_R: cmd = ARF;
default: cmd = NOP;
endcase
//*****************************************************************************//
//*****************************************************************************//
reg w_page_lbit;
always @ (posedge clk or negedge rst)
if(!rst)
w_page_lbit <= 1'b0;
else if(STATE[12])
w_page_lbit <= ~w_page_lbit;
else if(vsync_dly)
w_page_lbit <= 1'b0;
reg [9:0] w_page_hbit;
always @ (posedge clk or negedge rst)
if(!rst)
w_page_hbit <= 1'b0;
else if(STATE[12] & w_page_lbit) begin
if(w_page_hbit == 10'd574)
w_page_hbit <= 1'b1;
else if(w_page_hbit == 11'd575)
w_page_hbit <= 1'b0;
else
w_page_hbit <= w_page_hbit + 2'd2;
end
else if(STATE[8] & vsync_dly)
w_page_hbit <= 1'b0;
wire [10:0] w_page = {w_page_hbit,w_page_lbit};
reg [1:0] w_ba;
always @ (posedge clk or negedge rst)
if(!rst)
w_ba <= 1'b0;
else if(vsync_dly & !vsync_dly1) begin
w_ba <= w_ba + 1'b1;
end
//****************************************************************************//
//****************************************************************************//
reg [1:0] r_ba;
always @ (posedge clk or negedge rst)
if(!rst) begin
r_ba <= 1'b0;
end
else if(!vsync_vga_dly & vsync_vga_dly1)
r_ba <= w_ba + 2'd2;
reg [10:0] r_page;
always @ (posedge clk or negedge rst)
if(!rst)
r_page <= 1'b0;
else if(STATE[16])
r_page <= r_page + 1'b1;
else if(STATE[8] & vsync_vga_dly) begin
r_page<= 1'b0;
end
reg [7:0] Burst_cnt;
reg [1:0] RCDCL_CNT;
//********************************************************************************//
//********************************************************************************//
//the state machine
always @(posedge clk or negedge rst)
begin
if(!rst) begin
STATE<=IDLE;
s_enable<=0;
RCDCL_CNT<=0;
Burst_cnt<=0;
end
else
case(STATE)
IDLE:
if(start_read)
STATE<=PRECHARGE;
else
STATE<=IDLE;
PRECHARGE:
if(cmdack)
STATE<=PRECHARGE_ACK;
else
STATE<=PRECHARGE;
PRECHARGE_ACK:
STATE<=LOAD_MR;
LOAD_MR:
if(cmdack)
STATE<=LOAD_MR_ACK;
else
STATE<=LOAD_MR;
LOAD_MR_ACK:
STATE<=LOAD_R2;
LOAD_R2:
if(cmdack)
STATE<=LOAD_R2_ACK;
else
STATE<=LOAD_R2;
LOAD_R2_ACK:
STATE<=LOAD_R1;
LOAD_R1:
if(cmdack)
STATE<=IDLE_WR;
else
STATE<=LOAD_R1;
//page write burst
IDLE_WR: begin
if(r_req_dly) begin
STATE<=PAGE_WRITE;
end
else if( s_req_dly) begin
STATE<=PAGE_READ;
end
else
STATE<=IDLE_WR;
end
PAGE_WRITE:
if(cmdack) begin
STATE<=BURST_WRITE;
Burst_cnt<=1'b0;
end
else
STATE<=PAGE_WRITE;
BURST_WRITE: begin
if(Burst_cnt==(BL - 2'd3))
STATE<=BT_W;
else
STATE<=BURST_WRITE;
Burst_cnt<=Burst_cnt+1;
end
BT_W:begin
if(cmdack)
STATE<=WAIT_ACK_W_T;
else
STATE<=BT_W;
end
WAIT_ACK_W_T:begin
STATE<=CLOSE_PAGE_W;
end
//CLOSE CURRENT PAGE
CLOSE_PAGE_W:
if(cmdack)
STATE<=REFRESH_W;
else
STATE<=CLOSE_PAGE_W;
REFRESH_W:
if(cmdack)
STATE<=IDLE_WR;
else
STATE<=REFRESH_W;
//PAGE READ BURST TEST
PAGE_READ:begin
if(cmdack)
STATE<=BURST_READ;
else
STATE<=PAGE_READ;
Burst_cnt<=0;
RCDCL_CNT<=0;
end
BURST_READ:begin
if(Burst_cnt==(3'd6))
s_enable <= 1'b1;
else if(Burst_cnt==(BL-2'd3))//BL+RCD+CL
STATE<=BT;
else
STATE<=BURST_READ;
Burst_cnt<=Burst_cnt+1'b1;
end
BT:
if(cmdack)
STATE<=LAST_DATA;
else
STATE<=BT;
LAST_DATA:
STATE<=CLOSE_PAGE_R;
CLOSE_PAGE_R:begin
if(cmdack)
STATE<=REFRESH_R;
else
STATE<=CLOSE_PAGE_R;
if(RCDCL_CNT==2'd2)
s_enable<=0;
else
RCDCL_CNT<=RCDCL_CNT+1'b1;
end
REFRESH_R:begin
if(cmdack)begin
STATE<=IDLE_WR;
end
else
STATE<=REFRESH_R;
end
default:
STATE<=IDLE;
endcase
end
always @ (posedge clk)
s_enable_dly <= s_enable;
//generate the addr to the sdr_sdram_controller
always @ (STATE or w_page or r_page or r_ba or w_ba)
case(STATE)
PRECHARGE: addr = 21'h1f0000;
LOAD_MR: addr = 21'h37;
LOAD_R2: addr = 21'h5F6;
LOAD_R1: addr = 21'h12F; //'h10f
PAGE_WRITE: addr = {w_ba,w_page,8'b0};
PAGE_READ: addr = {r_ba,r_page,8'b0};
BT_W: addr = {w_ba,19'b0};
CLOSE_PAGE_W: addr = {w_ba,19'b0};
CLOSE_PAGE_R: addr = {r_ba,19'b0};
BT: addr = {r_ba,19'b0};
default: addr = 1'h0;
endcase
reg s_ack;
always @ (posedge clk or negedge rst)
if(!rst)
s_ack <= 1'b0;
else
s_ack <= STATE[13];
reg r_ack;
always @ (posedge clk or negedge rst)
if(!rst)
r_ack <= 1'b0;
else
r_ack <= STATE[9];
always @ (posedge clk or negedge rst)
if(!rst)
start_send <= 1'b0;
else if(w_ba[1])
start_send <= 1'b1;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -