Este estilo de codificación permite tan sólo 2 puntos de tiempo en cada transacción, correspondientes a la llamada y al retorno de la función b_transport. (usando el protocolo base, esto se correspondo con el inicio de la petición y el inicio de la respuesta de la transacción).Podemos elegir que estos dos puntos sean el mismo (y la transacción ocurre en tiempo 0)
El tiempo que se pasa como parámetro en la función b_transport indica el tiempo de inicio (y de respuesta) de la transacción respecto al tiempo actual de simulación. En el uso normal (sin usar temporal decoupling), este valor será siempre 0. El target de la transacción puede usar wait() dentro de la función b_transport para simular su tiempo de respuesta, etc.
Este sistema permite el uso del temporal decoupling que no es más que permitir que partes de nuestro modelo se ejecuten en su propio tiempo de simulación hasta que llegue el momento de tener que comunicarse con otra parte del sistema. En ese punto sincronizaremos los tiempos de las dos partes.
Cuando un módulo que se simula con temporal decoupling se encuentra en un tiempo avanzado y necesita el valor de una variable que o bien se encuentra en otro módulo (y tiene que interactuar con él) o modifica su valor otro módulo, tiene dos opciones:
- Suponer un valor de esa variable y seguir su simulación avanzada
- Sincronizarse con el resto de la simulación, es decir, esperarse a que “los demás” lleguen a su tiempo de simulación. Así, el módulo responsable de modificar esa variable podrá hacerlo y nuestro módulo podrá seguir la simulación con el valor correcto.
La primera opción se basa en que leer ese valor posiblemente incorrecto será corregido más adelante volviendo a leer dicho valor; mientras que la segunda opción garantiza el correcto funcionamiento de cualquier sistema y módulo.
En este tipo de modelado, se usa también la función b_tranport, pero en este caso se usa el parámetro de tiempo. Con este parámetro se lleva la cuenta del tiempo en avanzado que llevan esos módulos, de manera que el target vuelve de la función b_transport con el tiempo que deberia avanzar la simulación (que viene a ser el tiempo en avanzado que lleva), sumando el parámetro de tiempo al tiempo de simulación se obtiene el tiempo de simulación en que la transacción se completa, pero el tiempo de simulación no avanzará hasta que el initiator vuelva el control al simulador.
¿Y eso para qué? Pues con esta técnica podemos ganar en velocidad de simulación, ya que al simulador de SystemC se le reduce la tarea de calcular qué módulo simular en cada momento.
Si se permitiera que un módulo avanzase su tiempo de simulación sin límite y sin volver el control al simulador de SystemC, las demás partes de la simulación no se ejecutarían jamás. Para evitar esto, existe el llamado global quantum, que es el tiempo máximo que un módulo puede avanzarse al tiempo global de simulación. Este quantum se elige en cada simulación, siendo un compromiso entre velocidad de simulación y precisión. Si fijamos un quantum muy pequeño, será necesario muchos sincronizaciones (aumentado el tiempo de simulación), si por el contrario, damos un valor grande al quantum, la simulación puede ser incorrecta debido a los fallos de sincronización de variables compartidas.
El ejemplo típico de uso de temporal decoupling es el del caso de la simulación de un sistema compuesto de un procesador, memoria, un timer, i algún periférico lento (por ejemplo una UART). El software que se ejecuta en la CPU simulada, básicamente está cogiendo instrucciones de la memoria y ejecutándolas dentro la CPU y sólo interactúa con el resto del sistema cuando el timer lanza una interrupción (por ejemplo cada 1 milisegundo). En esta simulación, el simulador de la CPU podría permitirsele avanzarse al resto del sistema hasta 1 milisegundo, accediendo directamente a la memoria (usando DMI, ya lo contaremos). De esta forma, se podría tener un modelo muy detallado del timer, incluso a nivel de reloj del sistema, si que esto interfiera demasiado en la velocidad de la simulación global.
Podemos cambiar el tipo de codificación a media simulación. Por ejemplo, puede ser interesante correr una parte de la simulación más rápido y con menos precisión, y luego cambiar para tener mas precisión en todos los tiempos a cambio de una pérdida de prestaciones.
Deja un comentario