用户自定义和枚举数据类型
用户自定义数据类型在保证正确性和可综合性的前提下,允许在更高的抽象级上进行复杂的设计。
用户自定义数据类型
typedef int unsigned unit ;
unit a,b ;//自定义的32位无符号整数
typedef定义位置
- 模块内部:只有这个模块能访问,其他模块不受这个局部定义的影响。
- 编译单元域、包:共享typedef,其他模块导包即可访问。
package chip_types;
`ifdef TWO_STATE
typedef bit dtype_t ;
`else
typedef logic dtype_t ;
`endif
endpackage
module counter(
output chip_types::dtype_t[15:0] count ,
input chip_types::dtype_t clock,resetN
);
always @(posedge clock,negedge resetN)
if(~resetN) count <= 0;
else count <= count + 1;
endmodule
将typedef定义在包中实现共享访问,并可通过修改条件编译指令,即可实现二态逻辑和四态逻辑的快速转变便。
进一步改进可以在module声明上方,将包导入$unit。若包中包含多个typedef,可通过通配符导入。
import chip_types::dtype_t ;
module counter(
output dtype_t [15:0] count ,
input dtype_t clock,resetN
);
……
endmodule
推荐自定义数据类型,以_t作为后缀方便区分。
枚举数据类型
枚举数据类型提供了一种方式来声明一个具有特定允许值列表的抽象变量,每一个值都有一个标签。
enum {red,green,blue} RGB ;
verilog中没有枚举类型,一般使用parameter来为数值创建标签或者使用define来定义宏名代替数值。
使用enum构造状态机
package chip_types ;
typedef enum{FETCH,WRITE,ADD,SUB,MULT,DIV,SHIFT,NOP} instr_r;
endpackage
import chip_types::* ;
module controller(
output logic read,wirte,
input instr_t instruction ,
input iwre clock,resetN
);
enum {WAIT,LOAD,STORE} state,next_state;
always_ff@(posedge clock,negedge resetN)
if(!resetN) state <= WAIT ;
else state <= next_state ;
always_comb begin
case(state)
WAIT : next_state = LOAD ;
LOAD : next_state = STORE;
STORE: next_state = WAIT ;
endcase
end
always_comb begin
read = 0 ;
write = 0;
if(state==LOAD && instruction == FETCH)
read = 1;
else if(state == STORE && instruction == WRITE)
write = 1;
end
endmodule
注意事项
enum {RESET,S[5],W[6:9]}state //创建S0~S5,W6~W9,一共11个标签
同一个作用域中,标签名要唯一。
默认情况下,标签按顺序对应0123等。但也可以显示赋值,方便实现各种编码。
enum{ONE=1,FIVE=5,TEN=10} state
enum{A=1,B,C,X=24,Y,Z}//此时A=1,B=2,C=3,X=24,Y=25,Z=26
enum{A=1,B,C,D=3}//工具认为C和D都是3,会报错
默认情况下,枚举的基类是int,也可显式声明为其他数据类型
enum bit {TRUE,FALSE} bollean ;
enum logic[2:0]{WAIT=3'b001,LOAD=3'b010,READY=3'b100}state;
错误情况
enum{WAIT=3’b001,LOAD=3‘b010,READY=3'b100}state ;
enum logic {A=1'b0,B,C} list;//对1位位宽来说标签太多
若将基类声明为logic,同样可以给标签显式赋值为x或z。但若某个标签被显式赋值为x或z,他后面的标签也要显式赋值,无法通过x/z+1来自动获取值。
enum logic {A=1'bx,B=1’bz,C=1‘b0,D=1’b1} state ;//正确
枚举类型内嵌方法
module confidence_counter(
input logic synced,compare,resetN,clock,
output logic in_sync
);
enum{cnt[0:15]} state,next_state;
always_ff @(posedge clock ,negedge resetN)
if(!resetN) state <= cnt0;
else state <= next_state;
always_comb begin
next_state = state ;
case(state)
cnt0:if(compare && synced) next_state = state.next;
cnt1:begin
if(compare && synced) next_state = state.next;
if(compare && !synced)next_state = state.first;
end
cnt15: if(compare && synced) next_state = state.pre(2);
default: begin
if(compare && synced) next_state = state.next ;
if(compare && !synced) next_state= state.pre(2) ;
end
endcase
end
always_ff @(posedge clock,negedge resetN)
if(!resetN) in_sync <= 0;
else begin
if(state == cnt8) in_sync <= 1;
if(state == cnt0) in_sync <= 0;
end
endmodule