VerilogCPU/spi_slave.sv

51 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 clk_edge;
edge_detector clk_detector(
.in(master_clk),
.clk(clk),
.reset(reset),
.pos_edge(clk_edge));
always_ff@(posedge clk)
if(reset) begin
counter <= 0;
storage <= 0;
done <= 0;
ready <= 0;
end else begin
if (~ss & clk_edge) 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
end
assign data = storage;
endmodule