Diseño y Programación Orientados a Objetos
1er. Sem 2013
Tarea 1: Compuertas Digitales como Objetos de Software

Recomendación: Lea detenidamente la tarea. Si algo no lo entiende, consulte en clases. Si es preciso, se incorporarán aclaraciones al final.
Esta tarea tiene por objetivos:
* Creación de Interfaces gráficas en Java
* Desarrollar aplicaciones con barra de menú
* Ejercitar el modelo de programación conducido por eventos (o basado en eventos).
* Manejar eventos de software. 
* Ejercitar la creación y extensión de clases dadas para satisfacer nuevos requerimientos.
* Modelar un objeto físico como un objeto de software.
* Ejercitar una estrategia para programar simulaciones de fenómenos discretos.
* Generar documentación con Javadoc.

Descripción General
  En esta tarea su grupo extenderá la solución de la Tarea 1 para incorporar una interfaz gráfica a un simulador de circuitos digitales basados en compuertas. Además del crear una interfaz gráfica para su simulador, su grupo deberá incluir funcionalidades adicionales como borrado de elementos del circuito y la opción de re-hacer la simulación luego de haber editado el circuito.
  Su grupo contará con un avance para el software que se pide. A partir de éste su grupo deberá incorporar las nuevas funcionalidades. Una vista para un circuito de un flip-flop SR debería ser similar a la Figura 1.

Figura 1: Ejemplo parcial para el resultado pedido en esta tarea para el caso del flip-flop SR. Por simplicidad en la única línea de la compuerta OR se resumen todas sus entradas.

Para el caso del circuito de la Figura 1 y usando señales de entrada r.txt (fuente superior) y s.txt (fuente inferior) el meter captura el archivo de datos salida.txt (para este archivo meter registró además las señales de entrada R -reset- y S -set-) con resultado gráfico como el mostrado en la Figura 2 (Q es la salida del inversor superior).
 
Figura 2: Señales de entrada y salida del Flip-Flop SR. R entrada superior, Q salida superior en figura 1.

En esta tarea su grupo debe modelar la interacción entre compuertas digitales básicas: NOT, OR (ya adelantados), NAND y NOR (por incorporar). Se pide analizar también el resultado generado por el circuito de la figura 3.

Figura 3: Inversores interconectados: almacena 1 bit, sin control.

Modelos para los Objetos del Problema, son los mismos de la tarea 1.

Modelo para el avance del tiempo: En presencia de variables con cambios discretos en el tiempo, como en las señales digitales, las simulaciones consideran avances no regulares de tiempo y definidos según el evento de interés futuro más próximo. En estos casos el algoritmo de simulación informa del avance del tiempo a los objetos modelados que requieren cambio. En cada iteración se pide actualizar el objeto cuya salida cambia más próxima en el futuro. Para ello el algoritmo hace uso de la estructura de datos Cola de Prioridad. Ésta es una cola donde los objetos insertados deben tener una relación de orden. Cada objeto crea e inserta en esta cola un evento de cambio futuro. La operación para sacar elementos la controla el simulador  quien siempre extrae el evento de tiempo más pequeño de los insertados.
   En el caso de esta tarea, el cambio en una salida afectará las entradas de otras compuertas que deberán insertar en la cola eventos propios de actualización futura. El tiempo futuro de actualización depende del retardo de propagación de cada compuerta.
  A diferencia de la tarea 1, en este caso consideraremos que es posible tener varios eventos programados a ocurrir en el mismo instante. Para modelar mejor este escenario, debemos reconocer tres estados para cada compuerta: a) cálculo interno del nuevo valor de salida usando las entradas previo a ese instante, b) una vez transcurrido su retardo, actualización de la salida de cada compuerta, luego c) propagación de su salida hacia las compuertas alimentadas por ella. Es importante seguir ese orden para cada una de las compuertas cuyo cambio es simultáneo. En a) nos aseguramos que el cálculo de la salida futura usará los valores de entradas previos al instante de cambio. Con b) nos aseguramos que el cambio es reflejado en la salida de cada compuerta una vez transcurrido el retardo. Finalmente con y c) nos aseguramos todas las salidas son estables al momento de propagar sus efectos a las próximas entradas. Si se trata de cambios simultáneos en dos compuertas se puede ilustrar como:
 Cambia entrada1 >----> calcular e itinerar nueva salida1  >---> Luego del retardo, ese cambio pasa a la salida1 >----> otras compuertas reaccionan a esa salida.
 Cambia entrada2 >----> calcular e itinerar nueva salida2  >---> Luego del retardo, ese cambio pasa a la salida 2>----> otras compuertas reaccionan a esa salida.
