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;

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

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;

else begin

casex(data)

4'b00xx:  add <= 1;

4'b01xx:  add <= 2;

4'b10xx:  add <= 3;

4'b11xx:  add <= 4;

default: ;

endcase

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;

else begin

if(data<4) add <= 1;

else if(data<8) add <= 2;

else if(data<12) add <= 3;

else add <= 4;

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语句互相代替使用,所以放在后面再讨论。

Verilog代码优化之case语句       题记:那天做完13路脉冲计数并写入dual RAM模块的设计后组长看了我的资源占用,吃惊的说怎么占用资源这么少啊,以为我偷工减料了。呵呵,其实这个也是一直困扰初学者的一个课题,可综合的verilog是一个,最优化的代码也是一个,所以就想说说这方面的问题,算是自己攒的一点经验分享吧,可能会有所欠缺或者说的不太对,还望EDN的各路高手指点。那就先从
背景描述:将一个独热码转换成二进制。 分析:由于当前使用的zynq是6输入的lut,设计一个较简单的12bit独热码转换为4bit的二进制。根据如下代码可以知道每一个bit都可以用一个lut解决问题。 第一版的代码: assign binary_data = binary; always @(posedge clk) begin case (...
这几天在做一个无人机定位的项目,时间比较紧,自己也不太懂,所以就边忙别愁就没有了精力写博客了。可是想想这样也不好,还是抽出点时间写博客,即使写的比较简单也行,至少能解答自己的疑惑就够了。 Verilog HDL中的 case 语句 有两种变种, case x和 case z,既然存在这两种形式,肯定是合理的,为了应对特殊的情况。我们只需要掌握其具体用法,需用用到的地方就用上,倒也不必考虑太多。(我见有些人还分...
1、资源共享 资源共享主要是指在互斥(Mutually-Exclusive) 条件下(即不能同时运行)共享算术逻辑单元(Arithmetic Logic Unit)。 module test(a, b, c, sel, result); //相同运算符没有资源共享 input [7:0) a, b, c; input sel; output [8:0] result; reg [8:0] result; always @ (a or b or sel)begin if (sel) result = a
转自:https://blog.csdn.net/CLL_caicai/article/details/104395480 实际问题中常常需要用到多分支选择,使用if 语句 导致内容繁琐;更明智的做法是使用 case 语句 case 语句 是一种多分支选择 语句 ,可以方便的处理多分支选择。本文通过实际例子,讲解 case 语句 的使用,以及 case 语句 的变体 case z和 case x的使用: 一、 case 的用法 二、 case z与 case x的用法 三、参考文献 end case 其中,expression是一个表达式,可以是任何 Verilog 数据类型,value1、value2等是 case 分支的值,statement1、statement2等是与分支对应的 语句 。default是可选的,表示当expression的值不匹配任何分支时执行的 语句 。 下面是一个例子,演示了如何使用 case 语句 实现一个4位二进制加法器: module adder(input [3:0] a, b, output [3:0] sum); reg [3:0] carry; always @ (a, b) begin case ({carry, a} + {carry, b}) 2'b00: begin sum = {carry[3:1], a[0]}; carry = {1'b0, carry[2:0]}; 2'b01: begin sum = {carry[3:1], ~a[0]}; carry = {1'b1, carry[2:0]}; 2'b10: begin sum = {carry[3:1], ~b[0]}; carry = {1'b1, carry[2:0]}; 2'b11: begin sum = {carry[3:1], a[0]}; carry = {1'b1, carry[2:0]}; default: begin sum = 4'bxxxx; carry = 4'bxxxx; end case endmodule 在这个例子中,我们使用了 case 语句 来根据输入的a和b的值计算出输出的sum和进位carry的值。注意,我们使用了{carry, a}和{carry, b}来将进位和输入值组合成一个4位二进制数,以便于进行加法运算。同时,我们使用了~运算符来实现减法运算。如果输入的值不符合预期,我们将输出sum和carry设为xxxx,表示无效的值。