#hdl #vivado
#hdl #vivado
Вопрос:
Я пытаюсь упаковать 2D распакованный массив, передать его через оболочку Verilog и распаковать его в другой модуль (или тестовый стенд). Простейший код выглядит следующим образом:
module a_tb();
timeunit 10ns;
timeprecision 1ns;
localparam N = 4;
localparam WIDTH = 8;
logic [N*N*WIDTH-1:0] A_flat_1;
logic [WIDTH-1:0] A_1 [N][N];
logic [N*N*WIDTH-1:0] A_flat_2;
logic [WIDTH-1:0] A_2 [N][N];
assign {<<{A_flat_1}} = A_1;
assign A_flat_2 = A_flat_1;
assign A_2 = {<<{A_flat_2}}; // Line 13
initial begin
foreach (A_1[i,j]) begin
A_1[i][j] = 10*i j;
end
#10;
$display("%p", A_1);
$display("%p", A_2);
assert(A_1==A_2);
end
endmodule
И я получаю следующую ошибку в симуляторе Vivado 2018.2:
ERROR: [VRFC 10-1571] wrong element type in unpacked array concatenation [U:/path/array_test.tb.sv:13]
Из того, что я понимаю о потоковых операторах, это должно сработать. Может ли это быть ошибкой инструмента?
Комментарии:
1. Это может быть ошибка инструмента. Попробуйте свой код с другим симулятором на www.EDAplayground.com
2. @dave_59 Это ошибка инструмента. это работает в VCS. Большое спасибо. Я опубликовал ответ с обходным решением, которое работает в обоих случаях.
Ответ №1:
Это ошибка в симуляторе Vivado. Синтаксис работает в Synposis VCS (EDA playground).
После нескольких дней экспериментов я обнаружил, что в Vivado Simulator {<<{A_flat_2}}
просто переворачивает биты, сохраняя их упакованными, следовательно, возвращает logic [N*N*WIDTH-1:0]
вектор.
В качестве обходного пути я выяснил, что {>>{{<<{A_flat_2}}}}
возвращает распакованный вектор типа logic [WIDTH-1:0] A_2 [N][N]
.
Обходной путь (работает как в VCS, так и в Vivado)
module a_tb();
timeunit 10ns;
timeprecision 1ns;
localparam N = 4;
localparam WIDTH = 8;
logic [N*N*WIDTH-1:0] A_flat_1;
logic [WIDTH-1:0] A_1 [N][N];
logic [N*N*WIDTH-1:0] A_flat_2;
logic [WIDTH-1:0] A_2 [N][N];
assign {<<{A_flat_1}} = A_1;
assign A_flat_2 = A_flat_1;
assign A_2 = {>>{{<<{A_flat_2}}}};
initial begin
foreach (A_1[i,j]) begin
A_1[i][j] = 10*i j;
end
#10;
$display("%p", A_1);
$display("%p", A_2);
assert(A_1==A_2);
end
endmodule