Выражение Verilog оценивается как 'x' - PullRequest
0 голосов
/ 04 марта 2020

Я пишу модуль умножения матриц в Verilog, и я столкнулся с проблемой, когда выражение оценивается в кучу 'xxxx':

// multiplies 5x32 matrix by 32x5 matrix
module matmul(input [4959:0] A, input [4959:0] B, output reg [799:0] out);
    integer i,j,k;
    integer start = 0;

    reg [31:0] placeholder_A [4:0][31:0];
    reg [31:0] placeholder_B [31:0][4:0];
    reg [31:0] placeholder_out [4:0][4:0];

  always @(A or B) begin
      // initialize output to zeros
      for (i=0; i<800; i=i+1)
          out[i] = 0;

      // initialize placeholder output to zeros
      for (i=0; i<5; i=i+1)
        for(j=0; j<5; j=j+1)
          placeholder_out[i][j] = 32'd0;

      // turn flat vector A array into matrix
      for (i=0; i<5; i=i+1)
        for(j=0; j<32; j=j+1) begin
          placeholder_A[i][j] = A[start +: 31];
          start = start + 32;
        end
      start = 0;

      // turn flat vector B array into matrix
      for (i=0; i<32; i=i+1)
        for(j=0; j<5; j=j+1) begin
          placeholder_B[i][j] = B[start +: 31];
          start = start + 32;
        end
      start = 0;

      // do the matrix multiplication
      for (i=0; i<5; i=i+1) // A.shape[0]
        for(j=0; j<5; j=j+1) // B.shape[1]
          for(k=0; k<32; k=k+1) // B.shape[0] or A.shape[1]
            placeholder_out[i][j] = placeholder_out[i][j] + (placeholder_A[i][k]*placeholder_B[k][j]); // this is where I am having problems
      start = 0;

      // flatten the output
      for (i=0; i<5; i=i+1)
        for(j=0; j<5; j=j+1) begin
          out[start] = placeholder_out[i][j];
          start = start + 1;
        end
  end
endmodule 

placeholder_out переменная (и, следовательно, out вывод) оцениваются как «хх ... ххх» и я не могу понять почему. При проверке сигналов через испытательный стенд оба значения placeholder_A и placeholder_B содержат допустимые значения. Любая помощь будет оценена. Вы можете запустить тестовый стенд здесь: https://www.edaplayground.com/x/2P7m

1 Ответ

1 голос
/ 04 марта 2020

Пара вещей, которые я наблюдал из фрагмента кода. Прежде всего, ввод не имеет достаточной ширины. Требуемая ширина 32*5*5=5120. Поэтому нам нужны входные векторы 5120 бит (input [5119:0] A, input [5119:0] B). Инструмент для рисования мог бы решить эту проблему.

Во-вторых, start необходимо инициализировать в ноль в начале вычисления. Это позволит избежать защелок на start и будет вычислять из нулевого индекса A и избежать дальнейшего распространения X.

  always @(A or B) begin
  //...
    start=0;

Я бы посоветовал использовать Always_comb вместо ручной чувствительности, но это совершенно другой топи c.

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

...