86 lines
2.1 KiB
Verilog

/**
* SPI controller for W25Q16BV
*
* When load=1 transmission of byte in[7:0] is initiated. The byte is send to
* MOSI (master out slave in) bitwise together with 8 clock signals on SCK.
* At the same time the SPI recieves a byte at MISO (master in slave out).
* Sampling of MISO is done at rising edge of SCK and shiftingis done at
*/
`default_nettype none
module SPI(
input clk,
input load,
input [15:0] in,
output reg [15:0] out,
output reg CSX,
output reg SDO,
input SDI,
output reg SCK
);
// Put your code here:
// 1100 0000 0101 1011
// 1000 0000 0101 1011
reg active;
reg [2:0] bit_index;
reg [7:0] shift_out;
reg [7:0] shift_in;
reg [3:0] count;
wire is_sample_phase = (count >= 1 && count <= 15 && count[0] == 1);
wire is_shift_phase = (count >= 0 && count <= 14 && count[0] == 0);
initial begin
SDO <= 0;
CSX <= 1'b1;
out <= 16'b0;
bit_index <= 3'b0;
end
always @(posedge clk) begin
SCK <= 0;
if (load == 1) begin
CSX <= 1;
out <= { 8'b0, in[7:0] };
if (!in[8]) begin
active <= 1;
count <= 0;
bit_index <= 7; // byte order MSB->LSB
CSX <= 0;
out[15] <= 1;
shift_out[7:0] <= in[7:0];
SDO <= in[7];
end
end
else if (active==1) begin
SCK <= ~SCK;
if (count == 15) begin
SDO <= 0;
out <= {8'b0, shift_in};
active <= 0;
end else begin
count <= count + 1;
if (is_sample_phase) begin
bit_index <= bit_index - 1;
out[7:0] <= {out[6:0], shift_in[bit_index]};
shift_out <= {shift_out[6:0], 1'b0};
SDO <= shift_out[6]; // next bit
end
if (is_shift_phase) begin
shift_in[bit_index] <= SDI;
end
end
end
end
endmodule