Anexo

A1. Funciones  para control y reporte de tiempo:

sc_stop()

Para la simulación y causa el sc_start() para retornar el control a la rutina del sc_main().

sc_time_stamp()

Retorna un objecto sc_time con el tiempo actual de la simulación.

sc_simulation_time()

Retorna un valor de tipo double con el tiempo actual d ela simulacion la unidad actual del tiempo de defecto. Volver

 

A2. Pasos Del Planificador. 

1.- Fase De la Inicialización.  Cada proceso del método se ejecuta una vez durante la inicialización y se ejecuta cada proceso hilo es ejecutado hasta que se encuentra una declaración de la espera.

 El orden de la ejecución de procesos es  sin especificar.  El orden de la ejecución entre los procesos es determinista.  Esto significa que dos funcionamientos de simulación que usan la misma versión del mismo simulador deben rendir resultados idénticos.  Sin embargo, diversas versiones o un diverso simulador pueden rendir un diverso resultado si el cuidado no se toma al escribir modelos.

  2.- Fase de Evaluación (Evaluate Phase).  Del conjuntos de los procesos que están  listos para funcionar (correr), seleccionar un proceso y reanudar su ejecución.  El  orden en la cual los procesos se seleccionan para la ejecución del sistema de los procesos que están  listos  para funcionar está sin especificar.

La ejecución de un proceso puede incluir llamadas a la función del request_update() la cual  programa las llamadas pendientes a la función update() en la fase de la actualización.  La función del request_update() se puede llamar solamente dentro de funciones del miembro de un canal primitivo.

 3) repite el paso 2 para cualquier otro proceso que sea listo funcionar.

  4) Fase De la Actualización.  Ejecute cualquier llamada pendiente al update() de llamadas a la función del request_update() ejecutada en la fase de la evaluación.

 5) Si notificaciones pendientes, se determina qué procesos son listos funcionar e ir al paso 2.

  6) Si no hay mas notificaciones para tiempo posteriores (timed notification) se acaba la simulación.

7) Sino, avance el tiempo actual de la simulación  hasta que finalice la notificación sincronizada del acontecimiento.

8) Se determina qué procesos llegan a estar listos funcionar debido a los acontecimientos que tienen notificaciones pendientes en el tiempo actual.  Vaya al paso 2. Volver

 

A3. Tipos de datos en SystemC

sc_uint<>, sc_int<>

Este tipo son enteros de precision fija con y sin signo. Son representados como un arreglo de bits.

Syntax:

sc_int<length> variable_name, variable_name, ...;

sc_uint<length> variable_name, variable_name, ...;

Estos tipos se utilizan para las operaciones aritméticas y lógicas en enteros sin signo y con signos y menor que o igual a 64 bits.  Todas las operaciones se realizan con 64 bits de precisión y después se convierten al tamaño apropiado con el truncamiento.  Una representación del complemento de dos se utiliza para los enteros con signo.  El uso de estos tipos de datos será menos eficiente que el uso de los tipos de datos incorporados de C.

Ejemplo

sc_int<5> a; // a is a 5-bit signed integer

a = 13; // a gets 01101, a[4] = 0, a[3] = 1, ..., a[0] = 1

bool b;

b = a[4]; // b gets 0

b = a[3]; // b gets 1

c = a.range(3, 1); // c gets 110 - interpreted as -2

sc_biguint<>, sc_bigint<>

Estos tipos son enteros sin signo firmados y arbitrarios de la precisión.  Se representan como arreglo de bits.

Syntax:

sc_bigint<length> variable_name, variable_name, ...;

sc_biguint<length> variable_name , variable_name, ...;

Estos tipos se utilizan para las operaciones aritméticas en los enteros sin signo firmados y mayores que o igualan a 64 pedacitos.  Una representación del dos-complemento se utiliza para los enteros con signo.

sc_logic

Este tipo representa la lógica 4-valued.  El valor se interpreta como variable de un solo bit, no como número.  Es útil para modelar lógica de triple estado.  El uso de la lógica 4-valued será menos eficiente que el uso del sintaxis de la lógica 2-state (sc_int, sc_uint):

Syntax:

sc_logic variable_name, variable_name, . . . ;

Ejemplo

{
   bool control, data;
   sc_logic ts_out;
   if (control == false) {
      ts_out = 'Z'; // Set the drive to Z
   }
   else {
      ts_out = data; // Set the drive to data
   }
}

