Verilog Inter-FPGA SPI通信

时间:2015-06-17 15:29:11

标签: verilog fpga spi serial-communication

我正在尝试使用SPI通信和GPIO引脚在两个Xilinx Spartan 3e FPGA之间进行通信。目标是让主从通信工作,但是现在我只是将数据从Master发送到Slave并试图查看收到的数据是否正确。

这是以串行格式向Slave发送16位数据的主代码。在多次检查范围后,它似乎是正确的。

 module SPI_MASTER_SEND(
    input CLK_50MHZ,
    input [1:0] ID_user,
    input [15:0] DATA_TO_SEND,
    output reg SData,
    output SCLK,
    output notCS
    );
parameter max = 20; // max-counter size
reg [6:0]div_counter;
wire [6:0] data_count;
assign data_count[6:0] = div_counter[6:0];
reg CLOCK;
reg Clk_out;
reg CompleteB;

//have the notCS be low for 20 pulses, and hi for 20 pulses.
//sends 16 bits of data during low pulse

always@(posedge CLOCK) begin
   if (div_counter == max-1)
     begin
     div_counter <= 0;
     Clk_out <= ~Clk_out;
     end
   else
     begin
     div_counter <= div_counter + 1;
     end
end
assign notCS = Clk_out;
reg flag;
assign SCLK = flag&&CLOCK;   //Clock when notCS is down for 16 pulses

always @(posedge CLOCK) // Parallel to Serial
begin
if (data_count >= 7'd3 && data_count < 7'd18 && notCS ==0)
    begin

        SData <= DATA_TO_SEND[18-data_count];
        flag <=1;
        CompleteB<=0;

    end
else if (data_count == 7'd18 && notCS ==0)
    begin
        flag <=1;
        SData<=DATA_TO_SEND[0];
        CompleteB<=1;
    end

else


    begin
        CompleteB<=0;
        flag<=0;
        SData <= 0;
    end
end

endmodule

这是Slave接收端的代码,我检查时钟下降沿的数据(也尝试了posedge)以避免任何时序冲突。 时钟,非CS和SI(串行输入)都来自主设备通过gpio引脚

module SPI_COMM_SLAVE(CLK,SI,notCS,outputPO,ID_user);

input  CLK,SI,notCS; 
input [1:0] ID_user;
reg [15:0] PO;
output reg [15:0] outputPO;
reg CompleteB;
reg C;

reg [5:0] cnt;
initial cnt[5:0] = 6'b000000;


always@(negedge CLK) 

begin

if (cnt < 6'd15)
begin
PO[15-cnt] <= SI;
cnt <= cnt + 1'b1;
CompleteB<=0;
end
else if (cnt == 6'd15)
begin
    PO[0] <= SI;
    cnt<=6'b000000;
    CompleteB <=1;


end
else
begin
cnt <= cnt;
CompleteB<=0;
end
end

always@(*)begin
    if(CompleteB == 1)
    outputPO[15:0] <= PO[15:0];
    else
    outputPO[15:0]<=outputPO[15:0];
end

endmodule 

将“outputPO”输出到DAC后,它会产生一堆垃圾,显然不是单个值。 谢谢

1 个答案:

答案 0 :(得分:1)

要调试这样的FPGA问题,你应该绝对模拟设计。如果您还没有,请创建一个测试平台以在主模块中启动写入并将从模块连接到系统中。检查波形与您期望的行为相匹配。在此模拟工作之前,它无法在硬件中进行有效调试。如果您无法访问付费模拟器,则可以使用免费的verilog模拟器。一个建议是在EDA Playground中构建此模拟环境,然后您可以在此处作为问题描述的一部分进行共享。

其次,我注意到一些可以提高代码质量和可读性的方法,这使得调试变得更容易:

  1. 块内缩进代码(开始/结束对等)。
  2. 始终在时钟进程内使用非阻塞分配并阻止组合块中的分配。例如,组合过程中的非阻塞语句在SPI_COMM_SLAVE中分配outputPO是错误的。这可能导致模拟与合成结果不匹配。
  3. 不推荐用于fpga设计的锁存器。 SPI_COMM_SLAVE将为outputPO合成一个16位锁存器。考虑将此信号设为寄存器。
  4. 您的主架构看起来比它需要的更复杂。考虑将启动spi事务(div_counter)的功能与执行实际spi事务的逻辑分开。