Caso práctico: Contador binario en 7 segmentos con Basys 3

Caso práctico: Contador binario en 7 segmentos con Basys 3 — hero

Objetivo y caso de uso

Qué construirás: Un contador binario en la placa Basys 3 FPGA que muestra valores de 4 bits en un display de 7 segmentos.

Para qué sirve

  • Visualización de conteos en aplicaciones de control industrial.
  • Demostración de principios de diseño digital en entornos educativos.
  • Pruebas de funcionamiento de circuitos en sistemas embebidos.
  • Implementación de contadores en proyectos de robótica.

Resultado esperado

  • Contador que incrementa de 0000 a FFFF en el display de 7 segmentos.
  • Latencia de respuesta menor a 100 ms entre incrementos.
  • Consumo de recursos FPGA: menos del 20% de la lógica disponible.
  • Visualización clara y precisa de los valores en formato hexadecimal.

Público objetivo: Estudiantes y entusiastas de la electrónica; Nivel: Básico

Arquitectura/flujo: Implementación en Xilinx Vivado WebPACK con comandos de síntesis y programación.

Nivel: Básico

Objetivo del proyecto

Implementar un “binary-counter-on-seven-segment” en la placa Basys 3 (Xilinx Artix‑7), mostrando un contador binario (en formato hexadecimal) que incrementa de 0000 a FFFF en los cuatro dígitos del display de 7 segmentos integrado en la placa. Se empleará la toolchain Vivado WebPACK con comandos exactos de síntesis, implementación y programado por línea de comandos (CLI).


Prerrequisitos

Sistema operativo y arquitectura

  • Opción A (Linux):
  • Ubuntu 22.04 LTS (x86_64)
  • Kernel 5.x (cualquiera de la rama LTS)
  • Opción B (Windows):
  • Windows 10 22H2 o Windows 11 23H2 (64 bits)

Ambos sistemas son compatibles con Vivado. Las instrucciones de CLI son idénticas salvo pequeñas diferencias en rutas; se indicarán comandos genéricos válidos en ambos.

Toolchain concreta

  • Xilinx Vivado WebPACK 2023.2 (64 bits)
  • Versión exacta: Vivado 2023.2 WebPACK
  • Soporte de dispositivo: Artix‑7
  • Cable drivers: Digilent (instalados desde el propio Vivado)
  • Comprobación de versión:
  • Linux/Windows (terminal/Powershell):
    • vivado -version
    • Debe mostrar: Vivado v2023.2 (64-bit)

Conocimientos previos mínimos

  • Conceptos básicos de HDL (Verilog preferiblemente).
  • Conocimiento básico de la placa Basys 3 (reloj de 100 MHz, displays de 7 segmentos, noción de pines).
  • Uso básico de terminal.

Materiales

  • 1× Basys 3 (Xilinx Artix‑7) — modelo exacto: Basys 3 con FPGA XC7A35T-1CPG236C
  • 1× Cable micro‑USB a USB‑A (o USB‑C a USB‑A con adaptador)
  • 1× PC con el SO y Vivado WebPACK 2023.2 instalados

No se requiere cableado adicional: el proyecto usa exclusivamente periféricos integrados (reloj y display de 7 segmentos on-board).


Preparación y conexión

Pasos previos

  1. Verifica el jumper de alimentación:
  2. Ubica JP1 (power select) en la Basys 3 y colócalo en la posición “USB”.
  3. Conecta la Basys 3 al PC con el cable micro‑USB.
  4. Enciende la placa con el interruptor deslizante (ON).
  5. Verifica que el LED de alimentación (ON) en la placa está encendido.
  6. Asegúrate de que el driver Digilent para cable JTAG está instalado:
  7. Linux: lsusb debe mostrar un dispositivo Digilent.
  8. Windows: el Administrador de dispositivos debe listar el cable USB‑JTAG sin advertencias.

Señales y pines usados

Usaremos:
– Reloj de 100 MHz on-board.
– Display de 7 segmentos de 4 dígitos (común ánodo con control multiplexado).
– Sin botones ni entradas externas adicionales.

