FPGA 中 system verilog 的使用
语言选择 SV + IP + matlab
- IC或者fpga 设计常用的语言有verilog、vhdl、Sytem verilog、spinalhdl 、BSV、HLS等。国内verilog最主流使用人数最多,主流的IC和FPGA用这个最多,VHDL在FPGA开发领域,基本等同于verilog,语法更加准确,也更加繁琐一些。system verilog 为verilog的超集。增加了一些新特性,尤其是适合验证的特性。对于设计来说,和verilog 差异不大。spinalHDL 和 BSV等语言,更像一种verilog生成工具,最终会生成verilog代码。在复杂算法开发上有一些优势,在接口和业务逻辑处理上优势不明显。HLS 为高层次综合,工具使用要求比较高,要求能看懂硬件结构、懂verilog、懂c++、还得懂一些算法原理,常规工程师很难有着样的成长路径。除非在这个领域一直精进的大牛,产业化还是有一些距离。
- 我目前认为FPGA比较适合的工具是SV 语言和IP开发,IP越来强大,FPGA工程师趋向IP应用工程师。ip使用 sv语言 或者verilog语言差别并不大。sv的一点优势是 不在区分wire和reg,有interfcae/struct等特性,代码更加友好,可读性强。另外在Tb设计上 有一些优势。
- spinalHDL和BSV更适合开发IP比如算法处理模块,这些语言描述计算密集型功能更有优势,在对FPGA IP的支持我还有待提升。增加了开发负担,考虑到fpga 开发的算法不会经常调整,反倒是业务逻辑调整的多。所以生成器类的工具效果打折扣。
- hls要求太高,适合大牛使用。
- 最重要的一点是,如果有上板调试过程,脱离软件环境,spinal和bsv、hls 的软件特性反而成为负担,最终还要回到verilog进行调试。
sv 语言的一些特性和适用场景
-
interface struct。interface 和 module 是一个逻辑层级,使用方式也相似。可以用来简化接口
interface xx_if ( input logic clk, input logic rst ); logic rdy; logic valid; logic [7:0] data; modport master ( // 此处只需要定义方向,不需要定义数据类型和位宽 input clk,rst,rdy, output valid ,data ); modport slave ( // 此处只需要定义方向,不需要定义数据类型和位宽 input clk,rst,data,valid, output rdy ); ### // 可以添加测试信号,测试激励。 endinterface module top ( input logic clk, input logic rst ); ### endmodule xx_if xx_if_inst( .clk (clk), .clk (rst) ); // 引用方式 // xx_if_inst.master; // xx_if_inst.slave; // xx_if_inst.slave.rdy; module master( interface xx_if.master ); ### endmodule master master( .xx_if.master (xx_if.master) ); -
数组 logic [7:0] rega [256:1]运用
logic [7:0] rega [5:0] ... rega[5] <= 8'd9; //数组类型使用与赋值,index 标号从0开始 rega[3:0][5] <= 4'd4; // verilog 版本不支持这种模式,sv可以 always(*) begin for(int i = 0;i<6;i++)begin rega[i] = i; // 需要用组合逻辑(塞赋值),不需要时间直接赋值成功 end end always(posedge clk , negedge rst) begin if (!rst) begin for(int i = 0;i<6;i++)begin rega[i] <= i; // 需要用时序逻辑(非塞赋值),一个时钟后赋值成功 end end else begin ... end end ... rega = {8'd0,8'd1,8'd2,8'd3,8'd4,8'd5}; -
for 语句运用,硬件的复制操作,增加面积。
-
多次生成 genage
genvar gen_i generate for(gen_i = 0;gen_i<100;gen_i++)begin ... end endgenerate -
多数据量赋值,移位寄存器。
always(posedge clk , negedge rst) begin if (!rst) begin for(int i = 0;i<6;i++)begin rega[i] <= i; // 需要用时序逻辑(非塞赋值),一个时钟后赋值成功 end end else begin for(int gen_i = 0;gen_i<9;gen_i++)begin reg[i+1] <= reg[i]; end reg[0] <= i_reg; end end -
`include 使用 预编译命令,在编译前生效,在编译的时候,需要对include命令进行"文件包含"预处理:将File2.v的全部内容复制插入到`include "File2.v"命令出现的地方,即将File2.v被包含到File1.v中。常见用法有全局参数化。
// pra.sv
`define AA 01
`define BB 02
`define CC 03 // 没有分号的
//
--------------------------
//function.sv
`include pra.sv
module function(
input logic [`BB:0] reg,
...
);
assign reg = `AA;
...
endmodule
- 条件编译使用
- 仿真部分
FPGA 调试工具
- ILA
- VIO
- JTAG AXI
- ibert
FPGA 工程管理
- 个人开发
- 团队协作
- 版本管理与追溯
- 文档内容
- 需求 FS
- 架构 AS
- 实现 DS
- 测试 TR
- 发放 Release
硬件设计
- 元器件
- 原理图
- pcb
- 工艺
- 测试