2、Vivado开发环境搭建:Vivado安装与配置、创建第一个Vivado工程、硬件描述语言基础回顾
好,咱们正式开始动手了。这一章,我带你把吃饭的家伙——Vivado,给装好、配好,再跑通第一个工程。顺便把硬件描述语言的基础过一遍。别嫌啰嗦,我见过太多人卡在环境搭建上,一卡就是半天。
2.1 Vivado安装与配置
Vivado是Xilinx(现在叫AMD了)的官方IDE。说白了,它就是咱们写代码、仿真、综合、布局布线的“大本营”。
2.1.1 版本选择
我个人习惯用最新的稳定版。但这里有个坑:不是越新越好。新版本对操作系统和硬件要求更高。我建议你用Vivado 2020.1到2022.2之间的版本,对Zynq-7000系列支持最稳。
| 版本 | 推荐指数 | 备注 |
|---|---|---|
| Vivado 2020.1 | ⭐⭐⭐⭐⭐ | 最稳定,资料最多 |
| Vivado 2021.2 | ⭐⭐⭐⭐ | 支持新器件,但稍大 |
| Vivado 2022.2 | ⭐⭐⭐ | 功能全,但吃内存 |
2.1.2 安装步骤
安装其实不复杂,但有几个关键点要注意:
- 下载安装包:去官网注册下载,或者用我提供的网盘链接。注意要下载“Vivado HLx”版本,别下成“Vitis”了。
- 安装路径:不要有中文!不要有空格!我习惯装到
C:\Xilinx\Vivado\2020.1这种路径。 - 选择组件:勾选“Vivado”和“Vitis”即可。如果你只做Zynq,可以只选“Vivado”。
- 安装时间:大概30分钟到1小时。去喝杯咖啡吧。
2.1.3 配置License
安装完第一件事,就是配置License。没有它,Vivado只能当个文本编辑器用。
- 打开Vivado,点击 Help → Manage License
- 选择 Load License,加载你的.lic文件
- 确认状态显示 “Valid”
嗯,这里要注意:如果你用的是破解版或者学生版,可能会有功能限制。但咱们做图像采集,基本够用。
2.2 创建第一个Vivado工程
好,环境搭好了,咱们来建个工程。别怕,就是点几下鼠标的事。
2.2.1 新建工程
- 打开Vivado,点击 Create Project
- 输入工程名:
led_test(别用中文) - 选择 RTL Project,勾选 Do not specify sources at this time
- 选择器件:搜索 xc7z020clg400-1(这是Zynq-7020的型号)
- 点击Finish
核心知识点:器件型号怎么看?
xc7z020 表示Zynq-7020芯片,clg400 是封装,-1 是速度等级。咱们用-1就够了,-2和-3是更高速度等级,但价格也贵。
2.2.2 添加源文件
工程建好了,现在加个Verilog文件。右键 Design Sources → Add Sources,选择 Add or create design sources,然后 Create File,命名为 led_top。
双击打开,写个最简单的代码:
module led_top (
input wire clk, // 50MHz时钟
input wire rst_n, // 复位,低有效
output reg [3:0] led // 4个LED
);
reg [31:0] cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt <= 32'd0;
led <= 4'b0000;
end else begin
cnt <= cnt + 1'b1;
if (cnt == 32'd25_000_000) begin // 0.5秒翻转一次
cnt <= 32'd0;
led <= ~led;
end
end
end
endmodule
这段代码什么意思?说白了就是一个计数器。每0.5秒,LED状态翻转一次。你想想看,接上板子,四个LED就会轮流闪烁。
2.2.3 综合与实现
写完了,点 Run Synthesis。综合就是把你写的代码翻译成电路。如果报错,别慌,看错误信息。我刚开始学的时候,经常漏分号,一查就是半天。
综合通过后,点 Run Implementation。这一步是布局布线,把电路放到实际的芯片上。
2.2.4 生成比特流并下载
最后一步,点 Generate Bitstream。生成完成后,打开 Hardware Manager,连接开发板,点击 Program device。
看到LED闪烁了吗?恭喜你,第一个工程跑通了!
2.3 硬件描述语言基础回顾
咱们做图像采集,主要用Verilog。这里快速回顾一下核心语法。如果你已经会了,可以跳过;如果忘了,就当复习。
2.3.1 模块结构
Verilog的基本单元是 module。每个模块都有输入输出端口。
module my_module (
input wire a,
input wire b,
output wire c
);
assign c = a & b;
endmodule
这里 assign 是连续赋值,相当于把a和b相与的结果直接连到c上。
2.3.2 组合逻辑 vs 时序逻辑
这是FPGA设计的核心概念。我简单解释一下:
- 组合逻辑:输出只取决于当前输入。比如与门、或门。
- 时序逻辑:输出还取决于之前的状态。比如计数器、寄存器。
在Verilog里,组合逻辑用 assign 或 always @(*),时序逻辑用 always @(posedge clk)。
避坑指南:我曾经在项目中把组合逻辑和时序逻辑混在一起写,结果仿真没问题,上板就出bug。后来才明白,组合逻辑里不能有寄存器赋值,时序逻辑里不能有 assign。
2.3.3 常用数据类型
| 类型 | 说明 | 示例 |
|---|---|---|
wire |
线网,用于组合逻辑 | wire [7:0] data; |
reg |
寄存器,用于时序逻辑 | reg [31:0] cnt; |
integer |
整数,常用于仿真 | integer i; |
注意:reg 不一定真的综合成寄存器。如果你在 always @(*) 里用 reg,它其实是个组合逻辑。
2.3.4 参数化设计
咱们做图像采集,经常要处理不同分辨率。用参数化设计,可以方便地调整。
module counter #(
parameter WIDTH = 32,
parameter MAX = 25_000_000
) (
input wire clk,
input wire rst_n,
output reg [WIDTH-1:0] cnt
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt <= 0;
else if (cnt == MAX)
cnt <= 0;
else
cnt <= cnt + 1;
end
endmodule
这样,你实例化的时候可以传不同的参数,不用改代码本身。
2.3.5 状态机
图像采集里,状态机是核心。比如控制摄像头初始化、读取数据、存储等。
localparam IDLE = 2'b00;
localparam READ = 2'b01;
localparam DONE = 2'b10;
reg [1:0] state, next_state;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
state <= IDLE;
else
state <= next_state;
end
always @(*) begin
case (state)
IDLE: next_state = start ? READ : IDLE;
READ: next_state = done ? DONE : READ;
DONE: next_state = IDLE;
default: next_state = IDLE;
endcase
end
这种写法叫“三段式状态机”,我个人最喜欢。它把状态跳转、输出逻辑分开,调试起来特别清晰。
default 分支。否则综合工具可能会生成锁存器,导致时序问题。我曾经因为这个,在项目交付前熬了两个通宵。
2.4 本章知识体系
下面这张图,帮你理清这一章的核心逻辑:
这一章的内容,说白了就是三件事:装好工具、跑通工程、复习语法。别小看这些基础,后面做图像采集时,每一步都离不开它们。
核心要点总结:
- Vivado安装时注意版本和驱动,别踩坑
- 第一个工程从LED闪烁开始,建立信心
- Verilog的核心是模块、赋值、状态机
- 参数化设计让代码更灵活
好,这一章就到这儿。你先把环境搭好,把第一个工程跑通。后面咱们就要开始真正的图像采集了。