La Basys 3 tiene pines dedicados para los segmentos (CA..CG, DP) y para los ánodos (AN0..AN3). En el diseño, los agruparemos como:
– seg[6:0] mapea a segmentos a..g (activos en bajo)
– dp mapea al punto decimal (activo en bajo, lo dejaremos apagado = 1)
– an[3:0] mapea a los dígitos AN3..AN0 (activos en bajo; solo uno activo a la vez)

Tabla de mapeo de pines

La siguiente tabla describe exactamente el mapeo Basys 3 (Xilinx Artix‑7) para el proyecto:

Señal HDL Pin FPGA Net Basys 3 IOSTANDARD Activo Descripción
clk W5 SYSCLK LVCMOS33 Reloj on-board de 100 MHz
seg[6] (a / CA) U2 CA LVCMOS33 Bajo Segmento a
seg[5] (b / CB) V2 CB LVCMOS33 Bajo Segmento b
seg[4] (c / CC) U1 CC LVCMOS33 Bajo Segmento c
seg[3] (d / CD) V1 CD LVCMOS33 Bajo Segmento d
seg[2] (e / CE) U4 CE LVCMOS33 Bajo Segmento e
seg[1] (f / CF) V4 CF LVCMOS33 Bajo Segmento f
seg[0] (g / CG) W4 CG LVCMOS33 Bajo Segmento g
dp (DP) U7 DP LVCMOS33 Bajo Punto decimal (lo dejaremos apagado)
an[0] (AN0) W7 AN0 LVCMOS33 Bajo Dígito 0 (menos significativo, derecha)
an[1] (AN1) W6 AN1 LVCMOS33 Bajo Dígito 1
an[2] (AN2) U8 AN2 LVCMOS33 Bajo Dígito 2
an[3] (AN3) V8 AN3 LVCMOS33 Bajo Dígito 3 (más significativo, izquierda)

Nota:
– Los segmentos y ánodos son activos en bajo en Basys 3 (común ánodo).
– El reloj es de 100 MHz, por lo que definiremos un divisor para:
– Multiplexar los 4 dígitos (≈190–1 kHz por dígito, evitando parpadeo).
– Incrementar el conteo a ≈10 Hz para una visualización cómoda.


Código completo (Verilog) y explicación

Estructura del diseño

  • Módulo top: top_basys3_counter
  • Entradas: clk (100 MHz)
  • Salidas: seg[6:0], dp, an[3:0]
  • Bloques:
  • Divisor de reloj para refresco del display (multiplexación).
  • Divisor de reloj para tick de conteo (10 Hz).
  • Contador de 16 bits (se mostrará como 4 dígitos hex).
  • Decodificador HEX→7 segmentos (activos en bajo).
  • Multiplexor de dígitos (selecciona nibble y ánodo correspondiente).

Código Verilog (fuente principal)

Guarda este archivo como top_basys3_counter.v:

// top_basys3_counter.v
// Proyecto: binary-counter-on-seven-segment
// Placa: Basys 3 (Xilinx Artix-7, XC7A35T-1CPG236C)
// Toolchain: Vivado WebPACK 2023.2
// Descripción: Contador binario de 16 bits mostrado en 4 dígitos de 7 segmentos (hex),
//              con multiplexación y segmentos/ánodos activos en bajo.

