NEXYS 4: пропадание сигнала по проводу при инициализации порта

Я пытаюсь сделать секундомер, который может считать от 0:00,0 до 9:99,9 с точностью (1/10) секунды.

Мой секундомер работает, присваивая каждой цифре собственный двоичный счетчик (предоставленный IP-каталогом Vivado), который работает с часами и включает сигнал. Когда конкретная цифра сбрасывается обратно на ноль (например, при переходе от 9 к 0), она посылает импульс следующей цифре, сообщая ей, что нужно считать на единицу.

Я выделил каждой цифре свой модуль и соединил порты друг с другом через верхний модуль.

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

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

ЦИФРА 1 МОДУЛЬ:

// module that contains both digit 1 counter and decimal converter
module digit_1(
    input clk_10_Hz, clk_100_Hz, reset,
    output [7:0] digit_1_out,
    output [3:0] Q_1
    );

    c_counter_binary_9_count COUNTER_9 (.CLK(clk_100_Hz),.CE(clk_10_Hz),.SCLR(reset),.Q(Q_1));
    digit_1_bcd_to_decimal CONVERTER_DIGIT_1 (.Q_1,.clk_100_Hz,.digit_1_out);

endmodule

ЦИФРОВОЙ 2 МОДУЛЬ:

// module that contains both digit 2 counter and decimal converter
module digit_2(
    input clk_100_Hz, reset,
    input [3:0] Q_1,
    output [7:0] digit_2_out,
    output [3:0] Q_2
    );

reg THRESH1;
reg test_CE_2;

c_counter_binary_9_count COUNTER_9 (.CLK(clk_100_Hz),.CE(test_CE_2),.SCLR(reset),.Q(Q_2));
digit_2_bcd_to_decimal CONVERTER_DIGIT_2 (.Q_2,.clk_100_Hz,.digit_2_out);

// ensures that clock pulse will only be length of 100 Hz clock pulse 
always @ (negedge clk_100_Hz)
    if (Q_1 == 4'h9)
        THRESH1 = 1;
    else
        THRESH1 = 0;

always @ (posedge clk_100_Hz)
    if (THRESH1)
        begin
        if (Q_1 == 4'h0)
            test_CE_2 = 1;
        else
            test_CE_2 = 0;
        end
    else
        test_CE_2 = 0;

endmodule

ВЕРХНИЙ МОДУЛЬ:

// TOP module - combines all the other modules with each other
module stop_watch(
    input clk_100_MHz, reset, enable,
    output [7:0] an, display
    );

    wire clk_10_Hz, clk_100_Hz, clk_250_Hz;
    wire [7:0] digit_1_out ,digit_2_out,digit_3_out,digit_4_out; // connects digit outputs with display selector

    wire [3:0] Q_1, Q_2, Q_3; // connects outpus of binary counter with inputs of others

    clock CLOCK (.clk_100_MHz,.enable,.clk_10_Hz,.clk_100_Hz,.clk_250_Hz);

    digit_1 DIGIT_1 (.clk_10_Hz,.clk_100_Hz,.reset,.Q_1,.digit_1_out);
    digit_2 DIGIT_2 (.clk_100_Hz,.reset,.Q_1,.Q_2,.digit_2_out);
    digit_3 DIGIT_3 (.clk_100_Hz,.reset,.Q_2,.Q_3,.digit_3_out);
    digit_4 DIGIT_4 (.clk_100_Hz,.reset,.Q_3,.digit_4_out);

    anode_frequency ANODE_FREQUENCY (.clk_250_Hz,.an);
    display_selector DISPLAY_SELECTOR (.an,.digit_1_out,.digit_2_out,.digit_3_out,.digit_4_out,.display);

endmodule

Весь код составляет около 400 строк, поэтому я поместил только те части, которые представляют интерес, но я мог бы поместить весь код, если потребуется.

Я использую Vivado 2014.1, а плата FPGA — NEXYS 4.


person PizzaWenisaur    schedule 26.06.2015    source источник


Ответы (1)


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

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

if (Q_1 == 9 && Q_1_Enable)
  Q
/*  always @ (negedge clk_10_Hz) *No need for edge-triggered* */
always @ (*)
begin
   // Q_1_Enable is always 1(true) if using a 10 Hz clock
   if (Q_1 == 9)
     Q_2_Enable = 1;
   else 
     Q_2_Enable = 0;
   if (Q_2 == 9 && Q_2_Enable)
     Q_3_Enable = 1;
   else
     Q_3_Enable = 0;
   if (Q_3 == 9 && Q_3_Enable)
    ...
Enable = 1; else Q
/*  always @ (negedge clk_10_Hz) *No need for edge-triggered* */
always @ (*)
begin
   // Q_1_Enable is always 1(true) if using a 10 Hz clock
   if (Q_1 == 9)
     Q_2_Enable = 1;
   else 
     Q_2_Enable = 0;
   if (Q_2 == 9 && Q_2_Enable)
     Q_3_Enable = 1;
   else
     Q_3_Enable = 0;
   if (Q_3 == 9 && Q_3_Enable)
    ...
Enable = 0;

Таким образом, счетчик 2 увеличивает один и тот же счетчик циклов, переходя от 9 к > 0.

Наконец, если ваши часы с частотой 10 Гц не находятся в рабочем цикле 10%, ваш счетчик «децисекунд» будет фактически увеличиваться 5 раз в секунду вместо 1 раза в полусекунду. Несмотря на это, может быть лучше - если у вас есть возможность - использовать только тактовую частоту 10 Гц для всех счетчиков, после чего ваши сигналы включения становятся простыми.

/*  always @ (negedge clk_10_Hz) *No need for edge-triggered* */
always @ (*)
begin
   // Q_1_Enable is always 1(true) if using a 10 Hz clock
   if (Q_1 == 9)
     Q_2_Enable = 1;
   else 
     Q_2_Enable = 0;
   if (Q_2 == 9 && Q_2_Enable)
     Q_3_Enable = 1;
   else
     Q_3_Enable = 0;
   if (Q_3 == 9 && Q_3_Enable)
    ...
person wilcroft    schedule 28.06.2015
comment
Лучше всего, если вы сможете запускать всю свою логику на одних и тех же часах и на одном краю. Если вы делите часы, то вы должны учитывать дополнительный сдвиг часов между связанными доменами часов. Поскольку ваши часы очень медленные, вы можете обойтись без использования противоположных фронтов, но обычно использование противоположных фронтов просто съедает половину вашего временного запаса. - person Barry Moss; 29.06.2015
comment
Справедливая точка на краях - оглядываясь назад, сигналы включения не должны запускаться по краям; нет смысла их регистрировать. Думаю, обычный always @(*) подойдет. Что касается использования часов 10 Гц, мы надеемся, что OP использует PLL / DLL для генерации часов 10 Гц / 100 Гц, что должно минимизировать любой перекос. - person wilcroft; 29.06.2015
comment
Хорошо, милая, это сработало. Я понял (более или менее) то, что вы сказали. Моя тактовая частота 10 Гц работала нормально (я принял во внимание, что ширина импульса была достаточно малой, чтобы запускать тактовую частоту 100 Гц только один раз), но мои временные ограничения были испорчены. Так что ваши первый и второй советы действительно помогли. СПАСИБО ВАМ, РЕБЯТА! РЕДАКТИРОВАТЬ: Да, моя петля 10 Гц была синхронизирована по фазе. @барримосс - person PizzaWenisaur; 29.06.2015
comment
Отметить ответ как принятый и/или проголосовать за него — хороший способ показать, что было полезно :) - person wilcroft; 29.06.2015