参考TLC5615基于verilog HDL实现SPI时序
下面参考TLC5615 DAC芯片,用verilog HDL实现了SPI时序,便于大家参考,下面将代码整理如下,具体请参考注释。
module spi_test(
input wire sclk,//系统时钟,50MHz
input wire rstn,//系统复位
output reg spi_cs,//SPI片选,低电平有效
output reg spi_clk,//1MHz//SPI时钟
output reg spi_d//SPI数据
);
parameter SCLKCNT=5'd24;//分频系数,50M->1M
parameter NEGFLAGCNT=4'd9;//发送10比特,计数值
reg [4:0] sclk_cnt;//
reg [3:0] neg_cnt;
reg neg_flag;
reg spi_cs_reg;
reg spi_clk_reg;
reg [9:0] shift_buf;//移位寄存器,用于SPI数据输出
reg end_flag;//仅发送一个10位的数据
//产生分频计数
always@(posedge sclk or negedge rstn)
begin
if(rstn==1'b0)
sclk_cnt<=5'd0;
else if(sclk_cnt==SCLKCNT)
sclk_cnt<=5'd0;
else
sclk_cnt<=sclk_cnt+1'b1;
end
//产生SPI 1MHz时钟信号
always@(posedge sclk or negedge rstn)
begin
if(rstn==1'b0)
spi_clk_reg<=1'b0;
else if(sclk_cnt==SCLKCNT)
spi_clk_reg<=~spi_clk_reg;
end
//产生SPI 1MHz时钟的下降沿标识信号
always@(posedge sclk or negedge rstn)
begin
if(rstn==1'b0)
neg_flag<=1'b0;
else if(sclk_cnt==SCLKCNT&&spi_clk_reg==1'b1)
neg_flag<=1'b1;
else
neg_flag<=1'b0;
end
//产生下降沿标识信号的计数信号
always@(posedge sclk or negedge rstn)
begin
if(rstn==1'b0)
neg_cnt<=4'd0;
else if(neg_flag==1'b1&&neg_cnt==NEGFLAGCNT)
neg_cnt<=4'd0;
else if(neg_flag==1'b1)
neg_cnt<=neg_cnt+1'b1;
end
//产生SPI的片选信号
always@(posedge sclk or negedge rstn)
begin
if(rstn==1'b0)
begin
spi_cs_reg<=1'b1;
end_flag<=1'b0;
end
else if(sclk_cnt==5'd1&&end_flag==1'b0)
begin
spi_cs_reg<=1'b0;
end
else if(neg_flag==1'b1&&neg_cnt==NEGFLAGCNT)
begin
spi_cs_reg<=1'b1;
end_flag<=1'b1;
end
end
//产生SPI的数据移位信号
always@(posedge sclk or negedge rstn)
begin
if(rstn==1'b0)
shift_buf<=10'b10_1010_0101;
else if(spi_cs_reg==1'b0&&neg_flag==1'b1)
shift_buf<={shift_buf[8:0],1'b0};//采用移位的方式输出SPI数据
end
//所有SPI信号同步控制
always@(posedge sclk or negedge rstn)
begin
if(rstn==1'b0)
spi_cs<=1'b1;
else if(spi_cs_reg==1'b0)
spi_cs<=1'b0;
else
spi_cs<=1'b1;
end
always@(posedge sclk or negedge rstn)
begin
if(rstn==1'b0)
spi_clk<=1'b0;
else if(spi_cs_reg==1'b0)
spi_clk<=spi_clk_reg;
else
spi_clk<=1'b0;
end
always@(posedge sclk or negedge rstn)
begin
if(rstn==1'b0)
spi_d<=1'b0;
else if(spi_cs_reg==1'b0)
spi_d<=shift_buf[9];
else
spi_d<=1'b0;
end
endmodule
下面是仿真时序图,在SPI时钟上升沿采样数据。