module top_basys3_counter (
    input  wire        clk,       // 100 MHz
    output reg  [6:0]  seg,       // a..g (activos en bajo)
    output reg         dp,        // punto decimal (activo en bajo)
    output reg  [3:0]  an         // ánodos (activos en bajo)
);
    // ==========================
    // Parámetros de frecuencia
    // ==========================
    localparam integer CLK_FREQ_HZ      = 100_000_000; // 100 MHz
    localparam integer TICK_HZ          = 10;          // incremento del contador a 10 Hz
    localparam integer TICK_DIVISOR     = CLK_FREQ_HZ / TICK_HZ; // 10_000_000

    // ==========================
    // Divisor para tick del contador
    // ==========================
    reg [23:0] tick_div;   // 24 bits alcanzan 10,000,000 (2^24-1 = 16,777,215)
    reg        tick_10hz;

    always @(posedge clk) begin
        if (tick_div == TICK_DIVISOR - 1) begin
            tick_div   <= 24'd0;
            tick_10hz  <= 1'b1;
        end else begin
            tick_div   <= tick_div + 1'b1;
            tick_10hz  <= 1'b0;
        end
    end

    // ==========================
    // Contador de 16 bits (0x0000 .. 0xFFFF)
    // ==========================
    reg [15:0] counter;

    always @(posedge clk) begin
        if (tick_10hz) begin
            counter <= counter + 16'd1;
        end
    end

    // ==========================
    // Multiplexado de 4 dígitos
    // Usamos bits altos de un contador de refresco para seleccionar dígito.
    // Esto evita parpadeo sin necesidad de un divisor exacto.
    // ==========================
    reg [16:0] refresh_cnt;  // 17 bits -> ~763 Hz ciclo de multiplex, ~190 Hz por dígito (suficiente)
    always @(posedge clk) begin
        refresh_cnt <= refresh_cnt + 1'b1;
    end

    wire [1:0] digit_sel = refresh_cnt[16:15];

    // Selección de nibble para el dígito activo
    reg [3:0] nibble;

    always @(*) begin
        case (digit_sel)
            2'b00: nibble = counter[3:0];    // Dígito menos significativo (derecha)
            2'b01: nibble = counter[7:4];
            2'b10: nibble = counter[11:8];
            2'b11: nibble = counter[15:12];  // Dígito más significativo (izquierda)
            default: nibble = 4'h0;
        endcase
    end

    // ==========================
    // Decodificador HEX a 7 segmentos (activos en bajo)
    // Orden de bits: seg[6:0] = {a,b,c,d,e,f,g}
    // ==========================
    function [6:0] hex_to_sevenseg;
        input [3:0] hex;
        begin
            case (hex)
                4'h0: hex_to_sevenseg = 7'b0000001; // 0
                4'h1: hex_to_sevenseg = 7'b1001111; // 1
                4'h2: hex_to_sevenseg = 7'b0010010; // 2
                4'h3: hex_to_sevenseg = 7'b0000110; // 3
                4'h4: hex_to_sevenseg = 7'b1001100; // 4
                4'h5: hex_to_sevenseg = 7'b0100100; // 5
                4'h6: hex_to_sevenseg = 7'b0100000; // 6
                4'h7: hex_to_sevenseg = 7'b0001111; // 7
                4'h8: hex_to_sevenseg = 7'b0000000; // 8
                4'h9: hex_to_sevenseg = 7'b0000100; // 9
                4'hA: hex_to_sevenseg = 7'b0001000; // A
                4'hB: hex_to_sevenseg = 7'b1100000; // b
                4'hC: hex_to_sevenseg = 7'b0110001; // C
                4'hD: hex_to_sevenseg = 7'b1000010; // d
                4'hE: hex_to_sevenseg = 7'b0110000; // E
                4'hF: hex_to_sevenseg = 7'b0111000; // F
                default: hex_to_sevenseg = 7'b1111111; // apagado
            endcase
        end
    endfunction

    // ==========================
    // Actualización de segmentos y ánodos
    // ==========================
    always @(*) begin
        // Punto decimal apagado (activo en bajo -> 1 = off)
        dp  = 1'b1;

        // Selección de ánodo (activo en bajo)
        // an[0] => AN0 (derecha), an[3] => AN3 (izquierda)
        case (digit_sel)
            2'b00: an = 4'b1110; // AN0 activo
            2'b01: an = 4'b1101; // AN1 activo
            2'b10: an = 4'b1011; // AN2 activo
            2'b11: an = 4'b0111; // AN3 activo
            default: an = 4'b1111;
        endcase

        // Actualiza segmentos según nibble seleccionado (activos en bajo)
        seg = hex_to_sevenseg(nibble);
    end

endmodule

Explicación breve de partes clave

  • Divisor de tick (10 Hz): tick_div acumula ciclos del reloj de 100 MHz hasta 9,999,999. Al llegar, genera un pulso tick_10hz para incrementar el contador de 16 bits. El resultado es un conteo visible y cómodo.
  • Contador de 16 bits: counter se incrementa con cada tick de 10 Hz y se muestra en formato hexadecimal (0000 a FFFF), cumpliendo con la idea de “binary counter” representado en el display.
  • Multiplexado: refresh_cnt sube a 100 MHz continuamente; sus bits [16:15] generan 4 estados cíclicos que activan cada dígito de forma secuencial a ~190 Hz por dígito, evitando parpadeo visible.
  • Decodificador: hex_to_sevenseg entrega el patrón activo en bajo para cada dígito hexadecimal. dp se mantiene apagado (1), pero podría usarse como “latido” o indicador si se quisiese una variante.
  • Señales activas en bajo: tanto segmentos como ánodos requieren “0” para encenderse. Por eso la tabla de decodificación usa 0 para segmentos encendidos.

