使用SystemVerilog简化FPGA中的接口

news/2024/5/19 0:49:25 标签: fpga, css, os, jdbc, verilog

  FPGA工程师们应该都会吐槽Verilog的语法,相当的不友好,尤其是对于有很多接口的模块,像AXI4/AXI-Lite这种常用的总线接口,动不动就好几十根线,写起来是相当费劲。

  当然现在Xilinx推荐使用纯bd文件的方式来设计FPGA,这样HDL代码就会少了很多。但我们大多数的工程还是无法避免使用HDL来连接两个module。所以本文就推荐使用SystemVerilog来简化FPGA中接口的连接方式。

  也许很多FPGA工程师对SystemVerilog并不是很了解,因为以前的FPGA开发工具是不支持SystemVerilog的,导致大家都是用VHDL或者Verilog来开发,但现在Vivado对SystemVerilog的支持已经比较好了,完全可以使用SystemVerilog写出可综合的FPGA程序,而且FPGA开发中只会使用的SystemVerilog语法的一小部分,入门也很快,因此建议FPGA工程师学一下SystemVerilog。

本文中用到的logic关键字的解释可以参考SystemVerilog教程之数据类型1

  此次例程也比较简单,有两个模块module1module2module1中输出ab,在module2中完成加法后再返还给module1,最终输出的led=c | a

oss-process=image/format,png" title="image-20200720203534072" />
image-20200720203534072

  首先用Verilog来实现,代码也比较简单,就简单解释一句:文件格式都是.sv,这是因为SystemVerilog的语法都是包含Verilog的。

//top.sv
module top(
 input        clk,
 input        rst,
 output [3:0] led
 );

logic    [3:0] a ;
logic    [3:0] b ;
logic    [3:0] c ;

module1 inst_module1(
    .clk  (clk  ),
    .rst  (rst  ),
    .a    (a),
    .b    (b),
    .c    (c),
    .led  (led)
    );   

module2 inst_module2(
    .clk  (clk  ),
    .rst  (rst  ),
    .a    (a),
    .b    (b),
    .c    (c)
    );  

endmodule

// module1.sv
module module1(
 input clk,
 input rst,
 output logic [3:0] a,
 output logic [3:0] b,
 input  logic [3:0] c,
 output logic [3:0] led
    );

 assign led = c | a;

 always @ ( posedge clk ) begin
    if(rst) begin
        a <= 4'd1;
        b <= 4'd2;
    end
    else begin
        a <= a + 1'b1;
        b <= b + 1'b1;
    end
 end 

endmodule

// module2.sv

module module2(
 input clk,
 input rst,
 input  logic [3:0] a,
 input  logic [3:0] b,
 output logic [3:0] c
    );

 always @ ( posedge clk ) begin
    if(rst) 
        c <= 4'd1;
    else 
        c <= a + b;
 end 

endmodule

