这是允许的吗?
input w;
input [8:0]y;
output reg [8:0]x;
always@(w)
begin
//x[0] or A is never on in any next state
assign x[0] = 0;
assign x[1]= (y[0]&~w) | (y[5]&~w) | (y[6]&~w) | (y[7]&~w) | (y[8]&~w); //B
assign x[2]= (y[1]&~w); //C
assign x[3]= (y[2]&~w); //D
assign x[4]= (y[3]&~w) | (y[4]&~w); //E
assign x[5]= (y[0]&w) | (y[1]&w) | (y[2]&w) | (y[3]&w) | (y[4]&w); //F
assign x[6]= (y[5]&w);
assign x[7]= (y[6]&w);
assign x[8]= (y[7]&w) | (y[8]&w);
end
答案 0 :(得分:9)
你可以,它被称为“程序性连续分配”。它覆盖了普通的程序分配,似乎没有在您发布的代码中调用它们。我不确定它们是否可合成,但无论如何我都没有理由使用它们。
关于您的代码的说明 - 您在敏感度列表中遗漏了y
:例如always @( w or y )
或always @(*)
更安全。
答案 1 :(得分:6)
根据Marty的回答,您应该阅读IEEE Verilog标准(例如1364-2005)的9.3节,其中描述了“程序性连续分配”。规范允许assign
块中的always
语句。但是,根据我的经验,这是非常罕见的。
您的代码的另一个问题是,我尝试使用两个不同的模拟器编译错误。两者都生成错误消息,无法在赋值的左侧使用位选择或部分选择。
另一种可能的解决方案是摆脱always
块,只使用简单的连续分配。
input w;
input [8:0] y;
output [8:0] x;
assign x[0] = 0;
assign x[1]= (y[0]&~w) | (y[5]&~w) | (y[6]&~w) | (y[7]&~w) | (y[8]&~w); //B
assign x[2]= (y[1]&~w); //C
assign x[3]= (y[2]&~w); //D
assign x[4]= (y[3]&~w) | (y[4]&~w); //E
assign x[5]= (y[0]&w) | (y[1]&w) | (y[2]&w) | (y[3]&w) | (y[4]&w); //F
assign x[6]= (y[5]&w);
assign x[7]= (y[6]&w);
assign x[8]= (y[7]&w) | (y[8]&w);
答案 2 :(得分:1)
Assign是一个连续赋值语句,与Verilog中的连线一起使用。分配语句不要进入程序块,例如总是。寄存器可以在always块中给出值。
分配语句可以视为:
always @(*)
电线的陈述。
答案 3 :(得分:1)
过程连续assign
语句旨在成为编写类似mux行为的优化方法。例如,如果您有
always @(A or B or select)
if (select)
out = A;
else
out = B;
您可以这样写
always @(select)
assign out = A;
else
assign out = B;
但是人们不喜欢必须处理敏感度列表,因此@(*)
被添加到Verilog,而SystemVerilog添加了always_comb
。
但是这种构造的真正杀手是很多人会写类似的代码
always @(*)
assign out = A;
这可以很好地模拟,但是由于assign
语句已经对A的更改敏感,所以现在您的性能受到双重惩罚,always
块也是如此。这将重复执行程序assign
语句,以替换相同的RHS。
答案 4 :(得分:0)
是的,但你不想。由于x []不依赖于x [],因此顺序无关紧要。只需使用< =而不是assign =。
答案 5 :(得分:0)
不需要在程序块中使用assign(在本例中为Always)
Assign是一个连续的赋值,它必须超出程序块。
答案 6 :(得分:0)