【基于Tang Nano 9K FPGA 实现BCD-数码管译码器】点亮数码管~

【基于Tang Nano 9K FPGA 实现BCD-数码管译码器】点亮数码管~

目录

一. 项目背景&目标

74HC47是一种IC器件,它对一个BCD输入进行译码,并驱动7段显示器。当然,除了译码和段驱动的功能,74HC47还有很多其他的功能。我们基于74HC47的译码和段驱动的功能,系统以 4-bit 输入 bcd[3:0] 为数据源,输出 段选信号 seg[7:0](a~g + dp)与 位选信号 dig[3:0],实现数码管对 0~F 的稳定显示,并进一步扩展到 四位数码管的位选控制/动态扫描显示。

二. 硬件说明

本项目基于 Tang Nano 9K FPGA 开发板(GW1NR-9 系列器件)进行验证,主要使用外接四位七段数码管(带dp)SR420561K作为显示端,并通过拨码开关提供 4-bit 输入bcd[3:0]。由于板载可用的按键/拨码资源有限,位选控制不再通过外部输入动态设置,而是在顶层模块中对显示数据与位选策略进行静态配置:直接预置待显示的数值,并由顶层逻辑生成对应的位选(dig)与段选(seg)信号用于驱动数码管显示。

1.Tang Nano 9K FPGA 开发板(GW1NR-9 系列器件)

tang nano 9k 核心板引脚图

2.数码管 SR420561K

引脚如图所示(正面朝自己,小数点在下方)。a、b、c、d、e、f、g、dp为段引脚,1、2、3、4分别表示四个数码管的位。

数码管


数码管采用 “段选 + 位选”结构:
seg[7:0]:8 条段选线,通常对应 a,b,c,d,e,f,g,dp(dp 为小数点)
dig[3:0]:4 条位选线,用于选通第 0~3 位数码管

数码管为共阳极,低电平有效。
段选 seg:0 点亮,1 熄灭(active-low)
位选 dig:0 选通该位,1 关闭该位(active-low)

3.IO 电气约束(.cst 的意义)

引脚图
IO_LOC "dig[3]"30; IO_PORT "dig[3]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "dig[2]"33; IO_PORT "dig[2]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "dig[1]"34; IO_PORT "dig[1]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "dig[0]"40; IO_PORT "dig[0]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "seg[7]"38; IO_PORT "seg[7]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "seg[6]"37; IO_PORT "seg[6]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "seg[5]"36; IO_PORT "seg[5]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "seg[4]"39; IO_PORT "seg[4]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "seg[3]"25; IO_PORT "seg[3]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "seg[2]"26; IO_PORT "seg[2]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "seg[1]"27; IO_PORT "seg[1]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "seg[0]"28; IO_PORT "seg[0]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "sw[3]"74; IO_PORT "sw[3]" IO_TYPE=LVCMOS33 PULL_MODE=DOWN BANK_VCCIO=3.3; IO_LOC "sw[2]"73; IO_PORT "sw[2]" IO_TYPE=LVCMOS33 PULL_MODE=DOWN BANK_VCCIO=3.3; IO_LOC "sw[1]"72; IO_PORT "sw[1]" IO_TYPE=LVCMOS33 PULL_MODE=DOWN BANK_VCCIO=3.3; IO_LOC "sw[0]"71; IO_PORT "sw[0]" IO_TYPE=LVCMOS33 PULL_MODE=DOWN BANK_VCCIO=3.3;

Gowin FPGA 中,IO 并不是每个引脚都独立供电,而是按组(Bank)划分:同一 Bank 内的一组 IO 引脚共享同一组 IO 供电电压 VCCIO,并在电气能力上受该电压域约束。数码管输出属于“强驱动输出端”,尽量放在同一 3.3V Bank,因此:

  • 同一 Bank 的 IO_TYPE 必须与该 Bank 的 VCCIO 匹配。例如,当 BANK_VCCIO=3.3V 时,才能选择 LVCMOS33 一类 3.3V IO 标准;若该 Bank 供电为 1.8V,则应使用 LVCMOS18 等 1.8V IO 标准。
  • 同一 Bank 内的引脚通常应工作在同一电压域。若将 3.3V 外设信号与 1.8V IO 混在同一 Bank,会导致约束报错、下载失败,甚至存在电气风险(过压/夹管导通)。

