2015-06-17 2 views
0

Я пытаюсь установить связь между двумя FPGA Xilinx Spartan 3e, используя связь SPI и контакты GPIO. Цель состоит в том, чтобы работать с ведущим-ведомым, но на данный момент я просто отправляю данные с Master на Slave и пытаюсь проверить, правильно ли получены данные.Verilog Inter-FPGA SPI Communication

Это мастер-код, который отправляет 16 бит данных в Slave в последовательном формате. После проверки масштаба много раз это кажется правильным.

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 

[email protected](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 

Это код на ведомом приемном конец, я проверяю данные по заднему фронту тактового сигнала (попробовал posedge тоже), чтобы избежать любых конфликтов синхронизации. Часы, notCS и СИ (серийный в) все приходя от ведущего через 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; 


[email protected](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 

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

endmodule 

После вывода «outputPO» на ЦАП это дает кучу мусора и, очевидно, не одно значение , Спасибо

+3

Правильно ли он имитируется? – toolic

ответ

1

Чтобы отладить проблему FPGA, как это, вы должны абсолютно имитировать дизайн. Если вы еще этого не сделали, создайте testbench, чтобы инициировать запись в главном модуле и подключить подчиненный модуль так же, как и в системе. Проверьте формы волны, соответствующие ожидаемому поведению. Это не эффективная отладка аппаратных средств, пока эта симуляция не работает. Если у вас нет доступа к платному симулятору, доступны бесплатные симуляторы verilog. Одно из предложений - построить эту среду моделирования в EDA Playground, а затем вы можете поделиться ею здесь как часть описания проблемы.

Во-вторых, я заметил несколько вещей, которые можно было бы улучшить качество и читаемость кода, который делает отладку проще:

  1. отступа кода внутри блоков (начать/конец пары, и т.д.).
  2. Всегда используйте неблокирующие назначения внутри синхронизированных процессов и блокирующие назначения в комбинаторных блоках. Например, неблокирующие операторы в вашем комбинаторном процессе, назначающие outputPO в SPI_COMM_SLAVE, являются неправильными. Это может привести к симуляции, не соответствующей синтезированным результатам.
  3. Защелки не рекомендуются для конструкций fpga. SPI_COMM_SLAVE будет синтезировать 16-битную защелку для выводаPO. Подумайте о том, чтобы сделать этот сигнал регистром.
  4. Ваша архитектурная архитектура выглядит более сложной, чем она должна быть. Рассмотрим разделение функциональности, которая инициирует spi-транзакции (div_counter), из логики, которая выполняет фактическую транзакцию spi.