2010-02-17 4 views
6

tengo un valor de 256 bits en Verilog:El paso de un alambre de 256 bits para una función C a través de la Verilog VPI

reg [255:0] val; 

quiero definir un $ foo de tareas del sistema que llama a C externo utilizando el VPI, por lo que se puede llamar a $ foo como esto:

$foo(val); 

Ahora, en la definición de C para el 'foo' función, no puedo simplemente leer el argumento como un entero (PLI_INT32), porque tengo demasiados bits para encajar en uno de esos. Pero, puedo leer el argumento como una cadena, que es lo mismo que una matriz de bytes. Aquí está lo que escribí:

static int foo(char *userdata) { 
    vpiHandle systfref, args_iter, argh; 
    struct t_vpi_value argval; 
    PLI_BYTE8 *value; 

    systfref = vpi_handle(vpiSysTfCall, NULL); 
    args_iter = vpi_iterate(vpiArgument, systfref); 

    argval.format = vpiStringVal; 
    argh = vpi_scan(args_iter); 
    vpi_get_value(argh, &argval); 
    value = argval.value.str; 

    int i; 

    for (i = 0; i < 32; i++) { 
    vpi_printf("%.2x ", value[i]); 
    } 
    vpi_printf("\n"); 

    vpi_free_object(args_iter); 
    return 0; 
} 

Como se puede ver, este código lee el argumento como una cadena y luego imprime cada personaje (también conocido como byte) en la cadena. Esto funciona casi perfectamente. Sin embargo, el byte 00 siempre se lee como 20. Por ejemplo, si le asigno la reg Verilog de la siguiente manera:

val = 256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f; 

y llamarlo usando $foo(val), a continuación, las impresiones de función C este en tiempo de simulación:

VPI: 20 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 

He probado esto con muchos valores diferentes y ha encontrado que el byte 00 siempre se asigna a 20, sin importar dónde o cuántas veces aparezca en val.

Además, tenga en cuenta que si leo el valor como vpiHexStrVal e imprimo la cadena, se ve bien.

Así, dos preguntas:

  1. ¿Hay una mejor manera de leer en mi valor de 256 bits desde el Verilog?
  2. ¿Qué está pasando con el 20? ¿Es esto un error? ¿Me estoy perdiendo de algo?

Nota: Estoy utilizando Aldec para la simulación.

Respuesta

4

vpiStringVal se usa cuando se espera que el valor sea texto ASCII, para obtener el valor como un puntero a una cadena en C. Esto es útil si desea usarlo con funciones C que esperan una cadena C, como printf() con el formato %s, fopen(), etc. Sin embargo, las cadenas C no pueden contener el carácter nulo (dado que nulo se usa para terminar cadenas C), y tampoco puede representar x o z bits, por lo tanto, este no es un formato que deba usarse si necesita distinguir cualquier posible valor de vector. Parece que el simulador que está utilizando formatea el carácter nulo como un espacio (0x20); otros simuladores simplemente se saltan, pero eso tampoco te ayuda. Para distinguir cualquier posible valor de vector use vpiVectorVal (la representación más compacta) o vpiBinStrVal (una cadena binaria con un carácter 0/1/x/z para cada bit).

+0

No quise usar 'vpiBinStrVal' o' vpiVectorVal', porque era inconveniente tener la entrada formateada bit por bit. De hecho, quiero que los datos tengan el formato de 32 valores de 8 bits; Terminé empalmando el cable de 256 bits y enviándolo como 8 entradas de 32 bits, que pueden leerse como 'vpiIntVal', y convirtiéndolo trivialmente en una matriz de 32 bytes. – pheaver

+0

Ok, pero 'vpiVectorVal' le permite leer los bits como palabras de 32 bits; no es un poco a la vez. – mark4o

+0

Sí, tienes razón, y me equivoqué. Lo que quiero decir es que quiero un valor integral real, no algo que tenga 'x' y 'z' en él. No es un gran problema, puedo convertirlo. – pheaver

Cuestiones relacionadas