.cst 中的 BANK_VCCIO/IO_TYPE 实质是在告诉工具链:该端口所在 Bank 的供电电压与电平标准,从而确保布局布线与电气规则检查(DRC)一致。

三. BCD七段译码器(display8x1)

1.BCD码

BCD(Binary-Coded Decimal,二-十进制编码)是一种面向十进制显示的编码方式:它用 4 个二进制位来表示一个十进制数字(0~9),例如 0→0000,1→0001,…,9→1001;而 1010~1111 在标准 BCD 中属于无效码。与“用纯二进制表示整个数值”不同,BCD 的特点是每个十进制位独立编码,因此非常适合数码管等显示场景——译码逻辑简单、显示直观。在本项目中,bcd[3:0] 即为单个十进制位的 BCD 输入(也可扩展支持 0~F 作为 HEX 输入),经七段译码后生成对应的段选信号驱动数码管显示。

2.七段(a~g)+ dp 译码

七段数码管的显示本质上是一个查表映射:输入为 4-bit 的 bcd[3:0],输出为七段点亮状态 segt[6:0]。由于本项目使用的数码管为共阳极且低电平有效(active-low),因此对任意一段而言:

  • 输出 0 表示点亮该段
  • 输出 1 表示熄灭该段

基于这一约定,可以为每个输入值(0~F)预先定义需要点亮的段集合,并将其编码为 7-bit 段码。示例中 segt 仅包含 a~g 七段(不含 dp),并在注释中标注了该数字对应点亮的段。例如:
bcd==0 时点亮 a b c d e f(g 关闭),因此段码为 7'b0000_001
bcd==1 时仅点亮 b c,其余熄灭,因此段码为 7'b1001_111
bcd==8 时点亮 a~g 全部七段,因此段码为 7'b0000_000
同时,为了便于调试与扩展,本文将输入范围扩展到 0~F,使其不仅可显示十进制 0~9,也可显示十六进制字符 A~F(例如 A=abcefg、b=cdefg、C=adef 等)。当输入超出定义范围时,输出 7'b1111_111(全灭)作为默认保护状态,避免出现不可预期的随机亮段。
dp(小数点)通常单独作为第 8 路段选信号处理,原则与七段一致:在共阳极低有效条件下,dp=0 点亮、dp=1 熄灭。工程实现中一般将七段段码 segt[6:0] 与 dp 位拼接输出到 seg[7:0],从而形成完整的段选控制信号。

