Verilog:你能在always @或begin / end语句中加上“assign”语句吗?

时间:2009-10-29 01:39:53

标签: verilog

这是允许的吗?

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

7 个答案:

答案 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)

  1. 从电路级别思考:这总是(w)开始.....结束,因此每当w发生改变时,它内的每个代码都会被激活,即它会下降或上升。
  2. assign语句需要将其分配给某些连线或reg输出的引脚/端口
  3. 它是一个完整的组合电路我无法看到同样只会在w处激活,那就是谁/什么电路只会在w上升或下降时改变
  4. 无论如何你不能使用assign语句将一个reg输出分配给某些wire / reg输出,因为正如我所说的,它要求你只需要分配引脚/端口
  5. 无论如何,如果你选择基本的verilog而不是所谓的“程序性连续分配”,我猜它使用相同的奇怪。