Es importante que esto se haga en etapas "paralelas" para salidas que cambian en un mismo instante, éste es el paso b. Supongamos que estas dos salidas van a una misma tercera compuerta. Si la propagación del primer cambio (compuerta 1) se hace antes de estabilizar la salida de la compuerta 2, la tercera componente itinerará un cambio sin todas sus entradas actualizadas. Por esto es importante hacer la etapa c) luego que todos los cambios simultáneos han ocurrido en b).

  El algoritmo para un simulador mejorado de eventos discretos sería del tipo:
  simulate(PriorityQueue pq) {
      ChangeEvent e;                             // Objeto ChangeEvent almacena referencia a objeto
                                                            //involucrado, tiempo y valor de cambio futuro.

      insertar_eventos_de_partida(pq); // primer cambio para cada fuente digital e itinerar
                                                           // cambios para condición inicial de cada compuerta.

      while ( (e=pq.poll())!=null) {         // mientras haya eventos por procesar
            Avanzar el tiempo;
            Identificar todos los eventos simultáneos más próximos;
            Pedir a cada compuerta involucrada reflejar el nuevo valor en salida;
            Pedir a cada compuerta involucrada propagar la salida a nuevas compuertas;
// esto gatilla
                                                                          //nuevos eventos de cambios itinerados en pq.

      }                                                  
   }

Funcionalidades adicionales a incorporar: Usando el código entregado como avance (si lo desea puede desarrollar uno propio, si encuentra errores o mejoras, avisar) su grupo debe proveer las siguientes funciones adicionales:
a) En menú Insert bajo Edit agregar la opción NAND, NOR y Meter. Meter debe tener misma funcionalidad de la tarea 1 y puede tener apariencia similar a la de Figura 1.
b) En menú Insert bajo Edit agregar imágenes acorde a cada opción (inversor, or, nand, nor, wire, source, y meter).
c) Al seleccionar un elemento del circuito moviendo el mouse, el usuario lo debe poder eliminar (delete) presionando la tecla d.
d) Al seleccionar una compuerta del circuito moviendo el mouse) y luego presionar la letra r el usuario debe poder ingresar vía ventana un nuevo valor para el retardo por omisión de una compuerta.
e) En menú Simulate modificar la acción asociada a Start incluyendo un llamado a "re-inicialización" del circuito para llevar cada elemento del circuito a un estado inicial. Así será posible repetir la simulación cuantas veces se desee.

Resultados a Entregar de su Grupo
Preparar un archivo makefile (explicación) para compilar y ejecutar su tarea en aragorn. Además incluya rótulos "clean" para borrar todos los .class generados y "doc" para generar la documentación en directorio "documentation".
Entregue todo lo indicado en Normas de Entrega de Tareas. Su documentación automática con javadoc para las (dos) clases adicionales pedidas debe ser generable con:
$ make doc
Para complicar debería bastar con:
$ make
Para correr su programa:
$ make run
Para borrar los .class:
$ make clean
No incluya las páginas html generadas por javadoc, éstas serán generadas por este comando cuando el ayudante las revise.
En su archivo de documentación (pdf o html) incorpore el diagrama de clases de la aplicación. Para el caso del código entregado, éste es el diagrama. Como aquí, no incluya todas las referencias. Éste lo puede generar con jgrasp u otro programa.
En su documentación incluya dos diagramas similares a figura 2. Uno contendrá su resultado para el circuito de la figura 3 y el otro el resultado para el flip flip tipo D de la tarea 1. Estos dos diagramas se hacen usando una planilla excel o similar a partir del archivo generado por Meter.

Créditos extras: Su grupo puede recibir hasta 10 puntos adicionales su grupo muestra el identificador de cada elemento al interior de éste. La nota máxima sigue siendo 100, pero su posible trabajo adicional le permitirá compensar algún lado bajo de su solución. Ojo esto es opcional, usted debe rendir bien en los otros ramos también.

Ayudas
* Dé una mirada a la solución parcial del problema. Si encuentra errores o algo que pueda ser mejorado, avise al profesor.
* No dude en consultar al profesor o ayudante sobre dudas de esta tarea.