De alguna manera no puedo expresar mis pensamientos brevemente. El otoño pasado, hubo un deseo de contar con más detalles sobre la arquitectura de PSoC que dominé, lo que resultó en una serie de artículos al respecto. Ahora estoy involucrado en la preparación del hardware para nuestro complejo de depuración remota de Redd, que se describió
aquí , y quiero descartar la experiencia acumulada en forma de texto. Todavía no estoy seguro, pero me parece que nuevamente no es un artículo, sino un ciclo. En primer lugar, así es como documentaré los métodos de desarrollo desarrollados que pueden ser útiles para alguien cuando se trabaja con el complejo y, en general, y en segundo lugar, el concepto aún es nuevo, no está completamente establecido. Quizás, en el proceso de discusión de artículos, aparezcan algunos comentarios, de los cuales uno puede sacar algo para expandirlo (o incluso cambiarlo). Por lo tanto, procedemos.

Larga introducción
Realmente no me gusta teorizar, prefiero exponer algunas cosas prácticas a la vez. Pero al comienzo del primer artículo, sin una larga introducción en ningún lado. En él, justifico el enfoque actual del desarrollo. Y todo girará en torno a una cosa: la hora hombre es un recurso muy costoso. Y el asunto no es solo en los términos asignados para el proyecto. Él es físicamente caro. Si se gasta en el desarrollo del producto final, bueno, ¿qué puede hacer sin él en ninguna parte? Pero cuando se gasta en trabajo auxiliar, esto, en mi opinión, es malo. Recuerdo que tuve una disputa con un desarrollador que dijo que al hacer prototipos por su cuenta, ahorraría dinero para su empresa nativa. Argumenté que pasaría unos 3 días en la fabricación. Eso es 24 horas hombre. Tomamos su salario por estas horas, agregamos el impuesto social que "paga el empleador", así como el alquiler de la oficina por esas horas. Y estamos sorprendidos de ver que al ordenar tableros en el lateral, puede obtener costos más bajos. Pero ese soy yo, exagero. En general, si se pueden evitar los costos laborales, deberían evitarse.
¿Cuál es el desarrollo de "firmware" para el complejo Redd? Este es un trabajo auxiliar. El proyecto principal vivirá feliz para siempre; debe hacerse de la manera más eficiente posible, con una excelente optimización, etc. Pero gastar tiempo y energía en cosas auxiliares que irán al archivo después del desarrollo es un desperdicio. Fue con un ojo en este principio que se llevó a cabo el desarrollo del equipo Redd. Todas las funciones, si es posible, se implementan como elementos estándar. Los autobuses SPI, I2C y UART se implementan en microcircuitos FTDI estándar y se programan a través de controladores estándar, sin lujos. La gestión de los carretes se implementa en el formato de un puerto COM virtual. Se puede modificar, pero al menos todo se ha hecho para que tal deseo no surja. En general, todo lo estándar, si es posible, se implementa de manera estándar. De proyecto en proyecto, los desarrolladores simplemente necesitan escribir rápidamente el código típico para que la PC acceda a estos buses. La técnica de desarrollo en C ++ debería ser obvia para quienes desarrollan programas para microcontroladores (hablaremos de algunos detalles técnicos en otro artículo).
Pero FPGA está solo en el complejo. Se agrega al sistema para casos en los que es necesario implementar protocolos no estándar con un requisito de alto rendimiento. Si se requieren, tendrá que hacer el "firmware" para ello. Se trata de la programación FPGA y quiero hablar específicamente, todo con el mismo propósito: reducir el tiempo de desarrollo de las cosas auxiliares.
Para no confundir al lector, formularé el pensamiento en un marco:
No es necesario llevar a cabo el desarrollo de FPGA en cada proyecto. Si hay suficientes controladores de bus conectados directamente al procesador central para trabajar con el dispositivo de destino, debe usarlos.
FPGA agregado al complejo para la implementación de protocolos no estándar.
Diagrama de bloques del complejo.
Veamos el diagrama de bloques del complejo.

