实现 利用SPI 接口 发送 显示屏 初始化代码

发布时间 2023-11-25 09:57:59作者: xgj_0817
 1 `timescale 1ns/1ns
 2 module  lcd_spi_top_tb();
 3 
 4 reg clk_x2_i;
 5 reg rst_i;
 6 wire spi_cs;
 7 wire spi_scl;
 8 wire spi_mosi;
 9 wire spi_miso;
10 wire spi_init_done;
11 
12 
13 initial begin
14         clk_x2_i=0;
15         rst_i=0;
16         #1000;
17         rst_i=1;
18         #1000;
19         @(posedge spi_init_done)
20          $stop;        
21         
22         end
23 
24 always #125 clk_x2_i<=~clk_x2_i;
25 
26 lcd_spi_top
27 #(
28     .SPI_IN_WIDTH  (6'd9),//spi  输入位数
29     .SPI_OUT_WIDTH (6'd9),//SPI  输出位数
30     .SPI_CPOL      (1'b0),//空闲状态SCL电平 0:SCL=0  1:SCL=1
31     .SPI_CPHA      (1'b0) //SPI数据在哪个SCL边沿有效 0:数据在SCL第一个边沿有效,1:数据在SCL第二个边沿有效,
32 
33 )
34 lcd_spi_top_inst
35 (
36      .clk_x2_i  (clk_x2_i  ),
37      .rst_i     (rst_i     ),
38      .spi_cs_o  (spi_cs    ),
39      .spi_scl_o (spi_scl   ),
40      .spi_mosi  (spi_mosi  ),
41      .spi_miso  (spi_miso  ),
42      .spi_init_done(spi_init_done)
43 
44 );
45 
46 
47 
48 
49 endmodule
  1 module  lcd_spi_top
  2 #(
  3     parameter [5:0]SPI_IN_WIDTH  =6'd9,//spi  输入位数
  4     parameter [5:0]SPI_OUT_WIDTH =6'd9,//SPI  输出位数
  5     parameter [0:0]SPI_CPOL=1'b0,//空闲状态SCL电平 0:SCL=0  1:SCL=1
  6     parameter [0:0]SPI_CPHA=1'b0 //SPI数据在哪个SCL边沿有效 0:数据在SCL第一个边沿有效,1:数据在SCL第二个边沿有效,
  7 
  8 )
  9 (
 10      input    wire  [0:0] clk_x2_i,  //SPI输出时钟的2倍时钟输入
 11      input    wire  [0:0] rst_i,     //复位信号输入
 12      output   reg   [0:0] lcd_rst,    //显示屏复位
 13      output   wire  [0:0] spi_cs_o,  //
 14      output   wire  [0:0] spi_scl_o,
 15      output   wire  [0:0] spi_mosi,
 16      input    wire  [0:0] spi_miso,
 17      output   reg   [0:0] spi_init_done
 18 
 19 );
 20 
 21 reg [8:0] rom [386:0];
 22 initial begin
 23 rom[0]=9'h0B0;
 24 rom[1]=9'h104;
 25 rom[2]=9'h0B4;
 26 rom[3]=9'h140;
 27 rom[4]=9'h140;
 28 rom[5]=9'h0C1;
 29 rom[6]=9'h103;
 30 rom[7]=9'h11D;
 31 rom[8]=9'h182;
 32 rom[9]=9'h13A;
 33 rom[10]=9'h13A;
 34 rom[11]=9'h112;
 35 rom[12]=9'h102;
 36 rom[13]=9'h130;
 37 rom[14]=9'h142;
 38 rom[15]=9'h102;
 39 rom[16]=9'h1AA;
 40 rom[17]=9'h1AA;
 41 rom[18]=9'h168;
 42 rom[19]=9'h114;
 43 rom[20]=9'h101;
 44 rom[21]=9'h183;
 45 rom[22]=9'h10F;
 46 rom[23]=9'h0C2;
 47 rom[24]=9'h111;
 48 rom[25]=9'h108;
 49 rom[26]=9'h188;
 50 rom[27]=9'h106;
 51 rom[28]=9'h100;
 52 rom[29]=9'h0C8;
 53 rom[30]=9'h103;
 54 rom[31]=9'h110;
 55 rom[32]=9'h116;
 56 rom[33]=9'h11F;
 57 rom[34]=9'h11E;
 58 rom[35]=9'h11F;
 59 rom[36]=9'h11F;
 60 rom[37]=9'h11F;
 61 rom[38]=9'h11E;
 62 rom[39]=9'h11F;
 63 rom[40]=9'h11F;
 64 rom[41]=9'h126;
 65 rom[42]=9'h11C;
 66 rom[43]=9'h104;
 67 rom[44]=9'h103;
 68 rom[45]=9'h110;
 69 rom[46]=9'h116;
 70 rom[47]=9'h11F;
 71 rom[48]=9'h11E;
 72 rom[49]=9'h11F;
 73 rom[50]=9'h11F;
 74 rom[51]=9'h11F;
 75 rom[52]=9'h11E;
 76 rom[53]=9'h11F;
 77 rom[54]=9'h11F;
 78 rom[55]=9'h126;
 79 rom[56]=9'h11C;
 80 rom[57]=9'h104;
 81 rom[58]=9'h0C9;
 82 rom[59]=9'h103;
 83 rom[60]=9'h110;
 84 rom[61]=9'h116;
 85 rom[62]=9'h11F;
 86 rom[63]=9'h11E;
 87 rom[64]=9'h11F;
 88 rom[65]=9'h11F;
 89 rom[66]=9'h11F;
 90 rom[67]=9'h11E;
 91 rom[68]=9'h11F;
 92 rom[69]=9'h11F;
 93 rom[70]=9'h126;
 94 rom[71]=9'h11C;
 95 rom[72]=9'h104;
 96 rom[73]=9'h103;
 97 rom[74]=9'h110;
 98 rom[75]=9'h116;
 99 rom[76]=9'h11F;
100 rom[77]=9'h11E;
101 rom[78]=9'h11F;
102 rom[79]=9'h11F;
103 rom[80]=9'h11F;
104 rom[81]=9'h11E;
105 rom[82]=9'h11F;
106 rom[83]=9'h11F;
107 rom[84]=9'h126;
108 rom[85]=9'h11C;
109 rom[86]=9'h104;
110 rom[87]=9'h0CA;
111 rom[88]=9'h103;
112 rom[89]=9'h110;
113 rom[90]=9'h116;
114 rom[91]=9'h11F;
115 rom[92]=9'h11E;
116 rom[93]=9'h11F;
117 rom[94]=9'h11F;
118 rom[95]=9'h11F;
119 rom[96]=9'h11E;
120 rom[97]=9'h11F;
121 rom[98]=9'h11F;
122 rom[99]=9'h126;
123 rom[100]=9'h11C;
124 rom[101]=9'h104;
125 rom[102]=9'h103;
126 rom[103]=9'h110;
127 rom[104]=9'h116;
128 rom[105]=9'h11F;
129 rom[106]=9'h11E;
130 rom[107]=9'h11F;
131 rom[108]=9'h11F;
132 rom[109]=9'h11F;
133 rom[110]=9'h11E;
134 rom[111]=9'h11F;
135 rom[112]=9'h11F;
136 rom[113]=9'h126;
137 rom[114]=9'h11C;
138 rom[115]=9'h104;
139 rom[116]=9'h0CB;
140 rom[117]=9'h110;
141 rom[118]=9'h120;
142 rom[119]=9'h140;
143 rom[120]=9'h180;
144 rom[121]=9'h1A0;
145 rom[122]=9'h1C0;
146 rom[123]=9'h1D0;
147 rom[124]=9'h1E0;
148 rom[125]=9'h0CC;
149 rom[126]=9'h1FF;
150 rom[127]=9'h1FF;
151 rom[128]=9'h1FF;
152 rom[129]=9'h0CD;
153 rom[130]=9'h108;
154 rom[131]=9'h108;
155 rom[132]=9'h108;
156 rom[133]=9'h108;
157 rom[134]=9'h108;
158 rom[135]=9'h108;
159 rom[136]=9'h108;
160 rom[137]=9'h0CE;
161 rom[138]=9'h108;
162 rom[139]=9'h108;
163 rom[140]=9'h108;
164 rom[141]=9'h108;
165 rom[142]=9'h108;
166 rom[143]=9'h108;
167 rom[144]=9'h108;
168 rom[145]=9'h0CF;
169 rom[146]=9'h108;
170 rom[147]=9'h108;
171 rom[148]=9'h108;
172 rom[149]=9'h108;
173 rom[150]=9'h108;
174 rom[151]=9'h108;
175 rom[152]=9'h108;
176 rom[153]=9'h0C8;
177 rom[154]=9'h103;
178 rom[155]=9'h110;
179 rom[156]=9'h116;
180 rom[157]=9'h11F;
181 rom[158]=9'h11E;
182 rom[159]=9'h11F;
183 rom[160]=9'h11F;
184 rom[161]=9'h11F;
185 rom[162]=9'h11E;
186 rom[163]=9'h11F;
187 rom[164]=9'h11F;
188 rom[165]=9'h126;
189 rom[166]=9'h11C;
190 rom[167]=9'h104;
191 rom[168]=9'h103;
192 rom[169]=9'h110;
193 rom[170]=9'h116;
194 rom[171]=9'h11F;
195 rom[172]=9'h11E;
196 rom[173]=9'h11F;
197 rom[174]=9'h11F;
198 rom[175]=9'h11F;
199 rom[176]=9'h11E;
200 rom[177]=9'h11F;
201 rom[178]=9'h11F;
202 rom[179]=9'h126;
203 rom[180]=9'h11C;
204 rom[181]=9'h104;
205 rom[182]=9'h0C9;
206 rom[183]=9'h122;
207 rom[184]=9'h128;
208 rom[185]=9'h129;
209 rom[186]=9'h12D;
210 rom[187]=9'h128;
211 rom[188]=9'h123;
212 rom[189]=9'h122;
213 rom[190]=9'h11D;
214 rom[191]=9'h11D;
215 rom[192]=9'h11D;
216 rom[193]=9'h11B;
217 rom[194]=9'h120;
218 rom[195]=9'h11A;
219 rom[196]=9'h109;
220 rom[197]=9'h122;
221 rom[198]=9'h128;
222 rom[199]=9'h129;
223 rom[200]=9'h12D;
224 rom[201]=9'h128;
225 rom[202]=9'h123;
226 rom[203]=9'h122;
227 rom[204]=9'h11D;
228 rom[205]=9'h11D;
229 rom[206]=9'h11D;
230 rom[207]=9'h11B;
231 rom[208]=9'h120;
232 rom[209]=9'h11A;
233 rom[210]=9'h109;
234 rom[211]=9'h0CA;
235 rom[212]=9'h10E;
236 rom[213]=9'h118;
237 rom[214]=9'h11B;
238 rom[215]=9'h123;
239 rom[216]=9'h121;
240 rom[217]=9'h120;
241 rom[218]=9'h120;
242 rom[219]=9'h11F;
243 rom[220]=9'h11E;
244 rom[221]=9'h11E;
245 rom[222]=9'h11B;
246 rom[223]=9'h120;
247 rom[224]=9'h11A;
248 rom[225]=9'h107;
249 rom[226]=9'h10E;
250 rom[227]=9'h118;
251 rom[228]=9'h11B;
252 rom[229]=9'h123;
253 rom[230]=9'h121;
254 rom[231]=9'h120;
255 rom[232]=9'h120;
256 rom[233]=9'h11F;
257 rom[234]=9'h11E;
258 rom[235]=9'h11E;
259 rom[236]=9'h11B;
260 rom[237]=9'h120;
261 rom[238]=9'h11A;
262 rom[239]=9'h107;
263 rom[240]=9'h0CC;
264 rom[241]=9'h1FF;
265 rom[242]=9'h1E7;
266 rom[243]=9'h1EF;
267 rom[244]=9'h0CB;
268 rom[245]=9'h110;
269 rom[246]=9'h120;
270 rom[247]=9'h140;
271 rom[248]=9'h180;
272 rom[249]=9'h1A0;
273 rom[250]=9'h1C0;
274 rom[251]=9'h1D0;
275 rom[252]=9'h1E0;
276 rom[253]=9'h0CD;
277 rom[254]=9'h108;
278 rom[255]=9'h108;
279 rom[256]=9'h108;
280 rom[257]=9'h108;
281 rom[258]=9'h108;
282 rom[259]=9'h108;
283 rom[260]=9'h108;
284 rom[261]=9'h0CE;
285 rom[262]=9'h108;
286 rom[263]=9'h108;
287 rom[264]=9'h108;
288 rom[265]=9'h108;
289 rom[266]=9'h108;
290 rom[267]=9'h108;
291 rom[268]=9'h108;
292 rom[269]=9'h0CF;
293 rom[270]=9'h108;
294 rom[271]=9'h108;
295 rom[272]=9'h108;
296 rom[273]=9'h108;
297 rom[274]=9'h108;
298 rom[275]=9'h108;
299 rom[276]=9'h108;
300 rom[277]=9'h036;
301 rom[278]=9'h1C0;
302 rom[279]=9'h0B0;
303 rom[280]=9'h103;
304 rom[281]=9'h029;
305 rom[282]=9'h011;
306 rom[283]=9'h0B0;
307 rom[284]=9'h104;
308 rom[285]=9'h0C8;
309 rom[286]=9'h103;
310 rom[287]=9'h110;
311 rom[288]=9'h116;
312 rom[289]=9'h11F;
313 rom[290]=9'h11E;
314 rom[291]=9'h11F;
315 rom[292]=9'h11F;
316 rom[293]=9'h11F;
317 rom[294]=9'h11E;
318 rom[295]=9'h11F;
319 rom[296]=9'h11F;
320 rom[297]=9'h126;
321 rom[298]=9'h11C;
322 rom[299]=9'h104;
323 rom[300]=9'h103;
324 rom[301]=9'h110;
325 rom[302]=9'h116;
326 rom[303]=9'h11F;
327 rom[304]=9'h11E;
328 rom[305]=9'h11F;
329 rom[306]=9'h11F;
330 rom[307]=9'h11F;
331 rom[308]=9'h11E;
332 rom[309]=9'h11F;
333 rom[310]=9'h11F;
334 rom[311]=9'h126;
335 rom[312]=9'h11C;
336 rom[313]=9'h104;
337 rom[314]=9'h0C9;
338 rom[315]=9'h122;
339 rom[316]=9'h128;
340 rom[317]=9'h129;
341 rom[318]=9'h12D;
342 rom[319]=9'h128;
343 rom[320]=9'h123;
344 rom[321]=9'h122;
345 rom[322]=9'h11D;
346 rom[323]=9'h11D;
347 rom[324]=9'h11D;
348 rom[325]=9'h11B;
349 rom[326]=9'h120;
350 rom[327]=9'h11A;
351 rom[328]=9'h109;
352 rom[329]=9'h122;
353 rom[330]=9'h128;
354 rom[331]=9'h129;
355 rom[332]=9'h12D;
356 rom[333]=9'h128;
357 rom[334]=9'h123;
358 rom[335]=9'h122;
359 rom[336]=9'h11D;
360 rom[337]=9'h11D;
361 rom[338]=9'h11D;
362 rom[339]=9'h11B;
363 rom[340]=9'h120;
364 rom[341]=9'h11A;
365 rom[342]=9'h109;
366 rom[343]=9'h0CA;
367 rom[344]=9'h10E;
368 rom[345]=9'h118;
369 rom[346]=9'h11B;
370 rom[347]=9'h123;
371 rom[348]=9'h121;
372 rom[349]=9'h120;
373 rom[350]=9'h120;
374 rom[351]=9'h11F;
375 rom[352]=9'h11E;
376 rom[353]=9'h11E;
377 rom[354]=9'h11B;
378 rom[355]=9'h120;
379 rom[356]=9'h11A;
380 rom[357]=9'h107;
381 rom[358]=9'h10E;
382 rom[359]=9'h118;
383 rom[360]=9'h11B;
384 rom[361]=9'h123;
385 rom[362]=9'h121;
386 rom[363]=9'h120;
387 rom[364]=9'h120;
388 rom[365]=9'h11F;
389 rom[366]=9'h11E;
390 rom[367]=9'h11E;
391 rom[368]=9'h11B;
392 rom[369]=9'h120;
393 rom[370]=9'h11A;
394 rom[371]=9'h107;
395 rom[372]=9'h0D1;
396 rom[373]=9'h114;
397 rom[374]=9'h11D;
398 rom[375]=9'h123;
399 rom[376]=9'h144;
400 rom[377]=9'h153;
401 rom[378]=9'h19A;
402 rom[379]=9'h0C7;
403 rom[380]=9'h100;
404 rom[381]=9'h153;
405 rom[382]=9'h153;
406 rom[383]=9'h153;
407 rom[384]=9'h127;
408 rom[385]=9'h0B0;
409 rom[386]=9'h103;
410 end
411 
412 
413 
414 
415 localparam [3:0]SEND_IDLE   =0000;
416 localparam [3:0]LCD_RESET   =0001;
417 localparam [3:0]SEND_CMD    =0010;
418 localparam [3:0]SEND_DELAY  =0100;
419 localparam [3:0]SEND_END    =1000;
420 
421 
422 
423 reg [31:0] spi_data_i;
424 reg spi_start;
425 
426 wire spi_done;
427 wire spi_busy;
428 
429 wire [31:0] spi_data_o;
430 
431 reg [5:0]  state;
432 reg [10:0] reg_cnt;
433 reg [20:0] delay_cnt;
434 parameter [20:0] DELAY_50MS=21'd200_000;  //50MS*1000*1000/250NS=21'd200_000
435 parameter [20:0] DELAY_120MS=21'd480_000; //120MS*1000*1000/250NS=21'd480_000
436 
437 always @(negedge clk_x2_i or negedge rst_i )
438      begin
439          if(rst_i==1'b0)
440              begin
441                  state<=SEND_IDLE; 
442                  spi_data_i<=32'B0;
443                  spi_start<=1'B0;
444                  reg_cnt<=11'd0;
445                  delay_cnt<=20'd0;
446                  spi_init_done<=1'b0;
447                 lcd_rst<=1'b0;
448              end
449          else 
450              begin
451                  case(state)
452                      SEND_IDLE     : begin 
453                                         if(delay_cnt<DELAY_50MS)
454                                             begin
455                                                state<=SEND_IDLE; 
456                                                lcd_rst<=1'b0;  
457                                                delay_cnt<=delay_cnt+1'd1;                                              
458                                             end
459                                         else
460                                             begin
461                                                state<=LCD_RESET; 
462                                                lcd_rst<=1'b1; 
463                                                delay_cnt<=21'd0;                                               
464                                             end
465                          
466                                      end
467                      LCD_RESET     : begin 
468                                         if(delay_cnt<DELAY_120MS)
469                                             begin
470                                                state<=LCD_RESET; 
471                                                lcd_rst<=1'b1;  
472                                                delay_cnt<=delay_cnt+1'd1;                                              
473                                             end
474                                         else
475                                             begin
476                                                state<=SEND_CMD;  
477                                                delay_cnt<=20'd0;                                               
478                                             end                         
479                                      end
480                      SEND_CMD      :begin 
481                                          if(spi_busy==1'b0)
482                                               begin
483                                                  if(reg_cnt<=9'd386 )
484                                                      begin
485                                                          if(rom[reg_cnt]==9'h011)
486                                                              begin
487                                                                  spi_data_i<=rom[reg_cnt];
488                                                                  spi_start<=1'b1;
489                                                                  reg_cnt<=reg_cnt+1'd1;                                                                 
490                                                                  state<=SEND_DELAY; 
491                                                                  delay_cnt<=16'd0;                                                             
492                                                              end
493                                                          else
494                                                               begin
495                                                                  spi_data_i<=rom[reg_cnt];
496                                                                  spi_start<=1'b1;
497                                                                  reg_cnt<=reg_cnt+1'd1;
498                                                                  state<=SEND_CMD; 
499                                                                  
500                                                              end
501                                                          
502                                                      end
503                                                  else 
504                                                      begin
505                                                          state<=SEND_END;
506                                                          spi_init_done<=1'b1;
507                                                          reg_cnt<=11'd0;    
508                                                          spi_start<=1'b0;                                                     
509                                                      end    
510                                               end
511                                           else
512                                               begin
513                                                   state<=state;
514                                                   reg_cnt<=reg_cnt;    
515                                                   spi_start<=1'B0;                                              
516                                               end                                         
517                                           
518                                      end
519                      SEND_DELAY     :begin 
520                                          if(delay_cnt<DELAY_120MS)
521                                              begin
522                                                 delay_cnt<=delay_cnt+1'd1;    
523                                                 reg_cnt<=reg_cnt;        
524                                              end
525                                          else 
526                                              begin
527                                                  state<=SEND_CMD; 
528                                                  delay_cnt<=10'd0;
529                                                  reg_cnt<=reg_cnt;    
530                                              end                                             
531                                      spi_start<=1'b0; 
532                                      end 
533                     SEND_END       :begin
534                                         spi_data_i<=32'B0;
535                                         spi_start<=1'B0;
536                                         reg_cnt<=11'd0; 
537                                         spi_init_done<=1'b1;
538                                         state<=SEND_END;
539                                     end                                     
540 
541                    
542                      default         : begin 
543                                         spi_data_i<=32'B0;
544                                         spi_start<=1'B0;
545                                         reg_cnt<=8'd0; 
546                                         state<=SEND_END;                                         
547                                        end
548                  endcase
549              end
550      
551      end
552 
553 
554 
555 lcd_spi_m
556 #(
557     .SPI_IN_WIDTH  (SPI_IN_WIDTH),//spi  输入位数
558     .SPI_OUT_WIDTH (SPI_OUT_WIDTH),//SPI  输出位数
559     .SPI_CPOL      (SPI_CPOL),//空闲状态SCL电平 0:SCL=0  1:SCL=1
560     .SPI_CPHA      (SPI_CPHA) //SPI数据在哪个SCL边沿有效 0:数据在SCL第一个边沿有效,1:数据在SCL第二个边沿有效,
561 )
562 lcd_spi_m_inst
563 (
564      .rst_n_i    (rst_i)     , //复位输入,低电平复位 
565      .spi_x2clk_i(clk_x2_i)  ,//SPI系统时钟 为SCL输出时钟的两倍
566      .spi_data_i (spi_data_i),//输入32位要从MOSI发送出去的数据
567      .spi_start  (spi_start) , //单次发送开始,把数据送到spi_data_i 并把spi_start维技一个周期的高电平   
568      .spi_miso_i (spi_miso),//主机接收从机输出引脚
569      .spi_done   (spi_done)  ,//SPI完成一次传输并从spi_data_o输出读到的数据
570      .spi_busy   (spi_busy)  ,//SPI忙信号输出,在忙状态时不接收外部数据,高表示忙
571      .spi_cs_o   (spi_cs_o)  ,//SPI片选信号输出低有效
572      .spi_scl_o  (spi_scl_o) ,//SPI 时钟信号输出,请结合CPOL CPHA分析有效性
573      .spi_mosi_o (spi_mosi),//SPI主机输出从机输入接口
574      .spi_data_o (spi_data_o) //从从机读到的数据在SPI_DONE为高时为有效数据    
575              
576 );
577 
578 
579 
580 endmodule
  1 //主程???
  2 //功能:完成32位以内SPI接口的数据双向通信
  3 module  lcd_spi_m
  4 #(
  5     parameter [5:0]SPI_IN_WIDTH  =6'd9,//spi  输入位数
  6     parameter [5:0]SPI_OUT_WIDTH =6'd9,//SPI  输出位数
  7     parameter [0:0]SPI_CPOL=1'b0,//空闲状态SCL电平 0:SCL=0  1:SCL=1
  8     parameter [0:0]SPI_CPHA=1'b1 //SPI数据在哪个SCL边沿有效 0:数据在SCL第一个边沿有效,1:数据在SCL第二个边沿有效,
  9 
 10 
 11 )
 12 (
 13      input  wire  [0:0]  rst_n_i, //复位输入,低电平复位 
 14      input  wire  [0:0]  spi_x2clk_i,//SPI系统时钟 为SCL输出时钟的两???
 15      input  wire  [31:0] spi_data_i,//输入32位要从MOSI发送出去的数据
 16      input  wire  [0:0]  spi_start, //单次发送开始,把数据送到spi_data_i 并把spi_start维技一个周期的高电???  
 17      input  wire  [0:0]  spi_miso_i,//主机接收从机输出引脚
 18      output reg   [0:0]  spi_done,//SPI完成一次传输并从spi_data_o输出读到的数???
 19      output reg   [0:0]  spi_busy,//SPI忙信号输出,在忙状态时不接收外部数据,高表示忙
 20      output reg   [0:0]  spi_cs_o,//SPI片选信号输出低有效
 21      output reg   [0:0]  spi_scl_o,//SPI 时钟信号输出,请结合CPOL CPHA分析有效???
 22      output reg   [0:0]  spi_mosi_o,//SPI主机输出从机输入接口
 23      output reg   [31:0] spi_data_o//从从机读到的数据在SPI_DONE为高时为有效数据
 24      
 25              
 26 );
 27 
 28 localparam [7:0] CS_F_DELAY=8'D1; //CS前面延时
 29 localparam [7:0] CS_B_DELAY=8'D1; //CS后面延时
 30 localparam [7:0] CS_F_CNT=CS_F_DELAY+CS_F_DELAY; //CS前面延时
 31 localparam [7:0] CS_B_CNT=CS_B_DELAY+CS_B_DELAY; //CS后面延时
 32 localparam [7:0] WIDTH_MAX=(SPI_IN_WIDTH>SPI_IN_WIDTH)? (SPI_IN_WIDTH*2'D2+CS_F_CNT+CS_B_CNT) :(SPI_OUT_WIDTH*2'D2+CS_F_CNT+CS_B_CNT);
 33 
 34 
 35 
 36 
 37       
 38 //产生spi_x2clk_i时钟计数 
 39 reg [6:0] clk_cnt;
 40 always @(posedge spi_x2clk_i  or negedge rst_n_i)
 41      begin
 42          if(rst_n_i==1'b0)
 43              clk_cnt<=6'd0;
 44          else if(spi_busy==1'b1 )  
 45                  if(clk_cnt<WIDTH_MAX)                             
 46                        clk_cnt<=clk_cnt+1'd1;    
 47                    else 
 48                     clk_cnt<=7'd0;                
 49         else
 50                 clk_cnt<=7'd0;   
 51      end       
 52      
 53 //输出SPI_CS信号 
 54 always @(posedge spi_x2clk_i  or negedge rst_n_i)
 55      begin
 56          if(rst_n_i==1'b0)
 57              spi_cs_o<=1'b1;       
 58          else if(spi_start==1'b1 && spi_busy==1'b0)                                 
 59              spi_cs_o<=1'b0;                         
 60          else if(clk_cnt<(WIDTH_MAX-1'd1))
 61              spi_cs_o<=spi_cs_o; 
 62          else
 63             spi_cs_o<=1'b1;   
 64      end  
 65 
 66     
 67 
 68      
 69 //输出spi_scl信号
 70 always @(posedge spi_x2clk_i  or negedge rst_n_i)
 71      begin
 72          if(rst_n_i==1'b0)
 73              begin
 74                  if(SPI_CPOL==1'b0)
 75                      spi_scl_o<=1'b0;
 76                  else 
 77                     spi_scl_o<=1'b1;
 78                 spi_done<=1'b0;            
 79              end             
 80          else if(clk_cnt>CS_F_CNT-1'd1 && clk_cnt<(WIDTH_MAX-CS_B_CNT-1'd1))  
 81                  begin
 82                     spi_scl_o<=~spi_scl_o;
 83                 end
 84         else if(clk_cnt>=WIDTH_MAX-1'd1)
 85                 begin    
 86                      spi_done<=1'b1;
 87 
 88                  end
 89          else 
 90             begin
 91                  if(SPI_CPOL==1'b0)
 92                      spi_scl_o<=1'b0;
 93                  else 
 94                     spi_scl_o<=1'b1;
 95                 spi_done<=1'b0;
 96     
 97              end  
 98      end   
 99 //在spi_start???时捕获数???
100 reg [31:0] temp_data_i;               
101 //输出SPI_MOSI信号
102 always @(posedge spi_x2clk_i  or negedge rst_n_i)
103      begin
104          if(rst_n_i==1'b0)
105              begin
106                  spi_mosi_o<=1'b0;
107                  spi_busy<=1'b0;
108                  temp_data_i<=32'b0;
109              end
110          else if(spi_start==1'b1 && spi_busy==1'b0)  //在spi_start???时捕获数???
111             begin
112                 temp_data_i<=spi_data_i;
113                 spi_busy<=1'b1;
114             end 
115         else if(spi_done==1'b1)
116                  spi_busy<=1'b0;             
117          else if(SPI_CPHA==1'b0) 
118                  begin
119                      if((clk_cnt>=(CS_F_CNT-8'd1)) && (clk_cnt<(WIDTH_MAX-CS_B_CNT-CS_F_CNT)) && (clk_cnt%2==1)  )
120                          begin
121                              spi_mosi_o<=temp_data_i[SPI_OUT_WIDTH-1'd1];
122                              temp_data_i<={temp_data_i[(SPI_OUT_WIDTH-2'd2):0],temp_data_i[SPI_OUT_WIDTH-1'd1]};                             
123                          end
124                      else 
125                          begin                            
126                              spi_mosi_o<=spi_mosi_o;                         
127                          end
128 
129                  end    
130         else  if(SPI_CPHA==1'b1) 
131                  begin
132                      if((clk_cnt>=CS_F_CNT) && clk_cnt<(WIDTH_MAX-CS_B_CNT-CS_F_CNT) && (clk_cnt%2==0) )
133                          begin
134                              spi_mosi_o<=temp_data_i[SPI_OUT_WIDTH-1'd1];
135                              temp_data_i<={temp_data_i[SPI_OUT_WIDTH-2'd2:0],temp_data_i[SPI_OUT_WIDTH-1'd0]};                             
136                          end
137                      else 
138                          begin                            
139                              spi_mosi_o<=spi_mosi_o;                         
140                          end
141                  end    
142          else 
143              begin 
144                              spi_mosi_o<=1'b1;  
145              end
146                   
147      end 
148      
149 //接收SPI_MISO信号
150 always @(posedge spi_x2clk_i or negedge rst_n_i)
151      begin
152          if(rst_n_i==1'b0)
153              spi_data_o<=32'b0;
154          else if(SPI_CPHA==1'b0) 
155                  begin
156                      if((clk_cnt>=CS_F_CNT-8'D1) && (clk_cnt<(WIDTH_MAX-CS_B_CNT)) && (clk_cnt%2==1)  )
157                          begin         
158                              spi_data_o<={spi_data_o[30:0],spi_miso_i};                             
159                          end
160                      else 
161                          begin
162                              spi_data_o<=spi_data_o;                                                   
163                          end
164                  end    
165         else  if(SPI_CPHA==1'b1) 
166                  begin
167                      if((clk_cnt>=CS_F_CNT) && (clk_cnt<(WIDTH_MAX-CS_B_CNT)) && (clk_cnt%2==1) )
168                          begin
169                              spi_data_o<={spi_data_o[30:0],spi_miso_i};                             
170                          end
171                      else 
172                          begin
173                              spi_data_o<=spi_data_o;                                                   
174                          end
175                  end    
176          else 
177              begin
178                     spi_data_o<=spi_data_o;     
179              end
180                   
181      end 
182      
183 
184 endmodule