Verilog似乎默认了case语句中的一个选项

时间:2017-12-05 21:04:04

标签: case verilog

我正在写一个小型的大型项目的一部分。我是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个小时了。任何帮助都会很棒。

1 个答案:

答案 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;
// ...