数字硬件建模SystemVerilog-使用结构体和联合体的例子
使用结构体和联合体的例子
结构体和联合体可以包括压缩或非压缩数组,压缩结构体或联合体只能包括压缩数组。

压缩和非压缩的数组可以将结构体和联合体作为元素包含在数组中。在压缩数组中,结构体或联合体也必须是压缩的。

数组可以包含自定义结构体和自定义联合体。综合支持数组中的压缩或非压缩结构体。
示例4-8说明了如何使用结构体数组,该示例是一个指令寄存器模型,其中包含32条指令的非压缩数组,每条指令是一个复合值,表示为压缩结构体。指令中的操作数可以是有符号的或无符号的,表示为两种类型的联合体。
该指令寄存器的输入包括单独的操作数、一个操作码和一个指示操作数是有符号的还是无符号的标志。该模型将这些单独的输入值加载到指令寄存器阵列中。一种写入指针输入控件,用于加载数据。该模型的输出是单个指令结构体,使用读指针输入从指令寄存器中选择。
本例使用了前面示例4-6中所示的相同包项。
示例4-6:包含结构体和联合体定义的包
// //Packagewithunionandstructuredefinitions // //`begin_keywords"1800-2012"//useSystemVerilog-2012keywords `define_4bit//use4-bitdatafortestingsynthesis //`define_32bit//use32-bitdatawordsize //`define_64bit//use64-bitdatawordsize packagedefinitions_pkg; `ifdef_4bit typedeflogic[3:0]uword_t; typedeflogicsigned[3:0]sword_t; `elsif_64bit typedeflogic[63:0]uword_t; typedeflogicsigned[63:0]sword_t; `else//defaultis32-bitvectors typedeflogic[31:0]uword_t; typedeflogicsigned[31:0]sword_t; `endif typedefenumlogic[2:0]{ADD,SUB,MULT,DIV}op_t; typedefenumlogic{UNSIGNED,SIGNED}operand_type_t; //Packedunionrepresentsavariablethatcanstore //differenttypes typedefunionpacked{ uword_tu_data; sword_ts_data; }data_t; //Packedstructurerepresentsacollectionofvariables //thatcanreferencedandpassedthroughportsasagroup typedefstructpacked{ op_topcode; operand_type_top_type; data_top_a; data_top_b; }instruction_t; endpackage:definitions_pkg //`end_keywords示例4-8:使用结构体数组对指令寄存器建模
//`begin_keywords"1800-2012"//useSystemVerilog-2012keywords moduleinstruction_register importdefinitions_pkg::*;//wildcardimportthepackage (inputlogicclk,rstN,load_en, inputdata_top_a, inputdata_top_b, inputoperand_type_top_type, inputop_topcode, inputlogic[4:0]write_pointer, inputlogic[4:0]read_pointer, outputinstruction_tiw ); timeunit1ns;timeprecision1ns; instruction_tiw_reg[0:31];//arrayofstructures //writetotheregisterarray always_ff@(posedgeclkornegedgerstN)//asyncreset if(!rstN)begin//active-lowreset foreach(iw_reg[i]) iw_reg[i]<= '{opcode:ADD,default:0}; // reset values end else if (load_en) begin case (op_type) SIGNED: iw_reg[write_pointer] <= '{opcode,op_type,op_a.s_data,op_b.s_data}; UNSIGNED: iw_reg[write_pointer] <= '{opcode,op_type,op_a.u_data,op_b.u_data}; endcase end // read from the register array assign iw = iw_reg[read_pointer]; endmodule: instruction_register //`end_keywords
图4-5显示了综合该示例的结果。说明了如何使用结构体和联合体、数组来建模大量设计功能,只需很少的代码。示意图右上角的矩形符号是综合编译器选择报告的通用RAM的实例(在RTL模型中数组的存储。)综合编译器将在综合的最后一步将该通用RAM作为一个或多个同步存储设备来实现,其中通用门级功能映射到特定的ASIC或FPGA设备。
图4-5:示例4-8的综合结果:带结构体的指令寄存器 
附录-TestBench
//`begin_keywords"1800-2012"
moduletest
importdefinitions_pkg::*;
(inputlogictest_clk,
outputlogicload_en,
outputlogicrstN,
outputdata_top_a,
outputdata_top_b,
outputop_topcode,
outputoperand_type_top_type,
outputlogic[4:0]write_pointer,
outputlogic[4:0]read_pointer,
inputinstruction_tiw
);
timeunit1ns;timeprecision1ns;
intseed=555;
initialbegin
$display("
Resetingtheinstructionregister...");
write_pointer=5'h00;//initializewritepointer
read_pointer=5'h1F;//initializereadpointer
load_en=1'b0;//initializeloadcontrolline
rstN<= 1'b0; // assert rstN (active low)
repeat (2) @(posedge test_clk) ; // hold in reset for 2 clk cycles
rstN = 1'b1; // deassert reset_n (active low)
$display("
Writing values to register stack...");
op_type = SIGNED;
op_a.s_data = 3;
op_b.s_data = -5;
opcode = ADD;
load_en = 1'b1; // enable writing to register
@(posedge test_clk) ;
for (int i=0; i<=2; i++) begin
write_pointer = i;
$display("Writing to register location %0d: ", write_pointer);
$display(" opcode = %0d (%s)", opcode, opcode.name);
$display(" op_type = %0d (%s)", op_type, op_type.name);
if (op_type == SIGNED) begin
$display(" op_a.s_data = %0d", op_a.s_data);
$display(" op_b.s_data = %0d
", op_b.s_data);
end else begin
$display(" op_a.s_data = %0d", op_a.u_data);
$display(" op_b.s_data = %0d
", op_b.u_data);
end
@(negedge test_clk) ;
op_a++;
op_b--;
opcode = op_t'(opcode + 1);
op_type = op_type.next;
end
load_en = 1'b0; // turn-off writing to register
// read back and display same three register locations
$display("
Reading back the same register locations written...");
for (int i=0; i<=2; i++) begin
@(posedge test_clk) read_pointer = i;
@(negedge test_clk) ;
$display("Read from register location %0d: ", read_pointer);
$display(" iw.opcode = %0d (%s)", iw.opcode, iw.opcode.name);
$display(" iw.op_type = %0d (%s)", iw.op_type, iw.op_type.name);
if (iw.op_type == SIGNED) begin
$display(" iw.op_a.s_data = %0d", iw.op_a.s_data);
$display(" iw.op_b.s_data = %0d
", iw.op_b.s_data);
end else begin
$display(" iw.op_a.s_data = %0d", iw.op_a.u_data);
$display(" iw.op_b.s_data = %0d
", iw.op_b.u_data);
end
end
@(posedge test_clk) $finish;
end
endmodule: test
module top;
timeunit 1ns; timeprecision 1ns;
import definitions_pkg::*;
logic clk;
logic test_clk;
logic rstN;
logic load_en;
logic reset_n;
op_t opcode;
operand_type_t op_type;
data_t op_a, op_b;
logic [4:0] write_pointer, read_pointer;
instruction_t iw;
test test (.*);
instruction_register dut (.*);
initial begin
clk <= 0;
forever #5 clk = ~clk;
end
initial begin
test_clk <=0;
// offset test_clk edges from clk to prevent races between
// the testbench and the design
#4 forever begin
#2ns test_clk = 1'b1;
#8ns test_clk = 1'b0;
end
end
endmodule: top
//`end_keywords

SystemVerilog-联合体(union)

SystemVerilog-结构体(二)

原文标题:SystemVerilog-使用结构体和联合体的例子
文章出处:【微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。
-
寄存器
+关注
关注
31文章
5590浏览量
129098 -
数据
+关注
关注
8文章
7315浏览量
93999 -
硬件
+关注
关注
11文章
3556浏览量
68751
原文标题:SystemVerilog-使用结构体和联合体的例子
文章出处:【微信号:Open_FPGA,微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
如何利用三维建模加速FCB-CR8530的定制化开发?案例与工具详解
VirtualLab Fusion应用:Herriott池的建模
SOLIDWORKS建模秘籍——必学的五个草图与建模技巧
索尼FCB-ER8530:三维建模与视觉感知的跨界融合
VirtualLab应用:傅科刀口测试的建模
基于VT系统的MCU硬件在环建模与仿真应用分析
概伦电子先进器件建模平台BSIMProPlus介绍

数字硬件建模SystemVerilog
评论