在Verilog案例陈述中防止锁存

时间:2011-12-05 08:39:35

标签: verilog xilinx

我无法理解如何防止在Verilog项目中创建锁存器。我知道正在创建锁存器,因为我没有指定每个case语句中所有信号的内容。但是,我不知道是否有任何方法可以避免这种情况(除了我目前使用的严苛方法)。

我目前有两个移位寄存器register Xregister R。这些移位寄存器中的每一个都有一个5位宽的控制总线,由有限状态机控制。为了便于管理这些移位寄存器,我希望利用按位运算来设置和取消设置控制总线位。

例如,在状态done中,我需要取消设置shiftRight的{​​{1}}位。为此,我可以执行以下按位操作:

register R

这完美无缺。下面,您可以看到我为寄存器控制总线定义的所有信号和按位操作。但是,由于我不需要修改每个状态下两个寄存器的所有寄存器控制总线,因此我最终得到了锁存器。例如,在下面的状态rRegisterControlBus = rRegisterControlBus & ~register_ctrl_shiftRight; 内,我只需要修改done的寄存器控制总线。结果,为register R控制总线创建了一个锁存器。

目前,我已经解决了这个问题,只需在状态机的每个状态下设置两个寄存器控制总线的所有位,抛弃我对信号执行按位操作的想法。

但是,我相信按位操作方法更干净 - 我想知道我是否还有继续使用此方法而不处理锁存器。它使代码更容易阅读和修改。

一如既往,感谢您的帮助。

register X

以前的解决方案:

// Register Control Bus Signals
// bit # - purpose
// 0 - reset (rst)
// 1 - load (ld)
// 2 - shift left (sl)
// 3 - shift right (sr)
// 4 - auxilary 1 (mux select)
parameter register_ctrl_reset = 5'b00001;
parameter register_ctrl_load = 5'b00010;
parameter register_ctrl_shiftLeft = 5'b00100;
parameter register_ctrl_shiftRight = 5'b01000;
parameter register_ctrl_auxilary = 5'b10000;
parameter register_ctrl_width = 5;
output reg [register_ctrl_width-1:0] xRegisterControlBus;
output reg [register_ctrl_width-1:0] rRegisterControlBus;

2 个答案:

答案 0 :(得分:3)

这是verilog - 你可以直接得到这些位。也许将您的参数更改为位索引:


module case_statements #( parameter REGISTER_CTRL_WIDTH = 5 ) ( input [3:0] currentState, output reg [REGISTER_CTRL_WIDTH-1:0] xRegisterControlBus, output reg [REGISTER_CTRL_WIDTH-1:0] rRegisterControlBus );

localparam REGISTER_CTRL_RESET = 0;
localparam REGISTER_CTRL_LOAD = 1;
localparam REGISTER_CTRL_SHIFTLEFT = 2;
localparam REGISTER_CTRL_SHIFTRIGHT = 3;
localparam REGISTER_CTRL_AUXILARY = 4;

localparam STATE_SHIFTLEFT = 0;  // or enum, maybe?
localparam STATE_SHIFTRIGHT = 1;
localparam STATE_DONE = 2;

always@(*)
  begin
      // Defaults:
      rRegisterControlBus = 5'd0; // or whatever
      xRegisterControlBus = 5'd0;

      // Special cases:
      case(currentState)
        STATE_SHIFTRIGHT:
          begin
              rRegisterControlBus[REGISTER_CTRL_SHIFTRIGHT] = 1'b1;
          end
        STATE_SHIFTLEFT:
          begin
              rRegisterControlBus[REGISTER_CTRL_SHIFTLEFT] = 1'b1;
          end
        STATE_DONE:
          begin
              rRegisterControlBus[REGISTER_CTRL_SHIFTRIGHT] = 1'b0;
              rRegisterControlBus[REGISTER_CTRL_SHIFTLEFT] = 1'b0;
          end
      endcase
  end

localparam REGISTER_CTRL_RESET = 0; localparam REGISTER_CTRL_LOAD = 1; localparam REGISTER_CTRL_SHIFTLEFT = 2; localparam REGISTER_CTRL_SHIFTRIGHT = 3; localparam REGISTER_CTRL_AUXILARY = 4; localparam STATE_SHIFTLEFT = 0; // or enum, maybe? localparam STATE_SHIFTRIGHT = 1; localparam STATE_DONE = 2; always@(*) begin // Defaults: rRegisterControlBus = 5'd0; // or whatever xRegisterControlBus = 5'd0; // Special cases: case(currentState) STATE_SHIFTRIGHT: begin rRegisterControlBus[REGISTER_CTRL_SHIFTRIGHT] = 1'b1; end STATE_SHIFTLEFT: begin rRegisterControlBus[REGISTER_CTRL_SHIFTLEFT] = 1'b1; end STATE_DONE: begin rRegisterControlBus[REGISTER_CTRL_SHIFTRIGHT] = 1'b0; rRegisterControlBus[REGISTER_CTRL_SHIFTLEFT] = 1'b0; end endcase end

为了避免使用锁存器,并且为了避免必须编写verilog的负载以确保每个逻辑分支设置所有变量,我使用了一种我不知道名称的技术!

我们的想法是将您在endmodule 程序中指定的任何变量设置为一组合理的默认值。'在开始。然后,您可以将这些默认值的任何偏差视为特殊情况,而不必担心确保在代码的所有分支中设置所有变量 - 它们将获得默认值'值。

答案 1 :(得分:0)

这种类型的行不适用于组合声明。

interface Car {
    String getModel();

    int getYear();

    String getColor();

    int getMaxSpeed();

    List<String> getComments();

}

public class BaseCar {
    private String model;
    private int year;

    public BaseCar(Car c) {
        this.model = c.getModel();
        this.year = c.getYear();
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

}

public class FullCar extends BaseCar {
    private String color;
    private int maxSpeed;
    private List<String> comments;

    public FullCar(Car c) {
        super(c); // Set up base car.
        this.maxSpeed = c.getMaxSpeed();
        this.color = c.getColor();
        this.comments = new ArrayList<>(c.getComments());
    }

}

public BaseCar toBaseCar(Car car) {
      return new BaseCar(car);
}

public FullCar toFullCar(Car car) {
    return new FullCar(car);
}

输入组合地影响该行的输出。该工具可以看到这一点并让您知道这是一个问题。为了使问题更加清晰,并显示该工具担心的是什么,想象一下,如果我写了:

rRegisterControlBus = rRegisterControlBus & ~register_ctrl_shiftLeft;

组合地,信号总是要反转,它将以逻辑传播的速度进行反转。我刚制作了一个振荡器,因为它永远不会进入静止状态。工具知道这可能不是我想要的东西,让我知道。