gpt4 book ai didi

verilog - 在 Verilog 程序中使用连续赋值?

转载 作者:行者123 更新时间:2023-12-02 11:18:45 27 4
gpt4 key购买 nike

在 Verilog 程序中使用连续赋值是否可能和/或有用?例如,是否有任何理由将 assign 放在 always block 内?

例如这段代码:

always @(*) 
begin
assign data_in = Data;
end

此外,是否可以用这种方法生成顺序逻辑?

always @(posedge clk) 
begin
assign data_in = Data;
end

最佳答案

这称为过程连续赋值。它是在程序 block 中使用分配强制(及其相应的取消分配释放)。当到达程序 block 中的行时,将创建一个新的连续分配过程。 assign 可应用于寄存器类型,例如 regintegerrealforce 可以应用于寄存器和网络(即wire)。自 1364 年至 1995 年以来,它一直是 LRM 的一部分。

  • IEEE 标准 1364-1995 § 9.3
  • IEEE 标准 1364-2001 § 9.3
  • IEEE 标准 1364-2005 § 9.3
  • IEEE 标准 1800-2005 § 25.3
  • IEEE 标准 1800-2009 § 10.6
  • IEEE Std 1800-2012 §10.6

大多数工具都可以综合程序连续分配。然而,建议限制使用模拟 block 的行为建模、测试台文件或修复 RTL<-> 门功能不匹配。

  • always @* allocate data_in = Data;
    功能与
    always @* data_in = Data;
    < br/>
  • 始终@(posedge clk)分配data_in = Data;
    功能与:
    always @(posedge clk)
    enable = 1;
    always @*
    if (enable==1) data_in = Data;
    相同

程序连续赋值的有效使用应应用于以下情况:

always @(posedge clk or negedge rst_n, negedge set_n) begin
if (!rst_n) q <= 1'b0;
else if (!set_n) q <= 1'b1;
else q <= d;
end

它将合成一个具有异步设置和复位优先级的触发器。然而,在仿真中,如果 rst_n 和 set_n 都为低电平,然后 rst_n 为高电平,则模型不准确。 q 应转到 1,异步集仍处于启用状态,但敏感度列表中没有任何内容可触发。这是 Verilog 的一个有据可查的问题。这是 RTL 中允许程序连续赋值的一种情况,当与合成器的 translate off 关键字一起使用时。 release/deassign 允许以通常的方式分配寄存器/连线。

// translate_off
always @(rst_n or set_n)
if (rst_n && !set_n) force q = 1'b1;
else release q;
// translate_on

OR(当前有效但不鼓励)

// translate_off
always @(rst_n or set_n)
if (rst_n && !set_n) assign q = 1'b1;
else deassign q;
// translate_on

以这种方式使用分配/取消分配被视为在未来的 IEEE 1800 版本中被弃用。 IEEE 标准 1800-2005 § 25.3、IEEE 标准 1800-2009 § C.4.2 和 IEEE Std 1800-2012 § C.4.2 认识到以这种方式使用分配会导致困惑并且是错误的根源。如果需要过程连续赋值,请使用force/release

在使用过程连续赋值(使用force/release)的生成中,只有在绝对必要时才应使用。替代方法更可靠。

程序连续赋值的误用及解决方案:

  • reg 上的组合逻辑:

    always @(sel)
    if (sel) assign reg1 = func1(x,y,z);
    else assign reg1 = func2(a,b,c);
    • 解决方案:

      always @* // <- IEEE Std 1364-2001 construct
      if (sel) reg1 = func1(x,y,z);
      else reg1 = func2(a,b,c);
  • 线路上的组合逻辑:

    always @(sel)
    if (sel) force wire1 = func1(x,y,z);
    else force wire1 = func2(a,b,c);
    • 解决方案:

      assign wire1 = sel ? func1(x,y,z) : func2(a,b,c);
  • 顺序逻辑:

    always @(posedge clk)
    if (sel) assign reg2 = func1(x,y,z);
    else assign reg2 = func2(a,b,c);
    • 解决方案(假设原始功能错误):

      always @(posedge clk)
      if (sel) reg2 <= func1(x,y,z); // Non-blocking assignment !!!
      else reg2 <= func2(a,b,c);
    • 解决方案(假设原始功能正确):

      reg flop_sel;
      always @(posedge clk)
      flop_sel <= sel; // Non-blocking assignment !!!
      always @*
      if (flop_sel) reg2 = func1(x,y,z); // Blocking assignment !!!
      else reg2 = func2(a,b,c);

关于verilog - 在 Verilog 程序中使用连续赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23687172/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com