Количество бит для определенного числа в Verilog - PullRequest
0 голосов
/ 09 июля 2019

Пожалуйста, смотрите мой код испытательного стенда Verilog ниже.На самом деле я хотел заменить все операторы if-else одним или двумя выражениями.Код, как этот, выглядит очень свободно и грязно.Может кто-нибудь сказать, как я могу сделать этот код немного более компактным.Обратите внимание, что переменные 'i' и 'len' находятся в фокусе.

module xyz();

......
....some parts and variable declarations;
......


initial begin
for(i = 1; i <= 65535; i = i+1) begin
    if        (i <= 1)               len = 1;
    else if   (i>1 & i <= 3)         len = 2;
    else if   (i>3 & i <= 7)         len = 3;
    else if   (i>7 & i <= 15)        len = 4;
    else if   (i>15 & i <= 31)       len = 5;
    else if   (i>31 & i <= 63)       len = 6;
    else if   (i>63 & i <= 127)      len = 7;
    else if   (i>127 & i <= 255)     len = 8;
    else if   (i>255 & i <= 511)     len = 9;
    else if   (i>511 & i <= 1023)    len = 10;
    else if   (i>1023 & i <= 2047)   len = 11;
    else if   (i>2047 & i <= 4095)   len = 12;
    else if   (i>4095 & i <= 8191)   len = 13;
    else if   (i>8191 & i <= 16383)  len = 14;
    else if   (i>16383 & i <= 32767) len = 15;
    else if   (i>32767 & i <= 65535) len = 16;

    // This is a task(integer, integer, integer, vector)
    universal_test_task(len, 1, i, 16'hFFFF); 
    end
end
endmodule

Основной целью кода является контроль количества битов для конкретного счетчика.

Ответы [ 3 ]

2 голосов
/ 09 июля 2019

Verilog и System Verilog имеют встроенную системную функцию $clog2(), т. Е. Потолок-лог2.

Можно показать, что число цифр в базе b целое положительное число k равно image.

В вашем случае вы можете заменить все операторы if-else одной строкой:

len = $clog2(i+1)

Аналогично, $clog2 поддерживается всеми основными инструментами синтеза, если вы даете ему значение, которое постоянно во время компиляции.

1 голос
/ 16 июля 2019

В Verilog вы можете использовать Ternary Operator для достижения функциональности.

module test(i,len);
 input wire [16:0] i;
 output reg [16:0] len;
  
 initial 
     begin
       len = i> 32767 ? 16 :
             i> 16383 ? 15 :         
             i> 8191  ? 14 :
             i> 4095  ? 13 :
             i> 2047  ? 12 :         
             i> 1023  ? 11 :
             i> 511   ? 10 :
             i> 255   ? 9 :         
             i> 127   ? 8 :
             i> 63    ? 7 :
             i> 31    ? 6 :         
             i> 15    ? 5 :
             i> 7     ? 4 :
             i> 3     ? 3 :         
             i> 1     ? 2 : 1 ;
       
       $display(i,,,,,len);
     end
endmodule

В System Verilog $ clog2 () поможет вам в этом

module test;
 
 bit [16:0] i;
 bit [5:0] b;
 bit [16:0] len;
      
 
      
 initial
  begin
    repeat(5)
      begin
        assert(std::randomize(i,b) with { b inside {[1:15]};
                                          i == 2**b; });
        len = $clog2(i)+1;
        $display(i,,,,,len);
      end
  end
  
endmodule
1 голос
/ 09 июля 2019

Это звучит как задание для рекурсивной log2 функции:

  function int log2 (int i); 
    if (i <= 1)
      return 0;
    else
      return log2(i/2) + 1;
  endfunction

Эта функция рекурсивная, потому что она вызывает сама себя.Он работает с использованием этих двух истин:

  1. база журналов 2 из 1 равна 0
  2. база журналов 2 любого числа - это база журналов 2 от половины этого числа плюс 1

Это необходимо для вашего тестового стенда, но вы обнаружите, что эта функция на самом деле является синтезируемой.


https://www.edaplayground.com/x/3bTN

module xyz;

  function int log2 (int i); 
    if (i <= 1)
      return 0;
    else
      return log2(i/2) + 1;
  endfunction

  initial
    begin
      int len;
      for (int i = 1; i <= 65535; i++)
        begin
          len = log2(i)+1;
          $display("i=%d, len=%d", i, len);
        end
    end

endmodule
...