48 lines
1.2 KiB
Systemverilog
48 lines
1.2 KiB
Systemverilog
/**
|
|
* 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
|