Verilog代码优化之case语句
题记:那天做完13路脉冲计数并写入dual RAM模块的设计后组长看了我的资源占用,吃惊的说怎么占用资源这么少啊,以为我偷工减料了。呵呵,其实这个也是一直困扰初学者的一个课题,可综合的verilog是一个,最优化的代码也是一个,所以就想说说这方面的问题,算是自己攒的一点经验分享吧,可能会有所欠缺或者说的不太对,还望EDN的各路高手指点。那就先从case语句和if…else语句开始吧。
代码一:
module test_3(clk,rst_n,data,add);
input clk;
input rst_n;
input[3:0] data;
output[2:0] add;
reg[2:0] add;
always @ (posedge clk) begin
if(!rst_n) begin
add <= 0;
end
else begin
case(data)
0,1,2,3: add <= 1;
4,5,6,7: add <= 2;
8,9,10,11: add <= 3;
12,13,14,15: add <= 4;
default: ;
endcase
end
end
endmodule
资源占用情况:
Design Statistics
# IOs : 9
Macro Statistics :
# RAM : 1
# 16x3-bit single-port block RAM: 1
Cell Usage :
# BELS : 3
# GND : 1
# INV : 1
# VCC : 1
# RAMS : 1
# RAMB16_S36 : 1
# Clock Buffers : 1
# BUFGP : 1
# IO Buffers : 8
# IBUF : 5
# OBUF : 3
Selected Device : 3s50pq208-5
Number of bonded IOBs: 9 out of 124 7%
Number of BRAMs: 1 out of 4 25%
Number of GCLKs: 1 out of 8 12%
代码二:
module test_3(clk,rst_n,data,add);
input clk;
input rst_n;
input[3:0] data;
output[2:0] add;
reg[2:0] add;
always @ (posedge clk) begin
if(!rst_n) begin
add <= 0;
end
else begin
casex(data)
4'b00xx: add <= 1;
4'b01xx: add <= 2;
4'b10xx: add <= 3;
4'b11xx: add <= 4;
default: ;
endcase
end
end
endmodule
资源占用情况:
Design Statistics
# IOs : 9
Macro Statistics :
# Registers : 1
# 3-bit register : 1
Cell Usage :
# BELS : 4
# INV : 2
# LUT2 : 2
# FlipFlops/Latches : 3
# FDR : 3
# Clock Buffers : 1
# BUFGP : 1
# IO Buffers : 6
# IBUF : 3
# OBUF : 3
Selected Device : 3s50pq208-5
Number of Slices: 2 out of 768 0%
Number of Slice Flip Flops: 3 out of 1536 0%
Number of 4 input LUTs: 2 out of 1536 0%
Number of bonded IOBs: 9 out of 124 7%
Number of GCLKs: 1 out of 8 12%
代码三:
module test_3(clk,rst_n,data,add);
input clk;
input rst_n;
input[3:0] data;
output[2:0] add;
reg[2:0] add;
always @ (posedge clk) begin
if(!rst_n) begin
add <= 0;
end
else begin
if(data<4) add <= 1;
else if(data<8) add <= 2;
else if(data<12) add <= 3;
else add <= 4;
end
end
endmodule
资源占用情况:
Design Statistics
# IOs : 9
Macro Statistics :
# Registers : 3
# 1-bit register : 3
# Multiplexers : 1
# 3-bit 4-to-1 multiplexer : 1
# Comparators : 3
# 4-bit comparator less : 3
Cell Usage :
# BELS : 6
# INV : 1
# LUT2 : 4
# LUT3 : 1
# FlipFlops/Latches : 3
# FDR : 2
# FDRS : 1
# Clock Buffers : 1
# BUFGP : 1
# IO Buffers : 6
# IBUF : 3
# OBUF : 3
Number of Slices: 3 out of 768 0%
Number of Slice Flip Flops: 3 out of 1536 0%
Number of 4 input LUTs: 5 out of 1536 0%
Number of bonded IOBs: 9 out of 124 7%
Number of GCLKs: 1 out of 8 12%
结语:硬件设计和软件编程不同,在C语言里if…else和for循环满天飞,可以说用这两个语句打天下都是不成问题的,但是HDL设计中这是万万不可的。我们先分析上面的结果,从以上的代码综合后的占用资源情况对比,case语句和casex语句是差不多的,一般在设计中如果可以使用casex语句那就优先考虑,其次case语句也是很常用的,至于if…else语句,明眼人一看就知道,比case(x)语句多出的寄存器比较器如果是一个更高级的if…else嵌套那么无非对硬件资源是一个巨大的浪费,至于for语句,这里没有进行对比,虽然在很多的综合工具里这个语句是可综合的,但是因为它在设计中往往不是可以和case或者if…else语句互相代替使用,所以放在后面再讨论。