Unless you're doing combinatorial logic, always blocks should only be triggered by clocks, and occasionally an asynchronous reset if you have a good reason to use one. You should use write enables and busy flags to control how the module works with other parts of the system.
input wire reset;
input [7:0] datain;
input clk;
input write_enable;
output reg spi_data;
reg [4:0] state = 0;
reg [7:0] datareg;
always @(posedge clk)
begin
if (reset) begin
state <= 0;
spi_data <= 0;
end else
case (state)
0:
if (write_enable) begin
datareg <= datain;
state <= 1'b1;
end
9: begin
spi_data <= 0;
state <= 0;
end
default: begin
spi_data <= datareg[7];
datareg[7:1] <= datareg[6:0];
state <= state + 1'b1;
endcase
end
This does:
- After reset, go to the idle state (0).
- When write_enable is asserted, save datain to datareg and proceed to transmit states (1-8).
- states 1-8 are captured by the default: block. This is a simple way to use the state register as a counter. The other option would be to use a separate counter register. For eight bits, shift the MSB of data_reg into spi_data, and shift the rest up one bit.
- At state 9, go back to idle state.
I don't think this will work as-is, but it should give you a bit of an idea. If you were generating the clock in this state machine, you'd want to run it at double the clock rate and then only change the MOSI bit every other cycle, at your desired clock edge and polarity.