En la parte inferior del circuito hay una "calculadora". En realidad, esta es una PC estándar con Linux. Los desarrolladores pueden escribir programas regulares en C, C ++, Python, etc., que serán ejecutados por la computadora. En la parte superior derecha están los puertos estándar de los neumáticos estándar. A la izquierda hay un interruptor para dispositivos estándar (SPI Flash, tarjeta SD y varios relés de estado sólido de baja corriente, que pueden, por ejemplo, simular presionar botones). Y en el centro está precisamente esa parte, el trabajo con el que se planea considerar en esta serie de artículos. Su corazón es un FPGA de clase FPGA, del cual salen las líneas rectas (pueden usarse como pares diferenciales o líneas ordinarias sin búfer), líneas GPIO con un nivel lógico configurable, así como un bus USB 2.0 implementado a través de un chip ULPI.
Continuación de la introducción sobre el enfoque de programación FPGA
Cuando se desarrolla una lógica de control de alto rendimiento para FPGA, generalmente Su Majestad toca el primer violín en una máquina de estado. En las máquinas es posible implementar una lógica compleja pero de alta velocidad. Pero, por otro lado, un autómata se desarrolla más lentamente que un programa para un procesador, y su modificación es otro proceso. Existen sistemas que simplifican el desarrollo y mantenimiento de máquinas. Uno de ellos incluso fue desarrollado por nuestra empresa, pero aún así, el proceso de diseño para cualquier tipo de lógica compleja no es rápido. Cuando el sistema desarrollado es el producto final, tiene sentido prepararse, diseñar una buena máquina de control y dedicar tiempo a su implementación. Pero como ya se señaló, el desarrollo para Redd es un trabajo auxiliar. Está diseñado para facilitar el proceso, no para complicarlo. Por lo tanto, se decidió que el desarrollo no será automático, sino sistemas de procesador.
Pero por otro lado, al desarrollar el hardware, la opción más moderna hasta la fecha, FPGA con el núcleo ARM, fue rechazada. En primer lugar, por razones de precio. Una placa prototipo basada en SoC de Cyclone V es moderadamente costosa, pero curiosamente, una FPGA separada es mucho más costosa. Lo más probable es que el precio de las placas de creación de prototipos se descargue para atraer a los desarrolladores a usar datos FPGA, y las placas se venden individualmente. La serie tendrá que tomar fichas individuales. Pero además, también hay un "segundo". En segundo lugar, cuando estaba experimentando con Cyclone V SoC, resultó que este sistema de procesador no es así y es productivo cuando se trata de acceso único a los puertos. Lote: sí, el trabajo es rápido. Y en el caso de accesos únicos a una frecuencia de reloj del núcleo del procesador de 925 MHz, puede obtener acceso a los puertos a una frecuencia de unos pocos megahercios. Para todos, propongo llamar a la función estándar de ingresar datos en el FIFO del bloque UART, que verifica el desbordamiento de la cola, pero lo llama cuando la cola está obviamente vacía, es decir, nada interfiere con las operaciones. Mi productividad pasó de un millón a quinientas mil llamadas por segundo (por supuesto, trabajar con la memoria fue a la velocidad normal, se ajustaron todas las memorias caché, incluso la opción de función que no verificó FIFO por hacinamiento funcionó más rápido, solo la función en discusión se ha mezclado abundantemente escribir y leer desde los puertos). Este es FIFO! De hecho, FIFO se inventó para dejar caer datos allí y olvidar. ¡Salga rápido! Y no con rendimiento, menos de una mega operación por segundo a una frecuencia de procesador de 925 MHz ...
La latencia es la culpable. Entre el núcleo del procesador y el equipo se encuentra desde tres puentes o más. Además, la velocidad de acceso a los puertos depende del contexto (varios registros seguidos irán rápidamente, pero la primera lectura detendrá el proceso hasta que los datos en caché se descarguen por completo, demasiados registros seguidos también se ralentizarán, ya que las memorias intermedias de escritura están agotadas). Finalmente, el examen de las trazas acumuladas en el búfer de depuración mostró que la arquitectura
Cortex A puede ejecutar la misma parte para un número diferente de ciclos de reloj debido al complejo sistema de caché. En resumen, teniendo en cuenta todos estos factores (precio, reducciones de rendimiento cuando se trabaja con el equipo, inestabilidad de la velocidad de acceso al equipo, dependencia general del contexto), se decidió no colocar dicho chip en el complejo.
Los experimentos con el PSoC de Cypress mostraron que allí el núcleo
Cortex M proporciona resultados más predecibles y repetibles, pero la capacidad lógica y la frecuencia máxima de funcionamiento de estos controladores no correspondían a las especificaciones técnicas, por lo que también se descartaron.
Se decidió instalar un FPGA Cyclone IV típico de bajo costo y recomendar el uso de un núcleo de procesador NIOS II sintetizado. Bueno, y si es necesario, para llevar a cabo el desarrollo utilizando cualquier otro método (máquinas automáticas, lógica rígida, etc.).
Mencionaré por separado (e incluso destacaré este párrafo) que el procesador principal del complejo es x86 (x64). Es él quien es el procesador central del sistema. Es allí donde se ejecuta la lógica principal del complejo. El sistema de procesador, que se analizará a continuación, está diseñado para proporcionar simplemente la lógica del funcionamiento del equipo "flasheado" en el FPGA. Además, este equipo se vende solo si los desarrolladores no tienen suficientes módulos de tiempo completo conectados directamente al procesador central.
El proceso de desarrollo y depuración de "firmware"
Si el complejo Redd está ejecutando Linux, esto no significa que el desarrollo deba llevarse a cabo en este sistema operativo. Redd es un ejecutor remoto, y el desarrollo debe llevarse a cabo en su computadora, sea cual sea el sistema operativo. Quien tenga Linux es el más fácil, pero quién está acostumbrado a Windows (no me gustaba mucho WIN 3.1, pero me vi obligado a trabajar, pero en algún momento cuando WIN95 OSR2 se acostumbró, y ahora es inútil luchar contra él, es más fácil de aceptar) , esos pueden continuar liderando el desarrollo en él.
Como mi amistad con Linux no funcionó, no daré instrucciones paso a paso para configurar el entorno, pero me limitaré a las palabras generales. Quién trabaje con este sistema operativo será suficiente para eso, y para el resto ... Créame, es más fácil contactar a los administradores del sistema. Al final, hice exactamente eso. Pero no obstante.
Debe descargar e instalar Quartus Prime Programmer and Tools de la misma versión que su entorno de desarrollo. Si las versiones no coinciden, puede haber sorpresas. Pasé toda la tarde para comprender este hecho. Por lo tanto, solo descargue la herramienta de la misma versión que el entorno de desarrollo.
Después de la instalación, ingrese el directorio donde se instaló el programa, el subdirectorio bin. En general, el archivo más importante debe ser jtagconfig. Si lo ejecuta sin argumentos (por cierto, solicité persistentemente ingresar ./jtagconfig y solo así), se mostrará una lista de programadores disponibles en el sistema y los FPGA conectados a ellos. Debería haber un USB Blaster. Y el primer problema que arroja el sistema es que no hay suficientes derechos de acceso para trabajar con USB. Aquí se describe cómo resolverlo sin recurrir al sudo:
radiotech.kz/threads/nastrojka-altera-usb-blaster-v-ubuntu-16-04.1244Pero aquí hay una lista de dispositivos que se muestran. Ahora deberías escribir:
./jtagconfig --enableremote <password>
después de lo cual se inicia el servidor, accesible desde cualquier lugar de la red.
Todo estaría bien, pero el firewall del sistema no permitirá que nadie vea este servidor. Una verificación en Google mostró que para cada tipo de Linux (de los cuales hay muchos), los puertos en el firewall se abren a su manera, y se deben lanzar tantos hechizos que prefiero contactar a los administradores.
También vale la pena considerar que si jtagd no se registró en la ejecución automática, cuando abra el acceso remoto, se le informará que es imposible establecer una contraseña. Para evitar que esto suceda, jtagd debe iniciarse no mediante jtagconfig, sino antes.
En general, el chamanismo es sobre el chamanismo. Permítanme arreglar la tesis:
Existe, por supuesto, una ruta similar que pasa por la interfaz GUI, pero es más lógico hacer todo por lotes. Por lo tanto, describí una versión por lotes. Cuando se han completado todas estas tesis (y los administradores del sistema las han completado), lanzamos el programador en nuestra máquina, vemos un mensaje sobre la falta de equipo. Haga clic en Configuración de hardware:

