/*********************SPI环路测试********************* 1. I_spi_miso接收驱动,用于接收串口数据,当spi_rvalid代表接收驱动接收到了总线的有效数据 2. O_spi_mosi发送驱动,用于发送数据,当spi_tx_req为高电平,请求发送数据环路测试中*********************************************************************/ `timescale 1ns / 1ps//仿真时钟刻度和精度 module spi_master# ( parameter CLK_DIV = 10 ) ( input I_sysclk, //系统时钟 input I_rstn, //全局复位 output O_spi_sclk, //SPI MASTER输出时钟 input I_spi_sclk, //SPI Slave 输入时钟 output O_spi_mosi, //SPI MASTER输出数据 input I_spi_miso //SPI Slave 输入数据 );
wire spi_busy; reg spi_tx_req; reg [7:0] spi_tx_data; reg [1:0] M_S;
reg spi_ss_i;/*synthesis keep*/ wire spi_rvalid;/*synthesis keep*/ wire[7:0] spi_rdata;/*synthesis keep*/
reg [10:0] delay_cnt; wire delay_done;
assign delay_done = delay_cnt[10]; //复位延时计数 always @(posedge I_sysclk or negedge I_rstn) begin //异步复位 if(!I_rstn) delay_cnt <=0; //复位来的是,时钟清零 else if(delay_cnt[10] == 1'b0) //当delay_cnt[10]等于1时,计数清零,不满足就自+1 delay_cnt <= delay_cnt + 1'b1; else delay_cnt <= 0; //达到预期值,计数清零 end
always @(posedge I_sysclk or negedge I_rstn) begin //spi发送状态机 if(!I_rstn) begin spi_ss_i <= 1'b1; spi_tx_req <= 1'b0; spi_tx_data <= 8'd0; M_S <= 2'd0; end else begin case(M_S) 0:if(delay_done&&(!spi_busy))begin //延时完成且SPI传输非忙 spi_ss_i <= 1'b1; //拉高spi_ss_i信号,启动spi接收模块的数据的接收 M_S <= 2'd1; //从初始状态转入状态1 end 1:if(delay_done&&(!spi_busy))begin spi_ss_i <= 1'b0; //启动后,将 spi_ss_i信号复原 M_S <= 2'd2; end 2:if(delay_done&&(!spi_busy))begin //总线不忙启动传输 spi_tx_req <= 1'b1; //req信号拉高,准备发送 spi_tx_data <= spi_tx_data + 1'b1; //测试数据 M_S <= 2'd3; end 3:if(spi_busy)begin //如果spi总线忙,清除spi_tx_req spi_tx_req <= 1'b0; M_S <= 2'd0; end default:M_S <= 2'd0; endcase end end //spi master tx控制器例化 uimspi_tx# ( .CLK_DIV(CLK_DIV), .CPOL(1'b0), .CPHA(1'b0) ) uimspi_tx_inst( .I_clk(I_sysclk), .I_rstn(I_rstn), .O_spi_mosi(O_spi_mosi), .O_spi_sclk(O_spi_sclk), .I_spi_tx_req(spi_tx_req), .I_spi_tx_data(spi_tx_data), .O_spi_busy(spi_busy) ); //spi rx控制器例化 uispi_rx# ( .BITS_LEN(8), .CPOL(1'b0), .CPHA(1'b0) ) uispi_rx_inst( .I_clk(I_sysclk), .I_rstn(I_rstn), .I_spi_clk(I_spi_sclk), .I_spi_rx(I_spi_miso), .I_spi_ss(spi_ss_i), .O_spi_rvalid(spi_rvalid), .O_spi_rdata(spi_rdata) );
ila_0 ila_0( .clk(I_sysclk), .probe0(spi_rvalid), .probe1(spi_rdata) ); endmodule |