基于Xilinx K7平臺的W5500 SPI傳輸時序
開發語言為Verilog
在硬件平臺上打通,實測沒問題
支持1字節/2字節/4字節/多字節讀寫
微信截圖_20180412152850.png (12 KB, 下載次數: 109)
下載附件
2018-4-12 15:54 上傳
包含兩個文件:rw_w5500_intf.v
mspi.v
單片機源程序如下:
- `timescale 1ns / 1ps
- //////////////////////////////////////////////////////////////////////////////////
- // Company:
- // Engineer:
- //
- // Create Date: 12:00:49 04/12/2017
- // Design Name:
- // Module Name: rw_w5500_intf
- // Project Name:
- // Target Devices:
- // Tool versions:
- // Description:
- //
- // Dependencies:
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- // w5500讀寫控制及狀態機實現FPGA源代碼,可聯系wuh2017@163.com
- //
- //////////////////////////////////////////////////////////////////////////////////
- module rw_w5500_intf(
- input I_clk, // global clock
- input I_reset, // global async low reset
- input I_rw, // w5500 write/read -------------
- input I_sdi, // spi master data in (MISO)
- input [1:0] I_w5500_data_len, // w5500 data byte number:0:1BYTE 1:2BYTE 2:4BYTE 3:NBYTE --------
- input [15:0] I_w5500_addr, // w5500 addr phase 16bit
- input [7:0] I_w5500_ctl, // w5500 controlphase 8bit
- input [31:0] I_w5500_wr_data, // w5500 data 32bit --------------------
-
- output wire O_rw_done, // write done /read done
- output [31:0] O_w5500_rd_data, // w5500 data 32bit
- output O_sck, // spi master clock out
- output O_sdo, // spi master data out (MOSI)
- output wire O_scs, // spi cs
- output wire O_ready, // spi master O_ready (idle)
- output wire O_fifo_rd_en,
- output wire O_data_rd_valid,
-
- input [15:0]I_tx_length
- );
- // =========================================================
- //
- parameter BYTE_NUM_1 = 0;
- parameter BYTE_NUM_2 = 1;
- parameter BYTE_NUM_4 = 2;
- parameter IDLE = 0;
- parameter STEP1 = 1;
- parameter STEP2 = 2;
- parameter STEP3 = 3;
- parameter STEP4 = 4;
- // =========================================================
- //
- reg spi_wr;
- reg [31:0] spi_tx_data;
- reg [31:0] w5500_rd_data_reg;
- reg [2:0] state;
- reg [1:0] spi_wr_len;
- reg [1:0] rw_reg;
- // =========================================================
- //
- wire spi_wr_done;
- wire [31:0] spi_rddata;
- wire W_scs;
- wire [14:0] W_mspi_state;
- wire sdo_tick;
- (*KEEP="TRUE"*) wire W_Nbyte_rd_done = (W_scs == 0 && W_mspi_state[4:0]==0 && sdo_tick == 1);
- assign O_scs = (state==IDLE);
- (*KEEP = "TRUE" *)wire rw_pos = (rw_reg[1:0] == 2'b01);//本時刻1上時刻0
- assign O_ready = (state==IDLE);
- assign O_rw_done = (state==STEP4);
- assign O_w5500_rd_data = w5500_rd_data_reg;
- assign O_fifo_rd_en = ((W_mspi_state[4:0]==30) && sdo_tick == 1);
- assign O_data_rd_valid = W_Nbyte_rd_done;
- // =========================================================
- //
- mspi mspi_inst (
- .I_clk ( I_clk ),
- .I_reset ( I_reset ),
- .I_clk_div ( 4 ),
- .I_wr ( spi_wr ),
- .I_wr_len ( spi_wr_len ),
- .O_wr_done ( spi_wr_done ),
- .I_wrdata ( spi_tx_data ),
- .O_rddata ( spi_rddata ),
- .O_sck ( O_sck ),
- .I_sdi ( I_sdi ),
- .O_sdo ( O_sdo ),
- .O_scs ( W_scs ),
- .O_ready ( ),
- .O_state ( W_mspi_state ),
- .O_sdo_tick ( sdo_tick ),
- .I_tx_length( I_tx_length )
- );
- // ---------------------------------------------------------
- //
- always @(posedge I_clk or posedge I_reset)
- if(I_reset)
- rw_reg <= 0;
- else
- rw_reg <= {rw_reg[0],I_rw};
- // ---------------------------------------------------------
- //
- always @(posedge I_clk or posedge I_reset)
- if(I_reset)
- begin
- state <= IDLE;
- spi_wr <= 0;
- spi_tx_data <= 0;
- spi_wr_len <= 0;
- w5500_rd_data_reg <= 0;
- end
- else case(state)
- IDLE: //0state
- if(rw_pos)
- begin
- state <= STEP1;
- spi_wr <= 0;
- spi_tx_data <= 0;
- spi_wr_len <= 0;
- end
- STEP1: //寫入數據
- begin
- spi_wr <= 1'b1;
- spi_tx_data[31:16] <= I_w5500_addr[15:0];
- spi_tx_data[15:0] <= 0;
- spi_wr_len <= BYTE_NUM_2; // 地址段 16bit
- if(spi_wr_done)
- begin
- state <= STEP2;
- spi_wr <= 0;
- end
- end
- STEP2:
- begin
- spi_wr <= 1'b1;
- spi_tx_data[31:24] <= I_w5500_ctl[7:0];
- spi_tx_data[23:0] <= 0;
- spi_wr_len <= BYTE_NUM_1; // 控制段 8bit
- if(spi_wr_done)
- begin
- state <= STEP3;
- spi_wr <= 0;
- end
- end
- STEP3:
- begin//-------------------------------狀態機做出改變
- spi_wr <= 1'b1;
- spi_tx_data[31:0] <= I_w5500_wr_data[31:0];
- spi_wr_len <= I_w5500_data_len; // 數據段 0:1BYTE 1:2BYTE 2:4BYTE 3:NBYTE提供數據前要注意將有效位放至MSB
- if(spi_wr_done)
- begin
- state <= STEP4;
- spi_wr <= 0;
- end
-
- if(spi_wr_done || W_Nbyte_rd_done)
- begin
- if(I_w5500_data_len==0)
- begin
- w5500_rd_data_reg[31:24] <= spi_rddata[7:0];
- w5500_rd_data_reg[23:0] <= 0;
- end
- else if(I_w5500_data_len==1)
- begin
- w5500_rd_data_reg[31:16] <= spi_rddata[15:0];
- w5500_rd_data_reg[15:0] <= 0;
- end
- else
- begin
- w5500_rd_data_reg[31:0] <= spi_rddata[31:0];
- end
- end
- end
- STEP4:
- begin
- state <= IDLE;
- spi_wr <= 0;
- spi_tx_data <= 0;
- spi_wr_len <= 0;
- end
- default:
- begin
- state <= IDLE;
- spi_wr <= 0;
- spi_tx_data <= 0;
- spi_wr_len <= 0;
- w5500_rd_data_reg <= 0;
- end
- endcase
-
- endmodule
復制代碼
所有資料51hei提供下載:
rtl.zip
(3.78 KB, 下載次數: 160)
2018-4-12 15:58 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|