2016-11-30 61 views
0

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

下面是代码:

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; 

[email protected](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 
+0

尝试'我<(N-1)'而不是'我 noobuntu

+0

@noobuntu我试过了,它抛出了另一个错误,说“循环必须在5000次迭代内终止” – user7231602

+0

这通常是用for-循环。为什么认为这是不可能的? – toolic

回答

1

的问题不在于j,你可以很容易地解决这个问题,通过改变其声明的参数:

parameter j = N -1; 

真正的问题是i和您正在使用非阻止分配到i。所以while进入无限循环,因为(i<j)从来没有机会改变 - 它总是0.

您将需要一个不同的方法来解决这个问题。

0

几个问题:

  1. iknext被定义为单位。他们的价值不能超过一个。声明为:

    parameter j = N - 1; 
    bit [$clog2(N):0] next = 1; 
    bit [$clog2(N):0] i = 0; 
    logic [2:0] k = 0; 
    
  2. 当您指定iknext你需要使用阻塞赋值(=)。非阻塞(<=)推迟更新;每个循环将评估i<j,k>0,i + 1;与他们的前negedge KEY0价值。

  3. 阻塞赋值也应该在你的任务用于movebits出于同样的原因为iknext

  4. inext需要设置为0和1,每个回路k

  5. bits被分配两个不同的总是块,因此它不能合成。

  6. k环不能静态UNROLL这也意味着它不会合成

可以通过从[email protected](negedge KEY0)的循环逻辑移入的底部解决分2,3,4,和5 always_comb已经指定bits。然后将非阻塞更改为阻止已移动的逻辑。

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

我猜这是一个任务,你的老师要求你做一个没有for-loops的移位器。有一种方法可以在没有任何循环的情况下完成这项任务,并且可以减少比目前少得多的代码和变量。我不会给你代码,因为我认为这是作业。我会建议考虑和比较的概念:

  • 降档(>>)和算术降档(>>>)运营商
  • 部分选择解决

    • case语句(+:),也可以被称作范围切片

    您可能还需要对位级联(例如:{a,b})读取并复制器(例如:{4{1'b1}})。