always @(*) begin if(bcd==4'd0) segt <= 7'b0000_001;//abcdefelseif(bcd==4'd1) segt <= 7'b1001_111;//bcelseif(bcd==4'd2) segt <= 7'b0010_010;//abdegelseif(bcd==4'd3) segt <= 7'b0000_110;//abcdgelseif(bcd==4'd4) segt <= 7'b1001_100;//bcfgelseif(bcd==4'd5) segt <= 7'b0100_100;//acdfgelseif(bcd==4'd6) segt <= 7'b0100_000;//acdefgelseif(bcd==4'd7) segt <= 7'b0001_111;//abcelseif(bcd==4'd8) segt <= 7'b0000_000;//abcdefgelseif(bcd==4'd9) segt <= 7'b0000_100;//abcdfgelseif(bcd==4'd10) segt <= 7'b0001_000;//abcefgelseif(bcd==4'd11) segt <= 7'b1100_000;//cdefgelseif(bcd==4'd12) segt <= 7'b1110_010;//degelseif(bcd==4'd13) segt <= 7'b1000_010;//bcdegelseif(bcd==4'd14) segt <= 7'b0110_000;//adefgelseif(bcd==4'd15) segt <= 7'b0111_000;//aefgelse segt <=7'b1111_111; end assign seg ={segt,~dp};

四. 四位数码管位选模块(display8x4)

在四位数码管中,四个数码位通常共用同一组段选信号 seg[7:0],通过独立的位选信号 dig[3:0] 决定“当前哪一位被点亮”。因此,多位显示的核心不在于段码本身,而在于位选(digit select):在任意时刻只选通其中一位,同时输出对应的段码;通过高速轮询(动态扫描)即可实现肉眼可见的“同时显示四位”。
本项目的 display8x4 模块将“七段译码”和“位选控制”解耦:

  • 段码由子模块 display8x1 负责生成(bcd → seg)
  • 位选由 display8x4 根据位置参数 pos 生成 one-hot 的 dig

1.位选信号约定

位选信号有效电平看电路公共端
由于数码管为共阳极且低电平有效,位选端 dig(COM) 的有效电平为高电平:

  • dig[i] = 1:选通第 i 位(该位被点亮)
  • dig[i] = 0:关闭第 i 位

因此 dig 采用低有效 one-hot编码:任意时刻只有一个 bit 为 1,其余为 0。例如:

module display8x4( input [3:0] bcd, input dp, input en, input [1:0] pos, output [7:0] seg, output reg [3:0] dig ); display8x1 u1(.bcd(bcd),.dp(dp),.en(en),.seg(seg)); always @(*) begin if(pos==2'b00) dig<=4'b0001;//选第一位elseif(pos==2'b01) dig<=4'b0010;//选第二位elseif(pos==2'b10) dig<=4'b0100;//选第三位elseif(pos==2'b11) dig<=4'b1000;//选第四位else dig<=4'b0000; end endmodule 

这种编码方式直观、易调试,也便于后续做动态扫描。需要注意的是,seg 由子模块 display8x1 输出驱动,因此 display8x4 的 seg 端口应保持 net(wire 语义),不能声明为 reg 并在多个过程块中赋值。

五.顶层模块设计(display)

在顶层模块 display 中,本设计将拨码开关 sw[3:0] 直接作为显示数据输入,并调用 display8x4 模块完成段选与位选控制。由于当前实验阶段主要用于验证译码与位选功能,因此将小数点 dp 固定关闭,使能信号 en 固定开启,同时将位选位置 pos 设为常量 2'd0,从而仅点亮第1位数码管,便于观察显示结果与调试译码正确性。

module display( input [3:0] sw, output [7:0] seg, output [3:0] dig ); display8x4 u1(.bcd(sw),.dp(1'b0),//小数点常灭.en(1'b1),//使能信号固定开启.pos(2'd0),//点亮第一位数码管.seg(seg),.dig(dig)); endmodule 

1.系统框图

系统框图


系统输入来自拨码开关 sw[3:0],该信号作为显示数据输入 bcd[3:0] 进入顶层模块。顶层模块主要起到信号分配与功能组织的作用,并将输入数据分别送入两个功能子模块。
首先,bcd[3:0] 被送入 8×1 七段译码器,该模块负责将数字编码转换为对应的段选控制信号 seg[7:0],用于决定数码管各段(a~g 及 dp)是否点亮。与此同时,顶层模块还提供显示控制信号,包括小数点控制 dp、显示使能 en 以及位选控制 pos,其中 pos 进一步进入位选译码模块。
随后,2×4 位选译码器 根据 pos 的取值生成位选信号 dig[3:0],用于选择当前被激活的数码管位。最终,段选信号与位选信号共同作用,实现数码管字符显示功能。
通过这种模块化划分,系统将“字符译码”与“位选控制”分离,不仅结构清晰,而且便于后续扩展多位动态扫描与复杂显示逻辑。

2.实物图

实物图

Read more

掌握提问驱动AI:速通大模型提示工程

掌握提问驱动AI:速通大模型提示工程

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为ZEEKLOG博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理解,而且能够帮助新手快速入门。 本文主要介绍了掌握提问驱动AI:速通大模型提示工程,希望能对学习大模型的同学们有所帮助。 文章目录 * 1. 前言 * 2. 书籍推荐 * 2.1 内容简介 * 2.2 本书作者 * 2.3 本书目录 * 2.4 适合读者 * 3. 购买链接 1. 前言 我们正身处一场人类认知方式的深刻变革之中。 曾几何时,我们习惯于在搜索引擎的框框里输入关键词,试图在浩如烟海的信息碎片中拼凑出想要的答案。而如今,随着生成式人工智能的爆发,获取知识的门槛被瞬间拉平。超级算力被压缩进一个简单的对话框,似乎每个人都握住了一把通往全知全能的钥匙。 然而,在这场技术普惠的狂欢背后,一个新的鸿沟正在悄然拉开。

在国内环境部署 OpenClaw:从零到跑通的个人 AI 助手搭建指南

在国内环境部署 OpenClaw:从零到跑通的个人 AI 助手搭建指南 OpenClaw 是一个开源的个人 AI 助手框架,可以连接 WhatsApp、Telegram、Slack、Discord、飞书等 20+ 消息渠道。本文记录了在国内网络环境下部署 OpenClaw 的完整流程,包括网络适配、模型配置、渠道接入等实战经验。 什么是 OpenClaw? OpenClaw 是一个 local-first 的个人 AI 助手平台。它的核心是一个 Gateway 服务,运行在你自己的设备上,通过 WebSocket 管理会话、消息路由和工具调用。 核心特性: * 🏠 本地运行,数据不经过第三方 * 📱 支持 20+ 消息渠道(飞书、Telegram、Discord、Slack、微信等)

Harness Engineering:给 AI 套上缰绳的工程学(通俗易懂)

Harness Engineering:给 AI 套上缰绳的工程学(通俗易懂)

🐴 Harness Engineering:给 AI 套上缰绳的工程学 AI 写代码的速度已经超过了人类能"擦屁股"的速度。Harness Engineering,就是那根让烈马变战马的缰绳。 目录 * 🐴 Harness Engineering:给 AI 套上缰绳的工程学 * 一、前言:当 AI 开始"飙车" * 二、名词急救包——先扫盲再上路 * 🐎 Harness Engineering(驾驭工程) * 🧠 Context Engineering(上下文工程) * 🎵 Vibe Coding(氛围编程) * 🤖 Coding Agent(编码智能体) * 📋 AGENTS.md(AI 工作手册) * 🔌 MCP / ACP / A2A(

AI赋能智能终端PCB设计,核心是通过自动化布局布线、仿真加速、缺陷预测与制造协同

AI赋能智能终端PCB设计,核心是通过自动化布局布线、仿真加速、缺陷预测与制造协同

AI赋能智能终端PCB设计,核心是通过自动化布局布线、仿真加速、缺陷预测与制造协同,将传统“经验驱动”转为“数据决策”,显著缩短周期、提升性能与良率,适配高密度、高速、高可靠的终端需求。以下从核心场景、技术路径、实践案例、实施要点与趋势展开,形成可落地的创新实践指南。 一、核心应用场景与价值 应用环节核心痛点AI解决方案量化收益布局布线人工耗时久、串扰/阻抗难控强化学习+物理驱动AI自动规划,同步优化SI/PI/热/EMI12层板布线周期从3天缩至2小时,串扰降30%,阻抗偏差±3%内仿真验证传统EM仿真慢(小时级)神经网络替代部分计算,预仿真与实时校验仿真速度提升10–100倍,提前拦截70%以上信号/电源风险DFM/DFA量产缺陷多、返工率高学习历史数据,实时预警虚焊、铜箔撕裂、孔偏量产故障率降>30%,投板成功率提升至95%+电源/热设计纹波大、散热不均AI优化电源分配网络(