Vaya a la pestaña Configuración de JTAG y haga clic en Agregar servidor:

Ingrese la dirección de red de Redd (la tengo 192.168.1.100) y la contraseña:

Nos aseguramos de que la conexión haya sido exitosa.
Pasé tres vacaciones de mayo para lograr esto, y luego los administradores decidieron todo.

Cambie a la pestaña Configuración de hardware, abra la lista desplegable y seleccione el programador remoto allí:

Todo, ahora se puede usar. El botón de inicio está desbloqueado.

El primer "firmware"
Pues bien. Para que el artículo tenga un valor práctico real, analicemos el "firmware" más simple realizado con los métodos anteriores. Lo más simple que realmente logré implementar para el complejo es una prueba del chip SDRAM. Aquí en este ejemplo y práctica.
Hay varios núcleos de aficionados para admitir SDRAM, pero todos se activan de alguna manera complicado. Y dar cuenta de todos los trucos es trabajo. Intentaremos usar soluciones listas para usar que se puedan insertar en el sistema informático NIOS II, por lo que utilizaremos el controlador estándar SDRAM. El núcleo en sí se describe en el documento
Embedded Peripherals IP User Guide , y se dedica mucho espacio en la descripción al cambio de reloj para SDRAM en relación con el reloj del núcleo. Se dan cálculos y fórmulas teóricas complejas, pero no se informa particularmente qué hacer. Se puede encontrar qué hacer en el documento
Uso de la SDRAM en la placa DE0 de Altera con Verilog Designs . En el curso del análisis, aplicaré el conocimiento de este documento.
Estaré desarrollando en la versión gratuita de Quartus Prime 17.0. Me concentro en esto, ya que durante la asamblea, me dicen que en el futuro, el núcleo del
controlador SDRAM será expulsado de la versión gratuita. Si esto ya sucedió en su entorno de desarrollo, nadie se molestará en descargar la versión gratuita 17 e instalarla en una máquina virtual. El trabajo principal se realiza donde sea que esté acostumbrado, y el firmware para Redd con SDRAM está en la versión 17. Bueno, eso es si usas las opciones gratuitas. Nadie amenazó con echarlo de los pagados todavía. Pero estaba distraído. Crea un nuevo proyecto:

