Está en la página 1de 88

Minecraft para diseños HDL: Flujo

de Síntesis de Verilog para Circuitos


de Redstone - ID2019/076
PROGRAMA DE MEJORA DE LA CALIDAD

MEMORIA DE JUSTIFICACIÓN

12 de julio de 2020
Autor: Gabriel Villarrubia Gonzalez
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

Índice
MIEMBROS DEL EQUIPO DE TRABAJO: ...................................................................................... 2
MOTIVACIÓN DE ESTE TRABAJO:............................................................................................ 3
OBJETIVOS CONSEGUIDOS DURANTE LA REALIZACIÓN DE ESTE PROYECTO: ......................................... 8
TEMPORIZACIÓN DE TAREAS REALIZADAS .............................................................................. 10
PUNTO DE PARTIDA, ENCUESTA A ESTUDIANTES: ...................................................................... 10
FUNCIONAMIENTO DEL ALGORITMO: ................................................................................... 15
PUESTA EN FUNCIONAMIENTO: ........................................................................................... 31
CONCLUSIONES: ............................................................................................................ 35
CODIGO ADJUNTADO ................................................................................................. 38

1
Minecraft para diseños HDL: Flujo de
Síntesis de Verilog para Circuitos de
Redstone - ID2019/076
PROGRAMA DE MEJORA DE LA CALIDAD

Miembros del equipo de trabajo:

Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020
NIF Nombre y apellidos E-mail

Juan Francisco De Paz Santana fcofds@usal.es

María Navelonga Moreno mmg@usal.es

Juan Ramón Muñoz Rico rico@usal.es

Juan José Bullón Pérez perbu@usal.es

José Torreblanca González torre@usal.es

Vivian Félix López Batista vivian@usal.es

Daniel Hernández de la Iglesia danihiglesias@usal.es

Diego Manuel Jiménez Bravo dmjimenez@usal.es

André Filipe Sales Mendes andremendes@usal.es

Lucía Martin Gómez luciamg@usal.es

Rubén Martín García rubenmg@usal.es

Javier Pérez Marcos jpmarcos@usal.es

Javier Caridad Hernández jch@usal.es

Mario Muñoz Moreno mariomunoz3m@usal.es

Aarón González Hernández aarongh@usal.es

Yanira Navarro Marrero marnayan@usal.es

2
Motivación de este trabajo:

En los últimos meses todo el mundo habla de Minecraft como herramienta en


educación. El lanzamiento de Minecraft: Education Edition ha hecho que muchos
se interesen por el videojuego, siendo este el juego más vendido de la historia.
Tal y como recoge la página web guiainfantil.com, si hay un juego que cada vez
está más de moda en cuestiones virtuales, ése es el minecraft. Esta versión
online de construcciones puede ser utilizada por los adultos, pero cada vez
tiene más presencia en el mundo académico. A través del ordenador, tablet o
dispositivos móviles, los niños pueden jugar a minecraft, un juego de
construcciones en tres dimensiones a través del que el usuario puede erigir
desde un refugio hasta una casa pasando por un búnker a partir de distintas
herramientas.
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

El encanto de minecraft es que cada elemento que aparece está compuesto por
cubos de tres dimensiones y, a partir de distintos utensilios, puede cimentar
lugares en los que refugiarse dependiendo de las necesidades del juego.
Las 7 ventajas de jugar al Minecraft en el ámbito educativo son enumeradas a
continuación:
1. Creatividad. Minecraft es ante todo un juego creativo. Quien juegue a esta
actividad debe estar dispuesto a llevar a cabo construcciones en momentos de
supervivencia, además, gracias a los bloques de materiales, podrán establecerse
todo tipo de estructuras. Los niños podrán llevar a cabo casas de varios pisos,
habitaciones, pasadizos o pasillos, gestionando ellos mismos los bienes que
aparecen, utilizando su imaginación.
2. Visión espacial. Conceptos como el espacio, la longitud, el volumen o la
superficie van ligados a la fisionomía de los juegos de minecraft. Además de ser
divertidos y especiales para niños, incluyen este tipo de conceptos en las
construcciones online que irán haciendo los niños, que al fin y al cabo son
fundamentales para su desarrollo.
3. Relajación. Como todo juego, uno de sus principales beneficios es la
capacidad que tiene en los niños para relajarles. Nuestros hijos estarán
tranquilos con un juego como minecraft porque carece de violencia y no les
alterará, además, algunas partes del juego, como la recolección de herramientas,
pueden hacerse de forma automática y no hará que se pongan nerviosos.
4. Concentración. Aunque jugar a una actividad como minecraft ayuda a que la
mente esté despejada, también es cierto que requiere una concentración
especial. Los niños que lleven a cabo desarrollos dentro de este juego, tendrán
que estar muy atentos a la hora de crear su proyecto y de construir el refugio o la
casa que estén pensando en ese momento. Aunque el hecho de acumular o
colocar herramientas sea distendido, su capacidad de concentración
aumentará porque deberá estar muy pendiente de la construcción para que
funcione.
5. Capacidad de razonamiento. Para jugar a minecraft los niños tendrán que
aprender a discurrir rápidamente y con tiento, es decir, para establecer la
construcción y no equivocarse no vale con dejarse llevar, sino que los niños

3
tienen que pensar concienzudamente si cada paso es correcto y si merece la
pena para la estructura que están llevando a cabo.
6. Gestión de recursos. Otro de los beneficios de jugar a minecraft es que los
niños aprenderán a gestionar los recursos disponibles, ya que éstos no se
reproducen de forma mágica. Para llevar a cabo sus construcciones, se instruirán
en la necesidad de poder llevar a cabo las actividades con los bienes
disponibles que les da el propio juego en su versión de supervivencia, que va
más allá de la creatividad. Además de la gestión de estos recursos, también
aprenderán a descubrir la eficacia de estos para dotarles de mayor creatividad.
7. Superación personal. Teniendo en cuenta que los retos de minecraft se van
complicando conforme avanza el usuario, esto ayuda al niño a aumentar su
marca personal a la hora de establecer las construcciones. Los niños se
querrán superar a sí mismos para afrontar nuevos obstáculos según se vaya

Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020
complicando la actividad.
Minecraft es motivador y despierta el interés de los alumnos, que aprenden
mientras se divierten. Permite potenciar multitud de habilidades, desde
la creatividad, la imaginación, la resolución de problemas o la competencia
digital hasta nociones de ingeniería, matemáticas, historia o arte, según el
enfoque que le dé el profesor. Además, promueve el aprendizaje activo, el
esfuerzo, el afán de superación, el pensamiento crítico y la cooperación.
La clave de utilizar Minecraft en el ámbito educativo reside en utilizar un
videojuego que resulta divertido para los estudiantes y aprovechar esa
motivación para impulsar el aprendizaje. Partiendo de esta base, las opciones
son tan variadas como la creatividad del docente y el objetivo que busque.
Por sus características y su condición de videojuego online , mejora la
competencia digital y la creatividad, siendo adecuado para que los alumnos
aprendan a desenvolverse y utilizar las TIC, poniendo en práctica toda su
creatividad e imaginación.
Otra de las aplicaciones frecuentes de Minecraft en el aula es el practicar con la
arquitectura y diseñar mejores espacios y ciudades, espacios respetuosos con el
medio ambiente, nuevas soluciones arquitectónicas… Además, permite
comprender de forma gráfica las características de un movimiento arquitectónico
o las claves de la ingeniería y los materiales.
El juego también mejora la lectura y la expresión escrita permitiendo incluir
mensajes, expresarse y comunicarse con otros jugadores en el entorno virtual a
través del chat textual incorporado e incluso escribir libros o guías en el propio
juego con el objeto Libro y pluma.
La propia web de Minecraft Education Edition permite descargarse lecciones con
las que los alumnos pueden recorrer el templo de Artemisa o las pirámides de
Egipto, crear obras de arte o conocer las construcciones de la II Guerra Mundial.
También se puede aplicar el role-playing en los escenarios de Minecraft para
profundizar en culturas o civilizaciones.
Minecraft permite estudiar cualquier asignatura por muy específica que sea, por
ejemplo, estudiar química, ciencias… o cualquier otra materia. El blog Proyectos
de Ciencia y Tecnología recopila las numerosas aplicaciones que puede tener
Minecraft en la educación. Por ejemplo, los profesores Mark Lorch y Joel Millsy.

4
Sus alumnos crearon MolCraft http://hipertextual.com/2015/11/molcraft, un
mundo con representaciones de moléculas químicas que ahora cualquier usuario
puede descargar como paquete y agregarlo a su juego. Es una de las muchas
modificaciones, mods, que se añaden a Minecraft y suman nuevas opciones al
juego, resultando muy útiles para el ámbito educativo. El
propio MinecraftEdu nació como mod para docentes y ahora se está adaptando
para crear Minecraft Education Edition, en cuya web también pueden verse y
compartirse propuestas educativas con este videojuego.
Debido a lo mencionado anteriormente, el grupo de trabajo decide poner en
marcha este novedoso proyecto centrado en desarrollar contenidos relacionados
con las asignaturas de electrónica del Grado de Ingeniería Informática.
El objetivo de este proyecto es crear un espacio virtual mediante la
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

utilización de tecnología Minecraft que permita al estudiante aumentar el


contenido académico relacionado con los conocimientos impartidos en las
distintas ramas de las asignaturas de electrónica-física de la Universidad de
Salamanca. Con el presente proyecto, no se pretende sustituir las explicaciones
del profesor, sino crear una herramienta que sirva como complemento a las
lecciones estáticas y convencionales que se imparten a diario. El equipo de
trabajo que forma parte de la presente solicitud ha trabajado en el desarrollo de
un conjunto de módulos y plugins para Minecraft con objeto de que los
estudiantes de Ingeniería puedan diseñar y verificar el comportamiento de
los circuitos secuenciales que se enseñan en asignaturas de electrónica de una
forma atractiva, novedosa y que motive su utilización. Para ello, se utilizará como
lenguaje de programación JAVA y un framework de desarrollo de bloques
denominado MineCraftForge. El objetivo es utilizar RedStone para diseñar
circuitos digitales mejorando las capacidades de aprendizaje de los alumnos. La
planificación inicial prevista es desarrollar un módulo que permita interpretar el
código HDL (Hardware Description Language) utilizado como estándar en
electrónica y construir una secuencia de bloques digitales, con objeto de
comprender y verificar su correcto funcionamiento. A continuación, se visualiza
un ejemplo.

5
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020
I LUSTRACIÓN 1. E JEMPLO C IRCUITO ELECTRÓNICO BÁSICO CON DISPLAY

I LUSTRACIÓN 2. P RÁCTICA F INAL C OMPUTADORES R EALIZADA CON M INECRAFT

6
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

