Код Verilog работает в моделировании, как я и предсказывал, но не в FPGA.

Я пытаюсь написать модуль передатчика UART. Он получает данные из data[7:0], а затем отправляет их последовательно через Tx. Я написал модуль Tester для тестирования передатчика. Он имитирует в Изиме, как я и предсказывал, но не в Спартанце-6. Смотрел осциллографом вывод Tx, увидел только логическую 1. Неполадку обнаружить не смог. Что я сделал не так?

module Tester(
clk,
data,
oclk,
Tx
);
input wire clk;
output reg [7:0] data;
output wire oclk;
output wire Tx;

assign oclk = clk;

initial begin
data<=8'b11001010;
end

UartTransmitter UT(.clk(clk),.data(8'b11001010),.Tx(Tx),.transmit(1'b1)); 

endmodule


module UartTransmitter(
//Inputs
clk,
reset,
data,
transmit,
//Output
Tx
);
input wire clk;
input wire reset;
input wire [7:0] data;
input wire transmit;
output reg Tx;

reg [16:0] counter;
reg durum;
reg s_durum;
reg sendbyone;
reg [10:0]buffer;
reg [3:0]nbitstransmitted;

parameter IDLE = 1'b0;
parameter TRANSMITTING = 1'b1;

initial begin
    counter=0;
    Tx=1;
    s_durum = IDLE;
    durum=IDLE;
    sendbyone=0;
    buffer=0;
    nbitstransmitted=0;
end

always @(posedge clk) begin
    counter<=counter+1;
    if(counter>=13019) begin
        counter<=0;
        sendbyone<=1;
    end else begin
        sendbyone<=0;
    end
    durum<=s_durum;
end


always @(*) begin
    s_durum=durum;
    if((durum==IDLE) && (transmit==1)) begin
    buffer={1'b1,^data,data,1'b0};
    s_durum=TRANSMITTING;
    end

    else if(durum==TRANSMITTING && (sendbyone==1)) begin
        if(nbitstransmitted<10) begin
            Tx=buffer[nbitstransmitted];
            nbitstransmitted=nbitstransmitted+1;
        end else if(nbitstransmitted==10)begin
            Tx=buffer[10];
            nbitstransmitted=0;
            s_durum=IDLE;
        end
    end
end

endmodule

person user3790232    schedule 30.06.2014    source источник
comment
Вы проверяли, что вы можете фактически изменить вывод Tx, даже статически? Если вы просто установите его на 0 или 1 в зависимости от переключателя, вы увидите, как он переключается? Я бы проверил это в первую очередь.   -  person Tim    schedule 30.06.2014
comment
Tx и nbitstransmitted — предполагаемые защелки. В зависимости от синтезатора и синхронизации в состоянии TRANSMITTING может быть петля обратной связи. Попробуйте сделать nbitstransmitted триггером, так как именно здесь находится обратная связь. Я бы предпочел, чтобы Tx также был триггером, но это простой флоп, поэтому он не возмещается.   -  person Greg    schedule 30.06.2014


Ответы (1)


buffer, Tx и nbitstransmitted — предполагаемые защелки. Защелки выводятся, когда переменной не гарантируется назначение в комбинационном блоке (always @*). buffer — это простая защелка, потому что логика управления исходит от флопов. Tx будет простой защелкой после того, как nbitstransmitted будет изменен на триггер. Основной проблемой является nbitstransmitted, потому что у него есть обратная связь. С текущим дизайном в моделировании, если data изменится, когда durum==TRANSMITTING && sendbyone, то nbitstransmitted будет увеличиваться. Даже если data с флопа в том же тактовом домене, на FPGA может быть перекос в каждом бите и запускать несколько обновлений.

Сложные защелки подвержены гонкам и занимают много места. В качестве примера я скопировал код предоставления в EDAplayground и синтезировал его с помощью Yosys 0.3.0. При включенной опции «показать диаграмму» будет показано большое количество используемых логических элементов с достаточной обратной связью по защелке. Попробуйте запустить здесь (Извините, я не могу загрузить схему, может кто еще сможет)

Решение легко, если следовать той же стратегии, которая уже использовалась для durum; создать следующую переменную состояния. придерживаясь текущего соглашения, создайте новые переменные для buffer, Tx и nbitstransmitted с уважаемыми именами с префиксом s_. Комбинационный блок (always @*) будет назначать сигналы s_ и должен по умолчанию соответствовать соответствующей части. А последовательный блок (always @(posedge clk)) будет назначать флопы по их уважаемому s_. Флопы с удалением асинхронной обратной связи и упрощением конструкции. Для более чистого дизайна я переместил counter<=counter+1; в условие else и закомментировал if(nbitstransmitted==10). Попробуйте запустить здесь


Другое примечание, не связанное с проблемой:

Сигнал reset не используется. Я предлагаю использовать его в последовательном блоке и удалить блок initial. Большинство FPGA поддерживают initial, а большинство ASIC — нет. Я предпочитаю использовать сигналы сброса вместо начальных блоков, потому что это позволяет сбросить устройство без выключения и выключения питания. Просто предложение.

person Greg    schedule 30.06.2014