如何在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
`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
`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
`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综合看看结果:
采用结构体对信号进行分组,可实现偷懒以及更佳维护性效果。
以上。