Всегда блокировать игнорирование - PullRequest
1 голос
/ 19 января 2012

В рамках более крупной программы я хотел бы активировать зеленые светодиоды по одному на моей плате DE2 в их порядке (от 0 до 8), когда я нажимаю KEY [1]. Они должны выключаться по одному в обратном порядке, когда я нажимаю KEY [2]. Я почти уверен, что клавиши платы DE2 активны на низком уровне. Это мой код:

always@(negedge KEY[1], negedge KEY[2])
begin

    if(~KEY[1])
    begin
        LEDGValue <= LEDGValue << 1;
        LEDGValue[0] <= 1;
    end

    else if(~KEY[2]) 
        LEDGValue[0] <= LEDGValue >> 1;

end

Вместо этого все зеленые светодиоды загораются, как только я загружаю программу. На данный момент KEY [1] и KEY [2] не имеют никакого эффекта. Кто-нибудь видит что-то не так с моим кодом?

Ответы [ 3 ]

2 голосов
/ 19 января 2012

Вот детектор контуров.

module edge_detector (
    input wire clk,
    input wire in,
    output wire negedge_out
);

reg in_reg= 1'b0;

wire in_next = in;

assign negedge_out = ({in_reg,in) == 2'b10);

always @(posedge clk) in_reg <= in_next;

endmodule

Вот как вы используете детектор контуров.

reg [8:0] LEDGValue = 0, LEDGValue_next;

wire key1_edge;
wire key2_edge;

edge_detector
key1_edge_detector_inst (
    .clk(clk),
    .in(KEY[1]),
    .negedge_out(key1_edge)
);

edge_detector
key2_edge_detector_inst (
    .clk(clk),
    .in(KEY[2]),
    .negedge_out(key2_edge)
);

always @* begin : combinational_logic
    LEDGValue_next = LEDGValue;
    if (key1_edge)
        LEDGValue_next = {LEDGValue[7:0], 1'b1};
    else if (key2_edge)
        LEDGValue_next = {1'b0, LEDGValue[8:1]};
end

always @(posedge clk) begin : sequential_logic
    LEDGValue <= LEDGValue_next;
end

Ключ в том, что сигналы key1_edge и key2_edge утверждаютсятолько для одного такта.

0 голосов
/ 19 января 2012

Должно быть

 always@(negedge KEY[1] OR negedge KEY[2])
0 голосов
/ 19 января 2012

Я не Verilogger, но похоже, что вы просите код вызвать края двух разных сигналов. По моему опыту, это невозможно синтезировать, но синтезатор, возможно, пытался что-то и предупреждал вас (среди множества других предупреждений), что он сделал что-то другое, чем вы на самом деле имели в виду.


РЕДАКТИРОВАТЬ: Следующее не относится к упомянутой плате, так как на ней установлено оборудование для устранения неполадок (спасибо NathanFarrington за указание на это), но я оставляю это здесь на случай, если оно пригодится другим читателям:


Даже если синтезатор преуспел, запуск по фронту на входе переключателя является ужасной идеей: переключатель будет несколько раз отскакивать при нажатии, и FPGA достаточно быстро, чтобы увидеть все эти края .

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

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

Как только счетчик достигнет любого конца своего «путешествия», только , затем вы предпринимаете какие-либо действия (например, сдвигаете LEDGValue). Не забудьте подождать, пока выключатель не будет отпущен (ожидая, пока счетчик перейдет на другой «конец»).

...