简化的SPI接收机,用来完成8bit的数据传输。
sclk为时钟接口;srst为清零信号,低电平有效;sen为接口使能信号,高电平有效;ss_n为片选信号,选择从设备,高电平有效。
当电路上电时,首先将清零信号置位有效,初始化电路,当sen使能信号有效后,开始传输数据,由于传输数据为8bit,因此sen使能信号应该至少保持8个时钟周期。当8bit数据全部输入后,片选信号ss_n有效,选择从设备,将数据整体输出。片选信号ss_n由3bit计数器产生,当计数器计数到111状态时,ss_n=1,其他状态ss_n为0。
module SPI(sdout,MISO,sclk,srst,sen,ss_n);
input MISO,sclk,srst,sen;
output [7:0] sdout;
output ss_n;
reg [2:0] counter;
reg [7:0] shift_regist;
reg ss_n;
always @ (posedge sclk) begin
if(!srst)
counter <= 3'b000;
else if(sen) begin
if(counter == 3'b111) begin
counter <= 3'b000;
ss_n <= 1'b1;
end
else begin
counter <= counter+1;
ss_n <= 1'b0;
end
end
else
counter <= counter;
end
always @ (posedge sclk) begin
if(sen)
shift_regist <= {shift_regist[6:0],MISO};
else
shift_regist <= shift_regist;
end
assign sdout = ss_n?shift_regist:8'b0000_0000;
endmodule
测试代码
module SPI_tb;
reg sclk,MISO,sen,srst;
wire [7:0] sdout;
wire ss_n;
SPI n1 (sdout,MISO,sclk,srst,sen,ss_n);
initial begin
sclk = 0;srst = 0;MISO = 0;sen = 0;
#10 srst = 1;
#10 sen = 1;
#80 sen = 0;
#10 sen = 1;
#80 sen = 0;
end
initial begin
#30 MISO = 1;
#10 MISO = 0;
#10 MISO = 1;
#10 MISO = 0;
#10 MISO = 1;
#10 MISO = 0;
#10 MISO = 1;
#20 MISO = 1;
#10 MISO = 0;
#10 MISO = 1;
#10 MISO = 0;
#10 MISO = 1;
#10 MISO = 0;
#10 MISO = 1;
#10 MISO = 0;
end
always begin
#5 sclk = ~sclk;
end
endmodule