sc_lv<>

Este tipo es un arreglo de bits de tipo sc_logic. El valor es interpretado como un multi-bit variable, no como un numero. Es normalmente usado para el modelamiento de tri-state logic

Syntax:

sc_lv<length> variable_name, variable_name, ... ;

Ejemplo

sc_lv<38> a; // 38-bit bit vector
sc_lv<4> b;
sc_logic c;
b = "ZZZZ";
cout << "b = " << b.to_string();
// use to_string() method for readable character string

sc_fixed<>, sc_ufixed<>

Los modelos de un nivel más alto pueden utilizar números de punto flotante para modelar operaciones aritméticas.  Estos números se convierten a menudo a los tipos de datos del punto fijo para la puesta en práctica de hardware.  Estos tipos son precisión arbitraria y tienen argumentos estáticos.

Syntax:

sc_fixed<wl, iwl, q_mode, o_mode, n_bits> object_name, object_name, ... ;

sc_ufixed<wl, iwl, q_mode, o_mode, n_bits> object_name, object_name, ... ;

·        wl: total word length, number of bits used in the type.

·        iwl: integer word length, number of bits to the left of the binary point (.).

·        q_mode: quantization mode.

·        o_mode: overflow mode.

·        n_bits: number of saturated bits, used for overflow mode.

sc_fixed_fast<>, sc_ufixed_fast<>

Estos tipos utilizan una precisión fija y tienen argumentos estáticas.  La mantisa se limita a 53 bits.  Son implementadas con valores de doble punto flotante (double precision floating point).  Utilizan los mismos nombres de parámetros, argumentos y orden del tipos arbitrarios de precison de punto fijo:

Syntax:

sc_fixed_fast<wl, iwl, q_mode, o_mode, n_bits> object_name, object_name, ... ;

sc_ufixed_fast<wl, iwl, q_mode, o_mode, n_bits> object_name, object_name, ... ;

·        wl: total word length, number of bits used in the type.

·        iwl: integer word length, number of bits to the left of the binary point (.).

·        q_mode: quantization mode.

·        o_mode: overflow mode.

·        n_bits: number of saturated bits, used for overflow mode.

sc_fixed_fast<>, sc_ufixed_fast<>

Este tipo usa precision fija y tiene argumentos estaticos. La mantisa esta limitada a 53 bits.

Sintaxis::

sc_fixed_fast<wl, iwl, q_mode, o_mode, n_bits> object_name, object_name, ... ;

sc_ufixed_fast<wl, iwl, q_mode, o_mode, n_bits> object_name, object_name, ... ;

·        wl: total word length, number of bits used in the type.

·        iwl: integer word length, number of bits to the left of the binary point (.).

·        q_mode: quantization mode.

·        o_mode: overflow mode.

·        n_bits: number of saturated bits, used for overflow mode.

sc_fix, sc_ufix, sc_fix_fast, sc_ufix_fast

Estos tipos son los mismo que  sc_fix, sc_ufix, sc_fix_fast, sc_ufix_fast respectivamente  excepto los argumentos son non-static.

Syntax:

sc_fix object_name (list of options) ;

sc_ufix object_name (list of options) ;

Volver

 

 

A4. Tipos de canales

sc_signal:

The sc_signal channel implements the sc_signal_inout_if interface. Los canales  sc_signal son  referidos a menudo como señales.  Se utilizan para describir señales del hardware.  Se utiliza tanto para comunicaciones punto a punto o multipunto.  Las señales implementan la semántica evaluate-update para evitar dependencias de la orden de los datos.  La señal mantiene un current_value, un new_value y un old_value.

Durante la fase de la evaluación escribir en la señal causara que el valor sea escrito en new_value.  Sucesivo escrituras a la señal hará  que el new_value sea actualizado cada vez (el ultimo gana (last one wins)).  Durante la fase de la actualización si el new_value es diferente de current_value entonces el current_value se mueve al old_value y entonces el new_value se mueve al current_value y un acontecimiento ocurre.

Sintaxis:                    sc_signal<T> signal_name, signal_name, ... ;

Ejemplo:

SC_MODULE (module_name) {

sc_signal<int> d ;
sc_signal<char> e ;
sc_signal<sc_int<10> > f;

// rest of module not shown

} ;

 

