`include "spi_slave.v" module spi_if ( input i_rst_b, // FPGA Reset input i_sys_clk, // FPGA Clock output reg [4:0] o_ioc, output reg [7:0] o_data_in, // data that was received over SPI input [7:0] i_data_out, // data to be sent over the SPI output reg [3:0] o_cs, output reg o_fetch_cmd, output reg o_load_cmd, // SPI Interface input i_spi_sck, output o_spi_miso, input i_spi_mosi, input i_spi_cs_b ); localparam state_idle = 3'b000, state_fetch1 = 3'b001, state_fetch2 = 3'b010, state_load = 3'b011, state_post_op= 3'b100; // internal registers / wires reg [2:0] state_if; wire w_rx_data_valid; wire [7:0] w_rx_data; reg r_tx_data_valid; reg [7:0] r_tx_byte; reg [4:0] r_ioc; reg [7:0] r_data; // Initial conditions initial begin state_if = state_idle; end spi_slave spi ( .i_sys_clk (i_sys_clk), .o_rx_data_valid(w_rx_data_valid), .o_rx_byte (w_rx_data), .i_tx_data_valid(r_tx_data_valid), .i_tx_byte (r_tx_byte), .i_spi_sck (i_spi_sck), .o_spi_miso(o_spi_miso), .i_spi_mosi(i_spi_mosi), .i_spi_cs_b(i_spi_cs_b) ); always @(posedge i_sys_clk) begin if (i_rst_b == 1'b0) begin state_if <= state_idle; end else if (w_rx_data_valid == 1'b1) begin // whenever a new byte arrives case (state_if) //---------------------------------- state_idle: begin o_ioc = w_rx_data[4:0]; case (w_rx_data[6:5]) 2'b00: o_cs <= 4'b0001; 2'b01: o_cs <= 4'b0010; 2'b10: o_cs <= 4'b0100; 2'b11: o_cs <= 4'b1000; endcase if (w_rx_data[7] == 1'b1) begin // write command state_if <= state_load; end else begin // read command o_fetch_cmd <= 1'b1; state_if <= state_fetch1; end o_load_cmd <= 1'b0; r_tx_data_valid <= 1'b0; end //---------------------------------- state_load: begin o_data_in <= w_rx_data; o_load_cmd <= 1'b1; state_if <= state_idle; end //---------------------------------- state_post_op: begin o_fetch_cmd <= 1'b0; o_load_cmd <= 1'b0; state_if <= state_idle; end endcase end else begin if (state_if == state_fetch1) begin o_fetch_cmd <= 1'b0; state_if <= state_fetch2; end else if (state_if == state_fetch2) begin r_tx_byte <= i_data_out; r_tx_data_valid <= 1'b1; state_if <= state_post_op; end else begin o_load_cmd <= 1'b0; r_tx_data_valid <= 1'b0; end end end endmodule // spi_if