/** * Specialized SPI slave. * Reads width bits at a time, and sets the ready flag * whenever a full 32 bits has been read. Also, recognizes * 0x00 as a pattern, and when full 0s are read, sets the done flag. * 0x00 is a special value in the CPU programming process that indicates * end-of-program. * * master_clk, ss, and mosi are all SPI-specific inputs. * data should only be read when ready is high. */ module spi_slave #(width=32) (input logic clk, reset, input logic master_clk, ss, mosi, output logic ready, output logic done, output logic [width-1:0] data); logic [width-1:0] storage; logic unsigned [$clog2(width)-1:0] counter; logic old_clk; always_ff@(posedge clk) if(reset) begin counter <= 0; old_clk <= 0; storage <= 0; done <= 0; ready <= 0; end else begin if (~ss & master_clk & ~old_clk) begin storage <= storage << 1 | mosi; if (counter == width - 1) begin ready <= 1; done <= ~(|storage); counter <= 0; end else begin done <= 0; ready <= 0; counter <= counter + 1; end end old_clk <= master_clk; end assign data = storage; endmodule