sc_buffer

Un canal del sc_buffer se comporta exactamente como un canal del sc_signal excepto  que al  escribir el valor es siempre actualizado y ocurre un value_changed_event, incluso cuando el new_value es igual al current_value.

Sintaxis:                    sc_buffer<T> buffer_name, buffer_name, . . . ;

 

 sc_fifo:  implementa las interfaces  sc_fifo_in_if y  sc_fifo_out_if.  Un canal  sc_fifo implementa una FIFO.  Es una conexión punto a punto y puede ser conectado solamente con un entrada y un puerto de salida al conectar entre los módulos.

Syntax:                       sc_fifo<T> channel_name, channel_name, ... ;

Ejemplo:

SC_MODULE (module_name) {

// channels
sc_fifo<int> d; // type int, depth of 16
sc_fifo<char> e ; // type char,depth of 16
sc_fifo<sc_int<10> > f; // type sc_int<10>, depth of 16

// rest of module

} ;

sc_mutex:  implementa la interfaz sc_mutex_if . Se utiliza para el acceso seguro a un recurso compartido

Cada proceso puede procurar trabar el sc_mutex.  Una vez que el proceso trabe el canal entonces tiene acceso al recurso compartido.  Este acceso no es forzado por el canal sino es simplemente parte de la semántica del uso.  Después de que el canal se acabe con el recurso compartido abre el canal de modo que otros procesos puedan tener acceso al recurso compartido.  El canal advierte si las peticiones múltiples se publican durante el mismo ciclo del delta.  Solamente el proceso que trabó el canal puede abrirlo.  Si el canal entonces se traba la sensibilidad dinámica se utiliza para suspender y un-para suspender (un-suspend) un proceso de la petición.

Sintaxis:                    sc_mutex mutex_name, mutex_name, . . . ;

sc_semaphore

El canal  sc_semaphore implementa la interfaz sc_semaphore_if . Es similar al canal sc_mutex pero permite el acceso concurrente limitado.  Se crea con un parámetro positivo obligatorio del tipo int.  El parámetro se asigna a una variable interna de la "cuenta".  El parámetro representa el número máximo de "usuarios concurrentes" del canal.  La cuenta interna se decrementa en cada wait() o trywait() acertado.  La cuenta interna se incrementa en cada post().  El canal es tan largo disponible como cuenta interna > 0.

Sintaxis:                    sc_semaphore semaphore_name(count) ;    Volver

A5. Definición de modulos

Estos son los 3 pasos para definir módulos dentro otro módulo.

 

Paso1: Cree el caso del módulo

            El módulo se crea como miembro de los datos del módulo del padre.

Sintaxis:           module_name instance_name;

 

Paso 2: Inicialice el caso del módulo.

Inicialice los casos de módulos dentro de la lista de la inicialización del constructor del módulo del padre.  La secuencia que usted proporciona como parte de la inicialización es el string_name del módulo.  Se recomienda guardar el string_name igual que instance_name.

 

Paso 3: Unir los puertos.

Hay dos tipos de  sintaxis para unir los puertos.  El primero y preferido método está al lado de la conexión nombrada.  El segundo está al lado de conexión posicional. El estilo nombrado de la conexión es el mapeo explícito.  El unir se hace en el cuerpo del constructor del módulo.

Primera forma:

Sintaxis:           instance_name.port_name(channel_or_port);

El estilo posicional de la conexión es el mapeo implicado.

 

Segunda Forma:

El primer port_or_channel en la lista mapea al primer puerto definido en el módulo.  El segundo port_or_channel de la lista mapea al segundo puerto en el módulo, etcétera.

Sintaxis:          

instance_name(channel_or_port, channel_or_port, . . .);

 

Volver

 

A6.- Definición de módulos dentro del sc_main( ).

 

Paso 1: Definición y iniciación de un modulo.

La definición  del módulo es la creación de los objetos del módulo.

Sintaxis:           module_name instance_name ("string_name") ;

 

Paso 2: Unir los puertos.

Se hace al igual que en caso de modulo dentro de un modulo

Sintaxis:

instance_name.port_name(channel_or_port);

ó

module_name instance_name ("string_name") ;   Volver

 

A7.- Ejemplos de Canales.

#include "systemc.h"

#include "adder.h"

#include "stimgen.h"

