使用三元运算符的异常行为(Verilog)

时间:2018-11-25 14:10:38

标签: verilog

在下面的Verilog模块中,我想了解为什么使用串联的阻塞分配不会产生与2个注释掉的阻塞分配相同的结果。

当我在FPGA上运行程序时,它通过2个阻塞分配(指示灯闪烁)给出了预期的结果,但没有通过串联的阻塞分配(指示灯保持关闭状态)的预期结果。

奖励指向指向Verilog规范的答案,以解释此处的作用!

/* Every second, the set of leds that are lit will change */
module blinky(
input clk,
output [3:0] led
);
    reg [3:0] count = 0;
    reg [27:0] i = 0;
    localparam [27:0] nTicksPerSecond = 100000000;

    assign led = {count[3],count[2],count[1],count[0]};

    always @ (posedge(clk)) begin
        // This works:
        //count = i==nTicksPerSecond ? (count + 1) : count;
        //i     = i==nTicksPerSecond ? 0 : i+1;

        // But this doesn't:
        {count,i} = i==nTicksPerSecond ? 
          {count+1, 28'b0  } :
          {count  , i+1};
    end
endmodule

PS:我使用的是Vivado 2018.2

1 个答案:

答案 0 :(得分:2)

原因是因为count+1i+1的宽度均为32位。无大小的数字为32位宽(1800-2017 LRM第5.7.1节),加法运算符的宽度为最大操作数的大小(LRM第11.6.1节)。要使代码正常工作,请在数字文字中添加适当的大小

 {count,i} = i==nTicksPerSecond ? 
          {count+4'd1, 28'b0  } :
          {count  , i+28'd1};

编写此代码的一种更简单的方法是

  always @ (posedge clk) 
      if (i== nTicksPerSecond)
         begin 
           count <= count + 1;
           i <= 0;
         end
      else
         begin
           i <= i + 1;
         end