Constraints (XDC) para Basys 3

Guarda este archivo como basys3_7seg.xdc:

## basys3_7seg.xdc
## Placa: Basys 3 (Xilinx Artix-7, XC7A35T-1CPG236C)
## Reloj de 100 MHz y display de 7 segmentos (activos en bajo)
## Toolchain: Vivado WebPACK 2023.2

# Reloj 100 MHz
set_property PACKAGE_PIN W5 [get_ports {clk}]
set_property IOSTANDARD LVCMOS33 [get_ports {clk}]
create_clock -name sys_clk -period 10.000 [get_ports {clk}]

# Segmentos: seg[6:0] = {a,b,c,d,e,f,g}
set_property PACKAGE_PIN U2 [get_ports {seg[6]}]  ;# CA (a)
set_property PACKAGE_PIN V2 [get_ports {seg[5]}]  ;# CB (b)
set_property PACKAGE_PIN U1 [get_ports {seg[4]}]  ;# CC (c)
set_property PACKAGE_PIN V1 [get_ports {seg[3]}]  ;# CD (d)
set_property PACKAGE_PIN U4 [get_ports {seg[2]}]  ;# CE (e)
set_property PACKAGE_PIN V4 [get_ports {seg[1]}]  ;# CF (f)
set_property PACKAGE_PIN W4 [get_ports {seg[0]}]  ;# CG (g)
set_property IOSTANDARD LVCMOS33 [get_ports {seg[*]}]

# Punto decimal
set_property PACKAGE_PIN U7 [get_ports {dp}]      ;# DP
set_property IOSTANDARD LVCMOS33 [get_ports {dp}]

# Ánodos (activos en bajo): an[0]=AN0 ... an[3]=AN3
set_property PACKAGE_PIN W7 [get_ports {an[0]}]   ;# AN0 (derecha)
set_property PACKAGE_PIN W6 [get_ports {an[1]}]   ;# AN1
set_property PACKAGE_PIN U8 [get_ports {an[2]}]   ;# AN2
set_property PACKAGE_PIN V8 [get_ports {an[3]}]   ;# AN3 (izquierda)
set_property IOSTANDARD LVCMOS33 [get_ports {an[*]}]

Puntos clave:
– create_clock define explícitamente 100 MHz (10 ns). Esto ayuda a que las herramientas de temporización verifiquen la implementación correctamente.
– Las señales segmentadas y los ánodos están declarados como LVCMOS33, coherentes con la Basys 3.


Compilación, implementación y programado (CLI exacto)

A continuación, se ofrecen comandos reproducibles con Vivado 2023.2 WebPACK para:
– Crear proyecto, sintetizar, implementar, generar bitstream.
– Abrir y programar el hardware.

Preparar árbol de directorios y archivos

  • Crea un directorio de trabajo y copia los dos archivos previos:
  • top_basys3_counter.v
  • basys3_7seg.xdc

Ejemplo (Linux/macOS/Powershell adaptado):
– Linux (bash):

mkdir -p ~/fpga/basys3_counter_7seg
cd ~/fpga/basys3_counter_7seg

# Crear fuente Verilog
cat > top_basys3_counter.v << 'EOF'
[PEGA AQUÍ EL CONTENIDO COMPLETO DE top_basys3_counter.v]
EOF

# Crear constraints XDC
cat > basys3_7seg.xdc << 'EOF'
[PEGA AQUÍ EL CONTENIDO COMPLETO DE basys3_7seg.xdc]
EOF

En Windows PowerShell, puedes crear los archivos con un editor (Notepad/VSCode) dentro de la carpeta del proyecto, asegurando el nombre exacto.

Script de build (Tcl)

Guarda como build.tcl en el mismo directorio:

