FPGA——if...else语句和case语句综合后逻辑电路的区别

未经本人允许,禁止任何形式转载!!!!

        “条条大路通罗马”,FPGA也一样,实现同一功能的逻辑代码也可以不同的,当然消耗的FPGA芯片逻辑资源也是不同的。话不多上,上干货!

        举一个简单的例子,现在我们要用FPGA实现一个“四输入中,同一时刻只有一个高电平,且当某个高电平会点亮对应一颗LED灯”功能,我们现在用两种方法实现。

        方法一:用case语句实现,FPGA源码见附件一,逻辑综合后,电路如图1-1所示,由图可看出,该逻辑电路是一个多路选择器,即后级电路的输出只依赖于输入信号(o_led1,o_led2,0_led3,o_led4的优先级是一致的),逻辑电路简单明了,对电路时序也比较友好!!!

图1-1

        方法二:用if...else语句实现,FPGA源码见附件二,逻辑综合后,电路如图1-2所示,由图可看出,该逻辑电路是一个优先选择器电路,即后级电路的输出不仅依赖于输入信号,也依赖于前级电路(o_led1的优先级最高,以此类推,o_led4的优先级最低),消耗的逻辑资源相对于case语句多消耗了3个LUT资源(其中还有2个5输入的LUT资源),逻辑电路也相对复杂,对电路时序也不太友好!!!

图1-2

        因此,FPGA的逻辑代码的编写在保证功能正确的前提下,也应多从电路的角度来考虑逻辑代码如何编写可以更少的消耗FPGA逻辑资源,尤其是在做大型FPGA项目时(FPGA芯片资源往往很紧张,电路时序要求也比较严格),这点至关重要!!!

未经本人允许,禁止任何形式转载!!!!

附件一

module fpga_case(
  input  sys_clk,
  input  [3:0]  i_cs,
  input  i_rst,
  output  reg  o_led1,
  output  reg  o_led2,
  output  reg  o_led3,
  output  reg  o_led4
    );

always @(posedge  sys_clk)begin 
  if(i_rst)begin 
    o_led1 <= 'd0;
    o_led2 <= 'd0;
    o_led3 <= 'd0;
    o_led4 <= 'd0;
  end 
  else begin 
    case(i_cs)
      4'b0001:begin 
        o_led1 <= 'd1;
        o_led2 <= 'd0;
        o_led3 <= 'd0;
        o_led4 <= 'd0;
      end 
      4'b0010:begin 
        o_led1 <= 'd0;
        o_led2 <= 'd1;
        o_led3 <= 'd0;
        o_led4 <= 'd0;
      end
      4'b0100:begin 
        o_led1 <= 'd0;
        o_led2 <= 'd0;
        o_led3 <= 'd1;
        o_led4 <= 'd0;
      end  
      4'b1000:begin 
        o_led1 <= 'd0;
        o_led2 <= 'd0;
        o_led3 <= 'd0;
        o_led4 <= 'd1;
      end 
      default:begin 
        o_led1 <= 'd0;
        o_led2 <= 'd0;
        o_led3 <= 'd0;
        o_led4 <= 'd0;
      end 
    endcase 
  end 
end 
    
endmodule

附件二

module fpga_if_else(
  input  sys_clk,
  input  [3:0]  i_cs,
  input  i_rst,
  output  reg  o_led1,
  output  reg  o_led2,
  output  reg  o_led3,
  output  reg  o_led4
    );

always  @(posedge  sys_clk)begin 
  if(i_rst)begin 
    o_led1 <= 'd0;
    o_led2 <= 'd0;
    o_led3 <= 'd0;
    o_led4 <= 'd0;
  end 
  else if(i_cs == 4'b0001)begin 
    o_led1 <= 'd1;
    o_led2 <= 'd0;
    o_led3 <= 'd0;
    o_led4 <= 'd0;
  end
  else if(i_cs == 4'b0010)begin 
    o_led1 <= 'd0;
    o_led2 <= 'd1;
    o_led3 <= 'd0;
    o_led4 <= 'd0;
  end 
  else if(i_cs == 4'b0100)begin 
    o_led1 <= 'd0;
    o_led2 <= 'd0;
    o_led3 <= 'd1;
    o_led4 <= 'd0;
  end 
  else if(i_cs == 4'b1000)begin 
    o_led1 <= 'd0;
    o_led2 <= 'd0;
    o_led3 <= 'd0;
    o_led4 <= 'd1;
  end 
  else begin 
    o_led1 <= 'd0;
    o_led2 <= 'd0;
    o_led3 <= 'd0;
    o_led4 <= 'd0;
  end 
end 
  
endmodule
  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FPGA中,case语句常用于状态机的实现。在FPGA中,状态机是一种常见的电路实现方式,它可以根据输入信号的变化,自动地切换到不同的状态,并在每个状态中执行不同的操作。 case语句可以根据输入的控制信号,选择不同的操作。在FPGA中,控制信号常常是由时钟信号和触发信号组合而成的。时钟信号提供了时序控制,而触发信号则提供了事件触发的控制。 例如,在Verilog中,可以使用如下的代码实现一个简单的状态机: ``` module fsm ( input clk, input reset, input trigger, output reg [1:0] state ); // 定义状态常量 localparam ST_IDLE = 2'b00; localparam ST_COUNTING = 2'b01; localparam ST_DONE = 2'b10; always @(posedge clk) begin if (reset) begin state <= ST_IDLE; end else begin case (state) ST_IDLE: begin if (trigger) begin state <= ST_COUNTING; end end ST_COUNTING: begin if (count == 0) begin state <= ST_DONE; end end ST_DONE: begin // do nothing end endcase end end endmodule ``` 在上面的代码中,定义了三个状态常量,分别对应三个状态。在always块中,使用了case语句来根据当前状态和控制信号来选择不同的操作。在ST_IDLE状态中,当触发信号被触发时,状态切换为ST_COUNTING;在ST_COUNTING状态中,当计数器计数到0时,状态切换为ST_DONE;在ST_DONE状态中,不做任何操作。 使用case语句实现状态机是FPGA中常见的应用之一,它可以方便地实现复杂的逻辑控制,并且具有高度的可重用性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值