¿Cómo usar correctamente los arreglos 2D empaquetados como entradas y salidas de la tarea de verificación?

1

En una parte de mi proyecto verilog, estoy asignando datos al registro M [i] leyendo del registro N [j]. He escrito y simulado el código en verilog sin ningún problema. Como este patrón en particular se repite muchas veces en un módulo, me gustaría convertirlo en una tarea. Pero obtengo errores de compilación al usar una matriz 2D de registros como entrada y salida de la tarea. A continuación se muestra un código de ejemplo que ilustra el problema.

'timescale 1 ns/100 ps
module test(clk, rst_n);
    input clk, rst_n;
    reg [1:0] idx1;
    reg [2:0] idx2;
    reg [15:0] M[3:0];
    reg [15:0] N[7:0];

    always @(posedge clk or negedge rst_n) begin
        idx1 <= rst_n ? (idx1 + 1) : 0;
        idx2 <= rst_n ? (idx2 + 1) : 0;
    end

    always @(posedge clk or negedge rst_n) begin
        if(~rst_n) begin : reset_registers
            integer i;
            for(i = 0; i < 4; i = i+1) M[i] = 0;
            for(i = 0; i < 8; i = i+1) N[i] = i;
        end
        else begin
            M[idx1] <= N[idx2];
        end
    end
endmodule

El módulo compila y simula como se espera ahora. Me gustaría convertir el segmento M[idx1] <= N[idx2]; a una tarea. Entonces, el nuevo código que usa una tarea es:

'timescale 1 ns/100 ps
module test(clk, rst_n);
    input clk, rst_n;
    reg [1:0] idx1;
    reg [2:0] idx2;
    reg [15:0] M[3:0];
    reg [15:0] N[7:0];

    always @(posedge clk or negedge rst_n) begin
        idx1 <= rst_n ? (idx1 + 1) : 0;
        idx2 <= rst_n ? (idx2 + 1) : 0;
    end

    always @(posedge clk or negedge rst_n) begin
        if(~rst_n) begin : reset_registers
            integer i;
            for(i = 0; i < 4; i = i+1) M[i] = 0;
            for(i = 0; i < 8; i = i+1) N[i] = i;
        end
        else begin
            copy(idx1, idx2, M, N);
        end
    end

    task copy;
        input [1:0] x1;
        input [2:0] x2;
        output reg [15:0] A[3:0];
        input [15:0] B[7:0];
        begin
            A[x1] <= B[x2];
        end
    endtask
endmodule

Recibo los siguientes errores al intentar compilarlo con modelsim:

# -- Compiling module test
# ** Error: D:\projects\test.v(21): Illegal task output argument.
# ** Error: D:\projects\test.v(21): (vlog-2110) Illegal reference to memory "B".
# 
# ** Error: D:\projects\test.v(21): Illegal LHS of assignment.
# ** Error: D:\projects\test.v(21): (vlog-2110) Illegal reference to memory "N".
# 
# C:/modeltech64_10.2c/win64/vlog failed.

¿Alguien puede recomendar cómo utilizar los registros correctamente en una tarea? ¿Exactamente qué es lo que hace que las declaraciones sean ilegales? ¿Es posible algo como esto usando una tarea, o hay otra manera? Gracias.

    
pregunta Shafeey

2 respuestas

0

Debe usar SystemVerilog para desempaquetar matrices como argumentos para una tarea. Y la tarea como la ha escrito no hace lo mismo que el código sin la tarea. Esto se debe a que la matriz de salida A no está inicializada y solo está configurando el valor indexado por x1 .

    
respondido por el dave_59
0

Por lo que sé, Verilog no admite matrices multidimensionales en los puertos de entrada o salida.

Así que como sugirió @ dave_59, puede cambiar a Verilog del sistema para hacerlo, o si desea implementar la tarea dentro de Verilog puede combinar la matriz 2-d como una matriz 1-d como [15: 0] A [3: 0] será A [63: 0] con A [15: 0] = 1ra fila, A [31:16] = 2da fila y así sucesivamente ..., pero eso aumentaría el esfuerzo y no la de líneas de código, en su caso particular.

Además, las tareas también pueden usar variables globales, así que puedes hacer esto si resuelve tu propósito:

task copy;
    begin
            M[idx1] <= N[idx2];
    end
endtask

y llama a la tarea por copy();

También puede crear un módulo separado con solo la tarea que tenga arreglos 2-d como parámetros y, en lugar de llamar a una tarea, puede llamar al módulo con diferentes parámetros.

    
respondido por el Ashutosh Jain

Lea otras preguntas en las etiquetas