FPGA 中 system verilog 的使用

440 阅读4分钟

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
  • 工艺
  • 测试