7
I LUSTRACIÓN 3. P RÁCTICA F INAL C OMPUTADORES R EALIZADA CON M INECRAFT
Objetivos conseguidos durante la realización de este proyecto:
# OBJETIVO DESCRIPCIÓN

01 Especificaciones y definición de la herramienta. Descripción: Concepción y elaboración del diseño


del sistema interpretativo HDL.
Resultado: Diseño y elaboración de los objetivos
del sistema de creación de grafos mediante.

01.1 Especificación de requisitos funcionales. Descripción: Elicitación de los contenidos


funcionales que la herramienta debe cumplir en el
proceso de desarrollo.
Resultado: Conjunto de requisitos funcionales.

01.2 Especificación de requisitos no funcionales y de Descripción: Análisis de los requisitos necesarios


interoperabilidad en una clase. para el correcto desarrollo de la herramienta y su

Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020
incorporación en una clase.
Resultado: Conjunto de requisitos no funcionales y
medidas para la correcta incorporación del sistema
en cualquier clase.

02 Investigación de técnicas. Descripción: Investigación de técnicas para la


elaboración de la herramienta.
Resultado: Técnicas apropiadas la elaboración de la
herramienta.
02.1 Investigación de técnicas de diseño de circuitos Descripción: Análisis de las técnicas existentes para
y utilización de verilog la elaboración de aplicaciones de realidad virtual.
Resultado: Estado del arte de técnicas de realidad
virtual.
02.2 Investigación y estudio del SDK de Oculos Rift Descripción: Análisis del SDK y las
funcionalidades disponibles del dispositivo Oculos
Rift.
Resultado: Conocimiento detallado de todas las
posibilidades disponibles del dispositivo.

02.3 Investigación y estudio acerca del desarrollo de Descripción: Análisis de diferente documentación
plugins y mods para Minecraft para desarrollar módulos para Minecraft.
Resultado: Elección del framework y tecnologías de
implementación.

03 Elaboración de la herramienta. Descripción: Desarrollo del software para el


funcionamiento del sistema.
Resultado: Software necesario para la integración
de los diferentes componentes del sistema.

03.1 Desarrollar el software de interpretación de Descripción: Programación de la aplicación


circuitos HDL e implementación y construcción encargada de generar circuitos en Minecraft a partir
automática de bloques en Minecraft. del lenguaje HDL.
Resultado: Módulo Jar compatible con Minecraft.
03.2 Creación de diferentes entornos virtuales para la Descripción: Diseño y modelado de diferentes
simulación de diversos escenarios. entornos virtuales.
Resultado: Conjunto de entornos virtuales que
pueden ser usadas para el simulado de las clases y

8
prueba de circuitos digitales.

04 Instalación y entono de pruebas. Descripción: Instalación de la aplicación en las


Oculus Rift y generación de contendido multimedia
de pruebas.
Resultado: Versión alfa del sistema, para el testeo y
realización de pruebas con contenido multimedia de
prueba.

04.1 Generación de contenido de ejemplo para clases Descripción: Diseño del contenido multimedia y
de electrónica. manuales para formar a los profesores.
Resultado: Contenido de pruebas.

04.2 Instalación de la aplicación en las Oculus Rift Descripción: Instalación de la aplicación en las
para las pruebas. Oculus Rift.
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

Resultado: Oculus Rift con la aplicación preparada


para la asistencia de una clase virtual.

04.3 Detección de posibles errores. Descripción: Ensayo del funcionamiento de la


aplicación, para hallar posibles defectos.
Resultado: Estado de la aplicación para realizar
posibles correcciones de errores.

04.4 Implementación de posibles mejoras en la Descripción: Percepción de posibles mejoras que


usabilidad de la aplicación. aumenten las características del sistema.
Resultado: Incremento de la funcionalidad del
sistema.
05 Aplicación de la herramienta en escenario real Descripción: Comenzar pruebas en cursos reales en
las titulaciones de ingeniería.
Resultado: Resultados general y amplio es curso
académico.

05.1 Evaluación de la herramienta en un caso de Descripción: Evaluar el rendimiento en las


estudio real. asignaturas y de la herramienta.
Resultado: Obtención de resultados en asignaturas
de plan académico.

05.2 Medición del impacto mediante indicadores de Descripción: Medir si la herramienta presenta una
eficiencia. eficiencia en el rendimiento de los alumnos.
Resultado: Obtención de resultados académico
gracias a la implantación del proyecto.

05.3 Obtención de resultados obtenidos mediante el Descripción: Generar resultados de compromiso de


empleo de la aplicación. los estudiantes con los planes de estudio para el
análisis de resultados académicos en entregas.
Resultado: Documentación de la evolución de la
mejora en las técnicas de estudio aplicadas por los
alumnos.
06 Difusión de los resultados. Descripción: Difundir los resultados obtenidos
gracias a la implantación de la herramienta en el
campus.
Resultado: Difusión general y científica del empleo
del sistema.

9
06.1 Recogida y evaluación de la implantación del Descripción: Evaluación de todos los resultados
sistema. obtenidos mediante el desarrollo e implantación del
sistema.
Resultado: Documentar todos los resultados
obtenidos a nivel de usabilidad, desarrollo software,
empleo de los alumnos y beneficios académicos.
06.2 Publicación de los resultados obtenidos en Descripción: Exposición de los resultados
revistas científicas. obtenidos en Congreso y revistas del proyecto para
la difusión de los beneficios de este tipo de
herramientas.
Resultado: Publicación de artículo en congreso
internacional.

Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020
Temporización de Tareas Realizadas

F IGURA 2 T EMPORIZACIÓN DE T AREAS

Punto de partida, encuesta a estudiantes:


Con objeto de evaluar la propuesta y conocer el grado de aceptación de la
utilización de Minecraft en el aula, se han escogido a 15 estudiantes que ya
habían estudiado la asignatura de Computadores I del Grado de Ingeniería
Informática mediante métodos tradicionales. Estos alumnos, han compartido 5
licencias de Minecraft y unas gafas de tipo Oculus con objeto de poder evaluar la
experiencia de aprendizaje de Minecraft en un entorno VR.

A continuación, se muestran los resultados finales de la encuesta:

10
1. ¿Conoces Minecraft?

¿Conoces Minecraft?
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

SI No

2. ¿Has utilizado Minecraft alguna vez en el instituto o Universidad?

¿Has utilizado Minecraft en un ámbito


educativo?

SI No

11
3. ¿Crees que la utilización de Minecraft en el grado de Ingeniería
Informática podría facilitar la adquisición de conocimientos?

¿Utilizarías Minecraft en alguna asignatura


de tu carrera?

Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020
SI No

4. ¿Tienes un dispositivo para utilizar Minecraft de forma óptima?

¿Dispones de un PC y una buena conexión?

SI No

12
5. ¿Conoces RedStone?

¿Conoces RedStone?
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

SI No

6. ¿Has programado alguna vez un circuito HDL con RedStone?

¿Has utilizado RedStone alguna vez?

SI No

13
7. ¿Te gustaría que en la asignatura de Computadores I, los profesores
utilizasen Minecraft en alguna sesión?

¿Te gustaría aprender Computadores I con


la ayuda de Minecraft?

Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020
SI No

Tras la realización de la encuesta, podemos concluir que los alumnos conocen en


su completa mayoría Minecraft. Esto se debe a que Minecraft es el juego más
vendido, sin embargo, podemos contrastar que son muy pocos los que han
utilizado esta herramienta en un entorno educativo.
Una vez realizada la encuesta, se puede dirimir que todos están a favor de
incorporar esta herramienta en el Grado de Ingeniería Informática. Son varios
alumnos los que indican que necesitarían disponer de mejores recursos
informáticos ya que dudan del rendimiento del juego con su equipación
informática actual.
La encuesta también refleja que los alumnos usan Minecraft para jugar, no
conociendo RedStone, lo que da una mayor importancia a este proyecto de
innovación docente, que busca como enseñar a diseñar circuitos electrónicos
con Minecraft.

14
Funcionamiento Del Algoritmo:
El funcionamiento del sistema de conversión de circuitos de verilog a redstone se
ha implementado mediante el siguiente algoritmo:

MinecraftHDL: A Digital Synthesis Flow for Minecraft Circuits McGill University -


ECSE 457 – Group Three. Andrew Penhale, Omar Ba Mashmos, Francis O’Brien,
Brett H.Meyer.
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

15
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

16
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

17
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

18
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

19
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

20
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

21
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

22
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

23
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

24
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

25
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

26
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

27
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

28
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

29
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

30
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

31
Puesta en funcionamiento:

I LUSTRACIÓN 5. C REACIÓN DE CUENTA


I LUSTRACIÓN 4. C OMIENZO DE I NSTALACIÓN
I LUSTRACIÓN 6. A CCESO AL SISTEMA

I LUSTRACIÓN 7. P ANTALLA BIENVENIDA


Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

32
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

33
I LUSTRACIÓN 9. I NSTALACIÓN DE
MINECRAFT
I LUSTRACIÓN 8. I NSTALACIÓN D EL SISTEMA VR
I LUSTRACIÓN 11. EJEMPLO ALUMNO JUGANDO
I LUSTRACIÓN 10. F INALIZACIÓN DE INSTALACIÓN

Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

34
Conclusiones:
Vistos muchas veces como una pérdida de tiempo, los “juegos tienen más
beneficios que desventajas en la educación universitaria”. La idea de jugar o
divertirse jugando es una actividad que a menudo se relaciona con los niños. Los
adultos difícilmente podrían asociar en una primera instancia el juego a la vida
adulta. Al mismo tiempo, la consideración de que “jugar es perder el tiempo” se
encuentra largamente extendida en entornos educativos y profesionales de la
educación. Estos prejuicios y limitaciones iniciales cuando se aplican al mundo
educativo no hacen más que prohibir el pasaje al aula de una herramienta
sumamente útil tanto para docentes como para estudiantes de todos los niveles.
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

El juego, en sus múltiples facetas, puede resultar ampliamente beneficioso en el


