微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 14.1版本的ise xst综合器对状态机的处理 的疑问!同学们请进!

14.1版本的ise xst综合器对状态机的处理 的疑问!同学们请进!

时间:10-02 整理:3721RD 点击:
先付状态机代码:

为什么xst不把这段代码当成FSM处理?综合时,next_stute 变了生成了不推荐的锁存器。我百思不得其解,不知道是不是代码中存在一些不妥的地方,请指点!多谢!
付xst报告,大家可以拿去综合下,V7的片子。
</next_stute</next_stute</next_stute</next_stute

状态转换改成阻塞赋值也一样。

改成两段式结果也一样

case 'd1那里,只有if没有else造成if条件未击中时latch。
不建议fsm独立写组合逻辑,这个做法落后了20年。一个时序always块写完就可以了。



    小编的这种写法不是三段式吗?

最新的方法是怎么写?请指教!基本上每本教科书三段式和二段式是标准的推荐写法啊。
关于if,我去试一下

已经验证生成lutche不是因为if没有else保护。
从设计上来说,是可能生成lutch的,但是我以为,这种标准格式,综合其会自动识别,避免lutche,直接生成组合逻辑

已经验证生成lutche不是因为if没有else保护。
从设计上来说,是可能生成lutch的,但是我以为,这种标准格式,综合其会自动识别,避免lutche,直接生成组合逻辑



  1. `timescale 1ns/1ps

  2. module FSM_test
  3. (
  4.          input wire last,
  5.          input wire f_begin,
  6.          input wire clk,
  7.          input wire rst,
  8.          output reg [7:0] data
  9. );

  10. reg [3:0] stute;
  11. reg [3:0] next_stute;

  12. always @ (posedge clk or posedge rst)
  13. begin
  14.          if(rst)
  15.          begin
  16.                  stute <= 'd1;
  17.          end
  18.          else
  19.          begin
  20.                  stute <= next_stute;
  21.          end
  22. end

  23. always @ (*)
  24. begin
  25.          if(rst)
  26.          begin
  27.                  next_stute = 'd1;
  28.          end
  29.          else
  30.          begin
  31.                  case (stute)
  32.                          'd1 : begin
  33.                          if(f_begin)
  34.                                  next_stute = 'd2;
  35.                         
  36. else
  37.                                  next_stute = 'd1; //Modified                         end
  38.                          'd2 : begin
  39.                                  next_stute = 'd4;
  40.                          end
  41.                          'd4 : begin
  42.                                  next_stute = 'd8;
  43.                          end
  44.                          'd8 : begin
  45.                                  next_stute = 'd2;
  46.                                  if (last)
  47.                                          next_stute = 'd1;
  48.                          end
  49.                          default : begin
  50.                                  next_stute = 'd1;
  51.                          end
  52.                  endcase
  53.          end
  54. end

  55. always @ (posedge clk or posedge rst)
  56. begin
  57.          if(rst)
  58.          begin
  59.                  data <= 'd0;
  60.          end
  61.          else
  62.          begin
  63.                  case (stute)
  64.                          'd1 : begin
  65.                          if(f_begin)
  66.                                  data <= 'd2;
  67.                          end
  68.                          'd2 : begin
  69.                                  data <= 'd4;
  70.                          end
  71.                          'd4 : begin
  72.                                  data <= 'd8;
  73.                          end
  74.                          'd8 : begin
  75.                                  data <= data+1;
  76.                          end
  77.                          default : begin
  78.                                  data <= 'd0;
  79.                          end
  80.                  endcase
  81.          end
  82. end
  83. endmodule

复制代码


就这段代码,能综合出Latch我吃鼠标

你好。你的方法是正解!综合器认识他是状态机了!
为什么?请指点!多谢了!


dddk 发表于 2012-9-8 21:52

[/quote]
你的改动是
next_data = 'd1;
我的改动是next_state = next_state;
差距就有这么大?

真心感谢 Timme ,多谢指点!

原因我第一次回复已经说得比较明白了。如果你暂时理解不了,就在一个时序always块(always@(posedge clk))里写完整个状态机。不要分两段写,不要用always块写组合逻辑(always@(*)),可以100%避免出Latch,除非你把异步复位写成一个不定值。

现在的综合器对付一段式状态机毫无压力,不用担心有什么副作用。

你的改动是
next_data = 'd1;
我的改动是next_state = ne ...
dddk 发表于 2012-9-8 22:00
[/quote]
Latch就是实现一个“保持”的组合逻辑。比如:

  1. always@(*)
  2.   if(A)
  3.     Y = B;
  4.   else
  5.     Y = Y;

复制代码

不加else默认也是保持,所以这段代码可以简化为:

  1. always@(*)
  2.   if(A)
  3.     Y = B;

复制代码

以上两段没有任何区别。
为了去除Latch,我们需要去掉“保持”这个动作,即在else时不保持,如:

  1. always@(*)
  2.   if(A)
  3.     Y = B;
  4.   else
  5.     Y = C;

复制代码

这种写法有一个变种,就是先赋初值:

  1. always@(*)
  2.   begin
  3.      Y = C;
  4.      if(A)
  5.        Y = B;
  6.   end

复制代码

以上两种写法结果也是完全一样的。你在状态机里也用到上面这个写法,虽然我不知你是不是无意中使用的,因为这种写法相对比较高级。
当同一个always块中组合逻辑信号不止一个时,要留意隐含的“保持”动作,如:

  1. always@(*)
  2.   if(A)
  3.     begin
  4.         Y1 = B;
  5.         Y2 = C;
  6.     end
  7.   else
  8.     Y1 = D;

复制代码

在这里,else里Y2没写,默认是一个“保持”动作。所以Y2被综合为Latch。

多谢这么详细的指点!
那个保持的问题生成lutch,我能理解,这也是我之前为什么说按设计思路就应该是个lutch的原因。
还有那种先赋值再if的写法,我在实际功能上是出了问题的,存在严重的毛刺问题,不知道是不是其他原因造成的。

我还想请教下,就是你说分段式的状态机已经落后了,那么当前流行的状态机写法是什么样子的呢?能指点一二么?
我5年前搞了3年简单的逻辑,后来转做了其他的,现在换工作,又回到了逻辑的路上,所以请多指点。

   一段式状态机综合器是能识别,关键是代码可读性比较差,单位目前不允许使用一段式的。

深受启发 学习了


正解!



   小编高人!

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

网站地图

Top