• 如何在SV中使用结构体struct语法


    前言
    测试下可综合的struct,
    struct和interface的区别:两者都可以是信号的组合,但interface可以定义信号的不同方向,而struct中的所有信号都是同向的。
    struct可对像以太网帧格式进行建模(暂未用到)。

    流程
    (1)为了对struct进行建模,需要三个模块,顶层,信号输出模块,信号输入模块。
    (2)对于结构体的定义可放在模块外部的包里面,单独成一个文件。同时为了避免$unit的问题,使用类似C语法规则的条件编译。
    (3)条件编译文件中的内容:文件放在src同级目录即可。
    `ifndef DFFS_DONE
        `define DFFS_DONE
        package p_demo;
            typedef struct {
                logic l_clk_50M;
                logic l_clk_100M;
                logic l_rst_50M;
                logic l_rst_100M;
            } t_clk_rst;
        endpackage 
        import p_demo::*;
    `endif
    (4)顶层:注意需包含定义文件。同时定义结构体变量。实例化genafic和test模块。
    `include "definitions.sv"
    module demo_sv (
        input     i_clk       ,
        input     i_rst_n     ,
        input     i_a         ,
        output    o_b           
    );
    t_clk_rst t_gene_top;
    genafic  inst_genafic (
        .i_clk             (i_clk),
        .i_rst_n           (i_rst_n),        
        .t_gene            (t_gene_top)
    );

    test  inst_test (
        .i_a                  (i_a),
        .o_b                  (o_b),
        .t_gene_in            (t_gene_top)
    );

    endmodule:demo_sv
    (5)genafic文件内容:产生了两个时钟和复位。结构体的方向是输出。
    `include "definitions.sv"
    module genafic (
        input logic i_clk,
        input logic i_rst_n,
        output t_clk_rst t_gene          
    );
    logic l_locked;
    clk_wiz_0  inst_clk_wiz_0 (       
        .clk_out1          (t_gene.l_clk_50M),
        .clk_out2          (t_gene.l_clk_100M),
        .reset             (~i_rst_n),   
        .locked            (l_locked),  
        .clk_in1           (i_clk)  
    );

    logic l_rst_50M = 1'b1;
    logic [9:0] l_cnt_50M = '0;
    always_ff @(posedge t_gene.l_clk_50M)
    begin
        if (!i_rst_n)
            l_cnt_50M <= '0;
        else if (l_cnt_50M == 'd200)
            l_cnt_50M <= l_cnt_50M;
        else 
            l_cnt_50M <= l_cnt_50M + 'd1;
    end
    always_ff @(posedge t_gene.l_clk_50M)
    begin
        if (!l_locked)
            l_rst_50M <= 1'b1;
        else if (l_cnt_50M == 'd200)
            l_rst_50M <= 1'b0;
    end
    logic l_rst_100M = 1'b1;
    logic [9:0] l_cnt_100M = '0;
    always_ff @(posedge t_gene.l_clk_100M)
    begin
        if (!i_rst_n)
            l_cnt_100M <= '0;
        else if (l_cnt_100M == 'd200)
            l_cnt_100M <= l_cnt_100M;
        else 
            l_cnt_100M <= l_cnt_100M + 'd1;
    end
    always_ff @(posedge t_gene.l_clk_100M)
    begin
        if (!l_locked)
            l_rst_100M <= 1'b1;
        else if (l_cnt_100M == 'd200)
            l_rst_100M <= 1'b0;
    end
    assign t_gene.l_rst_50M = l_rst_50M;
    assign t_gene.l_rst_100M = l_rst_100M;

    endmodule:genafic
    (6)test文件内容:使用了50M的时钟,结构体为输入。
    `include "definitions.sv"
    module test (
        input logic i_a,
        output logic o_b,
        input t_clk_rst t_gene_in
    );
    logic [9:0] l_cnt_b = '0;
    always_ff @(posedge t_gene_in.l_clk_50M)
    begin
        if (!t_gene_in.l_rst_50M)
            l_cnt_b <= '0;
        else if (i_a)
            l_cnt_b <= l_cnt_b + 'd1;
    end
    assign o_b = l_cnt_b[9];

    endmodule:test

    (7)使用vivado2018.3综合看看结果:
    采用结构体对信号进行分组,可实现偷懒以及更佳维护性效果。

    以上。

  • 相关阅读:
    开发中的一些总结。。。
    Directory Listing Denied错误
    webservice的一些使用心得。。
    vs2005 sp1 补丁后,不能初始化
    谈C/C++指针精髓
    CString 的函数
    javaScript 中 call 函数的用法说明 & 继承
    条款12: 尽量使用初始化而不要在构造函数里赋值(effectiveC++)
    js日期时间函数(经典+完善+实用)
    学习之路一 记录学习中的手记
  • 原文地址:https://www.cnblogs.com/kingstacker/p/13492414.html
Copyright © 2020-2023  润新知