微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 关于FPGA中IF和CASE的区别

关于FPGA中IF和CASE的区别

时间:10-02 整理:3721RD 点击:

         经常在写程序的时候纠结同样的功能到底用if实现还是case实现,用if的时候是if,else if接连写还是if else嵌套写,书上有看到过但是自己没探索过,印象不深刻,经常还是会犯迷糊,这里写了简单的程序,对同一功能不同代码综合出来的电路做了对比,希望自己能对这块的东西有更深入的了解,也希望能够分享出来和大家进行探讨和交流,有不对的或者需要补充的地方欢迎大家批评指正。

         本次实例所实现的功能是在计数器等于四个特定值的时候将四个不同的输入值分别赋给输出。计数器为八位,从0到255循环计数。特点是计数器的值大于需要条件判断的数量,在计数器数值不满足判断条件的时候不执行操作。

         第一种情况,用if,else if来实现,Verilog代码如下:

module IF_CASE(

         inputclk,

         inputreset,

         input[15:0]data_in1,

         input[15:0]data_in2,

         input[15:0]data_in3,

         input[15:0]data_in4,

         outputreg [15:0]data

   );

         

         reg[7:0]counter;

         always@(posedge clk or negedge reset)

                   begin

                            if(!reset)

                                     begin

                                     counter<=0;

                                     end

                            else

                                     begin

                                               if(counter==8'hff)

                                                        begin

                                                        counter<=0;

                                                        end

                                               else

                                                        begin

                                                        counter<=counter+8'd1;

                                                        end

                                     end

                   end

         

         always@(posedge clk or negedge reset)

                   begin

                            if(!reset)

                                     begin

                                     data<=0;

                                     end

                            else

                                     begin

                                               if(counter==8'd1)

                                                        begin

                                                        data<=data_in1;

                                                        end

                                               elseif(counter==8'd10)

                                                        begin

                                                        data<=data_in2;

                                                        end

                                               elseif(counter==8'd20)

                                                        begin

                                                        data<=data_in3;

                                                        end

                                               elseif(counter==8'd30)

                                                        begin

                                                        data<=data_in4;

                                                        end

                                     end

                   end

endmodule

         第二种情况采用if,else的嵌套方式实现,由于计数器代码一样,整个外部接口代码也一样,这里只是列出输出值赋值的always块,其Verilog代码如下:

         always@(posedge clk or negedge reset)

                   begin

                            if(!reset)

                                     begin

                                     data<=0;

                                     end

                            else

                                     begin

                                               if(counter==8'd1)

                                                        begin

                                                        data<=data_in1;

                                                        end

                                               else

                                                        begin

                                                                 if(counter==8'd10)

                                                                           begin

                                                                           data<=data_in2;

                                                                           end

                                                                 else

                                                                           begin

                                                                                    if(counter==8'd20)

                                                                                             begin

                                                                                             data<=data_in3;

                                                                                             end

                                                                                    else

                                                                                             begin

                                                                                             if(counter==8'd30)

                                                                                                       begin

                                                                                                       data<=data_in4;

                                                                                                       end

                                                                                             else

                                                                                                       begin

                                                                                                       end

                                                                                             end

                                                                           end

                                                        end

                                     end

                                                        

                   end

         这两种情况所占用的逻辑资源和综合后的RTL级电路都是完全一样的,分别如图1和图2所示:

图1




                                                   图2



         电路图可能看不清,简单介绍一下,开始有两个选择器和8输入与门电路构成计数器,然后查找表判断四个条件,如果满足条件输出1,更具查找表的输出控制选择器和使能D触发器,来实现对应的值的输出。上面两种情况对比说明在类似这种功能的电路中,代码形式为if else if平铺式或者if else嵌套式对应的电路是一致的,个人推荐使用if else if平铺式,这样便于代码阅读,写代码也不容易出错,嵌套太多看花眼。

         第三种情况采用case语句实现,这里同样只列出输出幅值的代码,如下:

         always @(posedge clk or negedge reset)

                   begin

                            if(!reset)

                                     begin

                                     data<=0;

                                     end

                            else

                                     begin

                                               case(counter)

                                               8'd1:data<=data_in1;

                                               8'd10:data<=data_in2;

                                               8'd20:data<=data_in3;

                                               8'd30:data<=data_in4;

                                               default:begin

                                                        end

                                               endcase

                                     end

                   end

         对上述代码进行综合,最后使用资源列表和RTL级电路如图3和图4所示:


图3


图4

         由资源列表可以看出采用case语句多用了17个查找表,所以类似本实例的情况,使用case结构实现耗费资源更多,电路图最大的区别就是case结构在选择输出数据的时候采用门级电路完成,这块应该用去了更多的查找表资源,而if else结构综合出的电路使用选择器来选出输出数据。因此类似本实例的情况推荐大家用if else语句实现。


看的挺费劲,以后有机会再看,先留了

图二和图三的位置放反了,抱歉。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top