我正在写一个小型的大型项目的一部分。我是verilog的新手,所以任何建议都会受到赞赏。
我正在尝试编写一个case语句,一旦按下四个按钮之一,它将在四个7段显示中的第一个上写一个数字(1-4)。
module final(CLK,button1,button2,button3,button4,a0,b0,c0,d0,e0,f0,g0,a1,b1,c1,d1,e1,f1,g1,a2,b2,c2,d2,e2,f2,g2,a3,b3,c3,d3,e3,f3,g3);
input CLK,button1,button2,button3,button4;
output a0,b0,c0,d0,e0,f0,g0,a1,b1,c1,d1,e1,f1,g1,a2,b2,c2,d2,e2,f2,g2,a3,b3,c3,d3,e3,f3,g3; //What a mess
integer i = 0;
reg [6:0] temp;
reg [6:0] sevenDisp0;
reg [6:0] sevenDisp1;
reg [6:0] sevenDisp2;
reg [6:0] sevenDisp3;
reg [2:0] place;
initial begin
temp = 7'b1110111;
sevenDisp0 = 7'b1110111;
sevenDisp1 = 7'b1110111;
sevenDisp2 = 7'b1110111;
sevenDisp3 = 7'b1110111;
i = 0;
end
always @(button1 or button2 or button3 or button4)// or sevenDisp0 or sevenDisp1 or sevenDisp2 or sevenDisp3)//bit1 or bit2)
begin
case({button1,button2,button3,button4})
4'b0111: sevenDisp0 = 7'b1001111; //Have tried 4'b1111 to troubleshoot
4'b1011: sevenDisp0 = 7'b0010010;
4'b1101: sevenDisp0 = 7'b0000110;
4'b1110: sevenDisp0 = 7'b1001100;
//default: sevenDisp0 = 7'b1110111;
endcase
end
assign {a0,b0,c0,d0,e0,f0,g0} = sevenDisp0;
assign {a1,b1,c1,d1,e1,f1,g1} = sevenDisp1;
assign {a2,b2,c2,d2,e2,f2,g2} = sevenDisp2;
assign {a3,b3,c3,d3,e3,f3,g3} = sevenDisp3;
endmodule
从我的,非常有限的理解,无论何时按下我的四个按钮之一,它都会运行always语句。按下任何按钮都将被写入sevenDisp0寄存器。
有一点值得注意的是,按下时按钮会注册0,而7按0则为0。
我看到的是前七段中的头号。按下任何其他按钮将在按下按钮时显示相应的数字,然后切换回第一个按钮。
我一直试图解决这个问题6个小时了。任何帮助都会很棒。
答案 0 :(得分:0)
sevenDisp0
(电平敏感),因为未在所有可能的路径中为其分配值。您应该尝试避免使用锁存器,因为它们可能是意外行为的原因。大多数FPGA对锁存器的限制或不支持。您应该在设计中使用纯组合逻辑和触发器(时钟边沿触发)。
如果您不希望sevenDisp0
存储其值,请使用组合逻辑(使用阻止=
分配):
always @* // auto-sensitivity
begin
case({button1,button2,button3,button4})
4'b0111: sevenDisp0 = 7'b1001111; //Have tried 4'b1111 to troubleshoot
4'b1011: sevenDisp0 = 7'b0010010;
4'b1101: sevenDisp0 = 7'b0000110;
4'b1110: sevenDisp0 = 7'b1001100;
default: sevenDisp0 = 7'b1110111; //Needed or will be a latch
endcase
end
如果你确实希望sevenDisp0
存储它的值,那么通过在时钟边沿触发来使用make it sequential(使用非阻塞<=
赋值):
always @(posedge CLK)
begin
case({button1,button2,button3,button4})
4'b0111: sevenDisp0 <= 7'b1001111; //Have tried 4'b1111 to troubleshoot
4'b1011: sevenDisp0 <= 7'b0010010;
4'b1101: sevenDisp0 <= 7'b0000110;
4'b1110: sevenDisp0 <= 7'b1001100;
//default: //Retain previous value of sevenDisp0
endcase
end
仅供参考:对于组合(和有意锁存)逻辑,您应该使用自动敏感度@*
或同义@(*)
。仅当需要遵循Verilog-1995标准时,才需要灵敏度列表中的硬编码信号。由于Verilog-2001 @*
是首选,因为它没有丢失信号的风险,导致RTL仿真和门/ FPGA /等之间的行为不匹配。而且它的打字明显减少了。
另一个建议是使用ANSI样式标题(Verilog-2001中添加的另一个功能)。这允许您在端口列表顺序中声明端口方向和类型。打字也少了。例如:
module final(
input CLK,
input button1,button2,button3,button4,
output a0,b0,c0,d0,e0,f0,g0, // much
output a1,b1,c1,d1,e1,f1,g1, // easier
output a2,b2,c2,d2,e2,f2,g2, // to
output a3,b3,c3,d3,e3,f3,g3 ); // read
reg [6:0] sevenDisp0;
// ...