求助高手帮看看CPLD做SPI从的程序

qq_42232293 2018-05-29 05:27:40
我是用STM32和EPM240做SPI通信,STM32为主SPI,CPLD为从SPI,8位通信,将always@(posedge CS_N or negedge rst_n) 下的
else
begin
txd_data <=txd_data+1'b1;
end
换成 txd_data <=5'b11100;(固定赋值)或txd_data <=rxd_data,数据都可以正常传输给STM32,但是当换成txd_data+1'b1后,每次加的值都不对,我实测了几组数据大概如下:
1,5,9,13,17,22,24,27,30,16,35,38,41,46,48
1,5,9,13,17,22,24,27,30,16,35,39,42,47,51有一定的重复规律性
查了CS_N信号的边沿,也没有发现有多个上升沿,百思不得其解,情高手帮忙看看代码有没有问题

module spi(clk,rst_n,CS_N,SCK,MOSI,MISO,rxd_data);
input clk; //CPLD时钟,50MHZ
input rst_n;
input CS_N;
input SCK; //STM32发送的SPI时钟,实测周期2uS
input MOSI;
reg [7:0] txd_data;
output reg MISO;
reg [7:0] rxd_data;
output [7:0] rxd_data;



//-------------------------capture the sck-----------------------------
reg sck_r0,sck_r1;
wire sck_n,sck_p;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
sck_r0 <= 1'b1; //sck of the idle state is high
sck_r1 <= 1'b1;
end
else
begin
sck_r0 <= SCK;
sck_r1 <= sck_r0;
end
end

assign sck_n = (~sck_r0 & sck_r1)? 1'b1:1'b0; //capture the sck down
assign sck_p = (~sck_r1 & sck_r0)? 1'b1:1'b0; //capture the sck up


//-----------------------spi_slaver read data-------------------------------
reg rxd_flag_r;
reg [2:0] rxd_state;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rxd_data <= 1'b0;
rxd_flag_r <= 1'b0;
rxd_state <= 1'b0;
end
else if(sck_n && !CS_N)
begin
case(rxd_state)
3'd0:begin
rxd_data[7] <= MOSI;
rxd_flag_r <= 1'b0; //reset rxd_flag
rxd_state <= 3'd1;
end
3'd1:begin
rxd_data[6] <= MOSI;
rxd_state <= 3'd2;
end
3'd2:begin
rxd_data[5] <= MOSI;
rxd_state <= 3'd3;
end
3'd3:begin
rxd_data[4] <= MOSI;
rxd_state <= 3'd4;
end
3'd4:begin
rxd_data[3] <= MOSI;
rxd_state <= 3'd5;
end
3'd5:begin
rxd_data[2] <= MOSI;
rxd_state <= 3'd6;
end
3'd6:begin
rxd_data[1] <= MOSI;
rxd_state <= 3'd7;
end
3'd7:begin
rxd_data[0] <= MOSI;
rxd_flag_r <= 1'b1; //set rxd_flag
rxd_state <= 3'd0;
end
default: ;
endcase

end
end
always@(posedge CS_N or negedge rst_n) //当CPLD捕捉到SPI_CS信号的上升沿时,要给STM32发送的数据加1
begin
if(!rst_n)
begin
txd_data <= 1'b0;
end
else
begin
txd_data <=txd_data+1'b1;
end
end
//---------------------spi_slaver send data---------------------------
reg [2:0] txd_state;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
txd_state <= 1'b0;
MISO <=1'b0;

end
else if(sck_p && !CS_N)
begin
case(txd_state)
3'd0:begin
MISO <= txd_data[7];
txd_state <= 3'd1;
end
3'd1:begin
MISO <= txd_data[6];
txd_state <= 3'd2;
end
3'd2:begin
MISO <= txd_data[5];
txd_state <= 3'd3;
end
3'd3:begin
MISO <= txd_data[4];
txd_state <= 3'd4;
end
3'd4:begin
MISO <= txd_data[3];
txd_state <= 3'd5;
end
3'd5:begin
MISO <= txd_data[2];
txd_state <= 3'd6;
end
3'd6:begin
MISO <= txd_data[1];
txd_state <= 3'd7;
end
3'd7:begin
MISO <= txd_data[0];
txd_state <= 3'd0;

end
default: ;
endcase
end
else if(CS_N)
begin
MISO <=1'b0;
end


end


endmodule
...全文
1527 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
laidaihua 2018-06-23
  • 打赏
  • 举报
回复
这个设计方法有问题,因为CS_N要参与数据传输控制,你同时又用来控制被传输数据的累加,非常容易引入竞争冒险,导致传输的数据错误。一个比较好的解决办法是采用同步时钟进行设计。
异步方式下,因为延迟不可控,本来就容易出现失控,如果非得这么做,那么建议你将txd_data用sp锁存一下,看看能不能解决。。

6,125

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 硬件设计
社区管理员
  • 硬件设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