2014-09-20 146 views
1

我在这里给出2个Verilog模块,它们在模拟过程中表现相同。但我不明白为什么要在这些模块中使用assign/deassign,即这两个代码有什么区别?Verilog中需要分配/取消分配?

// Code 1 - Without assign-deassign 
module dff (q,qbar,clk,reset,d) 
    input clk, reset, d; 
    output reg q, qbar; 

    always @ (posedge reset, negedge clk) 
    begin 
    if(reset) 
    begin 
     q=1; 
     qbar=0; 
    end 
    else 
    begin 
     q=d; 
     qbar=~d; 
    end 
    end 
endmodule 

// Code 2 - With assign-deassign 
module dff (q,qbar,clk,reset,d) 
    input clk, reset, d; 
    output reg q, qbar; 

    always @ (negedge clk) 
    begin 
    q=d; 
    qbar=~d; 
    end 

    always @ (reset) 
    begin 
    if(reset) 
    begin 
     assign q=1; 
     assign qbar=0; 
    end 
    else 
    begin 
     deassign q; 
     deassign qbar; 
    end 
    end 
endmodule 
+0

IEEE Std 1800-2012对使用'deassign'有何评论? – toolic 2014-09-20 13:53:33

+0

因为只有我很困惑,使用取消分配的效果可以被删除。但我不知道它们究竟在哪里可以使用? – 2014-09-20 14:29:13

回答

2

您的示例中过程分配/取消分配语句的最初目的是在两个不同的过程中将同步逻辑与异步逻辑分开。这对于仿真更有效,因为同步模块不必在每个时钟周期检查一次复位信号。建模锁存器对于仿真也更高效,因为每次数据更改时都不必检查使能信号,只有在锁存器打开时才能检查使能信号。

这种结构可以通过早期合成工具合成,但不幸的是,合成供应商决定不支持它,因此没有人再使用这些程序结构。

+0

是的,但后来假设分配deassign,如果两个事件同时发生,那么会不会给多个驱动程序错误?在第一代码中,情况并非如此。 – 2014-09-21 04:39:39

+0

程序控制**分配**优先于正常的程序分配。 – 2014-09-21 14:20:52

+0

好的,非常感谢@ dave_59的答案。 – 2014-09-21 14:33:32

1

而不assign该语句是一个@边缘块内,并在该边缘被评估assign描述了组合连续逻辑,并且根据定义对其输入敏感。

Code 1q将改变只有当clkreset变化,而不是d变化时。

Code 2具有当reset被断言,此块将继续推动q=1效果(与任何其他驱动程序冲突的),但是当复位被否定,它就会停止驾驶q

这实际上可能是更为不寻常的用途,可能是在@edge块内分配。

更常规使用会像

assign out = (enable) ? data : 1'bz; 

这将改变每当启用或数据的变化。

+0

另外,如果我没记错的话,程序性的'assign/deassign'结构会被标记为废弃(至少在SystemVerilog中),所以最好不要使用它们。 – 2014-09-20 06:40:51

+0

是的我知道连续赋值语句,我只是想知道在代码中使用过程连续赋值 - 赋值是什么? &他们可以在哪里使用? – 2014-09-20 07:05:38