作为大型程序的一部分,当我按下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]无效。有人看到我的代码出了问题吗?
答案 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_edge
和key2_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])