# build.tcl
# Vivado WebPACK 2023.2 - Síntesis, implementación y bitstream
# Dispositivo: Artix-7 XC7A35T-1CPG236C (Basys 3)

set proj_name "basys3_counter_7seg"
set top_name  "top_basys3_counter"
set part_name "xc7a35tcpg236-1"

# Crear o limpiar proyecto
create_project $proj_name . -part $part_name -force

# Añadir fuentes
add_files [list "top_basys3_counter.v"]
# Añadir constraints
add_files -fileset constrs_1 [list "basys3_7seg.xdc"]

# Actualizar orden de compilación
update_compile_order -fileset sources_1

# Síntesis
synth_design -top $top_name -part $part_name
write_checkpoint -force ${proj_name}_post_synth.dcp
report_timing_summary -file ${proj_name}_timing_synth.rpt
report_utilization     -file ${proj_name}_util_synth.rpt

# Implementación (place & route)
opt_design
place_design
phys_opt_design
route_design
write_checkpoint -force ${proj_name}_post_route.dcp
report_timing_summary -file ${proj_name}_timing_route.rpt
report_utilization     -file ${proj_name}_util_route.rpt

# Bitstream
write_bitstream -force ${proj_name}.bit

# Programación (si la placa está conectada)
open_hw
connect_hw_server
open_hw_target

# Seleccionar el primer dispositivo disponible
set hw_device [lindex [get_hw_devices] 0]
current_hw_device $hw_device

# Configurar bitstream
set_property PROGRAM.FILE [get_property DIRECTORY [current_project]]/${proj_name}.bit [current_hw_device]

# Programar dispositivo
program_hw_devices [current_hw_device]

# Cerrar
close_hw
exit

Notas:
– El script crea el proyecto, sintetiza, implementa, genera el bitstream y programa la placa si está conectada.
– Se usa el part_name exacto del FPGA de Basys 3: xc7a35tcpg236-1 (coherente con el modelo especificado).

Ejecutar el flujo completo

  • Linux/Windows (terminal/Powershell) desde la carpeta del proyecto:
vivado -mode batch -source build.tcl

Lo esperado:
– Archivos de reporte (timing/utilización) y checkpoints en el directorio.
– Archivo bitstream: basys3_counter_7seg.bit
– Si la Basys 3 está conectada y detectada, queda programada automáticamente. Si no, se puede ejecutar la programación en una segunda pasada cuando esté conectada (repitiendo el mismo comando).

Solo programar (opcional)

Si ya tienes el bitstream y deseas únicamente programar:

Crea program_only.tcl:

# program_only.tcl
set proj_name "basys3_counter_7seg"

open_hw
connect_hw_server
open_hw_target

set hw_device [lindex [get_hw_devices] 0]
current_hw_device $hw_device

set_property PROGRAM.FILE [get_property DIRECTORY [current_project]]/${proj_name}.bit [current_hw_device]
program_hw_devices [current_hw_device]

close_hw
exit

Y ejecútalo:

vivado -mode batch -source program_only.tcl

Validación paso a paso

Para confirmar que el “binary-counter-on-seven-segment” funciona:

  1. Alimentación y enumeración:
  2. La Basys 3 está encendida (LED ON).
  3. Al ejecutar build.tcl, no aparecen errores de hardware (la programación finaliza sin errores).
  4. Visualización inicial:
  5. Los cuatro dígitos del display deben estar activos (con multiplexación sin parpadeo visible).
  6. El punto decimal (DP) permanece apagado en todos los dígitos.
  7. Conteo:
  8. Observa el dígito menos significativo (derecha). Debe cambiar aproximadamente cada 0,1 s (10 Hz).
  9. Los dígitos muestran valores hexadecimales (0..9, A..F).
  10. Progresión:
  11. Cuando el dígito menos significativo pasa de F a 0, el segundo dígito (desde la derecha) incrementa en 1 (hexadecimal).
  12. El conteo recorre 0000, 0001, 0002, …, 000F, 0010, …, 00FF, 0100, …, FFFF y vuelve a 0000.
  13. Multiplexación:
  14. No debe observarse parpadeo molesto. Si grabas en cámara lenta, verás cómo los dígitos se actualizan de forma secuencial; esto indica multiplexación correcta.
  15. Señales activas en bajo:
  16. Si cuentas con un multímetro/analizador, puedes medir que las líneas an[n] bajan secuencialmente, y las seg[] bajan según el patrón del dígito activo.

