我有一个总是涉及开关和键的块。当我只有灵敏度列表中的键时,它表现良好(只执行一次代码然后退出块)。当我将开关添加到灵敏度列表时,它变得疯狂,并且在我按住键的同时似乎无限循环,即使我只在按键的按键上触发它。
我正在尝试实施一个只在每次按键时递增一次的计数器。
以下是只有灵敏度列表中的键的工作代码(sw [1]用于指示它是向上还是向下计数):
always @ (negedge key[2]) begin
if (~key[2])
begin
if (sw[1] == 0) begin
if (p3ctr == 15) p3ctr = 0;
else p3ctr = p3ctr + 1;
end
else if (sw[1] == 1) begin
if (p3ctr == 0) p3ctr = 15;
else p3ctr = p3ctr - 1;
end
end
end
这是破碎的代码(我正在使用sw [7]在计数器被切换时重置计数器。此代码无限循环,而按键[2]被按下)
always @ (negedge key[2] or posedge sw[7]) begin
if (~key[2])
begin
if (sw[1] == 0) begin
if (p3ctr == 15) p3ctr = 0;
else p3ctr = p3ctr + 1;
end
else if (sw[1] == 1) begin
if (p3ctr == 0) p3ctr = 15;
else p3ctr = p3ctr - 1;
end
end
else begin
p3ctr = 0;
end
end
我认为只有当灵敏度列表中的信号发生变化时,始终阻止的代码才会被执行一次,但显然情况并非如此。
我知道如何在每次按键时只执行一次此代码,以便计数器正常运行吗?
谢谢!
答案 0 :(得分:2)
我假设在FPGA上运行时会出现问题;一个纯粹的模拟似乎很好。综合工具假设第一个if
是异步逻辑,else
条件被视为同步逻辑,因为这是正确的编码风格。在提供的代码中,第一个条件是if (~key[2])
,这意味着综合工具将negedge key[2]
视为活动的低异步逻辑。从重置条件if (sw[7])
开始,您应该得到所需的结果。
always @ (negedge key[2] or posedge sw[7]) begin
if (sw[7]) begin
p3ctr <= 0;
end
else begin
if (sw[1] == 0) begin
if (p3ctr == 15) p3ctr <= 0;
else p3ctr <= p3ctr + 1;
end
else if (sw[1] == 1) begin
if (p3ctr == 0) p3ctr <= 15;
else p3ctr <= p3ctr - 1;
end
end
end
注意:在触发器中使用非阻塞分配(<=
)的最佳做法。阻止分配(=
)用于组合逻辑。