Llamémoslo SDRAM_DEMO. El nombre debe recordarse: voy a llevar a cabo un desarrollo súper rápido, por lo que el sistema del procesador debería estar en el nivel superior, sin ninguna capa Verilog. Y para que esto suceda, el nombre del sistema del procesador debe coincidir con el nombre del proyecto. Así que recuérdalo.

De acuerdo con los valores predeterminados en unos pocos pasos, llegamos a la elección de un cristal. Seleccionamos el EP4CE10E22C7 utilizado en el complejo.

En el siguiente paso, por costumbre, elijo modelar en ModelSim-Altera. Hoy no modelaremos nada, pero todo puede ser útil. Es mejor desarrollar tal hábito y seguirlo:

El proyecto está creado. Vaya inmediatamente a la creación del sistema de procesador (Herramientas-> Diseñador de plataforma):

Hemos creado un sistema que contiene un reloj y un módulo de reinicio:

Pero como ya mencioné, se requiere un reloj especial para el núcleo SDRAM. Por lo tanto, el módulo estándar se tira sin piedad

Y en su lugar, agregue el Programa de la Universidad-> Sistema y Reloj SDRAM para el bloque de placas de la serie DE:

En las propiedades, seleccione DE0-Nano, ya que la inspiración para el circuito de conmutación SDRAM se extrajo de esta placa de pruebas:

Comenzamos a rellenar nuestro sistema de procesador. Por supuesto, lo primero que debe agregar es el núcleo del procesador en sí. Déjalo ser Procesador y periféricos-> Procesadores integrados-> Procesador NIOS II.

Para él, todavía no completamos ninguna propiedad. Simplemente haga clic en Finalizar, aunque hayamos formado una serie de mensajes de error. Hasta ahora, no hay equipos que eliminen estos errores.
Ahora agregue la SDRAM real. Interfaces y controladores de memoria-> SDRAM-> Controlador SDRAM.

Aquí tenemos que aferrarnos a completar las propiedades. Seleccione el microcircuito más cercano similar en la organización de la lista y haga clic en Apppy. Sus propiedades caen en los campos Perfil de memoria:

Ahora cambiamos el ancho del bus de datos a 16, el número de líneas de dirección a 13 y las columnas a 9.

Todavía no estoy corrigiendo los tiempos, quizás en el futuro esta recomendación cambie.
El sistema procesador implica un programa. El programa debe almacenarse en algún lugar. Probaremos el chip SDRAM. Por el momento, no podemos confiar en ella. Por lo tanto, para almacenar el programa, agregue memoria basada en el bloque RAM FPGA. Funciones básicas-> Memoria en chip-> Memoria en chip (RAM o ROM):

Volumen ... Bueno, que sea de 32 kilobytes.

Esta memoria debe estar cargando desde algún lugar. Para que esto suceda, marque la casilla Habilitar archivo de inicialización no predeterminado e ingrese algún nombre de archivo significativo. Digamos firmware.hex:

El artículo ya es complicado, por lo que no lo sobrecargaremos. Simplemente mostraremos el resultado físico de la prueba en forma de líneas PASS / FAIL (y veremos el resultado lógico con mi depuración JTAG favorita). Para hacer esto, agregue el puerto GPIO. Procesadores y periféricos-> Periféricos-> PIO (Parallel IO):

En las propiedades que configuramos 2 bits, también me gusta marcar la casilla para el control individual de bits. También solo un hábito.

Tenemos un sistema así con muchos errores:

Comenzamos a eliminarlos. Para empezar, romperemos el reloj y reiniciaremos. En el reloj y la unidad de reinicio, las entradas deben desecharse. Para hacer esto, hay campos que dicen "Haga doble clic para exportar":