Resultado satisfactorio:
– Un conteo suave y continuo en los cuatro dígitos, sin segmentos residuales encendidos, y sin parpadeo apreciable a simple vista.


Troubleshooting (errores típicos y soluciones)

  1. No aparece la placa en Vivado (open_hw_target no encuentra dispositivos)
  2. Causas:
    • Driver del cable Digilent no instalado.
    • Cable USB defectuoso o sin alimentación suficiente.
    • JP1 no está en USB o el switch de encendido está en OFF.
  3. Soluciones:

    • Reinstala cable drivers desde Vivado (Xilinx > Utilities > Install Cable Drivers).
    • En Linux, verifica lsusb; en Windows, revisa el Administrador de dispositivos.
    • Cambia el cable USB y usa un puerto USB diferente (evita hubs pasivos).
    • Asegura JP1 en USB y la placa encendida.
  4. Error de asignación de pines (DRC) o pines en bancos incorrectos

  5. Causas:
    • Nombres de puertos HDL no coinciden con los usados en XDC (por ejemplo, seg vs segments).
  6. Soluciones:

    • Asegura que los puertos del módulo top coinciden exactamente con los get_ports del XDC.
    • Revisa la tabla de pines y el archivo basys3_7seg.xdc.
  7. El display muestra “8” permanente en todas las posiciones

  8. Causas:
    • Ánodos sin multiplexar (an no cambia) o están activos todos a la vez.
    • Las salidas están activas en alto en lugar de activo en bajo.
  9. Soluciones:

    • Revisa el bloque always @(*) que controla an y seg; debe forzar un solo ánodo activo (bajo) por vez.
    • Verifica la tabla de decodificación (0 enciende) y que dp esté en 1 para estar apagado.
  10. Parpadeo excesivo o dígitos muy tenues

  11. Causas:
    • Frecuencia de multiplexado demasiado baja.
  12. Soluciones:

    • Ajusta refresh_cnt para usar menos bits (por ejemplo, [15:14]) y aumentar la velocidad de escaneo.
    • Evita valores muy altos que bajen la tasa por dígito por debajo de ~100 Hz.
  13. Conteo demasiado rápido o demasiado lento

  14. Causas:
    • Cálculo de TICK_DIVISOR incorrecto para 100 MHz.
  15. Soluciones:

    • Verifica el valor de TICK_DIVISOR = 100_000_000 / 10 = 10_000_000.
    • Confirma que el reloj en XDC está a 10 ns (100 MHz) con create_clock.
  16. Violaciones de temporización (timing) tras place/route

  17. Causas:
    • Inconsistencias de constraints o carga adicional inesperada.
  18. Soluciones:

    • Revisa los reportes ${proj_name}_timing_route.rpt.
    • Para un diseño tan simple, normalmente no hay problemas con 100 MHz; si los hubiera, verifica que create_clock esté correctamente aplicado a clk.
  19. Error al programar: “No current_hw_device selected” o “PROGRAM.FILE not set”

  20. Causas:
    • El script ejecutó open_hw_target, pero no seleccionó dispositivo.
  21. Soluciones:

    • Asegúrate de que get_hw_devices devuelve al menos un dispositivo.
    • Comprueba que el cable y la placa están conectados antes de ejecutar el script.
  22. Segmentos o dígitos invertidos (nibble en dígito equivocado)

  23. Causas:
    • Orden diferente entre an[0..3] y AN0..AN3, o digit_sel mal mapeado.
  24. Soluciones:
    • Revisa la sección “Multiplexación”: en este caso, 2’b00 → AN0 (derecha), 2’b11 → AN3 (izquierda).
    • Ajusta el case de digit_sel si prefieres otro orden.

