HMECMicroElectronicsCenter第5章数组、结构体和联合体结构体联合体结构体和联合的操作非压缩数组压缩数组数组操作数组foreach循环用于数组的特殊系统函数HMECMicroElectronicsCenter5.1结构体结构体提供了对相关信息进行分组的方法,结构体使用关键字struct声明,结构体内的成员可以是任何数据类型,包括用户自定义类型和其它的结构体类型;结构体是变量和常量的集合,整个集合可以用结构体名进行引用,也可以用结构体成员名来引用该成员。struct{inta,b;opcode_topcode;logic[31:0]address;biterror;}instruction_word;结构体内的成员引用:Instruction_word.address=32’hf000001e;结构体与数组有什么不同?HMECMicroElectronicsCenter5.1.1结构体声明变量或线网都可以定义为结构体,当结构体定义为线网时,结构体中所有成员必须都是四态类型的。varstruct{logic[31:0]a,b;logic[7:0]opcode;logic[23:0]address;}instruction_word_var;wirestruct{logic[31:0]a,b;logic[7:0]opcode;logic[23:0]address;}instruction_word_net;struct{logic[31:0]a,b;logic[7:0]opcode;logic[23:0]address;}instruction_word_var;Instruction_word_var是变量or线网类型?虽然结构体可以声明为线网类型,但结构体内成员不能使用线网类型!!HMECMicroElectronicsCenter5.1.1结构体声明自定义和匿名结构体:typedefstruct{logic[31:0]a,b;logic[7:0]opcode;logic[23:0]address;}instruction_word_t;instruction_word_tIW;struct{logic[31:0]a,b;logic[7:0]opcode;logic[23:0]address;}instruction;自定义结构体可以在模块或接口内定义,在整个模块或接口中都可以使用,如果一个自定义结构体需要在多个模块中使用,或者是作为模块或接口的端口使用,那么结构体定义应放在package中!HMECMicroElectronicsCenter5.1.2结构体赋值结构体初始化:用值列表方式初始化,值列表是使用’{}中的一组数值,大括号中的数值个数必须与成员个数一致。typedefstruct{logic[31:0]a,b;logic[7:0]opcode;logic[23:0]address;}instruction_word_t;instruction_word_tIW=‘{100,3,8’hff,0};//大括号间的数值必须与成员个数一致HMECMicroElectronicsCenter5.1.2结构体赋值结构体成员赋值:typedefstruct{logic[31:0]a,b;logic[7:0]opcode;logic[23:0]address;}instr_t;inst_tIW;always@(posedgeclk,negedgeresetN)if(!resetN)beginIW.a=100;IW.b=100;IW.opcode=8’hff;//成员引用IW.address=0;endelsebegin…endHMECMicroElectronicsCenter5.1.2结构体赋值结构体成员赋值:always@(posedgeclk,negedgeresetN)if(!resetN)IW=‘{100,3,8’hff,0};//结构体表达式赋值elsebegin…end//IW=‘{address:0,opcode:8’hff,a:100,b:5};//IW=‘{address:0,opcode:8’hff,100,5};//错误,混用成员名称//和成员顺序IW=‘{real:1.0,default:0};IW=‘{real:1.0,default:0,r1:3.14};struct{realr0,r1;inti0,i1;logic[7:0]opcode;logic[23:0]address;}IW;HMECMicroElectronicsCenter5.1.3压缩和非压缩结构体默认情况下,结构体是非压缩的,也就是说,虽然结构体成员使用一个共同的名字,但它们被当作是独立的变量,压缩结构体用packed关键字显式说明,其特点是所有成员被当作一个向量存储,第一个成员在向量的最左边,最后一个成员在最低位,其编号为0structpacked{logicvalid;logic[7:0]tag;logic[31:0]data;}data_word;validtagdata403931150压缩综合体中的成员只能是包含整数类型值:即可以表示为byte,int这样的向量以及用bit或logic创建的向量!!HMECMicroElectronicsCenter5.1.3压缩和非压缩结构体压缩结构体的操作:非压缩结构体的操作对压缩结构体一样适用,但压缩结构体还有与向量类似的操作,如算术操作、逻辑操作等typedefstructpacked{logicvalid;logic[7:0]tag;logic[31:0]data;}data_word_t;data_word_tpacket_in,packet_out;always@(posedgeclk)packet_out=packet_in2;HMECMicroElectronicsCenter5.1.3压缩和非压缩结构体有符号的压缩结构体:压缩结构体作为向量使用可以是有符号或无符号的,用关键字signed或unsigned来声明,但结构体中成员是有符号还是无符号的,只依赖于成员的类型声明,与结构体声明没有联系。压缩结构体的部分选择始终是无符号的。typedefstructpackedsigned{logicvalid;logic[7:0]tag;logic[31:0]data;}data_word_t;data_word_ta,b;always@(posedgeclk)if(ab)//有符号比较…HMECMicroElectronicsCenter5.1.4通过端口传递结构体结构体可以通过模块和接口的端口传递packagedefinitions;typedefenum{ADD,SUB,MULT,DIV}opcode_t;typedefstruct{logic[31:0]a,b;opcode_topcode;logic[23:0]address;logicerror;}instruction_word_t;endpackageimportdefinitions::*;modulealu(inputinstruction_word_tIW,inputwireclk);…endmodule在两个不同模块中声明的匿名结构体,即使它们具有相同的名称、同样的成员及名称,也不是相同的结构体!HMECMicroElectronicsCenter5.1.5将结构体作为任务和函数的自变量结构体可以作为自变量传递给任务和函数moduleprocessor(…);…typedefenum{ADD,SUB,MULT,DIV}opcode_ttypedefstruct{logic[31:0]a,b;opcode_topcode;logic[23:0]address;logicerror;}instruction_word_t;functionalu(inputinstruction_word_tIW);…endfunctionendmodule非压缩和压缩结构体都是可综合的,综合工具支持结构体通过模块端口、任务和函数传递,支持使用成员名和值的列表对结构体赋值!HMECMicroElectronicsCenter5.2联合体联合体只存储一个元素,但这个元素有多种表示方法,每种表示可以是不同的数据类型。联合体与结构体的声明类似,其成员引用也一样union{bytei;byteunsignedu;}data;data.i=-5;$display(“datais%d”,data.i);data.u=-5;$display(“nowdatais%d”,data.u);typedefunion{inti;intunsignedu;}data_t;data_ta,b;用户自定义和匿名联合体:区别在于是不是用typedef声明HMECMicroElectronicsCenter5.2.1非压缩联合体非压缩联合体可以包含任意变量类型,如real类型,非压缩结构体和非压缩数组等;非压缩联合体不可综合,可用于对高层次系统和交易级建模;如果从非压缩联合体中读取的成员不同于上次写入的成员,可能导致不确定的结果!struct{bitis_real;union{inti;realr;}value;}data;//…always@(posedgewrite)begincase(operation_type)INT_OP:begindata.value.i=5;data.value.r=0;endFP_OP:begindata.value.r=3.1415;data.is_real=1;endendcaseendalways@(posedgereal)beginif(data.is_real)real_opd=data.value.r;elseint_opd=data.value.i;endHMECMicroElectronicsCenter5.2.2标签联合体标签联合体包含一个存储“标签”的隐含成员,代表存储数值的最后一个联合体成员的名称,使用标签表达式可以将一个值写入标签联合体中,标签表达式具有关键字tagged,后面是成员名,再后面是要存储的值;标签联合体检测联合体使用是否一致;使用标签表达式将值赋给标签联合体后,可以使用成员名将值写取联合体成员中,如果指定的成员名与当前标签不匹配,将会产生错误。uniontagged{inti;realr;}data;data=taggedi5;//在data.i中存5,并设备隐含标签d_out=data.i;//从联合体中读值d_out=data.r;//错误:成员与联合的隐含标签不匹配data.i=7;//写到联合体成员中data.r=3.14;//??HMECMicroElectronicsCenter5.2.3压缩联合体压缩联合体声明方式与压缩结构体声明方式相同,在压缩联合体中,每个联合体成员的位数都必须是相同的,以保证压缩联合体使用同样的位数存储数据;压缩联合体只能存储两态或四态类型的数据,因此,压缩联合体不能包含real或shortreal变量,或非压缩结构体、非压缩联合体、非压缩数组;压缩联合体允许数据以一种格式写入,而以另一种格式读取。typedefstructpacked{logic[15:0]src_addr;logic[15:0]dest_addr;logic[23:0]data;logic[7:0]opcode;}data_packed_t;unionpacked{data_packet_tpacket;logic[7:0][7:0]bytes;//压缩数组}dreg;HMECMicroElectronicsCenter5.2.3压缩联合体always@(posedgeclk,negedgeresetn)if(!resetn)begindreg.packet=‘0;k=0;endelseif(load_data)begind