• 如何在SV代码中使用interface语法


    前言
    测试下可综合的interface接口,为了方便未来接口定义的懒惰操作以及减少出错的概率。
    综合工具:Vivado2018.3
    流程
    首先看接口是什么?
    顾名思义,用于模块间信号交互的路。是一系列信号组。
    想象一辆公交车(bus),分立的信号就是乘客,将乘客封装进bus,就是接口。
    对于最简单的使用interface的demo需要三个模块:top,输入,输出。用接口简化输入输出的信号组。
    (1)定义interface:interface可以有外界输入信号。通过modport定义不同的接口方向。
    interface f_bus1(input logic i_clk,i_rst_n);
        logic l_ready;
        logic l_valid;
        logic [7:0] l_cnt;
        modport master(input i_clk,i_rst_n,
                       output l_ready,l_valid,l_cnt);
        modport slave (input i_clk,i_rst_n,
                       input  l_ready,l_valid,l_cnt);
    endinterface //f_bus1
    (2)top层:
    使用了extern语法,对top层的信号组进行了外界定义,模块定义的时候信号组无需重复申明。
    定义interface及用modport指定不同方向,子模块的方向根据modport指定。
    interface的实例,如果没有外界信号送入,则为空,这里有时钟和复位送入。
    genafic产生interface的输出信号送入到test模块中。
    注意:bus的连接通过interface的实例加modport的名称指定。
    extern module demo_sv (
        input     i_clk       ,
        input     i_rst_n     ,
        input     i_a         ,
        output    o_b                    
    );

    ///子层模块定义
    interface f_bus1(input logic i_clk,i_rst_n);
        logic l_ready;
        logic l_valid;
        logic [7:0] l_cnt;
        modport master(input i_clk,i_rst_n,
                       output l_ready,l_valid,l_cnt);
        modport slave (input i_clk,i_rst_n,
                       input  l_ready,l_valid,l_cnt);
    endinterface //f_bus1

    module demo_sv (.*);
    f_bus1 inst_f_bus1 (
        .i_clk      (i_clk),
        .i_rst_n    (i_rst_n)
    );
    genafic  inst_genafic (
        .f_bus1            (inst_f_bus1.master),   
        .i_a               (i_a)
    );
    test  inst_test (
        .f_bus1            (inst_f_bus1.slave),   
        .o_b               (o_b)
    );

    endmodule

    (3)genafic模块:
    通过interface定义接口,后面跟上名字(任意)。
    模块内部要使用接口中的信号:通过接口名字加interface内部信号的方式进行使用。
    module genafic (
         interface f_bus1,
         input     i_a           
    );
    logic [7:0] l_cnt = '0;
    always_ff @(posedge f_bus1.i_clk)
    begin
        if (f_bus1.i_rst_n)
            l_cnt <= '0;
        else if (i_a)
            l_cnt <= l_cnt + 'd1;
    end
    assign f_bus1.l_ready = l_cnt[0];
    assign f_bus1.l_valid = l_cnt[1];
    assign f_bus1.l_cnt   = l_cnt;

    endmodule:genafic
    (4)test模块:
    同样定义interface,使用一样。
    module test (
        interface f_bus1,
        output o_b

    );
    logic l_b = '0;
    always_ff @(posedge f_bus1.i_clk)
    begin
        if (f_bus1.i_rst_n)
            l_b <= '0;
        else if (f_bus1.l_ready && f_bus1.l_valid)
        begin
            if (f_bus1.l_cnt == 'd10)
                l_b <= 1'b1;
            else 
                l_b <= 1'b0;
        end    
    end

    assign o_b = l_b;

    endmodule:test
    (5)导入vivado2018.3生成原理图看看。

    好处就是:如果interface内部信号发生更改,无需修改模块间例化的部分,降低工作量。
     
    以上。
  • 相关阅读:
    欧拉代码005
    欧拉计划003
    欧拉计划004
    欧拉计划006
    欧拉计划002
    LINUXS3C2440SJA1000驱动程序笔记
    WPF实现窗体内容分割
    InotifyPropertyChanged接口实现简单数据绑定
    C#的6种常用集合类大比拼
    WPF获取窗体或控件句柄
  • 原文地址:https://www.cnblogs.com/kingstacker/p/13490142.html
Copyright © 2020-2023  润新知