nand2/06_IO_Devices/SPI.v
2024-10-25 13:47:27 -04:00

126 lines
3.8 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=0;
reg csx_low=0;
reg out_low=1;
reg [7:0] totx;
reg [7:0] torx;
reg [4:0] is16;
always @(posedge clk) begin
CSX <= (csx_low) ? 0 : 1;
SDO <= 0;
SCK <= 0;
out <= (out)? out : 0;
if (load == 1) begin
out_low=0;
out[14:8] <= 0;
out[7:0] <= in[7:0];
if (in[8]==1) begin
out[15] <= 0;
csx_low <= 0;
CSX <= 1;
end
else if (in[8]==0) begin
out[15] <= 1;
csx_low <= 1;
CSX <= 0;
active <= 1;
is16 <= 1;
totx[7:0] <= in[7:0];
SDO <= in[7];
end
end
else if (active==1) begin
SCK <= ~SCK;
if (is16 == 16) begin
active <= 0;
out <= {8'b0, torx[7:0]};
end
else begin
csx_low <= 1;
is16 <= is16 + 1;
case (is16+1)
2 : SDO <= totx[7];
3 : SDO <= totx[6];
4 : SDO <= totx[6];
5 : SDO <= totx[5];
6 : SDO <= totx[5];
7 : SDO <= totx[4];
8 : SDO <= totx[4];
9 : SDO <= totx[3];
10 : SDO <= totx[3];
11 : SDO <= totx[2];
12 : SDO <= totx[2];
13 : SDO <= totx[1];
14 : SDO <= totx[1];
15 : SDO <= totx[0];
16 : SDO <= totx[0];
endcase
case (is16)
1 : torx[7] <= SDI;
3 : torx[6] <= SDI;
5 : torx[5] <= SDI;
7 : torx[4] <= SDI;
9 : torx[3] <= SDI;
11 : torx[2] <= SDI;
13 : torx[1] <= SDI;
15 : torx[0] <= SDI;
endcase
case (is16)
2 : out <= (out<<1);
4 : out <= (out<<1);
6 : out <= (out<<1);
8 : out <= (out<<1);
10 : out <= (out<<1);
12 : out <= (out<<1);
14 : out <= (out<<1);
endcase
case (is16)
2 : out[0] <= torx[7];
4 : out[0] <= torx[6];
6 : out[0] <= torx[5];
8 : out[0] <= torx[4];
10 : out[0] <= torx[3];
12 : out[0] <= torx[2];
14 : out[0] <= torx[1];
endcase
case (is16)
2 : out[15:8] <= 8'b10000000;
4 : out[15:8] <= 8'b10000000;
6 : out[15:8] <= 8'b10000000;
8 : out[15:8] <= 8'b10000000;
10 : out[15:8] <= 8'b10000000;
12 : out[15:8] <= 8'b10000000;
14 : out[15:8] <= 8'b10000000;
endcase
end
end else begin
out <= out_low? 16'b0 : out;
end
end
endmodule