我无法理解如何防止在Verilog项目中创建锁存器。我知道正在创建锁存器,因为我没有指定每个case语句中所有信号的内容。但是,我不知道是否有任何方法可以避免这种情况(除了我目前使用的严苛方法)。
我目前有两个移位寄存器register X
和register 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;
答案 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;
组合地,信号总是要反转,它将以逻辑传播的速度进行反转。我刚制作了一个振荡器,因为它永远不会进入静止状态。工具知道这可能不是我想要的东西,让我知道。