原创 2.深入理解fpga应用设计之验证if_else的不同使用方式

2016-4-30 10:31 3943 27 27 分类: FPGA/CPLD 文集: 深入理解fpga应用设计Verilog

验证: if_else不同使用方式,出来避免不受欢迎的意外产生的锁存器,同时还可以有效的利用逻辑资源,

修改:关于case,default......

        例程实现方式一:

module if_thn(current_state, x, y, z, state_out);
   input [8:0]     current_state;
   input           x;
   input           y;
   input           z;
   output [2:0]    state_out;

   parameter [8:0] s0 = 9'b000000000;
   parameter [8:0] s1 = 9'b100000001;
   parameter [8:0] s2 = 9'b100000010;
   parameter [8:0] s3 = 9'b100000100;
   parameter [8:0] s4 = 9'b100001000;
   parameter [8:0] s5 = 9'b100010000;
   parameter [8:0] s6 = 9'b100100000;
   parameter [8:0] s7 = 9'b101000000;
   parameter [8:0] s8 = 9'b110000000;
   
   reg             output1;
   reg             output2;
   reg             output3;
   
   always @(current_state or x or y or z)
      if ((current_state == s1) | (current_state == s3) | (current_state == s4))
         output1 <= x;
      else if ((current_state == s0) | (current_state == s2) | (current_state == s5))
         output2 <= y;
      else if ((current_state == s6) | (current_state == s7) | (current_state == s8))
         output3 <= z;
      else begin
         output1 <= 1'b0;
         output2 <= 1'b0;
         output3 <= 1'b0;
      end
   
   assign state_out = {output1, output2, output3};
   
endmodule

RTL:查看综合结果

2016-04-20_092342.jpg

分析:我们可以看到,X,Y,Z三个输入最终会个经过一次锁存器输出,他们会是设计的时序分析复杂化

 

Technology Map Viewer:显示工程实际的逻辑实现

1000001733-6359674164286494025105780.jpg-g560

同样后一级的3个LCELL的输出出来驱动设计的3个输出以外,同时还反馈到LCELL的输入端

 

片上资源使用: Total logic elements 

1000001733-6359674164277294024133964.jpg-g560

 

优化方式二:

always @(current_state or x or y or z)
   begin
      if ((current_state == s1) | (current_state == s3) | (current_state == s4))
         output1 <= x;
      else
         output1 <= 1'b0;
      if ((current_state == s0) | (current_state == s2) | (current_state == s5))
         output2 <= y;
      else
         output2 <= 1'b0;
      if ((current_state == s6) | (current_state == s7) | (current_state == s8))
         output3 <= z;
      else
         output3 <= 1'b0;
   end

 

RTL:查看综合结果

1000001733-6359674169262394024865797.jpg-g560

分析:不存在方式一中的锁存器出现

Technology Map Viewer:显示工程实际的逻辑实现

1000001733-6359674169277594026121693.jpg-g560

3个LCELL的输出出来驱动设计的3个输出以外,不存在输入反馈

片上资源使用

1000001733-6359674169270694022608368.jpg-g560

片上资源使用大大减少

 

方式三结果 同方式二)

always @(current_state or x or y or z)
   begin
      output1 <= 1'b0;
      output2 <= 1'b0;
      output3 <= 1'b0;
      
      if ((current_state == s1) | (current_state == s3) | (current_state == s4))
         output1 <= x;
      if ((current_state == s0) | (current_state == s2) | (current_state == s5))
         output2 <= y;
      if ((current_state == s6) | (current_state == s7) | (current_state == s8))
         output3 <= z;
   end

 

 

综合结果分析:if_else不同使用方式,除了避免不受欢迎的意外产生的锁存器,同时还可以有效的利用逻辑资源

----------------------以下为修改的内容-------------------------------

关于产生锁存器:

1.在case语句中,如果没有列出所有的状态"default"不要省略

2.条件语句中,"if....else if..."else"" 中最后一个else不要省略

----------------------以下为修改内容---------------------------

增加一个使用case default的例程


always@(posedge Clk or negedge Rst_n)
		if(!Rst_n)begin
			wave <= 3'd0;
			fword <= 32'd500000;//初始f为500Hz
			pword <= 8'd0;
			wr_act <= 1'b1;
		end
		else begin
			case(key_state)
				8'b0000_0001 : wave <= sin_wave;
				8'b0000_0010 : wave <= Triangle_wave;
				8'b0000_0100 : wave <= sawtooth_wave;
				8'b0000_1000 : wave <= square_wave;

				8'b0001_0000 : fword <= fword + 32'd100;//步进频率1Hz
				8'b0010_0000 : fword <= fword - 32'd100;
				8'b0100_0000 : pword <= pword + 8'd1;
				8'b1000_0000 : pword <= pword - 8'd1;
				//default : begin
						//fword <= 32'd500000;
						//wr_act <= 1'b1;
				//end	
			endcase
		end

这里case虽然使用的是独热码,但是并没有列出所有状态....(default)综合后可以看RTL中fword,wr_act 与加入default后的区别 (注释部分)

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
27
关闭 站长推荐上一条 /3 下一条