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:
- ¿Hay una mejor manera de leer en mi valor de 256 bits desde el Verilog?
- ¿Qué está pasando con el
20
? ¿Es esto un error? ¿Me estoy perdiendo de algo?
Nota: Estoy utilizando Aldec para la simulación.
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
Ok, pero 'vpiVectorVal' le permite leer los bits como palabras de 32 bits; no es un poco a la vez. – mark4o
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