课程:数字系统与处理器 | 理论课:91 | 实验课:99 | 关键词:FPGA / VGA / RTL / 应用层开发

数字系统与处理器课程及其实验实现

《数字系统与处理器》是卓越学院实验班核心课程之一。我在这门课中不仅取得了较好的理论和实验成绩,也基于 VGA 基础实验完成了一个可交互的数字时钟系统, 把“驱动层预置、应用层自主开发”的实验要求落实成了完整的 FPGA 工程实现。

授课教师:黄继业教授 理论课 91 分(排名 2/55) 实验课 99 分(课程记录 95) 后续被遴选为数电实验助教

课程背景与成绩概况

课程时间为 2024.09 至 2025.01。《数字系统与处理器》面向电子工程与集成电路两个大二实验班,由 黄继业教授 授课,内容覆盖数字逻辑、RTL 设计、74LS 系列电路应用以及 DAC / ADC 基础。

成绩表现

理论课 91 分(GPA 4.6/5,排名 2/55)

实验课 99 分(GPA 5.0/5,课程记录 95)

后续延伸

基于这一阶段的表现,我在大三被老师遴选为数电实验助教,并进一步承担 RV32I 相关教学项目。

实验训练特点

VGA 实验采用“驱动层预置、应用层自主开发”的方式,重点考察在既有底层时序上做功能扩展的能力。

实验总览

本实验基于 Altera Cyclone 10 LP FPGA,将 VGA 基础显示实验升级为可运行的数字时钟显示系统。 我完成了应用层时间逻辑、按键交互、字符渲染组合与硬件驱动层时序对接,实现了从图片读取显示到“可交互时钟界面”的工程化改造。

最终实现功能

屏幕实时显示 HH:MM:SS;按键用于时间快调;数字与冒号通过 ROM 像素查表稳定输出。

开发流程与步骤

Part 1:理解应用层的主要作用

提供的代码 vga_disp 在 25MHz 下输出当前像素坐标 x/y 与显示窗口控制,应用层每拍接收这些上下文。

Part 2:应用层时间状态更新

我在 rom_rgb.v 中定义 total_seconds 为全局时间状态,每秒更新一次,并根据 key[1:0] 注入不同步进策略。

Step 3:全局时间拆解,并进行显示映射

total_seconds 拆成 hoursminutesseconds,再通过区域编码 {y[6:5], x[8:5]} 决定当前像素属于哪一位数字或冒号。

Step 4:语义映射为像素

数字语义先映射到背景编号(ZERO..NINE/MAOHAO),再经 walk.mem + walk_pal.mem 查表输出 12bit rgb

Step 5:驱动层完成物理输出

驱动层只负责时序和门控:有效区输出 rgb,非显示区清零,并通过 HSYNC / VSYNC 保证显示器稳定锁定。

key + clk25M + x/ytotal_secondsdigitsbackground_idrgbVGA_D

VGA 驱动层理解

1. VGA 标准时钟域

pll.v 将 50MHz 分频到 25MHz,匹配 VGA 640×480 标准像素节拍。

2. 行场扫描

vga_disp.v 使用 hcnt / vcnt 双计数器形成逐行逐场扫描,构成完整帧时序。

3. 同步信号

在指定计数窗口拉低 HSYNC / VSYNC,向显示器声明行同步与场同步边界。

4. 有效显示门控

先将 512×128 内容区居中映射到 640×480,再用 dis_en 控制有效区输出 RGB,非显示区置零。

5. 帧级更新

vs_flag 可作为帧边沿信号,支持后续角色/动画等逻辑在帧同步点更新。

6. RGB 数据路径

应用层根据 x/y 输出 12bit rgb,驱动层在有效显示区送到 VGA_D,形成最终屏幕像素。

关键代码片段

vga_disp.v:有效显示区与同步信号生成

assign x = (hcnt >= (640-512)/2) ? hcnt-(640-512)/2 : 11'h7ff;
assign y = (vcnt >= (480-128)/2) ? vcnt-(480-128)/2 : 11'h7ff;
assign dis_en = (x<512 && y<128);

if((hcnt >=640+8+8) & (hcnt < 640+8+8+96))
  hs <= 1'b0;

if((vcnt >= 480+8+2) && (vcnt < 480+8+2+2))
  vs <= 1'b0;

rom_rgb.v:按键控制时间步进与数字显示

if (time_counter == 25000000) begin
  time_counter <= 0;
  case (key)
    2'b00: total_seconds <= (total_seconds >= 86400)?0:total_seconds + 3600;
    2'b01: total_seconds <= (total_seconds >= 86400)?0:total_seconds + 60;
    2'b10: total_seconds <= (total_seconds >= 86400)?0:total_seconds + 2;
    2'b11: total_seconds <= total_seconds + 1;
  endcase
end

case({y[6:5], x[8:5]})
  6'd20: background = (hours / 10);
  6'd21: background = (hours % 10);
  6'd22, 6'd25: background = MAOHAO; #时钟显示中间的冒号
  6'd23: background = (minutes / 10);
  6'd24: background = (minutes % 10);
  6'd26: background = (seconds / 10);
  6'd27: background = (seconds % 10);
endcase

vga_cartoon.qsf:板级引脚约束(节选)

set_location_assignment PIN_P16 -to VGA_HSYNC
set_location_assignment PIN_N15 -to VGA_VSYNC
set_location_assignment PIN_E15 -to clk50M
set_location_assignment PIN_M1  -to reset_n
set_location_assignment PIN_E1  -to key[1]
set_location_assignment PIN_F3  -to key[0]

工程预览与文件

VGA 驱动实验预览图
VGA 动态时钟实验预览图,可看到应用层逻辑已经完成稳定的数字显示。

关键工程文件(可查看原文)

笔记与仓库预览

笔记预览(期末总结)

整理了数电课程重点、实验调试记录与期末复习框架,便于快速回顾与复盘。

打开笔记原文(PDF)

返回主页对应模块