module spi_fifo ( input wire clock, reset, input wire bus_ssel, bus_wren, input wire [15:0] bus_mosi, output wire bus_busy, output wire spi_sel, output wire spi_sdo, output wire spi_clk ); wire int_rdempty, int_wrfull; wire [15:0] int_q; reg int_bus_busy; reg int_rdreq, int_wrreq; reg int_clken, int_sdo, int_sel; reg [15:0] int_bus_mosi; reg [15:0] int_data; reg [2:0] clk_cntr; reg [3:0] bit_cntr; reg [1:0] state; scfifo #( .add_ram_output_register("OFF"), .intended_device_family("Cyclone III"), .lpm_numwords(16), .lpm_showahead("ON"), .lpm_type("scfifo"), .lpm_width(16), .lpm_widthu(4), .overflow_checking("ON"), .underflow_checking("ON"), .use_eab("OFF")) fifo_tx ( .rdreq((~int_rdempty) & (int_rdreq) & (&clk_cntr)), .aclr(1'b0), .clock(clock), .wrreq(int_wrreq), .data(int_bus_mosi), .empty(int_rdempty), .q(int_q), .full(int_wrfull), .almost_empty(), .almost_full(), .sclr(), .usedw()); always @ (posedge clock) begin int_bus_busy <= int_wrfull; if (bus_ssel) begin if (~int_wrfull & bus_wren) begin int_bus_mosi <= bus_mosi; int_wrreq <= 1'b1; end end if (~int_wrfull & int_wrreq) begin int_wrreq <= 1'b0; end end always @ (posedge clock) begin clk_cntr <= clk_cntr + 3'd1; if (&clk_cntr) begin case (state) 0: begin int_sdo <= 1'b0; int_sel <= 1'b1; int_clken <= 1'b0; int_rdreq <= 1'b1; state <= 2'd1; end 1: begin if (~int_rdempty) begin int_rdreq <= 1'b0; int_data <= int_q; bit_cntr <= 4'd0; state <= 2'd2; end end 2: begin // data int_clken <= 1'b1; int_sel <= 1'b0; int_sdo <= int_data[11]; int_data <= {int_data[10:0], 1'b0}; bit_cntr <= bit_cntr + 4'd1; if (bit_cntr == 4'd11) begin state <= 2'd3; end end 3: begin int_sdo <= 1'b0; int_clken <= 1'b0; state <= 2'd0; end endcase end end // output logic assign bus_busy = int_bus_busy; assign spi_clk = (int_clken ? clk_cntr[2] : 1'b1); assign spi_sdo = int_sdo; assign spi_sel = int_sel; endmodule