始终阻止被忽略

时间:2012-01-19 00:46:59

标签: verilog

作为大型程序的一部分,当我按下KEY [1]时,我想按顺序(0到8)在我的DE2板上一次激活一个绿色LED。当我按下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

相反,加载程序后,所有绿色LED指示灯都会亮起。此时KEY [1]和KEY [2]无效。有人看到我的代码出了问题吗?

3 个答案:

答案 0 :(得分:2)

这是一个边缘检测器。

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_edgekey2_edge信号仅在一个时钟周期内被置位。

答案 1 :(得分:0)

我不是Verilogger,但看起来你要求代码触发两个不同的信号的边缘。这不是我的经验合成,但合成器可能会尝试某些并警告你(在众多其他警告之中)它已经完成了除了你真正意义之外的事情。


编辑:以下内容不适用于所提及的电路板,因为它已经在板上展示了硬件(感谢NathanFarrington指出了这一点)但是我把它放在这里以防它对其他读者有用:


即使合成器成功,开关输入上的边沿触发也是一个可怕的想法:the switch will bounce several times当你按下它时,FPGA很快就足以看到所有这些边缘。

您需要的是一个由良好的时钟源(毫无疑问是板上的水晶)提供时钟的过程,它可以在每个时钟事件中监控您的开关信号。

为每个信号保留一个计数器,每次信号为1时递增计数器,每次信号为0时递减计数器。将这些计数器钳制在0和一些最大时间,这样可以让开关有足够的时间来稳定(几毫秒可能就足够了)。

一旦计数器到达“旅行”的任何一端,只有然后你会采取一些行动(比如转移你的LEDGValue)。请记住等待之后释放开关(等待计数转到另一个'结束')。

答案 2 :(得分:-1)

应该是

 always@(negedge KEY[1] OR negedge KEY[2])