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