86 lines
2.1 KiB
Verilog
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
|
|
|