综合之后的Schematic如下图所示:(为了更好的表示电路结构,我将flatten_hierarchy选为了none

oss-process=image/format,png" title="image-20200720192328527" />
image-20200720192328527

  下面我们把程序稍作改动,将a/b/c三个接口使用SystemVerilog中的interface来连接。

  在工程中添加my_itf.sv文件如下:

// my_itf.sv
interface my_itf;
   logic [3:0] a, b, c;

   modport mod1 (input c,    output a, b);
   modport mod2 (input a, b, output c  );

endinterface : my_itf

关键字interface就表示要创建一个接口模块,里面包含了3个接口:a/b/c。

modport定义了这三个接口的方向,对于module1来说,a和b是输出,c是输入;对于module2来说,a和b是输入,c是输出。

注:也可以不使用modport,Vivado会根据代码自动推断出接口的方向,但不建议这么做

修改module1.sv如下,其中a/b/c端口换成了my_itf.mod1 itf_abcmy_itf.mod1就表示my_itf接口的方向按照mod1中指定的,而且代码中的a、b、c要相应的换成itf_abc.aitf_abc.bitf_abc.c.

// module1.sv
module module1(
 input clk,
 input rst,
 my_itf.mod1 itf_abc,
 output logic [3:0] led
    );

 assign led = itf_abc.c | itf_abc.a;

 always @ ( posedge clk ) begin
    if(rst) begin
        itf_abc.a <= 4'd1;
        itf_abc.b <= 4'd2;
    end
    else begin
        itf_abc.a <= itf_abc.a + 1'b1;
        itf_abc.b <= itf_abc.b + 1'b1;
    end
 end 

endmodule

修改module2.sv代码如下,原则跟上面是一样的,不再赘述。

// module2.sv
module module2(
 input clk,
 input rst,
 my_itf.mod2 itf_abc
    );


 always @ ( posedge clk ) begin
    if(rst) 
        itf_abc.c <= 4'd1;
    else 
        itf_abc.c <= itf_abc.a + itf_abc.b;
 end 

endmodule

修改top.sv如下,例化my_itf接口,将itf_abc.mod1传给module1,将itf_abc.mod2传给module2.

// top.sv
module top(
 input        clk,
 input        rst,
 output [3:0] led
    );

    logic    [3:0] a ;
    logic    [3:0] b ;
    logic    [3:0] c ;

    my_itf itf_abc();

    module1 inst_module1(
        .clk       (clk  ),
        .rst       (rst  ),
        .itf_abc   (itf_abc.mod1),
        .led       (led)
    );   

    module2 inst_module2(
        .clk       (clk  ),
        .rst       (rst  ),
        .itf_abc   (itf_abc.mod2)
    );  

endmodule

大功告成!!!

综合后Schematic如下,跟上面的图只是名字不同,电路是一样的。

oss-process=image/format,png" title="image-20200720201342972" />
image-20200720201342972

oss-process=image/format,png" />

FPGA时序约束教程

  1. FPGA时序约束理论篇之建立保持时间

  2. FPGA时序约束理论篇之时序路径与时序模型

   3. FPGA时序约束理论篇之IO约束

   4. FPGA时序约束理论篇之时钟周期约束

   5. FPGA时序约束理论篇之两种时序例外

   6. FPGA时序约束理论篇之xdc约束优先级

   7. FPGA时序约束实战篇之梳理时钟树

   8. FPGA时序约束实战篇之主时钟约束

   9. FPGA时序约束实战篇之衍生时钟约束

  10. FPGA时序约束实战篇之延迟约束

  11. FPGA时序约束实战篇之伪路径约束

  12. FPGA时序约束实战篇之多周期路径约束

  13. Vivado时序约束辅助工具

  14. FPGA时序约束之Tcl命令的对象及属性

微信公众号:Quant_Times

oss-process=image/format,png" />


http://www.niftyadmin.cn/n/791490.html

相关文章

mac下设置maven环境

在mac系统下设置maven环境。 1.首先通过终端打开 .bash_profile 2.设置maven解压后的路径地址 环境变量设置如下&#xff1a; MAVEN_HOME 、PATH 两个变量即可 3.保存后退出 终端 然后打开 maven/conf/settings.xml 文件 更改 <localRepository>节点 此节点为本地ma…

LeakCanary的使用及Application类的使用

Application类 Application和Activity,Service一样是Android框架的一个系统组件&#xff0c;当Android程序启动时系统会创建一个Application对象&#xff0c;用来存储系统的一些信息。 Android系统自动会为每个程序运行时创建一个Application类的对象且只创建一个&#xff0c;所…

SystemVerilog教程之数据类型1

内建数据类型逻辑类型我们知道&#xff0c;Verilog中&#xff0c;有两种基本的数据类型&#xff1a;reg和wire&#xff0c;reg在always、initial、task和funciton中被赋值&#xff0c;wire使用assign赋值。在systemVerilog中&#xff0c;引入了新的逻辑(logic)类型来代替reg类型…

线程同步的使用(synchronized)

线程同步结论&#xff1a;当多个线程共同修改同一个资源时使用线程同步&#xff0c;一个资源使用一个同步锁&#xff0c;尽量缩小同步块内的代码。 线程同步&#xff1a;线程同步的真实意思&#xff0c;其实是“排队”&#xff1a;几个线程之间要排队&#xff0c;一个一个对共享…

MAC下编译VTM

MAC下编译VTM 下载地址 官方的下载地址 使用git clone命令或者直接下载都可以。 编译 1.打开终端并cd到所下载的VTM的路径下 2.创建新的文件夹build mkdir build3.cd到新创建的build文件路径下&#xff0c;执行如下命令&#xff1a; cmake .. -G "Xcode"4.生成…

1346. Intervals of Monotonicity(dp)

&#xff11;&#xff13;&#xff14;&#xff16; 简单&#xff44;&#xff50; 1 #include <iostream>2 #include<cstdio>3 #include<cstring>4 #include<algorithm>5 #include<stdlib.h>6 #include<vector>7 using namespace std;8 #…

【帮推】研究生创“芯”大赛寻队友

帮忙替同学寻找一个研究生创“芯”大赛&#xff08;第三届中国研究生创“芯”大赛&#xff09;的队友。1&#xff0c;需求如下&#xff1a;题目&#xff1a;基于fpga的jpeg解码。需求&#xff1a;需要一个了解图像解码算法&#xff0c;掌握c/c的西电研究生同学或已获得研究生入…

IOS端xcode编译bug修复

IOS端写demo打bug记 BUG甲 This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app use…