Hacemos clic, pero damos nombres más o menos cortos.

También debe desechar la salida del reloj SDRAM:

Ahora dividimos sys_clk en todas las entradas de reloj y reset_source en todas las líneas de reinicio. Puede golpear suavemente los puntos que conectan las líneas correspondientes con el "mouse", o puede ir a la salida correspondiente, presionar el botón derecho del mouse y luego ir al submenú Conexiones en el menú desplegable y seleccionar las conexiones allí.


Luego conectamos los neumáticos juntos. Conectamos Data Master a todos los buses de todos los dispositivos, e Inctruction Master a casi todos. No es necesario conectarlo al bus PIO_0. A partir de ahí, las instrucciones definitivamente no se leerán.

Ahora puede resolver conflictos de direcciones. Para hacer esto, seleccione el elemento del menú Sistema-> Asignar direcciones base:

Y cuando tenemos direcciones, también podemos asignar vectores. Para hacer esto, vaya a las propiedades del núcleo del procesador (apúntelo, presione el botón derecho del mouse y seleccione el elemento del menú Editar) y configure los vectores en la Memoria Onchip allí. Simplemente seleccione este tipo de memoria en las listas desplegables, los números se sustituirán ellos mismos.

No quedan errores. Pero quedan dos advertencias. Olvidé exportar las líneas SDRAM y PIO.

Como ya hicimos para el restablecimiento y el bloqueo del reloj, haga doble clic en las patas requeridas y asígneles los nombres más cortos (pero comprensibles):

Todo, no hay más errores o advertencias. Guarda el sistema. Además, el nombre debe coincidir con el nombre del proyecto, de modo que el sistema procesador se convierta en un elemento del nivel superior del proyecto. ¿No has olvidado cómo lo llamamos?


Bueno, presionamos el botón más importante: generar HDL.

Todo, se crea la parte del procesador. Haz clic en Finalizar. Se nos recuerda que sería bueno agregar este sistema de procesador al proyecto:

Añadir:

Y allí, usando el botón Agregar, logramos la siguiente imagen:

El archivo SIP aún no se ha creado. Sí, y no lo necesitamos en el marco de este artículo.
Uhhhh El primer paso ha sido tomado. Redactamos el proyecto para que el sistema descubra la jerarquía del proyecto y las patas utilizadas. Los errores de compilación no dan miedo. Solo en la versión gratuita del entorno, se crearon núcleos que funcionan solo mientras el adaptador JTAG está conectado. Pero en el complejo Redd, siempre está conectado, ya que está divorciado en una junta común, es decir, no tenemos nada que temer. Entonces ignoramos estos errores.

Ahora volvamos a la descripción del núcleo SDRAM. Dice que la línea CKE no se usa y siempre está conectada a la unidad. De hecho, dentro del marco del complejo, las piernas FPGA no solo son caras, sino un recurso precioso. Y sería una tontería separar la pierna, que siempre está en la unidad (y en el tablero DE0-NANO tampoco está divorciada). Habría una capa Verilog, la cadena correspondiente podría cortarse allí, pero ahorro tiempo (risas nerviosas, mirando el volumen del documento ya obtenido, pero sin guardarlo habría resultado aún más). Por lo tanto, no hay capa. Como ser Vaya al Editor de tareas. Está en él, ya que en Pin Planner, a juzgar por las descripciones, no hay una funcionalidad similar.

Todavía no hay línea. Bueno Crea uno nuevo

Seleccionamos el siguiente icono:

En el sistema de búsqueda que configuramos, haga clic en Lista y en los resultados de búsqueda encontramos nuestro CKE:

Agréguelo a la columna derecha, haga clic en Aceptar.

Obtenemos la siguiente lista:

En el campo amarillo, haga clic en la lista desplegable y busque Pin virtual. Nosotros elegimos La amarillez se trasladó a otra celda:

Allí seleccionamos On:

Toda la amarillez se ha ido. Y la cadena ahora está marcada como virtual, lo que significa que no requiere una pierna física. Por lo tanto, no podemos asignarlo a la conclusión física de la FPGA. Cierre el Editor de tareas, abra el Planificador de clavijas. Puede asignar las piernas, haciendo referencia a la figura, o puede tomar la lista del archivo * .qsf, que es parte del proyecto, que adjuntaré al artículo.

Eso es todo, cierre Pin Planner, llevamos a cabo la compilación final del proyecto. El hardware está listo, procedemos al desarrollo del software para el sistema de procesador resultante. Pero el artículo resultó tan grande que lo haremos la
próxima vez .