contexto universitario. Los estudiantes inmersos en sus propios universos
particulares, con reglas y preocupaciones individuales, se distancian de sus
padres, docentes e incluso del propio conocimiento al permanecer en el aula
escuchando las mismas lecciones estáticas durante horas. Es por ello por lo que
los profesionales docentes deben de intentar mejorar las capacidades grupales
de los alumnos mejorando la forma en la que estos procesan la
información recibida en clase, su vínculo con los compañeros, y la relación con
los docentes. Es de vital importancia incorporar a las tradicionales clases
magistrales una mínima parte lúdica. Jugar aprendiendo, crea un nuevo universo
“colectivo” que permite olvidar las reglas y limitaciones individuales, los
prejuicios y las dudas, potenciando el completo desarrollo de las propias
capacidades y fijando de mejor forma los conocimientos. Los expertos señalan
que la única solución viable para cubrir estas necesidades pasa por asociarla a
la educación digital. Ante esta previsión se están implementando y buscando
soluciones basadas en las posibilidades que ofrece la tecnología y que, según
fuentes de Telefónica Educación Digital, la división especializada en soluciones
de educación de Telefónica, permiten desarrollar programas de transformación
tecno-pedagógicas y avanzar hacia nuevas modalidades de capacitación.
A nivel técnico y una vez finalizado este proyecto, se puede concluir que se ha
diseñado e implementado una utilidad que permite enseñar contenidos de las
asignaturas de electrónica mediante Minecraft y Redstone. Toda la
documentación del proyecto, códigos fuente, manual de instalación y pruebas de
funcionamiento han sido almacenadas en un repositorio público con objeto de
que otros docente y entidades académicas pueda beneficiarse de este trabajo.
La dirección del repositorio es la siguiente:
https://github.com/gabri15/MinecraftHDL

35
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

Este proyecto de innovación docente ha tenido gran repercusión en los medios y


entre el alumnado de Salamanca. Diferentes medios nacionales se hicieron eco
del desarrollo del proyecto y son numerosos los usuarios que de forma voluntaria
se encuentran desarrollando contenido en un servidor público que ha sido
liberado durante la ejecución de este proyecto.

36
Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

I LUSTRACIÓN 12. N OTICIA EL MUNDO : HTTPS :// DIARIODECASTILLAYLEON . ELMUNDO . ES / ARTICULO / INNOVADORES / LECCION -
UNIVERSITARIA - BASE - CUBOS - PIXELES /20200519120412009801. HTML

Por último, agradecer a la Universidad de Salamanca su compromiso de mejorar


continuamente para alcanzar los niveles de excelencia necesarios para una
adecuada formación académica y capacitación profesional de sus estudiantes.
La realización de este proyecto ha permitido poner en marcha una novedosa
forma de impartir conocimientos relacionados con asignaturas de electrónica.

37
CODIGO ADJUNTADO

Minecraft para diseños HDL: Flujo de Síntesis de Verilog para Circuitos de Redstone - ID2019/076 | 12 de julio de 2020

38
File: /home/gabri/MinecraftHDL/src/…crafthdl/block/BasicBlock.java Page 1 of 1

package minecrafthdl.block;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;

public class BasicBlock extends Block {

public BasicBlock(String unlocalizedName, Material material, float hardness,


float resistance) {
super(material);
this.setUnlocalizedName(unlocalizedName);
this.setCreativeTab(CreativeTabs.MISC);
this.setHardness(hardness);
this.setResistance(resistance);
}

public BasicBlock(String unlocalizedName, float hardness, float resistance) {


this(unlocalizedName, Material.ROCK, hardness, resistance);
}

public BasicBlock(String unlocalizedName) {


this(unlocalizedName, 2.0f, 10.0f);
}

}
File: /home/gabri/MinecraftHDL/src/…locks/BlockRenderRegister.java Page 1 of 1

package minecrafthdl.client.render.blocks;

import minecrafthdl.MinecraftHDL;
import minecrafthdl.block.ModBlocks;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;

public class BlockRenderRegister {


public static void registerBlockRenderer() {
reg(ModBlocks.synthesizer);
}

public static void reg(Block block) {


Minecraft.getMinecraft().getRenderItem().getItemModelMesher()
.register(Item.getItemFromBlock(block), 0, new
ModelResourceLocation(MinecraftHDL.MODID + ":" +
block.getUnlocalizedName().substring(5), "inventory"));
}
}
File: /home/gabri/MinecraftHDL/src/…synthesis/routing/Channel.java Page 1 of 7

package minecrafthdl.synthesis.routing;

import minecrafthdl.Utils;
import minecrafthdl.synthesis.Circuit;
import minecrafthdl.synthesis.routing.pins.Pin;
import minecrafthdl.synthesis.routing.pins.PinPair;
import minecrafthdl.synthesis.routing.pins.PinsArray;
import minecrafthdl.synthesis.routing.vcg.VerticalConstraintGraph;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;

import java.util.ArrayList;

public class Channel {


public PinsArray pinsArray;
public ArrayList<ArrayList<Net>> tracks = new ArrayList<ArrayList<Net>>();

public void findAvailableTrack(Net net, VerticalConstraintGraph vcg){


if (net == null){
return;
}
int highest_track = 0;
try {
for (int vc_id : vcg.getEdgeIDList(net.id)){
for (ArrayList<Net> track : this.tracks){
for (Net n : track){
if (n.id == vc_id && n.track >= highest_track)
highest_track = n.track + 1;
}
}
}

} catch (Exception e) {
e.printStackTrace();
}

for(int i = highest_track; i < this.tracks.size(); i++){


boolean hasConflict = false;
for (Net n : this.tracks.get(i)){
hasConflict = n.hasHorizontalConflict(net);
if (hasConflict) break;
}
if (!hasConflict){
this.tracks.get(i).add(net);
net.setTrack(i);
return;
}
}
ArrayList<Net> new_track = new ArrayList<Net>();
new_track.add(net);
this.tracks.add(new_track);
net.setTrack(this.tracks.size() - 1);
}

public Circuit genChannelCircuit(){


int length = 2 + (3 * this.tracks.size());
int height = 3;
int width = 0;

for (ArrayList<Net> track : this.tracks){


for (Net n : track){
if (n.x_max > width) width = n.x_max;
}
}
File: /home/gabri/MinecraftHDL/src/…synthesis/routing/Channel.java Page 2 of 7

width += 1;

Circuit circuit = new Circuit(width, height, length);

ArrayList<Net> nets_done = new ArrayList<Net>();

for(ArrayList<Net> track : this.tracks){


for (Net n : track){
if (nets_done.contains(n)) continue;
this.placeTrack(circuit, n.track, n.x_min, n.x_max, n.getpins());
nets_done.add(n);

if (n.isOutpath()){
circuit.setBlock(n.x_max, 0, n.trackZ() + 1,
Blocks.WOOL.getDefaultState());
circuit.setBlock(n.x_max, 1, n.trackZ() + 1,
Blocks.REDSTONE_WIRE.getDefaultState());
}

if (n.out_partner != null && !n.isOutpath()){


circuit.setBlock(n.x_max, 0, n.trackZ() - 1,
Blocks.WOOL.getDefaultState());
circuit.setBlock(n.x_max, 1, n.trackZ() - 1,
Blocks.REDSTONE_WIRE.getDefaultState());
}

this.wireColumns(circuit, n);
this.repeatNets(circuit, n);
}
}

return circuit;
}

public void printChannel(){


int width = pinsArray.getPairs().size();
int height = tracks.size() + 2;

String[][] chars = new String[width][height];

for (int x = 0; x < width; x++){


for (int y = 0; y < height; y++){
chars[x][y] = ".";
}
}

for (int x = 0; x < width; x++){


PinPair pair = pinsArray.getPair(x);

chars[x][0] = Integer.toString(pair.top.netID()).charAt(0) + "";


chars[x][height - 1] = Integer.toString(pair.bot.netID()).charAt(0) +
"";
if (pair.top.empty()) chars[x][0] = " ";
if (pair.bot.empty()) chars[x][height - 1] = " ";
}

for (ArrayList<Net> t : tracks){


for (Net n: t){
for (Pin p : n.getpins()){
if (p.top) {
for(int i = 1; i <= n.track + 1; i++){
chars[p.xPos()/2][i] = "│";
File: /home/gabri/MinecraftHDL/src/…synthesis/routing/Channel.java Page 3 of 7

}
} else {
for(int i = n.track + 1; i < height - 1; i++){
chars[p.xPos()/2][i] = "│";
}
}
}
}
}

for (ArrayList<Net> t : tracks) {


for (Net n : t) {
if (n.isOutpath()){
for (int y = n.track; y <= n.out_partner.track; y++){
chars[n.x_max / 2][y + 1] = "|";
}
}
}
}

for (ArrayList<Net> t : tracks){


for (Net n: t){
for (int i = n.x_min/2; i <= n.x_max/2; i++){
if(n.x_max == n.x_min) continue;
chars[i][n.track + 1] = "─";
}
}
}

for (ArrayList<Net> t : tracks){


for (Net n: t){

if(n.isOutpath()){
chars[n.x_max / 2][n.track+1] = "┐";
chars[n.x_max / 2][n.out_partner.track+1] = "┘";
}

for (Pin p : n.getpins()){


int x = p.xPos() / 2;

boolean up = false;
boolean down = false;
boolean left = n.x_min / 2 < x;
boolean right = n.x_max / 2 > x;

if (p.top){
up = true;
for (Pin p2 : n.getpins()){
if (p2 != p && p.xPos() == p2.xPos()) down = true;
}
} else {
down = true;
for (Pin p2 : n.getpins()){
if (p2 != p && p.xPos() == p2.xPos()) up = true;
}
}

if (up){
if (down){
if (left){
if (right) chars[x][n.track + 1] = "┼";
else chars[x][n.track + 1] = "┤";
} else {
if (right) chars[x][n.track + 1] = "├";
//else chars[x][n.track + 1] = "│";
File: /home/gabri/MinecraftHDL/src/…synthesis/routing/Channel.java Page 4 of 7

}
} else {
if (left){
if (right) chars[x][n.track + 1] = "┴";
else chars[x][n.track + 1] = "┘";
} else {
if (right) chars[x][n.track + 1] = "└";
else chars[x][n.track + 1] = "?";
}
}
} else {
if (down){
if (left){
if (right) chars[x][n.track + 1] = "┬";
else chars[x][n.track + 1] = "┐";
} else {
if (right) chars[x][n.track + 1] = "┌";
else chars[x][n.track + 1] = "?";
}
} else {
if (left){
//if (right) chars[x][n.track + 1] = "─";
//else chars[x][n.track + 1] = "?";
} else {
if (right) chars[x][n.track + 1] = "?";
else chars[x][n.track + 1] = "?";
}
}
}
}
}
}

for (int y = 0; y < height; y++){


String row = "";
for (int x = 0; x < width; x++){
row += chars[x][y];
//row += " ";
}
System.out.println(row);
}

public void placeTrack(Circuit channel, int track_number, int xmin, int xmax,
ArrayList<Pin> pins){
int z_min = 1 + (3 * track_number);
int z_track = z_min + 1;

for (int x = xmin; x <= xmax; x++){


channel.setBlock(x, 1, z_track, Blocks.WOOL.getDefaultState());
channel.setBlock(x, 2, z_track,
Blocks.REDSTONE_WIRE.getDefaultState());
}

for (Pin p : pins){


if (p.top) {
channel.setBlock(p.xPos(), 0, z_min,
Blocks.WOOL.getDefaultState());
channel.setBlock(p.xPos(), 1, z_min,
Blocks.REDSTONE_WIRE.getDefaultState());
} else {
channel.setBlock(p.xPos(), 0, z_track + 1,
Blocks.WOOL.getDefaultState());
channel.setBlock(p.xPos(), 1, z_track + 1,
Blocks.REDSTONE_WIRE.getDefaultState());
File: /home/gabri/MinecraftHDL/src/…synthesis/routing/Channel.java Page 5 of 7

}
}
}

public void wireColumns(Circuit channel, Net n) {


for (Pin p : n.getpins()){
if (p.top) {
for (int z = 0; z < n.trackZ() - 1; z++){
channel.setBlock(p.xPos(), 0, z,
Blocks.REDSTONE_WIRE.getDefaultState());
}
} else {
for (int z = n.trackZ() + 2; z < this.sizeZ(); z++){
channel.setBlock(p.xPos(), 0, z,
Blocks.REDSTONE_WIRE.getDefaultState());
}
}
}

if (n.isOutpath()){
for (int z = n.trackZ() + 2; z < n.out_partner.trackZ() - 1; z++){
channel.setBlock(n.x_max, 0, z,
Blocks.REDSTONE_WIRE.getDefaultState());
}
}
}

public void repeatNets(Circuit channel, Net n) {

for (Pin p : n.getpins()) {


if (p.top) {
if (n.trackZ() > 10) {
for (int z = n.trackZ() - 10; z > -1; z -= 10){
channel.setBlock(p.xPos(), 0, z,
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.NORTH));
}
}

if (p.xPos() > n.x_min) {


channel.setBlock(p.xPos() - 1, 2, n.trackZ(),
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.EAST));
}

if (p.xPos() < n.x_max) {


channel.setBlock(p.xPos() + 1, 2, n.trackZ(),
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.WEST));
}
} else {
if (channel.getSizeZ() - n.trackZ() > 10) {
for (int z = n.trackZ() + 3; z < channel.getSizeZ(); z += 10){
channel.setBlock(p.xPos(), 0, z,
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.NORTH));
}
}
if (!(!n.outpath && n.out_partner != null)) {
if (p.xPos() > n.x_min) {
if (p.xPos() > n.top_pin.xPos())
channel.setBlock(p.xPos() - 1, 2, n.trackZ(),
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.WEST));
}
File: /home/gabri/MinecraftHDL/src/…synthesis/routing/Channel.java Page 6 of 7

if (p.xPos() < n.x_max) {


if (p.xPos() < n.top_pin.xPos())
channel.setBlock(p.xPos() + 1, 2, n.trackZ(),
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.EAST));
}
} else {
channel.setBlock(p.xPos() + 1, 2, n.trackZ(),
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.EAST));
}
}
}

