D1 驱动代码
`timescale 1ns / 1ps
module qspi2
#(
parameter DATA_SIZE=9600 /* 400*3=1200 bytes */
)
(
input clk,
input rst_n,
(*mark_debug="true"*)input xfer_start,
(*mark_debug="true"*)output reg xfer_final,
(*mark_debug="true"*)output xfer_rdy,
(*mark_debug="true"*)input [7:0] cmd,
(*mark_debug="true"*)input [23:0] addr,
(*mark_debug="true"*)input [0: DATA_SIZE-1] din,
(*mark_debug="true"*)input [10:0] vadid_length, /* Max suppport DATA_SIZE=2047*8=16376 */
(*mark_debug="true"*)input [1:0] data_mode, /*00: cmd, 01: cmd+addr, 10: cmd+addr+1wire data, 11: cmd+addr+4wire data*/
(*mark_debug="true"*)input cs_mode, /*IDLE state, 0: cs=0, 1:cs=1, to support multi data_bursts while keep cs=0*/
(*mark_debug="true"*)output reg csx,
(*mark_debug="true"*)output reg sck,
(*mark_debug="true"*)output reg [3:0] dout
);
parameter IDLE=2'b00;
parameter SEND_CMD=2'b01;
parameter SEND_DATA=2'b10;
parameter SEND_WAIT=2'b11;
reg [1:0] state;
reg [6:0] lsm_cnt;
reg [10:0] xfer_valid_cnt;
reg xfer_end;
wire [10:0] valid_length_min;
assign valid_length_min=(vadid_length<=DATA_SIZE/8)? vadid_length:(DATA_SIZE/8);
always @(posedge clk or negedge rst_n)
if(rst_n==0)
state<=IDLE;
else case(state)
IDLE: if(xfer_start)
state<=SEND_CMD;
SEND_CMD: if(xfer_end && xfer_final)
state<=IDLE;
else if(xfer_end && ~xfer_final)
state<=SEND_DATA;
SEND_DATA: if(xfer_end && xfer_final && cs_mode)
state<=IDLE;
else if(xfer_end && xfer_final && ~cs_mode)
state<=SEND_WAIT;
SEND_WAIT: if(xfer_start)
state<=SEND_DATA;
default: state<=IDLE;
endcase
always @(posedge clk or negedge rst_n)
if(rst_n==0)
xfer_valid_cnt<=11'd0;
else if((state==IDLE|| state==SEND_WAIT) && xfer_start)
xfer_valid_cnt<=valid_length_min;
else if(state==SEND_DATA) begin
if((data_mode==2'b10) && lsm_cnt==16-1 /* 1wire */
|| (data_mode==2'b11) && lsm_cnt==4-1) /* 4wire */
xfer_valid_cnt<=xfer_valid_cnt-1;
end
always @(posedge clk or negedge rst_n)
if(rst_n==0)
lsm_cnt<=0;
else if(state==IDLE || state==SEND_WAIT)
lsm_cnt<=0;
else if(state==SEND_CMD) begin
if(xfer_end)
lsm_cnt<=0;
else
lsm_cnt<=lsm_cnt+1;
end
else if(state==SEND_DATA) begin
if((data_mode==2'b10) && lsm_cnt==16-1 /* 1wire */
|| (data_mode==2'b11) && lsm_cnt==4-1) /* 4wire */
lsm_cnt<=0;
else
lsm_cnt<=lsm_cnt+1;
end
reg [0:7] din_tmp;
always @(*) begin
if(state==SEND_DATA && xfer_valid_cnt>=1)
din_tmp=din[(valid_length_min-xfer_valid_cnt)*8 +:8];
else
din_tmp=8'h00;
end
always @(posedge clk or negedge rst_n)
if(rst_n==0) begin
csx<=1;
sck<=0;
dout<=4'h0;
end
else case(state)
IDLE: begin csx<=1; sck=0; end //begin and final state
SEND_WAIT: begin csx<=0; sck=0; end //intermediate state
SEND_CMD: begin
dout[3:1]<=3'b000;
if(data_mode==2'b00)
case(lsm_cnt)
0: begin csx<=0;end
1: begin dout[0]<=cmd[7];end
2: begin sck<=1;end
3: begin dout[0]<=cmd[6]; sck<=0; end
4: begin sck<=1;end
5: begin dout[0]<=cmd[5]; sck<=0; end
6: begin sck<=1;end
7: begin dout[0]<=cmd[4]; sck<=0; end
8: begin sck<=1;end
9: begin dout[0]<=cmd[3]; sck<=0; end
10: begin sck<=1;end
11: begin dout[0]<=cmd[2]; sck<=0; end
12: begin sck<=1;end
13: begin dout[0]<=cmd[1]; sck<=0; end
14: begin sck<=1;end
15: begin dout[0]<=cmd[0]; sck<=0; end
16: begin sck<=1;end
endcase
else if(data_mode!=2'b00)
case(lsm_cnt)
0: begin csx<=0;end
1: begin dout[0]<=cmd[7];end
2: begin sck<=1;end
3: begin dout[0]<=cmd[6]; sck<=0; end
4: begin sck<=1;end
5: begin dout[0]<=cmd[5]; sck<=0; end
6: begin sck<=1;end
7: begin dout[0]<=cmd[4]; sck<=0; end
8: begin sck<=1;end
9: begin dout[0]<=cmd[3]; sck<=0; end
10: begin sck<=1;end
11: begin dout[0]<=cmd[2]; sck<=0; end
12: begin sck<=1;end
13: begin dout[0]<=cmd[1]; sck<=0; end
14: begin sck<=1;end
15: begin dout[0]<=cmd[0]; sck<=0; end
16: begin sck<=1;end
17: begin dout[0]<=addr[23]; sck<=0; end
18: begin sck<=1;end
19: begin dout[0]<=addr[22]; sck<=0; end
20: begin sck<=1;end
21: begin dout[0]<=addr[21]; sck<=0; end
22: begin sck<=1;end
23: begin dout[0]<=addr[20]; sck<=0; end
24: begin sck<=1;end
25: begin dout[0]<=addr[19]; sck<=0; end
26: begin sck<=1;end
27: begin dout[0]<=addr[18]; sck<=0; end
28: begin sck<=1;end
29: begin dout[0]<=addr[17]; sck<=0; end
30: begin sck<=1;end
31: begin dout[0]<=addr[16]; sck<=0; end
32: begin sck<=1;end
33: begin dout[0]<=addr[15]; sck<=0; end
34: begin sck<=1;end
35: begin dout[0]<=addr[14]; sck<=0; end
36: begin sck<=1;end
37: begin dout[0]<=addr[13]; sck<=0; end
38: begin sck<=1;end
39: begin dout[0]<=addr[12]; sck<=0; end
40: begin sck<=1;end
41: begin dout[0]<=addr[11]; sck<=0; end
42: begin sck<=1;end
43: begin dout[0]<=addr[10]; sck<=0; end
44: begin sck<=1;end
45: begin dout[0]<=addr[9]; sck<=0; end
46: begin sck<=1;end
47: begin dout[0]<=addr[8]; sck<=0; end
48: begin sck<=1;end
49: begin dout[0]<=addr[7]; sck<=0; end
50: begin sck<=1;end
51: begin dout[0]<=addr[6]; sck<=0; end
52: begin sck<=1;end
53: begin dout[0]<=addr[5]; sck<=0; end
54: begin sck<=1;end
55: begin dout[0]<=addr[4]; sck<=0; end
56: begin sck<=1;end
57: begin dout[0]<=addr[3]; sck<=0; end
58: begin sck<=1;end
59: begin dout[0]<=addr[2]; sck<=0; end
60: begin sck<=1;end
61: begin dout[0]<=addr[1]; sck<=0; end
62: begin sck<=1;end
63: begin dout[0]<=addr[0]; sck<=0; end
64: begin sck<=1;end
endcase
end
SEND_DATA: begin
if(data_mode==2'b10) begin
dout[3:1]<=3'b000;
case(lsm_cnt)
0: begin dout[0]<=din_tmp[0]; sck<=0; end
1: begin sck<=1;end
2: begin dout[0]<=din_tmp[1]; sck<=0; end
3: begin sck<=1;end
4: begin dout[0]<=din_tmp[2]; sck<=0; end
5: begin sck<=1;end
6: begin dout[0]<=din_tmp[3]; sck<=0; end
7: begin sck<=1;end
8: begin dout[0]<=din_tmp[4]; sck<=0; end
9: begin sck<=1;end
10: begin dout[0]<=din_tmp[5]; sck<=0; end
11: begin sck<=1;end
12: begin dout[0]<=din_tmp[6]; sck<=0; end
13: begin sck<=1;end
14: begin dout[0]<=din_tmp[7]; sck<=0; end
15: begin sck<=1;end
endcase
end
else if(data_mode==2'b11)
case(lsm_cnt)
0: begin dout[3:0]<=din_tmp[0:3]; sck<=0; end
1: begin sck<=1;end
2: begin dout[3:0]<=din_tmp[4:7]; sck<=0; end
3: begin sck<=1;end
endcase
end
endcase
//xfer_end要单独产生,因为它只占一个aclk脉宽,与其它信号不一样
always @(posedge clk or negedge rst_n)
if(rst_n==0)
xfer_end<=0;
else if(state==SEND_CMD && (data_mode==2'b00) && lsm_cnt==17)
xfer_end<=1;
else if(state==SEND_CMD && (data_mode!=2'b00) && lsm_cnt==65)
xfer_end<=1;
else if(state==SEND_DATA && (data_mode==2'b10) && lsm_cnt==16-1 && xfer_valid_cnt==1)
xfer_end<=1;
else if(state==SEND_DATA && (data_mode==2'b11) && lsm_cnt==4-1 && xfer_valid_cnt==1)
xfer_end<=1;
else
xfer_end<=0;
always @(posedge clk or negedge rst_n)
if(rst_n==0)
xfer_final<=0;
else if(state==SEND_CMD && (data_mode==2'b00) && lsm_cnt==17) //cmd only
xfer_final<=1;
else if(state==SEND_CMD && (data_mode==2'b01) && lsm_cnt==65) //cmd+addr
xfer_final<=1;
else if(state==SEND_DATA && (data_mode==2'b10) && lsm_cnt==16-1 && xfer_valid_cnt==1) //data use 1wire
xfer_final<=1;
else if(state==SEND_DATA && (data_mode==2'b11) && lsm_cnt==4-1 && xfer_valid_cnt==1) //data use 4wire
xfer_final<=1;
else
xfer_final<=0;
assign xfer_rdy=(state==IDLE || state==SEND_WAIT)? 1:0;
endmodule
D2 st77903初始化代码
`timescale 1ns / 1ps
module qspi_init(
input clk,
input rst_n,
output csx,
output sck,
output [3:0] dout,
output reg rst_o
);
parameter CNT1_MAX=50_000_0;
parameter CNT2_MAX=34;
parameter CNT3_MAX=50_000_0;
reg [19:0] cnt1; /* generate rst_o and xfer_start */
reg [9:0] cnt2; /* counter init-seq numbers */
reg [19:0] cnt3; /* counter init-seq interval */
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt1<=0;
else if(add_cnt1) begin
if(end_cnt1)
cnt1<=0;
else
cnt1<=cnt1+1;
end
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt2<=0;
else if(add_cnt2) begin
if(end_cnt2)
cnt2<=0;
else
cnt2<=cnt2+1;
end
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt3<=0;
else if(add_cnt3) begin
if(end_cnt3)
cnt3<=0;
else
cnt3<=cnt3+1;
end
// always @(posedge clk or negedge rst_n)
// if(rst_n==0)
// cnt4<=0;
// else if(add_cnt4) begin
// if(end_cnt4)
// cnt4<=0;
// else
// cnt4<=cnt4+1;
// end
assign add_cnt1=cnt1_en;
assign end_cnt1=add_cnt1 && (cnt1==CNT1_MAX-1);
assign add_cnt2=(end_cnt3) && cnt2_en;
assign end_cnt2=add_cnt2 && (cnt2==CNT2_MAX-1);
assign add_cnt3=cnt3_en;
assign end_cnt3=add_cnt3 && (cnt3==CNT3_MAX-1);
// assign add_cnt4=cnt4_en;
// assign end_cnt4=add_cnt4 && (cnt4==CNT4_MAX-1);
reg cnt1_en;
reg cnt2_en;
reg cnt3_en;
// reg cnt4_en;
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt1_en<=1;
else if(end_cnt1)
cnt1_en<=0;
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt2_en<=1;
else if(end_cnt2)
cnt2_en<=0;
// always @(*)
// cnt3_en=~cnt4_en;
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt3_en<=0;
else if(end_cnt1)
cnt3_en<=1;
else if(end_cnt2)
cnt3_en<=0;
always @(posedge clk or negedge rst_n)
if(rst_n==0)
rst_o<=0;
else if(add_cnt1 && (cnt1==CNT1_MAX/2-1))
rst_o<=1;
reg [0: 128*CNT2_MAX-1] rom={
{8'd2,8'hf0, 8'hc3,{13{8'h00}}},
{8'd2,8'hf0, 8'h96,{13{8'h00}}},
{8'd2,8'hf0, 8'ha5,{13{8'h00}}},
{8'd2,8'he9, 8'h20,{13{8'h00}}},
{8'd5,8'he7, 8'h80, 8'h77, 8'h1f, 8'hcc,{10{8'h00}}},
{8'd5,8'hc1, 8'h77, 8'h07, 8'hcf, 8'h16,{10{8'h00}}},//Normal:VGHS/VGLS/VSP/VSN电压
{8'd5,8'hc2, 8'h77, 8'h07, 8'hcf, 8'h16,{10{8'h00}}},//Idle: VGHS/VGLS/VSP/VSN电压
{8'd5,8'hc3, 8'h22, 8'h02, 8'h22, 8'h04,{10{8'h00}}},//Normal: VGH/VGL/VSP/VSN Clk
{8'd5,8'hc4, 8'h22, 8'h02, 8'h22, 8'h04,{10{8'h00}}},//Idle: VGH/VGL/VSP/VSN Clk
{8'd2,8'hc5, 8'hed,{13{8'h00}}}, //VCOM
{8'd15,8'he0, 8'h87, 8'h09, 8'h0c, 8'h06, 8'h05, 8'h03, 8'h29, 8'h32, 8'h49, 8'h0f, 8'h1b, 8'h17, 8'h2a, 8'h2f},
{8'd15,8'he1, 8'h87, 8'h09, 8'h0c, 8'h06, 8'h05, 8'h03, 8'h29, 8'h32, 8'h49, 8'h0f, 8'h1b, 8'h17, 8'h2a, 8'h2f},
{8'd15,8'he5, 8'hbe, 8'hf5, 8'hb1, 8'h22, 8'h22, 8'h25, 8'h10, 8'h22, 8'h22, 8'h22, 8'h22, 8'h22, 8'h22, 8'h22},
{8'd15,8'he6, 8'hbe, 8'hf5, 8'hb1, 8'h22, 8'h22, 8'h25, 8'h10, 8'h22, 8'h22, 8'h22, 8'h22, 8'h22, 8'h22, 8'h22},
{8'd3,8'hec, 8'h40, 8'h03,{12{8'h00}}},
{8'd2,8'h36, 8'h0c,{13{8'h00}}},
{8'd2,8'h3a, 8'h07,{13{8'h00}}},
{8'd2,8'hb2, 8'h00,{13{8'h00}}},//GIP pattern
{8'd2,8'hb3, 8'h01,{13{8'h00}}},//video mode dot-inversion
{8'd2,8'hb4, 8'h01,{13{8'h00}}},
{8'd5,8'hb5, 8'h00, 8'h08, 8'h00, 8'h08,{10{8'h00}}}, //vfp
{8'd3,8'hb6, 8'hc7, 8'h31,{12{8'h00}}},
{8'd10,8'ha5, 8'h00, 8'h00, 8'h00, 8'h00, 8'h00, 8'h15, 8'h2a, 8'h8a, 8'h02,{5{8'h00}}},
{8'd10,8'ha6, 8'h00, 8'h00, 8'h00, 8'h00, 8'h00, 8'h15, 8'h2a, 8'h8a, 8'h02,{5{8'h00}}},
{8'd8,8'hba, 8'h0a, 8'h5a, 8'h23, 8'h10, 8'h25, 8'h02, 8'h00,{7{8'h00}}},
{8'd9,8'hbb, 8'h00, 8'h30, 8'h00, 8'h2c, 8'h82, 8'h87, 8'h18, 8'h00,{6{8'h00}}},
{8'd9,8'hbc, 8'h00, 8'h30, 8'h00, 8'h2c, 8'h82, 8'h87, 8'h18, 8'h00,{6{8'h00}}},
{8'd12,8'hbd, 8'ha1, 8'hb2, 8'h2b, 8'h1a, 8'h56, 8'h43, 8'h34, 8'h65, 8'hff, 8'hff, 8'h0f,{3{8'h00}}},
{8'd2,8'h35, 8'h00,{13{8'h00}}},
{8'd1,8'h21,{14{8'h00}}},
{8'd1,8'h11,{14{8'h00}}},
{8'd1,8'h29,{14{8'h00}}},
{8'd2,8'hb0, 8'ha5,{13{8'h00}}},
{8'd10,8'hcc, 8'h40, 8'h00, 8'h3f, 8'h00, 8'h14, 8'h14, 8'h20, 8'h20, 8'h03,{5{8'h00}}}
};
reg xfer_start;
wire xfer_final;
wire [3:0] dout;
reg [0:127] cmd_line;
reg [7:0] cmd;
reg [23:0] addr;
reg [0:127] din;
reg [10:0] vadid_length; /* Max suppport DATA_SIZE=2047*8=16376 */
reg [1:0] data_mode; /*00: cmd, 01: cmd+addr, 10: cmd+addr+1wire data, 11: cmd+addr+4wire data*/
reg cs_mode; /*IDLE state, 0: cs=0, 1:cs=1, to support multi data_bursts while keep cs=0*/
always @(posedge clk or negedge rst_n)
if(rst_n==0)
xfer_start<=0;
else if((end_cnt1 || end_cnt3) && cnt2<CNT2_MAX-1)
xfer_start<=1;
else
xfer_start<=0;
always @(*)
if(cnt2<CNT2_MAX)
cmd_line=rom[128*cnt2 +:128];
else
cmd_line=0;
always @(*) begin
vadid_length=cmd_line[0:7]-1;
cmd=8'hde;
addr={8'h00, cmd_line[8:15], 8'h00};
din={cmd_line[16:127], 16'h0};
data_mode=(vadid_length==0)? 2'b01: 2'b11;
cs_mode=1;
end
qspi2 #(.DATA_SIZE(128)) qspi2_inst(
// Input Ports - Single Bit
.clk (clk),
.cs_mode (cs_mode),
.rst_n (rst_n),
.xfer_start (xfer_start),
// Input Ports - Busses
.addr (addr),
.cmd (cmd),
.data_mode (data_mode),
.din (din),
.vadid_length (vadid_length),
// Output Ports - Single Bit
.csx (csx),
.sck (sck),
.xfer_final (xfer_final),
.xfer_rdy (xfer_rdy),
// Output Ports - Busses
.dout (dout)
// InOut Ports - Single Bit
// InOut Ports - Busses
);
endmodule
D3 st77903刷图代码
`timescale 1ns / 1ps
module qspi_fillcolor(
input clk,
input rst_n,
input start_pulse,
output csx,
output sck,
output [3:0] dout,
output vs,
output hs
);
parameter LCD_BPP=24;
parameter LCD_X_SIZE=400;
parameter LCD_Y_SIZE=400;
parameter LCD_PBYTE=(LCD_BPP+0)/8;
parameter LCD_HBYTE=(LCD_X_SIZE * LCD_PBYTE);
parameter LCD_VSW=1;
parameter LCD_HFP=8;
parameter LCD_HBP=8;
parameter CNT1_MAX=4880; //line_cycles(精确值是4871)
parameter CNT2_MAX=LCD_VSW+LCD_HBP+LCD_Y_SIZE+LCD_HFP;
parameter CNT3_MAX=LCD_HBYTE;
reg [19:0] cnt1;
reg [10:0] cnt2; /*总行数计数器*/
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt1<=0;
else if(add_cnt1) begin
if(end_cnt1)
cnt1<=0;
else
cnt1<=cnt1+1;
end
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt2<=0;
else if(add_cnt2) begin
if(end_cnt2)
cnt2<=0;
else
cnt2<=cnt2+1;
end
assign add_cnt1=cnt1_en; //有条件的计数,因此有计数使能, 一行的定时计数器
assign end_cnt1=add_cnt1 && (cnt1==CNT1_MAX-1);
assign add_cnt2=end_cnt1;
assign end_cnt2=add_cnt2 && (cnt2==CNT2_MAX-1);
reg cnt1_en;
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt1_en<=0;
else if(start_pulse)
cnt1_en<=1;
reg xfer_start;
always @(posedge clk or negedge rst_n)
if(rst_n==0)
xfer_start<=0;
// else if(start_pulse || xfer_rdy &&end_cnt1)
else if(add_cnt1 && (cnt1==0))
xfer_start<=1;
else
xfer_start<=0;
wire [7:0] cmd;
reg [23:0] addr;
reg [0:9600-1] din;
reg [10:0] vadid_length; /* Max suppport DATA_SIZE=2047*8=16376 */
reg [1:0] data_mode; /*00: cmd, 01: cmd+addr, 10: cmd+addr+1wire data, 11: cmd+addr+4wire data*/
wire cs_mode; /*IDLE state, 0: cs=0, 1:cs=1, to support multi data_bursts while keep cs=0*/
assign cmd=8'hde;
assign cs_mode=1;
always @(posedge clk or negedge rst_n)
if(rst_n==0) begin
addr<=24'h0;
data_mode<=2'b01;
vadid_length<=0;
end
else if(cnt2>=0 && cnt2<LCD_VSW) begin
addr<={8'h00, 8'h61, 8'h00};
data_mode<=2'b01;
vadid_length<=0;
end
else if(cnt2>=LCD_VSW && cnt2<LCD_VSW+LCD_HBP) begin
addr<={8'h00, 8'h60, 8'h00};
data_mode<=2'b01;
vadid_length<=0;
end
else if(cnt2>=LCD_VSW+LCD_HBP && cnt2<LCD_VSW+LCD_HBP+LCD_Y_SIZE) begin
addr<={8'h00, 8'h60, 8'h00};
data_mode<=2'b11;
vadid_length<=400*3;
end
else if(cnt2>=LCD_VSW+LCD_HBP+LCD_Y_SIZE && cnt2<LCD_VSW+LCD_HBP+LCD_Y_SIZE+LCD_HFP) begin
addr<={8'h00, 8'h60, 8'h00};
data_mode<=2'b01;
vadid_length<=0;
end
//在这里定义图像
always @(posedge clk or negedge rst_n)
if(rst_n==0) begin
din<={400{24'h000000}};
end
else if(cnt2>=LCD_VSW+LCD_HBP && cnt2< LCD_VSW+LCD_HBP+LCD_Y_SIZE/3) begin
din<={400{24'hff0000}}; //r
end
else if(cnt2>= LCD_VSW+LCD_HBP+LCD_Y_SIZE/3 && cnt2<LCD_VSW+LCD_HBP+LCD_Y_SIZE*2/3) begin
din<={400{24'h00ff00}}; //g
end
else if(cnt2>= LCD_VSW+LCD_HBP+LCD_Y_SIZE*2/3 && cnt2<LCD_VSW+LCD_HBP+LCD_Y_SIZE*3/3) begin
din<={400{24'h0000ff}}; //b
end
else
din<={400{24'h000000}};
assign vs=add_cnt2 && (cnt2==0);
assign hs=add_cnt1 && (cnt1==0);
qspi2 #(.DATA_SIZE(9600)) qspi2_inst(
// Input Ports - Single Bit
.clk (clk),
.cs_mode (cs_mode),
.rst_n (rst_n),
.xfer_start (xfer_start),
// Input Ports - Busses
.addr (addr),
.cmd (cmd),
.data_mode (data_mode),
.din (din),
.vadid_length (vadid_length),
// Output Ports - Single Bit
.csx (csx),
.sck (sck),
.xfer_final (xfer_final),
.xfer_rdy (xfer_rdy),
// Output Ports - Busses
.dout (dout)
// InOut Ports - Single Bit
// InOut Ports - Busses
);
endmodule
D4 top总拼代码
`timescale 1ns / 1ps
module qspi_init_and_fillcolor(
input clk,
input rst_n,
input bist_mode_en,
output csx,
output sck,
output [3:0] dout,
output rst_o,
output vs,
output hs
);
parameter CNT1_MAX=50_000_000;
reg [31:0] cnt1;
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt1<=0;
else if(add_cnt1) begin
if(end_cnt1)
cnt1<=0;
else
cnt1<=cnt1+1;
end
assign add_cnt1=cnt1_en; //有条件的计数,因此有计数使能
assign end_cnt1=add_cnt1 && (cnt1==CNT1_MAX-1);
reg cnt1_en;
always @(posedge clk or negedge rst_n)
if(rst_n==0)
cnt1_en<=1;
else if(end_cnt1)
cnt1_en<=0;
assign start_pulse=end_cnt1;
wire [3:0] dout1;
wire [3:0] dout2;
assign csx=(cnt1_en)? csx1: csx2;
assign sck=(cnt1_en)? sck1: sck2;
assign dout=(cnt1_en)? dout1:dout2;
//qspi_init qspi_init_inst(
qspi_init qspi_init_inst(
.clk(clk),
.rst_n(rst_n),
.bist_mode_en(bist_mode_en),
.csx(csx1),
.sck(sck1),
.dout(dout1),
.rst_o(rst_o)
);
// defparam qspi_init_inst.CNT1_MAX=1000;
// defparam qspi_init_inst.CNT4_MAX=100;
qspi_fillcolor qspi_fillcolor_inst(
.clk(clk),
.rst_n(rst_n),
.start_pulse(start_pulse),
.csx(csx2),
.sck(sck2),
.dout(dout2),
.vs(vs),
.hs(hs)
);
// defparam qspi_fillcolor_inst.LCD_X_SIZE=40;
// defparam qspi_fillcolor_inst.LCD_Y_SIZE=40;
endmodule
D5 测试代码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/03/31 12:44:53
// Design Name:
// Module Name: tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
//module tb;
// reg clk, rst_n;
// initial clk=0;
// always #10 clk=~clk;
// initial begin
// rst_n=0;
// #1000;
// rst_n=1;
// end
// reg xfer_start;
// reg [7:0] cmd;
// reg [23:0] addr;
// reg [191:0] din;
// reg [6:0] current_vadid_length;
// reg [17:0] total_length;
// reg [1:0] data_mode;
// wire [3:0] dout;
// initial begin
// xfer_start=0;
// cmd=8'h00;
// addr=24'hf0000f;
// din=8'h00;
// current_vadid_length=0;
// total_length=0;
// data_mode=2'b00;
// wait(rst_n==1);
// #1000;
// //send command only
// current_vadid_length=0;
// total_length=0;
// data_mode=2'b00;
// cmd=8'hf0;
// @(posedge clk) #1 xfer_start=1;
// @(posedge clk) #1 xfer_start=0;
// wait(xfer_final==1);
// #100;
// //send command+addr
// current_vadid_length=3;
// total_length=3;
// data_mode=2'b01;
// cmd=8'hf0;
// @(posedge clk) #1 xfer_start=1;
// @(posedge clk) #1 xfer_start=0;
// wait(xfer_final==1);
// #100;
// //send command+addr+data, 1wire mode
// current_vadid_length=3;
// total_length=3;
// data_mode=2'b10;
// cmd=8'hf0;
// din={24'hf0f0f0,168'b0};
// @(posedge clk) #1 xfer_start=1;
// @(posedge clk) #1 xfer_start=0;
// wait(xfer_final==1);
// #100;
// //send command+addr+data, 4wire mode
// current_vadid_length=24;
// total_length=40;
// data_mode=2'b10;
// cmd=8'h23;
// din={12{16'h1234}};
// @(posedge clk) #1 xfer_start=1;
// @(posedge clk) #1 xfer_start=0;
// wait(xfer_end==1);
// #100;
// current_vadid_length=16;
// din={12{16'h5678}};
// @(posedge clk) #1 xfer_start=1;
// @(posedge clk) #1 xfer_start=0;
// wait(xfer_final==1);
// #1;
// end
// qspi qspi_inst(
// .clk(clk),
// .rst_n(rst_n),
// .xfer_start(xfer_start),
// .xfer_end(xfer_end),
// .xfer_final(xfer_final),
// .xfer_rdy(xfer_rdy),
// .cmd(cmd),
// .addr(addr),
// .din(din),
// .current_vadid_length(current_vadid_length),
// .total_length(total_length),
// .data_mode(data_mode),
// .csx(csx),
// .sck(sck),
// .dout(dout)
// );
//endmodule
module tb;
reg clk, rst_n;
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#1000;
rst_n=1;
end
reg xfer_start;
reg [7:0] cmd;
reg [23:0] addr;
reg [9600-1:0] din;
reg [10:0] vadid_length;
reg [1:0] data_mode;
reg cs_mode;
wire [3:0] dout;
initial begin
xfer_start=0;
cmd=8'h00;
addr=24'h000000;
din=8'h00;
vadid_length=0;
data_mode=2'b00;
cs_mode=1;
wait(rst_n==1);
#1000;
//send command only
data_mode=2'b00;
cmd=8'hf0;
@(posedge clk) #1 xfer_start=1;
@(posedge clk) #1 xfer_start=0;
wait(xfer_final==1);
#100;
//send command+addr
data_mode=2'b01;
cmd=8'hf0;
addr=24'hf0f0f0;
@(posedge clk) #1 xfer_start=1;
@(posedge clk) #1 xfer_start=0;
wait(xfer_final==1);
#100;
//send command+addr+data, 1wire mode
vadid_length=3;
data_mode=2'b10;
cmd=8'hf0;
addr=24'hf0f0f0;
din={24'hf0f0f0,9576'b0};
@(posedge clk) #1 xfer_start=1;
@(posedge clk) #1 xfer_start=0;
wait(xfer_final==1);
#100;
//send command+addr+data, 4wire mode
vadid_length=700;
data_mode=2'b11;
cs_mode=0;
cmd=8'h23;
addr=24'hf0f0f0;
din={600{16'h1234}};
@(posedge clk) #1 xfer_start=1;
@(posedge clk) #1 xfer_start=0;
wait(xfer_final==1);
#100;
//send command+addr+data, 4wire mode
vadid_length=700;
data_mode=2'b11;
cs_mode=1;
cmd=8'h23;
addr=24'hf0f0f0;
din={600{16'h4321}};
@(posedge clk) #1 xfer_start=1;
@(posedge clk) #1 xfer_start=0;
wait(xfer_final==1);
#100;
end
qspi2 qspi_inst(
.clk(clk),
.rst_n(rst_n),
.xfer_start(xfer_start),
.xfer_final(xfer_final),
.xfer_rdy(xfer_rdy),
.cmd(cmd),
.addr(addr),
.din(din),
.vadid_length(vadid_length),
.data_mode(data_mode),
.cs_mode(cs_mode),
.csx(csx),
.sck(sck),
.dout(dout)
);
endmodule
module tb2;
reg clk, rst_n;
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#1000;
rst_n=1;
end
qspi_init qspi_init_inst(
.clk(clk),
.rst_n(rst_n)
);
defparam qspi_init_inst.CNT1_MAX=1000;
defparam qspi_init_inst.CNT3_MAX=200;
endmodule
module tb3;
reg clk, rst_n;
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#1000;
rst_n=1;
end
bit start_pulse;
initial begin
start_pulse=0;
#5000;
@(posedge clk) #1 start_pulse=1;
@(posedge clk) #1 start_pulse=0;
end
qspi_fillcolor qspi_fillcolor_inst(
.clk(clk),
.rst_n(rst_n),
.start_pulse(start_pulse)
);
defparam qspi_fillcolor_inst.LCD_X_SIZE=40;
defparam qspi_fillcolor_inst.LCD_Y_SIZE=40;
endmodule
module tb4;
reg clk, rst_n;
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#1000;
rst_n=1;
end
qspi_init_and_fillcolor qspi_init_and_fillcolor_inst(
.clk(clk),
.rst_n(rst_n)
);
defparam qspi_init_and_fillcolor_inst.CNT1_MAX=50_000;
defparam qspi_init_and_fillcolor_inst.qspi_init_inst.CNT1_MAX=1000;
defparam qspi_init_and_fillcolor_inst.qspi_init_inst.CNT4_MAX=100;
defparam qspi_init_and_fillcolor_inst.qspi_fillcolor_inst.LCD_X_SIZE=400;
defparam qspi_init_and_fillcolor_inst.qspi_fillcolor_inst.LCD_Y_SIZE=40;
endmodule