-
Notifications
You must be signed in to change notification settings - Fork 0
Log
Notas y pruebas en sucio sobre las herramientas para diseño de chips (asic)
Quiero aprender a utilizar la herramienta magic, para el diseño de ASICs. Este es el repositorio de magic: https://github.com/RTimothyEdwards/magic
Se instala fácilmente utilizando la appimage de la última release. La que descargo es esta: Magic-8.3.681.20260807.4432d7ec-x86_64-EL10.AppImage
La copio al directorio Bin y la ejecuto
![]()
Aparece esto:
![]()
Son dos ventanas independientes, que las he puesto una encima de otra en el pantallazo
Escribo estos comandos:
box 0 0 20 10
paint ndiff
El primer comando se lo traga, pero con el segundo optengo este mensaje de error: Unrecognized layer: ndiff ...
Parece que el problema está que hay que arrancar magico de esta forma, indicando que se quiere usar la tecnología sky130A:
./Magic-8.3.681.20260807.4432d7ec-x86_64-EL10.AppImage -T sky130A test.mag
El mensaje de error que se obtiene ahora es:
Could not find file 'sky130A.tech' in any of these directories: [...]
OK.. tengo que instalar algo más... Parece que hay que instalar el open-pdk: https://github.com/fossi-foundation/open-pdks
Para instalarlo hay que compilar cosas... Estoy leyendo la información de su web: https://opencircuitdesign.com/open_pdks/ Mencionan que hay un gestor de paquetes, ciel para hacer más fácil su instalación. Este es su repositorio: https://github.com/fossi-foundation/ciel
Para instalar las herramientas necesarias voy a crear el entorno virtual de python asic:
obijuan@JANEL:~$ python -m venv $HOME/venv/asicEntramos en el entorno virtual:
obijuan@JANEL:~$ . $HOME/venv/asic/bin/activate
(asic) obijuan@JANEL:~$Instalamos ciel siguiendo las instrucciones:
(asic) obijuan@JANEL:~$ python3 -m pip install cielSe instala correctamente. Lo comprobamos:
(asic) obijuan@JANEL:~$ ciel --version
Ciel v2.6.1 ©2022-2025 Efabless Corporation and Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this program except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
(asic) obijuan@JANEL:~$Vamos a comprobar todos los pdks precompilados listos para instalar:
(asic) obijuan@JANEL:~$ ciel ls-remote --pdk-family sky130
Pre-built sky130 PDK versions
├── 026824c7969ce6f4fc9678e6ca04b0a06a596c4b (2026.08.04)
├── f6eeac7dad085ffcc829ccfd721f7b4ce39edcf7 (2026.07.14)
├── d658698bd8bcf4e05fc7b5991a701247ba0d744c (2026.07.04)
[...]Comprobamos los que están instalados:
(asic) obijuan@JANEL:~$ ciel ls --pdk-family sky130
No PDKs installed.
(asic) obijuan@JANEL:~$Ninguno. Vamos a instalar el último (2026.08.04). Hay que utilizar su hash:
(asic) obijuan@JANEL:~$ ciel enable --pdk-family sky130 026824c7969ce6f4fc9678e6ca04b0a06a596c4b
Version 026824c7969ce6f4fc9678e6ca04b0a06a596c4b not found locally, attempting
to download…
Downloading common.tar.zst… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Downloading sky130_fd_io.tar.zst… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Downloading sky130_fd_pr.tar.zst… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Downloading sky130_fd_sc_hd.tar.zst… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Downloading sky130_fd_sc_hvl.tar.zst… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Downloading sky130_ml_xx_hd.tar.zst… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Downloading sky130_sram_macros.tar.zst… ━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Version 026824c7969ce6f4fc9678e6ca04b0a06a596c4b enabled for the sky130 PDK.
(asic) obijuan@JANEL:~$Ahora ya sí que aparece que tengo uno instalado:
(asic) obijuan@JANEL:~$ ciel ls --pdk-family sky130
In /home/obijuan/.ciel/ciel/sky130/versions:
└── 026824c7969ce6f4fc9678e6ca04b0a06a596c4b (2026.08.04) (enabled)
(asic) obijuan@JANEL:~$Ahora ya sí que está el fichero sky130A.tech en el directorio ~/.ciel/sky130A/libs.tech/magic
obijuan@JANEL:~/.ciel/sky130A/libs.tech/magic$ ls
bump_bond_generator generate_fill.py sky130A-BindKeys sky130A.tcl
check_antenna.py run_standard_drc.py sky130A-GDS.tech sky130A.tech
check_density.py seal_ring_generator sky130A.magicrc
obijuan@JANEL:~/.ciel/sky130A/libs.tech/magic$Voy a reproducir lo anterior, desde 0, con las herramientas ya instaladas. Partimos del directorio de este log
obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$Entramos en el entorno virtual: . $HOME/venv/asic/bin/activate
obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$ . $HOME/venv/asic/bin/activate
(asic) obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$Comprobamos que ciel sigue accesible:
(asic) obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$ ciel --version
Ciel v2.6.1 ©2022-2025 Efabless Corporation and Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this program except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
(asic) obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$Comprobamos que tenemos seleccionado e instalado sky130
(asic) obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$ ciel ls --pdk-family sky130
In /home/obijuan/.ciel/ciel/sky130/versions:
└── 026824c7969ce6f4fc9678e6ca04b0a06a596c4b (2026.08.04) (enabled)
(asic) obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$Lanzamos magic:
(asic) obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$ $HOME/Bin/Magic-8.3.681.20260807.4432d7ec-x86_64-EL10.AppImage -T sky130A test.mag
-- # Starting MagicEn la consola de magic sigue apareciendo este error:
loading history file ... 3 events added
Use openwrapper to create a new GUI-based layout window
Use closewrapper to remove a new GUI-based layout window
Magic 8.3 revision 681 - Compiled on Sat Aug 8 07:04:03 UTC 2026.
Starting magic under Tcl interpreter
Using Tk console window
Using TrueColor, VisualID 0x21 depth 24
Could not find file 'sky130A.tech' in any of these directories:
. $CAD_ROOT/magic/sys $CAD_ROOT/magic/sys/current
Failed to load technology "sky130A"
[...]
Main console display active (Tcl9.0.4 / Tk9.0.4)
% Ejecuto este comando, pasándole como argumento el fichero sky130A.magicrc
$HOME/Bin/Magic-8.3.681.20260807.4432d7ec-x86_64-EL10.AppImage -rc ~/.ciel/sky130A/libs.tech/magic/sky130A.magicrc
-- # Starting MagicSe lanza magic pero acaba muy rápidamente, y no me da tiempo a ver qué ha ocurrido
OK. Ya consigo lanzar magic con este comando. Hay que exportar la variable PDK_ROOT:
(asic) obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$ export PDK_ROOT=$HOME/.ciel
$HOME/Bin/Magic-8.3.681.20260807.4432d7ec-x86_64-EL10.AppImage -rc ~/.ciel/sky130A/libs.tech/magic/sky130A.magicrc test.mag
-- # Starting Magic
(asic) obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$Esto es lo que sale ahora:
![]()
Ahora ya podemos ver en la parte de la derecha todas las capas disponibles en sky130. Este es el log que sale en la consola de tcl, para tenerlo como referencia. No aparece ningún mensaje de error y termina con el prompt:
loading history file ... 3 events added
Use openwrapper to create a new GUI-based layout window
Use closewrapper to remove a new GUI-based layout window
Magic 8.3 revision 681 - Compiled on Sat Aug 8 07:04:03 UTC 2026.
Starting magic under Tcl interpreter
Using Tk console window
Using TrueColor, VisualID 0x21 depth 24
Processing system .magicrc file
Switching to WIRING tool.
Switching to NETLIST tool.
Switching to PICK tool.
Switching to BOX tool.
Sourcing design .magicrc for technology sky130A ...
2 Magic internal units = 1 Lambda
Input style sky130(): scaleFactor=2, multiplier=2
The following types are not handled by extraction and will be treated as non-electrical types:
ubm
Scaled tech values by 2 / 1 to match internal grid scaling
Loading sky130A Device Generator Menu ...
New windows will not have a title caption.
New windows will not have scroll bars.
New windows will not have a border.
Repainting console in magic layout window colors
Using technology "sky130A", version 1.0.588-56-g026824c
Root cell box:
width x height ( llx, lly ), ( urx, ury ) area (units^2)
microns: 0.010 x 0.010 ( 0.000, 0.000), ( 0.010, 0.010) 0.000
lambda: 1.00 x 1.00 ( 0.00, 0.00 ), ( 1.00, 1.00 ) 1.00
internal: 2 x 2 ( 0, 0 ), ( 2, 2 ) 4
Main console display active (Tcl9.0.4 / Tk9.0.4)
% Ahora es el momento de pintar una capa de difusión n. Ejecutamos estos comandos en la consola:
box 0 0 20 10
paint ndiff
![]()
En la consola de magic vemos esto:
% box 0 0 20 10
Root cell box:
width x height ( llx, lly ), ( urx, ury ) area (units^2)
microns: 0.200 x 0.100 ( 0.000, 0.000), ( 0.200, 0.100) 0.020
lambda: 20.00 x 10.00 ( 0.00, 0.00 ), ( 20.00, 10.00) 200.00
internal: 40 x 20 ( 0, 0 ), ( 40, 20 ) 800
% paint ndiff
Loading DRC CIF style
%
Ahora metemos la capa de polisilicio para hacer el mosfet n:
box 8 -5 12 15
paint poly
![]()
Con esto se supone que ya tenemos un mosfet n hecho (a falta de los contactos). Vemos que hay 6 errores de DRC...
Voy a empezar otra vez desde 0... a ver si consigo ir diseñando sin errores de DRC
(asic) obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$ $HOME/Bin/Magic-8.3.681.20260807.4432d7ec-x86_64-EL10.AppImage -rc ~/.ciel/sky130A/libs.tech/magic/sky130A.magicrc test1.mag
-- # Starting Magicok... tras trastear con magic ya parece que empiezo a entender un poco el funcionamiento. Voy a hacer un minitutorial, para ir aprendiendo
Arrancamos magic desde cero:
(asic) obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$ $HOME/Bin/Magic-8.3.681.20260807.4432d7ec-x86_64-EL10.AppImage -rc ~/.ciel/sky130A/libs.tech/magic/sky130A.magicrc
-- # Starting MagicSe nos abre esta pantalla gráfica, donde destacamos algunos elementos:
![]()
- DRC: Reglas de diseño. Inicialmente no hay diseño, y por eso no se están violando ninguna de las reglas de diseño
- Nombre del diseño actualmente cargado. Por defecto es UNLOADED
- Tecnología: Sky130A
- Bloque cursor: Zona del chip con la zona activa, donde afectarán los diferentes comandos que se usen
Una cosa muy importante es que los elementos de diseño dentro del chip siempre son zonas rectangulares. Por eso el cursor es un bloque, que puede tener las dimensiones que le demos, pero siempre es un rectángulo. No es posible crear otras geometrías diferentes a rectángulos
El bloque cursor lo vamos a nombre como la caja
Las unidades por defecto que vamos a utilizar son micrómetros (µm), que en magic se usa el prefijo um. Las dimensiones de la caja por defecto, la que aparece al inicio son de 0.010um x 0.010um
Para hacer zoom pulsamos en la tecla z. Vemos como la caja se ve más grande
![]()
Para alejar el zoom (zoom out) pulsamos shift-z
![]()
Podemos centrar la caja con la tecla ctrl-z
![]()
Todas estas opciones están disponibles también desde el menú windows
![]()
Antes de empezar a diseñar vamos configurar el grid. Pinchamos en windows y luego Set grid 0.05um. Con esto establecemos la resolución de la cuadrícula en 0.05µm (50nm)
![]()
Se activa automáticamente, y veremos la cuadrícula:
![]()
Si echamos el zoom hacia atrás vemos más cuadrículas
![]()
Hay un punto negro en la esquina inferior izquierda de la caja. Indica donde se encuentra el origen de coordenadas (0, 0)
Ahora pinchamos en la opción windows/Snap-to-grid-on para que la caja esté siempre sobre el grid
![]()
Si pinchamos en la opción Windows/Measure box o apretamos la tecla b, nos aparecerán las dimensiones de la caja actual en la ventana de texto:
![]()
Comprobamos que son de 0.05umx0.05um (una celda del grid)
Otra forma de obtener el tamaño de la caja es escribiendo el comando box
![]()
Este diseño lo vamos a guardar en el fichero mosfet-n.mag. Para ello pinchamos en cell/save as
![]()
Se nos abre una ventana de diálogo donde escribimos el nombre del diseño. Como vamos a construir un mosfet N lo llamaremos mosfet-n. Una vez escrito pinchamos en ok
![]()
Vemos en la parte superior cómo ha cambiado el nombre a mosfet-n.
![]()
También se nos ha generado el fichero mosfet-n.mag en el directorio de trabajo
obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$ ls
images mosfet-n.mag
obijuan@JANEL:~/Develop/Learn-open-silicon/wiki/Log$El diseño es un fichero de texto, que podemos ver y editar:
magic
tech sky130A
timestamp 0
<< end >>
Vamos a crear nuestro primero MOSFET-N. Se hace dibujando 2 rectángulos: uno para marcar las zonas N, y otro para el polisilicio de la puerta. A partir de estos dos rectángulos, magic calcula los parámetros necesarios para la fabricación del mosfet
La zona N mínima que podemos dibujar está determinada por el tamaño del grid, que lo hemos fichado en 0.050um x 0.050um (50nm x 50nm). Este es el tamaño que tiene la caja actual. Pulsamos ctrl-z para verlo centrado y a su mayor tamaño
![]()
Nos fijamos que se cumples las reglas DRC (básicamente porque NO hay diseñado nada todavía)
Para dibujar una zona N en la caja actual, ejecutamos este comando: paint ndiffusion. Esto es lo que nos aparece en la consola de magic:
![]()
En la ventana del diseño vemos que la caja se pone de color verde, y en los cuadrados del grid superior y derecho aparece un patrón de puntitulos
![]()
También observamos que el DRC FALLA: Hay 2 errores. Esto es debido a que NO se puede construir una zona N tan pequeña, sino que hay unas dimensiones mínima. Pero vamos a investigar sobre esto
Para ver el diseño completo, pinchamos en windows/full view o bien apretamos la tecla v
![]()
Ahora se ven todas las cuadrículas nuevas. Por la parte superior hay 2 que indican que hay errores, y por la parte derecha hay otras 2 también de errores. Los patrones de relleno de estas capas se pueden ver en la parte derecha. Ahí vemos las capas ndifussion y errors
![]()
Para ver los errores pinchamos en Options/DRC Manager
![]()
Se nos abre una ventana nueva, donde nos indica la regla que se está violando: Diffusion width < 0.15um (diff/tap.1)
![]()
Lo que significa es que la zona de difusión N tiene unas dimensiones menores que las mínimas permitidas. Las mínimas son de 0.15um. Esto es lo que nos indican las cuadrículas de la capa de error: Al menos, tanto la anchura como la altura de la zona n tiene que ocupar 3 cuadrículas
Vamos a solucionar primero el problema de la anchura. La anchura actual es de 0.050um, pero debe ser al menos de 0.150um. Situamos el puntero del ratón cerca de la zona donde queremos que se sitúe la esquina superior derecha de la nueva caja y pulsamos el botón derecho del ratón
![]()
Se dibuja una nueva caja que mantiene la izquina inferior izquierda en el mismo sitio que antes, pero sitúa la esquina superior derecha en el nuevo punto (alineado con la cuadrícula)
Ahora pintamos la nueva zona, ejecutando el comando paint ndiffusion, igual que antes
![]()
Ahora sólo queda 1 error de DRC. Se muestra en la capa errors las cuadrículas que deberían ser zonas de difusión n, es decir, hay que ampliar la altura para que sea de al menos 0.150um
Repetimos el proceso. Con el botón derecho seleccionamos el punto de la cuadrícula donde queremos que se sitúe la esquina superior derecha de la caja
![]()
Y la convertimos en zona de difusión n. Ahora ya sín se cumplen las reglas DRC, y no hay errores
![]()
Hemos dibujado la zona N mínima
Cuando creamos un mosfet N, la zona N tiene que ser más grande, para cumplir con todas las reglas de diseño. Su tamaño tiene que ser al menos de 0.650um x 0.450um. Así que la vamos a crear desde 0
Partimos del estado anterior, donde la caja rodea toda la zona N. Ejecutamos el comando erase y la zona desaparece, pero la caja sigue estando
![]()
Ahora vamos a poner una zona N de 0.65 x 0.45 (um) en el origien. Utilizamos el comando box 0 0 0.65 0.45 seguido de paint ndiffusion
![]()
Ahora hay que poner la zona de polisilicio que atraviesa la zona N, para generar las 2 zonas N, una a la izquierda y otra a la derecha, y la conexión con la puerta. Para no violar las reglas DRC, el polisilicio debe sobresalir 0.15um por arriba y por abajo
Primero marcamos la casilla donde va a estar la esquina inferior izquierda del polisilicio. Esto lo hacemos apretando el botón izquierdo del ratón
![]()
Se sitúa la caja actual con su esquina inferior izquierda en la cuadrícula indicada, ajustada al grid. Ahora posicionamos el ratón en la esquina superior derecha de la zona donde queremos que esté el polisicio
![]()
Apretamos el botón derecho y aparece la nueva caja
![]()
Escribimos paint polysilicon para convertirla en la zona de polisilicio
![]()
En la pantalla gráfica vemos el polisilicio. Observamos que NO HAY ERRORES DE DRC. ¡Nuestro primer MOSFET!
![]()
En el MOSFET N hay 3 capas:
- ndifussion: Las 2 zonas N, que aparecen delimitadas por el polisilicio. Se dibuja una única zona N y magic calcula las dos a partir de la intersección con el polisilicio
- polysilicon: La capa de polisilicio que hemos dibujado. Magic calcula su intersección con la zona N y divide esta capa en dos zonas. Una de polisilio puro, que sobresale por la zona N y la zona de intersección que conforma la siguiente capa (ntransistor)
- ntransistor: Es la capa de intersección entre la zona N y el polisilicio. En la fabricación del chip esta zona se dopa para que haya muchos electrones libres y la puerta del transistor conduzca
![]()
Todas las capas definidas en la tecnología Sky130A se encuentran en el panel de la derecha, como ya hemos visto. Es posible ocultar las capas visibles, así como volver a mostrarlas. Para ocultar hay que pinchar en la capa correspondiente usando el botón derecho del ratón
En esta imagen vemos cómo se ha ocultado la capa ntransistor. Podemos ver que efectivamente ahora la zona N se ha dividido en 2 zonas N
![]()
Para volver a visualizar cualquier capa basta con pinchar en la capa y usar el botón izquierdo
Vamos a aprender a realizar conexiones a la fuente y el drenador, que son iguales. Ambos parten de la capa ndiffusion
El punto de partida es una zona N cruzada por el polisilicio, como en el apartado anterior, pero con la geometría ligeramente cambiada: más espacio en las zonas N para que quepan los contactos nuevos que vamos a añadir
El objetivo es conectar la zona N de la fuente con un contacto metálico, que es el que sale fuera del chip. Las conexiones están en capas independientes a mayor altura que el substrato. Estas capas de conexión están separadas, y son independientes. Por eso hay que añadir contactos entre ellas, que reciben el nombre de vías
🚧 TODO 🚧
-
Contactos metálicos y vías
-
diseño final mosfet-n!
-
Simulacion del transistor!
-
Mostrar transistor en 3D!
-
Formato GDS!
-
Tutorial magic: https://www.youtube.com/watch?v=D32woicgdRk