2016-06-20 9 views
0

Следующий код реализует (или должен реализовывать) 7-сегментный драйвер, который считывает значение с некоторых коммутаторов и показывает это значение в сегменте 4 7 сегментов. Симуляция работает нормально, но когда она работает в FPGA, 7-сегментные дисплеи показывают что-то в течение доли времени, и тогда ни один сегмент не загорается. Я понятия не имею, почему это не работает. Кроме того, я реализовал простой счетчик. Когда у меня было «< =» внутри всегда блокирует его, и когда у меня было «=», это не так, но в симуляции он работал с обоими. Разница между «< =» и «=» заключается в том, что «< =» работает параллельно и «=» в последовательности?FPGA (Verilog) - Работа в симуляции, но не работающая на FPGA

Я также должен сказать, что он работает, если вместо отправки значения из переключателей в модуль отображения я отправляю постоянное значение.

display.v:

module display(
    input [15:0] count, 
    output reg [6:0] seg, 
    output dp, 
    output [3:0] an, 
    input clk 
    ); 

reg [3:0] an_temp; 
reg [6:0] rom [9:0]; 

initial 
begin 
    an_temp <= 1; 
    rom[0] <= 'b1000000; 
    rom[1] <= 'b1111001; 
    rom[2] <= 'b0100100; 
    rom[3] <= 'b0110000; 
    rom[4] <= 'b0011001; 
    rom[5] <= 'b0010010; 
    rom[6] <= 'b0000010; 
    rom[7] <= 'b1111000; 
    rom[8] <= 'b0000000; 
    rom[9] <= 'b0110000; 
end 

assign dp = 1; 
assign an = ~an_temp; 

wire [3:0] disp [3:0]; 

assign disp[0] = count % 10; 
assign disp[1] = ((count - disp[0])/10) % 10; 
assign disp[2] = ((count - disp[1]*10 - disp[0])/100) % 10; 
assign disp[3] = ((count - disp[2]*100 - disp[1]*10 - disp[0])/1000) % 10; 

always @ (posedge clk) 
begin 
    if (an_temp == 'b1000) an_temp = 1; 
    else an_temp = an_temp = 1; 
    case (an_temp) 
     'b0001: seg <= rom[disp[0]]; 
     'b0010: seg <= rom[disp[1]]; 
     'b0100: seg <= rom[disp[2]]; 
     'b1000: seg <= rom[disp[3]]; 
     default: seg <= 'b1111111; 
    endcase 
end 

endmodule 

disp_clk.v:

module disp_clk(
    input clk, 
    output disp_clk 
    ); 

reg [31:0] count; 

initial count = 0; 

always @ (posedge clk) 
begin 
    count = count + 1; 
    if (count == 400000) count = 0; 
end 

assign disp_clk = (count > 200000) ? 1 : 0; 

endmodule 

top.v:

module top(
    input clk, 
    input [15:0] sw, 
    output [6:0] seg, 
    output dp, 
    output [3:0] an 
    ); 

wire disp_clk; 

disp_clk disp_clk0(
    .clk(clk), 
    .disp_clk(disp_clk) 
    ); 

display disp0(
    .count(sw), 
    .seg(seg), 
    .dp(dp), 
    .an(an), 
    .clk(disp_clk) 
    ); 

endmodule 

Спасибо

+1

Это выглядит странно: 'else an_temp = an_temp = 1;' – toolic

+0

Извините, так оно и появилось после копирования. Правильно: else an_temp = an_temp << 1; –

+0

Это работает, если я заменил sw на некоторую константу в верхнем модуле. –

ответ

0

Я также скажем, что он работает, если вместо отправки значения от переключатели на модуль отображения посылают постоянное значение.

Похоже, вы не встречаете свое временное окно. Если count является постоянным вектором, то все назначения должны быть предварительно вычислены в синтезе. В противном случае они должны вычисляться «на лету», и логика логики выводится (что довольно медленно).

((count - disp[2]*100 - disp[1]*10 - disp[0])/1000) % 10 имеет множитель, подающий в подразделение, подаваемое в другое подразделение. Можно было бы надеяться, что это будет выведено как каскадные DSP, но вы должны проверить свой отчет о ресурсе, чтобы убедиться, и в качестве дополнительной проверки работоспособности убедитесь, что количество ресурсов для постоянной или переключение сигнализации показывает разницу.

Возможно, вам понадобится выполнить эти операции, если вы не можете думать о более оптимальной логике.

Разница между «< =» и «=» только что «< =» работает параллельно и «=» в последовательности?

Да, в некотором смысле. <= и = относятся к неблокирующие и блокировка присвоений соответственно.

Симулятор будет вычислять логическое назначение на каждом шаге.

Для неблокирующей, правая часть вычисляется и может быть обновлена ​​позже в шаге времени, если она логически зависит от другой сигнализации, а затем непосредственно перед началом следующего шага по времени, левая часть всего неблокирующие назначения назначаются обновленной правой стороне.

В назначении блокирования, тренажер будет оценивать правую часть и сразу же назначить его на левую сторону, таким образом, другая логикой является блокирован от изменения назначения.

Вы можете считать это последовательным, но имейте в виду, что последовательность истинна только в пределах функциональный блок. Если у вас есть два всегда блока, которые выполняют зависящие друг от друга оценки на одном и том же шаге, вам не гарантируется, какой блок сначала будет оценивать симулятор, и вы можете увидеть какое-то причудливое поведение, основанное на том, как симулятор выполняет его планирование.

Лучшая практика заключается в использовании блокирующего задания для поведения, которые предназначены, чтобы быть комбинаторными (т.е. [email protected](*)) и неблокирующие задания для тех, которые предназначены, чтобы быть последовательными (т.е. [email protected](posedge Clock)).

+0

Спасибо! Я попытался уменьшить тактовую частоту дисплея, чтобы увидеть, сохраняется ли проблема. Я сократился до секунды, чтобы я мог видеть, что происходит. Первый и третий сегментные дисплеи находятся на большем количестве времени, чем остальные 2 дисплея. Остальные 2 дисплея отображаются только на мгновение. Почему это происходит? Если бы это было из-за проблем с синхронизацией, тогда это не произошло бы с такими медленными часами. –

+0

Когда я увеличиваю скорость часов до обычной частоты, только первый и третий сегменты включаются. Это подтверждается медленными часами, первый и третий сегменты в большинстве случаев, а остальные 2 - мгновенно. –

+0

Это может быть проблема с тем, как синтезируется ваш счетчик звонков. Попробуйте заменить этот код: 'если (an_temp ==«B1000) an_temp = 1; '' еще an_temp = an_temp = 1; ' с этим: ' an_temp <= {an_temp [2: 0 ], an_temp [3]}; ' - это более простой код и более непосредственно описывает поведение колебаний колец, которое вы хотите. – bnd

Смежные вопросы