cariboulabs-cariboulite/firmware/spi_if.v

111 wiersze
2.8 KiB
Verilog

`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