#include "monitor.h"

int sc_main(int argc, char *argv[ ])

{

// Create fifos with a depth of 10

sc_fifo<int> s1(10);

sc_fifo<int> s2(10);

sc_fifo<int> s3(10);

 

// rest of body not shown

return 0;

}

 

Volver

 

A.8 Ejemplo de reloj.

sc_time t1(20,SC_NS);

sc_time t2(10,SC_NS);

sc_clock clk2("clk2", t1, 0.5, t2, true);

// periodo de 20ns

// ciclo de trabajo de 50%

// Primer canto a  10ns

// Si el primer canto es positivo

Nombre Sintaxis

Nombre

Tipo

period:

Periodo del reloj

variable del tipo sc_time

 

 

Valor por defecto: 1 de la unidad tiempo por defecto

duty_cycle:

Ciclo de trabajo

variable tipo double

 

 

Valor por defecto: 0,5

start_time:

tiempo del primer

variable del tipo sc_time

 

canto

Valor  por defecto: 0

positive_first:

Primer canto positivo

Variale tipo Bool

 

 

Valor por defecto: true

Volver.

 

 

 

 

 

 

 

 

 

 

 

 

A.9 Ejemplo de implementación:

Se implementara una compuerta EXOR, usando 4 puertas NAND.

 

 

El Codigo para una compuerta NAND, es el siguiente:

# include “systemc.h”

SC_MODULE (nand2)

{

            sc_in<bool> A, B;

            sc_out<bool> F;

           

            void do_nand2 ()

            {

                        F.write (! A.read() &&B.read() ) );

            }

            SC_CTOR(nand2)

            {

                        SC_METHOD(do_nand2);

            Sensitive <<A << B;

            }

};

 

 

 

 

 

 

 

 

 

 

 

 

Para que finalmente tengamos el EXOR, se usan 4 módulos del tipo NAND, simplemente llamando al modulo NAND.

# include “systemc.h”

# include “nand2.h”

SC_MODULE(exor29

{

            sc_in<bool> A, B;

            sc_out<bool> F;

           

            nand2 n1, n2, n3, n4;

sc_signal<bool> S1, S2, S3;

SC_CTOR(exor) : n1(“N1”), n2(“N2”), n3(“N3”), n4(“N4”),

{

                        n1.A(A);

                        n1.B(B);         

n1.F(S1);

 

n2<< A << S1 << S2;

 

n3.(S1);

                        n3.(B);

n3.(S3);

 

n4.A(S2);

                        n4.B(S3);        

n4.F(F);

}

 

};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Para Probar nuestro EXOR, esta el siguiente codigo, que simula las entradas al EXOR.

#include “systemc.h”

SC_MODULE (stim)

{

            sc_out<bool> A, B;

            sc_in_clk Clk;

 

            void StimGen()

            {

                        A.write (false);

                        B.write (false);

                        wait ();

                        A.write (false);

B.write (true);

wait ();

A.write (true);

                        B.write (false);

                        wait ();

                        A.write (true);

B.write (true);

wait ();

sc_stop();

            }

            SC_CTOR(stim)

            {

                        SC_CTHREAD(StimGen, Cñk.pos());

            }

};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

El siguiente código, moritonea la salida del EXOR.

#include “systemc.h”

#include “stim.h”

#include “exor2.h”

#include “mon.h”

 

int sc_main (int argc, char* argv [])

{

            sc_signal<bool> Asig, Bsig, Fsig;

            sc_clock TestClk(“TestClock”, 10, SC_NS_0.5);

           

            stim Stim1(“Stimulus”);

            Stim1.A(Asig);

            Stim1.B(Bsig);

            Stim1.Clk(TestClk);

 

            Exor2 DUT(“exor2”);

            DUT.A(Asig) ;

            DUT.B(Bsig) ;

            DUT.F(Fsig) ;

 

            mon Monitor1(“Monitor”)

            Monitor1.A(Asig);

            Monitor1.B(Bsig);

            Monitor1.F(Fsig);

            Monitor1.Clk(TestClk);

 

            sc_start() ;

            return 0;

            }

 

 

 

La salida por consola, es la siguiente:

 

Time    A         B         F

  0  s    0          0          1

10 ns    0          0          0         

20 ns    0          1          1

30 ns    1          0          1

40 ns    1          1          0