¿Qué hay de malo en seguir el código de Verilog donde intento pasar una matriz unidimensional?

0

¿Qué hay de malo en seguir el código de Verilog en el que estoy tratando de pasar una matriz unidimensional?

module stimulus;             
wire [3:0] max,med,min;                  
reg[3:0] row_data[0:2];               
reg cin;               
sorting_three sr(max,med,min,row_data,cin);      // line no.27      
initial begin              
row_data[0]=4'b0010;            
row_data[1]=4'b1001;                 
row_data[2]=4'b1010;              
cin=1'b0;                      
end                   
endmodule   

Está dando un error como:

  

ERROR: HDLCompiler: 251 - "stimulus.v" Línea 27. No se puede acceder a la memoria row_data directamente   ERROR: HDLCompiler: 598 - "stimulus.v" Línea 21. Módulo de estímulo ignorado debido a errores anteriores

    
pregunta SW.

1 respuesta

5

Parece que hay un problema en la declaración del puerto para el módulo sorting_three . Estás intentando pasar un argumento que no puede existir.

Parece que el módulo stimulus debe ser un banco de pruebas para el módulo sorting_three , ya que el módulo stimulus no tiene ningún puerto de entrada o salida.

El módulo del banco de pruebas stimulus declara la memoria row_data como una matriz unidimensional de registros de 4 bits, la primera dirección 0 última dirección 2. Por lo tanto, esta memoria debe tener dos bits de dirección y cuatro bits de datos . Los valores iniciales se declaran en el bloque initial . Parece que se usa como memoria de solo lectura, no hay nada que indique que los valores se cambiarían de los valores iniciales cuando se sintetiza el circuito.

Pero, ¿cómo se conecta la memoria row_data al módulo sorting_three ?

Verilog es un lenguaje de síntesis de hardware. La memoria de solo lectura row_data debe conectarse al módulo sorting_three a través de su puerto de dirección de 2 bits y su puerto de datos de 4 bits. No existe tal cosa como la dirección de la matriz row_data "en la memoria", solo existe el código RTL que describe el hardware. Si tiene experiencia en programación de software, esto es lo más difícil de aprender sobre Verilog o VHDL: piense qué circuito de hardware desea sintetizar en lugar de describir su comportamiento en tiempo de ejecución.

El banco de pruebas debe declarar no solo que la matriz de memoria row_data existe en algún lugar del hardware, sino también los cables que se conectan a la dirección de la memoria y los puertos de datos:

reg  [3:0] row_data[0:2];  // read-only memory, 4-bit data x 2-bit address
wire [1:0] row_data_address; // driven by module sorting_three
wire [3:0] row_data_dout; // driven by row_data[row_data_address]
assign row_data_dout = row_data[row_data_address];

La declaración para sorting_three debería tener este aspecto (tenga en cuenta que estoy usando las declaraciones de puertos del estilo Verilog 2001 para facilitar la lectura):

module sorting_three_Memory (
    output reg  [3:0] max,
    output reg  [3:0] med,
    output reg  [3:0] min,
    output reg  [1:0] row_data_address, // drives row_data address
    input  wire [3:0] row_data_dout, // driven by row_data data out
    input  wire cin // clock
    );

Dentro del módulo sorting_three , el puerto de salida row_data_address debe dirigirse a 2'b00 , 2'b01 o 2'b10 para seleccionar un elemento de row_data en cada ciclo de reloj. Luego, en el siguiente ciclo de reloj, los datos válidos de row_data deberían estar disponibles desde row_data_dout .

Si el módulo necesitaba poder escribir en la memoria además de leer, entonces la memoria debe usar puertos adicionales para data_in y write_enable.

Si el módulo estaba accediendo a la memoria fuera del chip, es posible que se necesiten ciclos de reloj adicionales (conocidos como "estados de espera") antes de que los datos válidos estén disponibles. Pero para la memoria en chip dentro de un FPGA, generalmente acceso de un solo ciclo.

Alternativa sin acceso a memoria síncrona

Como solo hay tres direcciones, y parecen ser de solo lectura, puede pasarlas todas individualmente en lugar de guardarlas en la memoria de datos de la fila:

module sorting_three_noMemory (
    output reg  [3:0] max,
    output reg  [3:0] med,
    output reg  [3:0] min,
    input  wire [3:0] row_data_0, // example 4'b0010
    input  wire [3:0] row_data_1, // example 4'b1001
    input  wire [3:0] row_data_2, // example 4'b1010
    input  wire cin
    );

Sin embargo, Verilog no admite una declaración de puerto como el cable de entrada [3: 0] row_data_array [0: 2], eso no es algo que pueda sintetizarse en hardware.

No hay reloj en el banco de pruebas

Un segundo problema es que este banco de pruebas no parece estar manejando un reloj. Usualmente uso algo como esto para generar un reloj de banco de pruebas para la simulación:

localparam CLK_FREQ_HZ = 50_000_000;
localparam CLK_PERIOD_NS = 1_000_000_000 / CLK_FREQ_HZ;
always begin 
    #(CLK_PERIOD_NS/2.0); 
    clk=1; 
    #(CLK_PERIOD_NS/2.0); 
    clk=0; 
end
    
respondido por el MarkU

Lea otras preguntas en las etiquetas