if (n.x_max - n.x_min > 19) {


for (int x = n.x_min + 2; x < n.x_max - 2; x += 14) {
for (Pin p : n.getpins()){
if (x == p.xPos()) x-= 1;
}

if (!(!n.outpath && n.out_partner != null)) {


if (x < n.top_pin.xPos())
channel.setBlock(x, 2, n.trackZ(),
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.EAST));
if (x > n.top_pin.xPos())
channel.setBlock(x, 2, n.trackZ(),
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.WEST));
} else {
channel.setBlock(x, 2, n.trackZ(),
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.EAST));
}
}
}

if (n.isOutpath()){
if (n.out_partner.trackZ() - n.trackZ() > 14) {
for (int z = n.trackZ() + 3; z < n.out_partner.trackZ() - 2; z +=
13){
channel.setBlock(n.x_max, 0, z,
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.NORTH));
}
}

channel.setBlock(n.x_max - 1, 2, n.trackZ(),
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.WEST));
}

if (!n.isOutpath() && n.out_partner != null){


channel.setBlock(n.x_max - 1, 2, n.trackZ(),
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.EAST));

}
}

public int sizeX(){


int x_max = 0;

for (ArrayList<Net> t : this.tracks){


for (Net n : t){
if (n.x_max > x_max) x_max = n.x_max;
File: /home/gabri/MinecraftHDL/src/…synthesis/routing/Channel.java Page 7 of 7

}
}
return x_max;
}

public int sizeZ(){


return 2 + (this.tracks.size() * 3);
}

}
File: /home/gabri/MinecraftHDL/src/…rafthdl/synthesis/Circuit.java Page 1 of 3

package minecrafthdl.synthesis;

import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntitySign;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Circuit {

public static boolean TEST = false;

ArrayList<ArrayList<ArrayList<IBlockState>>> blocks;
HashMap<Vec3i, TileEntity> te_map = new HashMap<Vec3i, TileEntity>();

public Circuit(int sizeX, int sizeY, int sizeZ){


this.blocks = new ArrayList<ArrayList<ArrayList<IBlockState>>>();
for (int x = 0; x < sizeX; x++) {
this.blocks.add(new ArrayList<ArrayList<IBlockState>>());
for (int y = 0; y < sizeY; y++) {
this.blocks.get(x).add(new ArrayList<IBlockState>());
for (int z = 0; z < sizeZ; z++) {
if (!Circuit.TEST)
this.blocks.get(x).get(y).add(Blocks.AIR.getDefaultState());
}
}
}
}

public void setBlock(int x, int y, int z, IBlockState blockstate) {


if (TEST) return;
this.blocks.get(x).get(y).set(z, blockstate);
}

public void placeInWorld(World worldIn, BlockPos pos, EnumFacing direction) {


int width = blocks.size();
int height = blocks.get(0).size();
int length = blocks.get(0).get(0).size();

int start_x = pos.getX();


int start_y = pos.getY();
int start_z = pos.getZ();

if (direction == EnumFacing.NORTH){
start_z += 2;
} else if (direction == EnumFacing.SOUTH) {
start_z -= length + 1;
} else if (direction == EnumFacing.EAST){
start_x -= width + 1;
} else if (direction == EnumFacing.WEST) {
start_x -= width + 1;
}
File: /home/gabri/MinecraftHDL/src/…rafthdl/synthesis/Circuit.java Page 2 of 3

int y = start_y - 1;
for (int z = start_z - 1; z < start_z + length + 1; z ++){
for (int x = start_x - 1; x < start_x + width + 1; x++){
worldIn.setBlockState(new BlockPos(x, y, z),
Blocks.STONEBRICK.getDefaultState());
}
}

HashMap<Vec3i ,IBlockState> torches = new HashMap<Vec3i, IBlockState>();

for (int i = 0; i < width; i++){


for (int j = 0; j < height; j++) {
for (int k = 0; k < length; k++) {
if (this.getState(i, j, k).getBlock().getDefaultState() ==
Blocks.REDSTONE_TORCH.getDefaultState()) {
torches.put(new Vec3i(i, j, k), this.getState(i, j, k));
} else {
BlockPos blk_pos = new BlockPos(start_x + i, start_y + j,
start_z + k);
worldIn.setBlockState(blk_pos, this.getState(i, j, k));

TileEntity te = this.te_map.get(new Vec3i(i, j, k));


if (te != null) {
worldIn.setTileEntity(blk_pos, te);
}
}
}
}
}

for (Map.Entry<Vec3i, IBlockState> set : torches.entrySet()){


worldIn.setBlockState(new BlockPos(start_x + set.getKey().getX(),
start_y + set.getKey().getY(), start_z + set.getKey().getZ()), set.getValue());
}
}

public int getSizeX() {


return this.blocks.size();
}

public int getSizeY() {


return this.blocks.get(0).size();
}

public int getSizeZ() {


return this.blocks.get(0).get(0).size();
}

public IBlockState getState(int x, int y, int z){


return this.blocks.get(x).get(y).get(z);
}

public void insertCircuit(int x_offset, int y_offset, int z_offset, Circuit c)


{
for (int x = 0; x < c.getSizeX(); x++) {
for (int y = 0; y < c.getSizeY(); y++) {
for (int z = 0; z < c.getSizeZ(); z++) {
this.setBlock(x + x_offset, y + y_offset, z + z_offset,
c.getState(x, y, z));

TileEntity te = c.te_map.get(new Vec3i(x, y, z));


if (te != null) {
this.te_map.put(new Vec3i(x + x_offset, y + y_offset, z +
z_offset), te);
}
}
File: /home/gabri/MinecraftHDL/src/…rafthdl/synthesis/Circuit.java Page 3 of 3

}
}
}
}
File: /home/gabri/MinecraftHDL/src/…hdl/synthesis/CircuitTest.java Page 1 of 1

package minecrafthdl.synthesis;

import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

import java.util.ArrayList;

public class CircuitTest {


ArrayList<ArrayList<ArrayList<String>>> blocks;

public CircuitTest(int sizeX, int sizeY, int sizeZ){


this.blocks = new ArrayList<ArrayList<ArrayList<String>>>();
for (int x = 0; x < sizeX; x++) {
this.blocks.add(new ArrayList<ArrayList<String>>());
for (int y = 0; y < sizeY; y++) {
this.blocks.get(x).add(new ArrayList<String>());
for (int z = 0; z < sizeZ; z++) {
this.blocks.get(x).get(y).add(".");
}
}
}
}

public void setBlock(int x, int y, int z, String blockstate) {


this.blocks.get(x).get(y).set(z, blockstate);
}

public int getSizeX() {


return this.blocks.size();
}

public int getSizeY() {


return this.blocks.get(0).size();
}

public int getSizeZ() {


return this.blocks.get(0).get(0).size();
}

public String getState(int x, int y, int z){


return this.blocks.get(x).get(y).get(z);
}
}
File: /home/gabri/MinecraftHDL/src/…/minecrafthdl/ClientProxy.java Page 1 of 1

package minecrafthdl;

import minecrafthdl.client.render.blocks.BlockRenderRegister;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

public class ClientProxy extends CommonProxy {

@Override
public void preInit(FMLPreInitializationEvent e) {
super.preInit(e);
}

@Override
public void init(FMLInitializationEvent e) {
super.init(e);
BlockRenderRegister.registerBlockRenderer();
}

@Override
public void postInit(FMLPostInitializationEvent e) {
super.postInit(e);
}

}
File: /home/gabri/MinecraftHDL/src/…/minecrafthdl/CommonProxy.java Page 1 of 1

package minecrafthdl;

import minecrafthdl.block.BasicBlock;
import minecrafthdl.block.ModBlocks;
import minecrafthdl.block.blocks.Synthesizer;
import minecrafthdl.gui.MinecraftHDLGuiHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.ForgeRegistries;

