module
spi_mosi(rst,clk,rd,wr,datain,
spics,spiclk,spido,spidi,dataout);
input
rst;
//置位信号,低有效
input
clk;
//时钟信号
input
rd;
//接收数据命令
input
wr;
//发送数据命令
input
spidi;
//SPI数据输入信号
input
[7:0]
datain;
//发送数据输入
output
spics;
//SPI片选信号
output
spiclk;
//SPI时钟信号
output
spido;
//SPI数据输出信号
output
[7:0]
dataout;
//接收数据输出
reg
spics;
reg
spiclk;
reg
spido;
reg
[7:0]
dstate,
dsend,dataout,dreceive
;//,cnt;
reg
[1:0]
spistate;
parameter
idle
=
2'b00;
parameter
send_data
=
2'b01;
parameter
receive_data
=
2'b10;
initial
begin
spics
<=
1'b1;
spiclk
<=
1'b1;
spido
<=
1'b1;
end
always
@(posedge
clk)
begin
if(!rst)
begin
spistate
<=
idle;
//
cnt
<=
8'd0;
spics
<=
1'b1;
spiclk
<=
1'b1;
spido
<=
1'b1;
dstate
<=
8'd0;
end
else
begin
case
(spistate)
2'b00:
begin
//
spics
<=
1'b1;
//
spiclk
<=
1'b1;
//
spido
<=
1'b1;
//
if(cnt
==
8'd0)
//
begin
//
cnt
<=
8'd0;
if((wr
==
1'b0)
&&
(rd
==
1'b1))
//发送资料转换
begin
spistate
<=
send_data;
dstate
<=
8'd0;
dsend
<=
datain;
end
else
if((wr
==
1'b1)
&&
(rd
==
1'b0))
//接收数据转换
begin
spistate
<=
receive_data;
dstate
<=
8'd0;
end
else
begin
spistate
<=
idle;
dstate
<=
8'd0;
end
//
end
//
else
//
begin
//
cnt
<=
cnt
+
8'd1;
//
end
end
2'b01:
//发送数据状态
begin
case
(dstate)
8'd0:
//产生片选信号有效
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
1'b1;
dstate
<=
8'd1;
end
8'd1:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
1'b1;
dstate
<=
8'd2;
end
8'd2:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
spido
<=
1'b1;
dstate
<=
8'd3;
end
8'd3:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
dsend[7];
//发送数据最高位
dstate
<=
8'd4;
end
8'd4:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
spido
<=
dsend[7];
dstate
<=
8'd5;
end
8'd5:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
dsend[6];
dstate
<=
8'd6;
end
8'd6:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
spido
<=
dsend[6];
dstate
<=
8'd7;
end
8'd7:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
dsend[5];
dstate
<=
8'd8;
end
8'd8:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
spido
<=
dsend[5];
dstate
<=
8'd9;
end
8'd9:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
dsend[4];
dstate
<=
8'd10;
end
8'd10:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
spido
<=
dsend[4];
dstate
<=
8'd11;
end
8'd11:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
dsend[3];
dstate
<=
8'd12;
end
8'd12:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
spido
<=
dsend[3];
dstate
<=
8'd13;
end
8'd13:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
dsend[2];
dstate
<=
8'd14;
end
8'd14:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
spido
<=
dsend[2];
dstate
<=
8'd15;
end
8'd15:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
dsend[1];
dstate
<=
8'd16;
end
8'd16:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
spido
<=
dsend[1];
dstate
<=
8'd17;
end
8'd17:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
//发送最低位数据
spido
<=
dsend[0];
dstate
<=
8'd18;
end
8'd18:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
spido
<=
dsend[0];
//spiclk的下降沿让最低位数据被读取
dstate
<=
8'd19;
end
8'd19:
//置片选信号无效
begin
spics
<=
1'b1;
spiclk
<=
1'b1;
spido
<=
1'b1;
dstate
<=
8'd20;
end
8'd20:
begin
spics
<=
1'b1;
spiclk
<=
1'b1;
spido
<=
1'b1;
dstate
<=
8'd0;
spistate
<=
idle;
end
default
begin
spics
<=
1'b1;
spiclk
<=
1'b1;
spido
<=
1'b1;
spistate
<=
idle;
end
endcase
end
2'b10:
//接收数据状态
begin
case
(dstate)
//片选信号有效
8'd0:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
1'b1;
dstate
<=
8'd1;
end
8'd1:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
1'b1;
dstate
<=
8'd2;
end
8'd2:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
spido
<=
1'b1;
dstate
<=
8'd3;
end
8'd3:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
dstate
<=
8'd4;
end
8'd4:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
//紧接着上升沿的下降沿数据被读取
dreceive[7]
<=
spidi;
//接收数据最高位
dstate
<=
8'd5;
end
8'd5:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
dstate
<=
8'd6;
end
8'd6:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
dreceive[6]
<=
spidi;
dstate
<=
8'd7;
end
8'd7:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
dstate
<=
8'd8;
end
8'd8:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
dreceive[5]
<=
spidi;
dstate
<=
8'd9;
end
8'd9:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
dstate
<=
8'd10;
end
8'd10:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
dreceive[4]
<=
spidi;
dstate
<=
8'd11;
end
8'd11:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
dstate
<=
8'd12;
end
8'd12:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
dreceive[3]
<=
spidi;
dstate
<=
8'd13;
end
8'd13:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
dstate
<=
8'd14;
end
8'd14:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
dreceive[2]
<=
spidi;
dstate
<=
8'd15;
end
8'd15:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
dstate
<=
8'd16;
end
8'd16:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
dreceive[1]
<=
spidi;
dstate
<=
8'd17;
end
8'd17:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
dstate
<=
8'd18;
end
8'd18:
begin
spics
<=
1'b0;
spiclk
<=
1'b0;
dreceive[0]
<=
spidi;
//接收数据最低位
dstate
<=
8'd19;
end
8'd19:
begin
spics
<=
1'b0;
spiclk
<=
1'b1;
spido
<=
1'b1;
dstate
<=
8'd20;
dataout<=
dreceive;
end
8'd20:
begin
spics
<=
1'b1;
//片选信号无效
spiclk
<=
1'b1;
spido
<=
1'b1;
dstate
<=
8'd0;
spistate
<=
idle;
end
endcase
end
default:
begin
spics
<=
1'b1;
spiclk
<=
1'b1;
spido
<=
1'b1;
spistate
<=
idle;
end
endcase
//对应上面的发送数据情形
end
//对应上面的RST没有按下的情形
end
//对应最上面的always@(posedge
clk)
endmodule