Mejoras y variantes

  • Ajuste de velocidad de conteo:
  • Añadir un parámetro o constantes para cambiar TICK_HZ (1 Hz, 2 Hz, 5 Hz, 20 Hz).
  • Mapear a los switches on-board (SW) para seleccionar TICK_HZ a tiempo de ejecución (requiere añadir puertos y pines en XDC).
  • Indicador de vida (heartbeat) con DP:
  • Usar dp como latido (p. ej., alternar dp del dígito activo a 1 Hz).
  • Modo decimal:
  • En lugar de HEX, implementar conversión a BCD de 16 bits (hasta 65535) y mostrar en decimal. Implica un conversor binario→BCD y modificación del decodificador.
  • Reset del contador:
  • Añadir un botón (BTNC) como reset síncrono. Requiere agregar pin en XDC y lógica simple.
  • Doble velocidad de multiplexado adaptativa:
  • Aumentar frecuencia de refresco con iluminación PWM para balancear brillo si algún dígito luce más tenue.
  • Modo “hold”:
  • Congelar el conteo cuando se presione un botón, o avanzar paso a paso con pulsadores (requiere anti-rebote).

Estas variantes siguen el mismo flujo de trabajo con Vivado y conservan la coherencia con la Basys 3, el display de 7 segmentos y la idea de un contador binario mostrado en el display.


Checklist de verificación (marcable)

  • [ ] Uso del modelo exacto: Basys 3 (Xilinx Artix‑7, XC7A35T‑1CPG236C).
  • [ ] Toolchain exacta: Vivado WebPACK 2023.2 instalada y “vivado -version” correcto.
  • [ ] JP1 en posición USB y placa encendida (LED ON).
  • [ ] Archivos creados: top_basys3_counter.v y basys3_7seg.xdc con el contenido indicado.
  • [ ] Script build.tcl creado sin modificaciones de nombres/part.
  • [ ] Comando ejecutado: vivado -mode batch -source build.tcl (sin errores).
  • [ ] Bitstream generado: basys3_counter_7seg.bit en el directorio del proyecto.
  • [ ] Programación exitosa de la placa (sin errores de open_hw_target ni de cable).
  • [ ] Display muestra cuatro dígitos HEX con conteo de 0000 a FFFF.
  • [ ] Punto decimal apagado en todos los dígitos.
  • [ ] Sin parpadeo visible excesivo; brillo uniforme.
  • [ ] Reportes de timing razonables (sin violaciones) y utilización baja.

Si todo lo anterior está marcado, el caso práctico está completado con éxito.


Resumen final

Has implementado un “binary-counter-on-seven-segment” en la Basys 3 usando exclusivamente recursos on-board, con Verilog y la toolchain Vivado WebPACK 2023.2. El diseño integra:
– Un contador binario de 16 bits con tick a 10 Hz.
– Multiplexación de 4 dígitos y decodificación HEX a segmentos activos en bajo.
– Constraints correctas para Basys 3 y flujo de compilación/implementación/programado por CLI.

Este caso práctico consolida los fundamentos de flujo FPGA con Xilinx, la manipulación de periféricos on-board y la disciplina de trabajo reproducible con scripts. A partir de aquí, puedes extender el comportamiento con entradas (botones/switches), diferentes bases numéricas, o nuevas salidas visuales.

Encuentra este producto y/o libros sobre este tema en Amazon

Ir a Amazon

Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.

Quiz rápido

Pregunta 1: ¿Cuál es el objetivo principal del proyecto?




Pregunta 2: ¿Qué sistema operativo se menciona como opción A?




Pregunta 3: ¿Qué versión de Vivado WebPACK se debe utilizar?




Pregunta 4: ¿Cuál es la arquitectura de la placa Basys 3?




Pregunta 5: ¿Qué tipo de display se utiliza en el proyecto?




Pregunta 6: ¿Qué tipo de conocimientos previos se requieren?




Pregunta 7: ¿Cuál es la frecuencia del reloj de la placa Basys 3?




Pregunta 8: ¿Qué tipo de cable se necesita para conectar la placa Basys 3 al PC?




Pregunta 9: ¿Qué comando se utiliza para comprobar la versión de Vivado?




Pregunta 10: ¿Qué tipo de pines se deben conocer para trabajar con la placa Basys 3?




Carlos Núñez Zorrilla
Carlos Núñez Zorrilla
Electronics & Computer Engineer

Ingeniero Superior en Electrónica de Telecomunicaciones e Ingeniero en Informática (titulaciones oficiales en España).

Sígueme:
error: Contenido Protegido / Content is protected !!
Scroll to Top