public class CommonProxy {

public void preInit(FMLPreInitializationEvent e) {


ModBlocks.createBlocks();

public void init(FMLInitializationEvent e) {


NetworkRegistry.INSTANCE.registerGuiHandler(MinecraftHDL.instance, new
MinecraftHDLGuiHandler());
}

public void postInit(FMLPostInitializationEvent e) {

}
File: /home/gabri/MinecraftHDL/src/…in/java/minecrafthdl/Demo.java Page 1 of 2

package minecrafthdl;

import MinecraftGraph.*;

public class Demo {

public static Graph create4bitmuxgraph(){


Graph mux = new Graph();

Vertex i = new In_output(1, VertexType.INPUT, "i");


Vertex j = new In_output(1, VertexType.INPUT, "j");

mux.addVertex(i);
mux.addVertex(j);

Vertex not_1 = new Function(1, FunctionType.INV, 1);


Vertex not_2 = new Function(1, FunctionType.INV, 1);

mux.addVertex(not_1);
mux.addVertex(not_2);

Vertex a = new In_output(1, VertexType.INPUT, "a");


Vertex b = new In_output(1, VertexType.INPUT, "b");
Vertex c = new In_output(1, VertexType.INPUT, "c");
Vertex d = new In_output(1, VertexType.INPUT, "d");

mux.addVertex(a);
mux.addVertex(b);
mux.addVertex(c);
mux.addVertex(d);

Vertex and_1 = new Function(1, FunctionType.AND, 3);


Vertex and_2 = new Function(1, FunctionType.AND, 3);
Vertex and_3 = new Function(1, FunctionType.AND, 3);
Vertex and_4 = new Function(1, FunctionType.AND, 3);
Vertex or_1 = new Function(1, FunctionType.OR, 4);

mux.addVertex(and_1);
mux.addVertex(and_2);
mux.addVertex(and_3);
mux.addVertex(and_4);
mux.addVertex(or_1);

Vertex o = new In_output(1, VertexType.OUTPUT, "o");

mux.addVertex(o);

mux.addEdge(i, not_1);
mux.addEdge(j, not_2);

mux.addEdge(i, and_2);
mux.addEdge(i, and_4);
mux.addEdge(not_1, and_1);
mux.addEdge(not_1, and_3);

mux.addEdge(j, and_3);
mux.addEdge(j, and_4);
mux.addEdge(not_2, and_1);
mux.addEdge(not_2, and_2);

mux.addEdge(a, and_1);
mux.addEdge(b, and_2);
File: /home/gabri/MinecraftHDL/src/…in/java/minecrafthdl/Demo.java Page 2 of 2

mux.addEdge(c, and_3);
mux.addEdge(d, and_4);

mux.addEdge(and_1, or_1);
mux.addEdge(and_2, or_1);
mux.addEdge(and_3, or_1);
mux.addEdge(and_4, or_1);

mux.addEdge(or_1, o);

return mux;
}

}
File: /home/gabri/MinecraftHDL/src/…sis/routing/pins/EmptyPin.java Page 1 of 1

package minecrafthdl.synthesis.routing.pins;

import minecrafthdl.MHDLException;

public class EmptyPin extends Pin {


public EmptyPin(int x, boolean top) {
super(x, top);
}

public void setNet(int net_id, boolean out_net){


throw new MHDLException("Cant set net of empty pin");
}

public boolean empty(){


return true;
}
}
File: /home/gabri/MinecraftHDL/src/…a/MinecraftGraph/Function.java Page 1 of 1

package MinecraftGraph;

public class Function extends Vertex {


public FunctionType func_type;
protected int id;

public Function(int i, FunctionType f_t, int x){

super.type=VertexType.FUNCTION;
super.bits_n=x;
id=i;
this.func_type=f_t;
}

public FunctionType getFunc_Type(){


return this.func_type;

@Override
public void addToNext(Vertex v){
super.addToNext(v);
}

@Override
public void addToBefore(Vertex v){
super.addToBefore(v);
}

@Override
public String getID(){
return String.valueOf(id);

public int get_num_inputs() {


return this.bits_n;
}
}
File: /home/gabri/MinecraftHDL/src/…necraftGraph/FunctionType.java Page 1 of 1

package MinecraftGraph;

public enum FunctionType {


OR,XOR, AND, INV, MUX, RELAY, IO, HIGH, LOW, D_LATCH, Input, Output;
}
File: /home/gabri/MinecraftHDL/src/…necrafthdl/synthesis/Gate.java Page 1 of 1

package minecrafthdl.synthesis;

import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.Vec3d;

import java.util.HashMap;

public class Gate extends Circuit {

public int num_inputs, num_outputs, input_spacing, output_spacing = 0;


public int[] output_lines;

public String[] id_txt;


public boolean is_io = false;

public Gate(int sizeX, int sizeY, int sizeZ, int num_inputs, int num_outputs,
int input_spacing, int output_spacing, int[] output_lines) {
super(sizeX, sizeY, sizeZ);

this.num_inputs = num_inputs;
this.num_outputs = num_outputs;
this.input_spacing = input_spacing;
this.output_spacing = output_spacing;
this.output_lines = output_lines;
}
}
File: /home/gabri/MinecraftHDL/src/…sis/routing/pins/GatePins.java Page 1 of 2

package minecrafthdl.synthesis.routing.pins;

import MinecraftGraph.Vertex;
import minecrafthdl.MHDLException;
import minecrafthdl.synthesis.Gate;

import java.util.ArrayList;

public class GatePins {

private final Vertex vertex;


protected ArrayList<Pin> pins = new ArrayList<Pin>();

protected int next_free_input_pin = 0;


protected int next_free_output_pin = 0;

protected int gate_width;


protected int offset;
protected boolean top;

public GatePins(Gate g, Vertex v, int offset, boolean top){


this.vertex = v;
this.offset = offset;
this.top = top;
this.gate_width = g.getSizeX();

if (top){
for(int i = 0; i < g.num_outputs; i++){
pins.add(new Pin(offset + (i * (1 + g.output_spacing)), true));
}
} else {
for(int i = 0; i < g.num_inputs; i++){
pins.add(new Pin(offset + (i * (1 + g.input_spacing)), false));
}
}
}

public ArrayList<Pin> getPins(){


return this.pins;
}

public boolean hasNet(int net_id){


for (Pin p : this.pins) {
if (p.netID() == net_id) return true;
}
return false;
}

public Pin getNextPin(Vertex v){


if (next_free_input_pin == this.pins.size()) {
throw new MHDLException("To many input pins requested from gate");
}

this.next_free_input_pin += 1;
return pins.get(this.next_free_input_pin - 1);
}

public boolean hasNextPin(){


return next_free_input_pin < this.pins.size();
}

public String printPins(){


String str = "";
for (int i = 0; i < gate_width; i++) {
str += ".";
File: /home/gabri/MinecraftHDL/src/…sis/routing/pins/GatePins.java Page 2 of 2

for(Pin p : pins){
if(p.x - offset == 0) str = 'x' + str.substring(p.x - offset + 1);
else if (p.x - offset == gate_width - 1) str = str.substring(0, p.x -
offset) + 'x';
else str = str.substring(0, p.x - offset) + 'x' + str.substring(p.x
- offset + 1);
}

return str;
}
}
File: /home/gabri/MinecraftHDL/src/…java/MinecraftGraph/Graph.java Page 1 of 2

package MinecraftGraph;

import java.util.ArrayList;

public class Graph {

//only input vertices


private ArrayList<Vertex> vertices;

public Graph(){
vertices=new ArrayList<Vertex>();
}

public void addVertex(Vertex v){


vertices.add(v);
}

public void addEdge(Vertex v1, Vertex v2){

if (v2.type == VertexType.FUNCTION){
Function f = (Function) v2;
if (f.func_type == FunctionType.MUX){
MuxVertex m = (MuxVertex) f;

}
}

v1.addToNext(v2);
v2.addToBefore(v1);

public void removeEdge(Vertex v1, Vertex v2){


v1.removeNext(v2);
v2.removeBefore(v1);
}

public void removeVertex(Vertex v){


//remove v from all neighbors

for(Vertex ver: vertices){


ver.removeNext(v);
ver.removeBefore(v);
}
//remove v from vertices list
vertices.remove(v);

//This function takes the inputs to the first vertex v1 and adds them to v2
public void mergeVertices(Vertex v1, Vertex v2){

//v1 is to be merged(source)
for(Vertex v: v1.getBefore()){
v2.addToBefore(v);
v.addToNext(v2);
}

}
File: /home/gabri/MinecraftHDL/src/…java/MinecraftGraph/Graph.java Page 2 of 2

public ArrayList<Vertex> getVertices(){

return vertices;

public void print(){


System.out.println(this.vertices.size());

for (Vertex v : this.vertices){


v.print();
}
}
}
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.java Page 1 of 15

package GraphBuilder;

import GraphBuilder.json_representations.JCell;
import GraphBuilder.json_representations.JPort;
import GraphBuilder.json_representations.JsonFile;
import GraphBuilder.json_representations.Module;
import MinecraftGraph.*;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
import minecrafthdl.MHDLException;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

//main class
//json file->javaObject->Vertex->graph
public class GraphBuilder {
private static ArrayList<String> ports_names=new ArrayList<String>();
private static ArrayList<String> cells_names=new ArrayList<String>();
private static ArrayList<Port> ports=new ArrayList<Port>();
private static ArrayList<Cell> cells=new ArrayList<Cell>();

private static ArrayList<In_output> inputs=new ArrayList<In_output>();


private static ArrayList<In_output> outputs=new ArrayList<In_output>();
private static ArrayList<Function> gates=new ArrayList<Function>();

static int test_i = 1;

static int high_low_nets = Integer.MAX_VALUE;


static int cell_ids = 0;
static HashMap<Integer, Vertex> from_net = new HashMap<Integer, Vertex>();
static HashMap<Integer, ArrayList<Vertex>> to_net = new HashMap<Integer,
ArrayList<Vertex>>();

public static int putInToNet(int i, Vertex v, Graph g){


ArrayList<Vertex> l = to_net.get(i);

if (i == 0) {
high_low_nets--;
Function f = new Function(cell_ids++, FunctionType.LOW, 0);
from_net.put(high_low_nets, f);
to_net.put(high_low_nets, new ArrayList<Vertex>());
to_net.get(high_low_nets).add(v);
g.addVertex(f);
return high_low_nets;
} else if (i == 1){
high_low_nets--;
Function f = new Function(cell_ids++, FunctionType.HIGH,
0);
from_net.put(high_low_nets, f);
to_net.put(high_low_nets, new ArrayList<Vertex>());
to_net.get(high_low_nets).add(v);
g.addVertex(f);
return high_low_nets;
} else {
if (l == null) to_net.put(i, new ArrayList<Vertex>());
to_net.get(i).add(v);
return i;
}

}
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.java Page 2 of 15

public static int putInFromNet(int i, Vertex v){


Vertex vr = from_net.get(i);

if (vr != null) throw new MHDLException("TWO OUTPUTS ON SAME NET");


from_net.put(i, v);
return i;
}

public static Graph buildGraph(String path){


high_low_nets = Integer.MAX_VALUE;

Gson gson= new com.google.gson.Gson();


JsonFile jf = null;
try {
FileReader fr = new FileReader(path);
JsonReader jreader = new JsonReader(fr);
jreader.setLenient(true);
jf = gson.fromJson(jreader, JsonFile.class);
fr.close();
jreader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

jf.postInit();

Graph g = new Graph();

Module m = jf.modules.values().iterator().next();

from_net = new HashMap<Integer, Vertex>();


to_net = new HashMap<Integer, ArrayList<Vertex>>();

for (String p_name : m.ports.keySet()){


JPort p = m.ports.get(p_name);

In_output io;

if (p.direction.equals("input")){

io = new In_output(p.bits.size(),
VertexType.INPUT, p_name);

for (int i : p.bits){


putInFromNet(i, io);
}

} else {

io = new In_output(p.bits.size(),
VertexType.OUTPUT, p_name);

for (int i : p.bits){


putInToNet(i, io, g);
}

g.addVertex(io);
}

cell_ids = 0;
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.java Page 3 of 15

for (String c_name : m.cells.keySet()){


JCell c = m.cells.get(c_name);

FunctionType f_type = resolveType(c.type);

Function f;

if (f_type == FunctionType.MUX){
f = new MuxVertex(cell_ids++, f_type,
c.numInputs());
} else {
f = new Function(cell_ids++, f_type,
c.numInputs());
}

for (String conn_name : c.connections.keySet()){


String direction =
c.port_directions.get(conn_name);
ArrayList<Integer> conn_nets =
c.connections.get(conn_name);

int conn_net = -1;

if (direction.equals("input")){
for (int i : conn_nets){
conn_net = putInToNet(i, f, g);
}
} else {
for (int i : conn_nets){
conn_net = putInFromNet(i, f);
}
}

if (f_type == FunctionType.MUX){
if (conn_name.equals("S")){
((MuxVertex) f).s_net_num =
conn_net;
} else if (conn_name.equals(("A"))) {
((MuxVertex) f).a_net_num =
conn_net;
} else if (conn_name.equals(("B"))) {
((MuxVertex) f).b_net_num =
conn_net;
}
}
}

g.addVertex(f);
}

for (int i : to_net.keySet()){


for (Vertex v : to_net.get(i)){
Vertex from = from_net.get(i);
if (from == null){
throw new MHDLException("NET HAS NO FROM
VERTEX");
}

if (v.type == VertexType.FUNCTION){
Function f = ((Function) v);
if (((Function) v).func_type ==
FunctionType.MUX){
MuxVertex mux = ((MuxVertex) f);

if (i == mux.a_net_num){
mux.a_vertex = from;
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.java Page 4 of 15

} else if (i == mux.b_net_num){
mux.b_vertex = from;
} else if (i == mux.s_net_num){
mux.s_vertex = from;
}
}
}

g.addEdge(from, v);
}
}

return g;
}

public static Graph buildxGraph(String path){

ArrayList<String> ports_names=new ArrayList<String>();


ArrayList<String> cells_names=new ArrayList<String>();
ArrayList<Port> ports=new ArrayList<Port>();
ArrayList<Cell> cells=new ArrayList<Cell>();

ArrayList<In_output> inputs=new ArrayList<In_output>();


ArrayList<In_output> outputs=new ArrayList<In_output>();
ArrayList<Function> gates=new ArrayList<Function>();

test_i = 1;
System.out.println(test_i++); //1

//create jsononjects
Gson gson= new com.google.gson.Gson();
JsonFile jf = null;
try {
FileReader fr = new FileReader(path);
JsonReader jreader = new JsonReader(fr);
jreader.setLenient(true);
jf = gson.fromJson(jreader, JsonFile.class);
fr.close();
jreader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

System.out.println(test_i++); //2

jf.postInit();

Module m = jf.modules.values().iterator().next();

if (m == null) return null;

//read all ports names and create port objects

for(String s: m.ports.keySet()){
JPort p = m.ports.get(s);
Port port=new Port(s, p.direction, p.bits);
ports.add(port);

}
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.java Page 5 of 15

System.out.println(test_i++); //3

int j=1; //count to assign ids to gates

for(String s: m.cells.keySet()){

JCell c = m.cells.get(s);

ArrayList<Connection> conn_list = new


ArrayList<Connection>();

for(JPort p : c.ports.values()){

conn_list.add(new Connection(p.direction, p.bits,


p.name));

Cell cell=new Cell(j, c.type, conn_list );

cells.add(cell);
j++;
}

System.out.println(test_i++); //4

Graph graph=new Graph();

//add inputs to graph vertices


for(Port p: ports){
if(p.direction.equals("input")){
In_output in=new In_output(p.bits.size(),
VertexType.INPUT, p.name);
inputs.add(in);
graph.addVertex(in);
}
else{
outputs.add(new In_output(p.bits.size(),
VertexType.OUTPUT, p.name));
}

System.out.println(test_i++); //5

//add all cells


for(Cell c:cells){

Function v = null;

FunctionType type = resolveType((c.type));


if (type == FunctionType.MUX){
Connection c_sel = c.getConn("S");

if (c_sel == null) {
throw new MHDLException("MUX MUST HAVE S
INPUT");
}
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.java Page 6 of 15

v = new MuxVertex(c.id, type, c.inputs.size());


} else {
v=new Function(c.id, resolveType(c.type),
c.inputs.size());
}

gates.add(v);
graph.addVertex(v);
}

System.out.println(test_i++); //6

for(In_output v:outputs){
graph.addVertex(v);
}

System.out.println(test_i++); //7

//resolve connections
for(Port port:ports){

for(Port toCom:ports){
if(!port.equals(toCom)){
int conn_count=areConnected(port.bits,
toCom.bits);

if(port.direction.equals("input")&&toCom.direction.equals("output")&&conn_count>0){
for(int h=0; h<conn_count;h++)

graph.addEdge(getVertex(graph, port), getVertex(graph, toCom));


}else
if(port.direction.equals("output")&&toCom.direction.equals("input")&&conn_count>0){
for(int h=0; h<conn_count;h++)

graph.addEdge(getVertex(graph, toCom), getVertex(graph, port));

}
}

System.out.println(test_i++); //8

//add cells edges


for(Cell cell:cells){

for(Port port:ports){

int c1=areConnected(port.bits, cell.inputs);


if(port.direction.equals("input")&& c1>0){
for(int h=0; h<c1;h++){

graph.addEdge(getVertex(graph,
port), getVertex(graph, cell));

int c2=areConnected(port.bits, cell.outputs);


File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.java Page 7 of 15

if(port.direction.equals("output")&&c2>0){

for(int h=0; h<c2;h++){


graph.addEdge(getVertex(graph,
cell), getVertex(graph, port));

}
}

for(Cell c:cells){

if(!c.equals(cell)){
if(areConnected(cell.outputs, c.inputs)>0)
graph.addEdge(getVertex(graph,
cell), getVertex(graph, c));
}

System.out.println(test_i++); //9

optimizeGraph(graph);
System.out.println(test_i++); //10

return graph;
}

// public static Graph buildxGraph(String path){


//
// File file=new File(path);
// //Three string builder for the three json blocks: cells, ports,
netnames
// StringBuilder sb1=new StringBuilder();
// StringBuilder sb2=new StringBuilder();
// StringBuilder sb3=new StringBuilder();
//
// FileReader reader;
// BufferedReader b_r;
//
// String portsBlock="";
// String cellsBlock="";
// String netnamesBlock="";
//
// String pattern = "[:{\"\\s]";
//
// try {
// reader = new FileReader(file);
// b_r=new BufferedReader(reader);
//
// //skip first four lines
// b_r.readLine();
// b_r.readLine();
// b_r.readLine();
// b_r.readLine();
//
// int port_braces=1;
// String line=b_r.readLine();
//
// sb1.append("{");
//
// while(port_braces!=0){
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.java Page 8 of 15

// sb1.append(line);
// line=b_r.readLine();
//
// if(line.contains("{")){
// ports_names.add(line.replaceAll(pattern,
""));
// port_braces++;
// }
// else if (line.contains("}")){port_braces--;}
// }
// sb1.append("}");
// sb1.append("}");
// portsBlock=sb1.toString();
//
// //read gates block in the json file
// int cells_braces=1;
// line=b_r.readLine();
// sb2.append("{");
//
// while(cells_braces!= 0){
//
// sb2.append(line);
// line=b_r.readLine();
//
// if(line.contains("{")){
// cells_braces++;
// if(cells_braces==2){
// cells_names.add(line.replace(":
{", "").replaceAll("[\"\\s]", ""));
// }
// }
// else if (line.contains("}")){cells_braces--;}
//
//
//
// }
//
// sb2.append("}");
// sb2.append("}");
// cellsBlock=sb2.toString();
//
//
//
// }catch (FileNotFoundException e) {
// e.printStackTrace();
// } catch (IOException f) {
// f.printStackTrace();
// }
//
// //create jsononjects
// Gson gson= new com.google.gson.Gson();
// System.out.println(portsBlock);
//
// JsonObject ports_obj=gson.fromJson(portsBlock,
JsonElement.class).getAsJsonObject().get("ports").getAsJsonObject();
//
//
//
// //read all ports names and create port objects
//
// for(String s: ports_names){
// JsonObject js=ports_obj.get(s).getAsJsonObject();
// Port port=new Port(s, js.get("direction").getAsString(),
js.get("bits").getAsJsonArray());
// ports.add(port);
//
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.java Page 9 of 15

//
// }
//
// JsonObject cells_obj=gson.fromJson(cellsBlock,
JsonElement.class).getAsJsonObject().get("cells").getAsJsonObject();
//
//
// int j=1; //count to assign ids to gates
//
// for(String c: cells_names){
//
// JsonObject js_c=cells_obj.get(c).getAsJsonObject();
// JsonObject
param_obj=js_c.get("parameters").getAsJsonObject();
// JsonObject
conn_obj=js_c.get("connections").getAsJsonObject();
// JsonObject
dir_obj=js_c.get("port_directions").getAsJsonObject();
//
//
// String[] param=param_obj.toString().replaceAll("[{]",
"").split(",");
// String[] port_dir=conn_obj.toString().replaceAll("[{]",
"").split(",");
// String[] conn=dir_obj.toString().replaceAll("[{]",
"").split(",");
// ArrayList<Connection> conn_list=new ArrayList<>();
//
// for(int k=0; k<port_dir.length;k++){
//
// String holder=port_dir[k].split(":")
[0].replaceAll("[\"]", "");
// String dir=dir_obj.get(holder).getAsString();
// JsonArray n=conn_obj.get(holder).getAsJsonArray();
//
// conn_list.add(new Connection(dir, n));
//
//
//
// }
//
//
//
// Cell cell=new
Cell(j,js_c.get("type").getAsString(),conn_list );
//
// cells.add(cell);
// j++;
// }
//
// Graph graph=new Graph();
//
// //add inputs to graph vertices
// for(Port p: ports){
// if(p.direction.equals("input")){
// In_output in=new In_output(p.bits.size(),
VertexType.INPUT, p.name);
// inputs.add(in);
// graph.addVertex(in);
// }
// else{
// outputs.add(new In_output(p.bits.size(),
VertexType.OUTPUT, p.name));
// }
//
//
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.javaPage 10 of 15

// }
// //add all cells
// for(Cell c:cells){
//
// Function v=new Function(c.id, VertexType.FUNCTION,
resolveType(c.type), c.inputs.size());
// gates.add(v);
// graph.addVertex(v);
// }
//
//
// for(In_output v:outputs){
// graph.addVertex(v);
// }
//
//
// //resolve connections
// for(Port port:ports){
//
// for(Port toCom:ports){
// if(!port.equals(toCom)){
// int conn_count=areConnected(port.bits,
toCom.bits);
//
if(port.direction.equals("input")&&toCom.direction.equals("output")&&conn_count>0){
// for(int h=0; h<conn_count;h++)
//
graph.addEdge(getVertex(graph, port), getVertex(graph, toCom));
// }else
if(port.direction.equals("output")&&toCom.direction.equals("input")&&conn_count>0){
// for(int h=0; h<conn_count;h++)
//
graph.addEdge(getVertex(graph, toCom), getVertex(graph, port));
//
// }
// }
//
// }
//
// }
//
// //add cells edges
// for(Cell cell:cells){
// for(Port port:ports){
// int c1=areConnected(port.bits, cell.inputs);
// if(port.direction.equals("input")&& c1>0){
// for(int h=0; h<c1;h++)
//
// graph.addEdge(getVertex(graph,
port), getVertex(graph, cell));
// }
//
// int c2=areConnected(port.bits, cell.outputs);
//
// if(port.direction.equals("output")&&c2>0){
//
// for(int h=0; h<c2;h++)
// graph.addEdge(getVertex(graph,
cell), getVertex(graph, port));
// }
//
// }
//
// for(Cell c:cells){
//
// if(!c.equals(cell)){
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.javaPage 11 of 15

// if(areConnected(cell.outputs, c.inputs)>0)
// graph.addEdge(getVertex(graph,
cell), getVertex(graph, c));
// }
//
// }
//
// }
//
// optimizeGraph(graph);
// return graph;
// }
//
private static void optimizeGraph(Graph graph){
//iterate through all the nodes of the graph
//if or or and gate check outputs
//if all outputs are of the same type
//remove lower level and reconnect its inputs with the higher level
//got back
ArrayList<Vertex> verToRemove=new ArrayList<Vertex>();
for(Vertex v: graph.getVertices()){
System.out.println("vertex for");

//check if vertex is a gate


if(v.getType()==VertexType.FUNCTION){
//check if gate type is and, or
Function f=(Function)v;

FunctionType f_t=f.getFunc_Type();
if(f_t==FunctionType.AND||f_t==FunctionType.OR){
if(canMerge(f)){
for(Vertex s:f.getNext()){
System.out.println("vertex
inner for");

graph.mergeVertices(f, s);
verToRemove.add(f);
}

}
}

for(Vertex t:verToRemove){
System.out.println("vertex inner 2 for");

graph.removeVertex(t);
}
}

private static boolean canMerge(Function v){


for(Vertex x:v.getNext()){
if(x.getType()!=VertexType.FUNCTION){
return false;

}
Function f=(Function)x;
if(f.getFunc_Type()!=v.getFunc_Type()){
return false;
}
}

return true;
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.javaPage 12 of 15

//getting vertices

private static Vertex getVertex(Graph g, Port p){

for(Vertex v:g.getVertices()){

if(v.getID().equals(p.name)){
return v;
}

}
return null;

private static Vertex getVertex(Graph g, Cell p){

for(Vertex v:g.getVertices()){

if(v.getID().equals(String.valueOf(p.id))){
return v;
}

}
return null;

//checks if signals, gates are connected


private static int areConnected(ArrayList<Integer> bits,
ArrayList<Integer> inputs2){

int count=0;

for(Integer x: bits){
for(Integer y: inputs2){
if(x==y){
count++;
}

}
return count;

private static int num_of_inputs(JsonObject j_o){


int num=0;
char[] connection=j_o.get("connections").toString().toCharArray();
for(char c: connection){
if(c==':') num++;
}
return num-1;
}
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.javaPage 13 of 15

private static FunctionType resolveType(String type){

//make sure that all string included

if(type.contains("and")||type.contains("AND")){
return FunctionType.AND;

}else if(type.contains("MUX")||type.contains("mux")){
return FunctionType.MUX;
}else if(type.contains("XOR")||type.contains("xor")){
return FunctionType.XOR;

}else if(type.contains("or")||type.contains("OR")){
return FunctionType.OR;

}else if(type.contains("dlatch_p")||type.contains("DLATCH_P")) {
return FunctionType.D_LATCH;

}else if(type.contains("not")||type.contains("NOT")){
return FunctionType.INV;

}else{
throw new MHDLException("Unknown Cell:" + type);
}

class Port{
String name;
String direction;
ArrayList<Integer> bits=new ArrayList<Integer>();

public Port(String n, String d, ArrayList<Integer> b){


name=n;
direction=d;
bits=b;
}

class Cell{
int id;
String type;
ArrayList<Connection> connections=new ArrayList<Connection>();

ArrayList<Integer> inputs=new ArrayList<Integer>();


ArrayList<Integer> outputs=new ArrayList<Integer>();

public Cell(int i, String t, ArrayList<Connection> cns){


id=i;
type=t;
connections=cns;

for(Connection c:connections){
if(c.direction.equals("input")){
for(int j=0; j<c.IDs.length; j++){
inputs.add(c.IDs[j]);
}
}
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.javaPage 14 of 15

else{
for(int j=0; j<c.IDs.length; j++){
outputs.add(c.IDs[j]);
}
}

public Connection getConn(String name){


for (Connection c : this.connections){
if (c.name.equals(name)) return c;
}
return null;
}

class Connection{
String name;
String direction;
int IDs[];

public Connection(String d, ArrayList<Integer> arr, String name){


this.name = name;
direction=d;
IDs= new int[arr.size()];
for(int j=0; j<arr.size(); j++){
IDs[j]=arr.get(j);

//
//class Port{
// String name;
// String direction;
// ArrayList<Integer> bits=new ArrayList<>();
//
// public Port(String n, String d, JsonArray b){
// name=n;
// direction=d;
//
//
// for(int i=0; i<b.size(); i++){
// bits.add(b.get(i).getAsInt());
// }
//
// }
//
//}
//
//class Cell{
// int id;
// String type;
// ArrayList<Connection> connections=new ArrayList<>();
//
// ArrayList<Integer> inputs=new ArrayList<Integer>();
// ArrayList<Integer> outputs=new ArrayList<>();
File: /home/gabri/MinecraftHDL/src/…GraphBuilder/GraphBuilder.javaPage 15 of 15

//
// public Cell(int i, String t, ArrayList<Connection> cns){
// id=i;
// type=t;
// connections=cns;
//
//
// for(Connection c:connections){
// if(c.direction.equals("input")){
// for(int j=0; j<c.IDs.length; j++){
// inputs.add(c.IDs[j]);
// }
// }
// else{
// for(int j=0; j<c.IDs.length; j++){
// outputs.add(c.IDs[j]);
// }
// }
//
// }
//
//
// }
//
//
//}
//
//class Connection{
//
// String direction;
// int IDs[];
//
// public Connection(String d, JsonArray arr){
// direction=d;
// IDs= new int[arr.size()];
// for(int j=0; j<arr.size(); j++){
// IDs[j]=arr.get(j).getAsInt();
//
// }
//
//
// }
//
//}
//
File: /home/gabri/MinecraftHDL/src/…/MinecraftGraph/In_output.java Page 1 of 1

package MinecraftGraph;

public class In_output extends Vertex{


private String name;

public In_output(int num, VertexType v_t, String n){

super.bits_n=num;
super.type=v_t;
this.name=n;

@Override
public String getID(){
return name;

}
File: /home/gabri/MinecraftHDL/src/…hesis/IntermediateCircuit.java Page 1 of 5

package minecrafthdl.synthesis;

import MinecraftGraph.*;
import minecrafthdl.MHDLException;
import minecrafthdl.Utils;
import minecrafthdl.synthesis.routing.Channel;
import minecrafthdl.synthesis.routing.Net;
import minecrafthdl.synthesis.routing.Router;
import minecrafthdl.synthesis.routing.pins.GatePins;
import minecrafthdl.synthesis.routing.pins.PinsArray;
import minecrafthdl.testing.TestLogicGates;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

import java.util.ArrayList;
import java.util.HashMap;

public class IntermediateCircuit {

public ArrayList<ArrayList<Vertex>> vertex_layers = new


ArrayList<ArrayList<Vertex>>();
public ArrayList<ArrayList<Gate>> gate_layers = new
ArrayList<ArrayList<Gate>>();
public ArrayList<Channel> channels = new ArrayList<Channel>();

public void loadGraph(Graph graph) {


System.out.println("Graph built");

ArrayList<Vertex> finished = new ArrayList<Vertex>();


ArrayList<Vertex> in_process = new ArrayList<Vertex>();
ArrayList<Vertex> process_done = new ArrayList<Vertex>();
ArrayList<Vertex> to_process = new ArrayList<Vertex>();

for (Vertex v : graph.getVertices()) {


if (v.getType() == VertexType.INPUT) {
in_process.add(v);
} else if (v.getType() == VertexType.FUNCTION){
Function f = (Function) v;
if (f.func_type == FunctionType.HIGH || f.func_type ==
FunctionType.LOW) in_process.add(v);
}

int layer_num = 0;

while (in_process.size() > 0){


int size = in_process.size();
vertex_layers.add(new ArrayList<Vertex>());
for (Vertex v : in_process){
boolean valid = true;
for (Vertex p : v.getBefore()){
if (!finished.contains(p)) {
valid = false;
break;
}
}

if (valid){
vertex_layers.get(layer_num).add(v);
process_done.add(v);

for (Vertex n : v.getNext()){


File: /home/gabri/MinecraftHDL/src/…hesis/IntermediateCircuit.java Page 2 of 5

to_process.add(n);
}
}
}
for (Vertex v : process_done){
in_process.remove(v);
finished.add(v);
}
for (Vertex v : to_process){
if (!in_process.contains(v)) in_process.add(v);
}
process_done.clear();
to_process.clear();
layer_num++;

ArrayList<Vertex> outputs_not_in_last = new ArrayList<Vertex>();

for (ArrayList<Vertex> v_l : this.vertex_layers){


if (this.vertex_layers.indexOf(v_l) == vertex_layers.size() - 1) break;
ArrayList<Vertex> to_remove = new ArrayList<Vertex>();

for (Vertex v : v_l){


if (v.type == VertexType.OUTPUT) {
outputs_not_in_last.add(v);
to_remove.add(v);
}
}

for (Vertex v : to_remove){


v_l.remove(v);
}
}

ArrayList<Vertex> last_layer =
this.vertex_layers.get(this.vertex_layers.size() - 1);
for (Vertex v : outputs_not_in_last){
last_layer.add(v);
}

for (int i = 0; i < vertex_layers.size() - 1; i++){


ArrayList<Vertex> layer = vertex_layers.get(i);
ArrayList<Vertex> next_layer = vertex_layers.get(i+1);

for (Vertex v : layer){


ArrayList<Vertex> addToNext = new ArrayList<Vertex>();
ArrayList<Vertex> removeFromNext = new ArrayList<Vertex>();

for (Vertex next : v.getNext()){


if (!next_layer.contains(next)){
Vertex relay = new Function(1, FunctionType.RELAY, 1);

next_layer.add(relay);

removeFromNext.add(next);
next.removeBefore(v);

addToNext.add(relay);
relay.addToBefore(v);

relay.addToNext(next);
next.addToBefore(relay);

next.handleRelay(v, relay);
}
File: /home/gabri/MinecraftHDL/src/…hesis/IntermediateCircuit.java Page 3 of 5

for (Vertex x : addToNext){


v.addToNext(x);
}

for (Vertex x : removeFromNext){


v.removeNext(x);
}
}
}

public void printLayers(){


for (ArrayList<Vertex> layer : vertex_layers){
for (Vertex v : layer) {
if (v.getType() == VertexType.INPUT){
System.out.print("I, ");
}
if (v.getType() == VertexType.FUNCTION){
System.out.print(((Function) v).getFunc_Type() + ", ");
}
if (v.getType() == VertexType.OUTPUT){
System.out.print("O, ");
}
}
System.out.print("\n");
}
}

public void buildGates() {


if (this.vertex_layers.size() == 0) throw new MHDLException("Must load
graph before building gates");

for (ArrayList<Vertex> v_layer : this.vertex_layers) {


ArrayList<Gate> this_layer = new ArrayList<Gate>();
for (Vertex v : v_layer) {
this_layer.add(genGate(v));
}
this.gate_layers.add(this_layer);
}
}

public void routeChannels() {


for (int i = 0; i < vertex_layers.size() - 1; i++){
ArrayList<Vertex> top_vertices = vertex_layers.get(i);
ArrayList<Gate> top_gates = gate_layers.get(i);
ArrayList<Vertex> bottom_vertices = vertex_layers.get(i+1);
ArrayList<Gate> bottom_gates = gate_layers.get(i + 1);

Router.PinInitRtn rtn = Router.initializePins(top_vertices, top_gates,


bottom_vertices, bottom_gates, 1);

HashMap<Vertex, GatePins> pin_map = rtn.pin_map;


PinsArray pins_array = rtn.pins_array;

HashMap<Integer, Net> nets = Router.initializeNets(top_vertices,


bottom_vertices, pin_map);

this.channels.add(Router.placeNets(nets, pins_array));

Net.num_nets = 0;
}
File: /home/gabri/MinecraftHDL/src/…hesis/IntermediateCircuit.java Page 4 of 5

public Circuit genCircuit(){


if (this.gate_layers.size() == 0) throw new MHDLException("Must build
gates before generating final circuit");

int size_x = 0;
int size_y = 0;
int size_z = 0;

int[] layers_size_z = new int[this.gate_layers.size()];

for (ArrayList<Gate> layer : this.gate_layers){


int this_size_x = layer.size() == 0 ? 0 : layer.size() - 1;
int this_size_y = 0;
int this_size_z = 0;

for (Circuit c : layer){


this_size_x += c.getSizeX();
if (c.getSizeY() > this_size_y) this_size_y = c.getSizeY();
if (c.getSizeZ() > this_size_z) this_size_z = c.getSizeZ();
}

if (this_size_x > size_x) size_x = this_size_x;


if (this_size_y > size_y) size_y = this_size_y;
size_z += this_size_z;

layers_size_z[this.gate_layers.indexOf(layer)] = this_size_z;
}

if (size_y < 3) size_y = 3;

for (Channel c : this.channels){


if (c.sizeX() + 1 > size_x) size_x = c.sizeX() + 1;
size_z += c.sizeZ() + 1;
}

Circuit circuit = new Circuit(size_x, size_y, size_z);

int z_offset = 0;
for (int i = 0; i < this.gate_layers.size(); i++) {
int x_offset = 0;
for (Gate g : this.gate_layers.get(i)){
circuit.insertCircuit(x_offset, 0, z_offset, g);

if (g.getSizeZ() - 1 < layers_size_z[i]) {


for (int z = g.getSizeZ(); z < layers_size_z[i]; z++){
if (z == layers_size_z[i] - 1) circuit.setBlock(x_offset,
0, z_offset + z,
Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(Utils.getPropertyByName(Blocks.UNPOWERED
"facing"), EnumFacing.NORTH));
else circuit.setBlock(x_offset, 0, z_offset + z,
Blocks.REDSTONE_WIRE.getDefaultState());
}
}

x_offset += 1 + g.getSizeX();
}
z_offset += layers_size_z[i];

if (i < this.gate_layers.size() - 1) {
Channel c = this.channels.get(i);
circuit.insertCircuit(0, 0, z_offset, c.genChannelCircuit());
z_offset += c.sizeZ();
}
}
File: /home/gabri/MinecraftHDL/src/…hesis/IntermediateCircuit.java Page 5 of 5

return circuit;
}

private static FunctionType getFunctionType(Vertex v) {

if (v.getType() == VertexType.FUNCTION) {
return ((Function) v).getFunc_Type();
} else {
if (v.getType() == VertexType.INPUT) return FunctionType.Input;
else return FunctionType.Output;
}

private static Gate genGate(Vertex v) {


if (getFunctionType(v) == FunctionType.AND) {
return Circuit.TEST?
TestLogicGates.AND(((Function)v).get_num_inputs()) :
LogicGates.AND(((Function)v).get_num_inputs());
} else if ( getFunctionType(v) == FunctionType.OR){
return Circuit.TEST?
TestLogicGates.OR(((Function)v).get_num_inputs()) :
LogicGates.OR(((Function)v).get_num_inputs());
} else if ( getFunctionType(v) == FunctionType.INV){
return Circuit.TEST? TestLogicGates.NOT() : LogicGates.NOT();
} else if ( getFunctionType(v) == FunctionType.RELAY) {
return Circuit.TEST ? TestLogicGates.RELAY() : LogicGates.RELAY();
}else if ( getFunctionType(v) == FunctionType.XOR){
return Circuit.TEST? TestLogicGates.IO() : LogicGates.XOR();
}else if ( getFunctionType(v) == FunctionType.MUX){
return Circuit.TEST? TestLogicGates.IO() : LogicGates.MUX();
}
// else if ( getFunctionType(v )== FunctionType.IO){
// return Circuit.TEST? TestLogicGates.IO() : LogicGates.IO();
// }
else if ( getFunctionType(v) == FunctionType.Input){
return Circuit.TEST? TestLogicGates.IO() : LogicGates.Input(v.getID());
}else if ( getFunctionType(v) == FunctionType.Output){
return Circuit.TEST? TestLogicGates.IO() :
LogicGates.Output(v.getID());
}else if ( getFunctionType(v) == FunctionType.HIGH){
return Circuit.TEST? TestLogicGates.IO() : LogicGates.HIGH();
}else if ( getFunctionType(v) == FunctionType.LOW){
return Circuit.TEST? TestLogicGates.IO() : LogicGates.LOW();
}else if ( getFunctionType(v) == FunctionType.D_LATCH){
return Circuit.TEST? TestLogicGates.IO() : LogicGates.D_LATCH();
}
else throw new MHDLException("NO SUCH GATE AVAILABLE");
}

public void verify(World worldIn, BlockPos pos) {

}
}
File: /home/gabri/MinecraftHDL/src/…son_representations/JCell.java Page 1 of 1

package GraphBuilder.json_representations;

import java.util.ArrayList;
import java.util.HashMap;

public class JCell extends Node{

public String type;


public HashMap<String, String> port_directions;
public HashMap<String, ArrayList<Integer>> connections;

public HashMap<String, JPort> ports = new HashMap<String, JPort>();

@Override
public ArrayList<Integer> getNets() {
return null;
}

public void posInit(){


for (String p : port_directions.keySet()){
ports.put(p, new JPort(p, port_directions.get(p), connections.get(p)));
}

public int numInputs(){


int conns = 0;
for (String dir: port_directions.values()){
if (dir.equals("input")) conns += 1;
}
return conns;
}

public void print(int tabs) {


System.out.println(JsonFile.tabs(tabs) + "type: " + type);
System.out.println(JsonFile.tabs(tabs) + "Ports: " + type);

for (String p : ports.keySet()){


System.out.println(JsonFile.tabs(tabs + 1) + p);
ports.get(p).print(tabs + 1);
}
}
}
File: /home/gabri/MinecraftHDL/src/…son_representations/JPort.java Page 1 of 1

package GraphBuilder.json_representations;

import java.util.ArrayList;

public class JPort extends Node {


public String name;
public String direction;
public ArrayList<Integer> bits;

public JPort(String name, String direction, ArrayList<Integer> bits) {


this.name = name;
this.direction = direction;
this.bits = bits;
}

@Override
public ArrayList<Integer> getNets() {
return null;
}

public void print(int tabs) {


System.out.println(JsonFile.tabs(tabs) + "direction: " + direction);
System.out.println(JsonFile.tabs(tabs) + "bits:");
for(int i : bits){
System.out.println(JsonFile.tabs(tabs + 1) + i);

}
File: /home/gabri/MinecraftHDL/src/…_representations/JsonFile.java Page 1 of 1

package GraphBuilder.json_representations;

import java.util.HashMap;

public class JsonFile {

public HashMap<String, Module> modules;

public void print(){


for (Module m : modules.values()){
m.print();
}
}

public static String tabs(int tabs) {


String str = "";
for (int i = 0; i < tabs; i++){
str += "\t";
}
return str;
}

public void postInit(){


for (Module m : modules.values()){
m.postInit();
}
}
}

También podría gustarte