虽然循环具有非恒定循环条件,但使用参数

时间:2016-11-30 15:37:04

标签: parameters while-loop system-verilog

我目前正在尝试使用两个while循环编译一个移位器。 For循环,移位功能和日志功能是不可能的。但是,当我尝试编译它时,它会在指示的行处抛出一个“带有非恒定循环条件的循环”错误。该行的while条件是i <1。 j,其中j是N-1,N是参数。我的问题是,由于N是一个参数,为什么即使在编译时它也不是常量,因此被认为是一个恒定的循环条件?

以下是代码:

module shifter(input logic [0:0] SW0, SW1, SW2, SW3, SW4, SW5, SW6, SW7, SW8, SW9, SW10,
               input logic [0:0] KEY0, KEY1,
                    output logic [0:0] LEDG0, LEDG1, LEDG2, LEDG3, LEDG4, LEDG5, LEDG6, LEDG7);
parameter N=8;          

//receive input from switches

logic [7:0] bits = '0;
logic [7:0] out = '0;
logic [0:0] move = '0;
logic [2:0] shift = '0;
logic next = 1;

always_comb
  begin
    bits[7] = SW7[0];
    bits[6] = SW6[0];
    bits[5] = SW5[0];
    bits[4] = SW4[0];
    bits[3] = SW3[0];
    bits[2] = SW2[0];
    bits[1] = SW1[0];
    bits[0] = SW0[0];
    shift[2] = SW10[0];
    shift[1] = SW9[0];
    shift[0] = SW8[0];
  end 

logic i = 0;     
logic k = 0;
logic [31:0] j = N - 1;

always@(negedge KEY0)
    begin
      k <= shift[2:0];
      do 
         begin
            move <= bits[0];
            do 
              begin 
                 bits[i] <= bits[next];
                 i <= i + 1;     
                 next <= i + 1;
              end    
            while (i < j); //<-------indicated line
            bits[7] <= move;
            k <= k - 1;
         end
      while(k > 0);
      out <= bits; 
    end

always_comb 
  begin
      LEDG0 = out[0];
      LEDG1 = out[1];
      LEDG2 = out[2];
      LEDG3 = out[3];
      LEDG4 = out[4];
      LEDG5 = out[5];
      LEDG6 = out[6];
      LEDG7 = out[7];
  end 

endmodule  

2 个答案:

答案 0 :(得分:1)

问题不在于j,您可以通过将其声明更改为参数来轻松解决此问题:

parameter j = N -1;

真正的问题在于i,并且您正在使用i的非阻止分配。因此while进入无限循环,因为(i<j)永远不会有机会改变 - 它总是为0。

您需要采用不同的方法解决此问题。

答案 1 :(得分:0)

几个问题:

  1. iknext被定义为单个位。它们不能保持高于1的值。将它们声明为:

    parameter j = N - 1;
    bit [$clog2(N):0] next = 1;
    bit [$clog2(N):0] i = 0;
    logic [2:0] k = 0;
    
  2. 分配iknext时,您需要使用屏蔽分配(=)。非阻塞(<=)推迟更新;每个循环将评估i<jk>0i + 1;及其前negedge KEY0值。

  3. 出于与movebitsi相同的原因,还应在knext的作业中使用屏蔽作业。 。

  4. inext需要为k的每个循环设置为0和1。

  5. bits分配了两个不同的always块,因此无法合成。

  6. k循环不能静态展开,这也意味着它不会合成

  7. 您可以通过将循环逻辑从always@(negedge KEY0)移动到已分配always_comb的{​​{1}}的底部来解决第2,3,4和5点。然后将非阻塞更改为阻止移动的逻辑。

    据我所知,并非每个合成器都支持while循环。即使您的合成器支持while循环,它也必须静态展开;所有可合成循环的要求。

    我猜这是一个任务,你的教练要求你做一个没有for循环的移位器。有一种方法可以在没有任何循环的情况下完成这项任务,并且可以使用比现在少得多的代码和变量行来减少它。我不会给你代码因为我认为这是作业。我建议调查并比较以下概念:

    • bits陈述
    • 降档(case)和算术降档(>>)运算符
    • 部分选择寻址(>>>),也可称为范围切片

    您可能还想阅读比特连接(例如:+:)和复制器(例如:{a,b})。