免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4678 | 回复: 6
打印 上一主题 下一主题

看到网上有些人写的数字设计中关于三段式的文章 [复制链接]

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-06-03 11:11 |只看该作者 |倒序浏览
觉得其中有误解的成分,特别是对于编译/综合的误解,有必要解释一下
再加上好久没写什么文章,版面又冷清,似乎有点不称职了.

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2011-06-07 16:40 |只看该作者
我们假设有这么一个状态机:
有一个输入S是用来改变状态机的状态的,每当上沿时就改变一下状态机的状态
另外有两个输入A,B,有一个输出C
还有一个时钟clk以及一个复位nrst
初始的时候(复位后)状态为0
输出值为两个输入值的与
状态为1时
输出值为两个输入的或
状态为2时
输出值为两个输入的异或
状态为3时
输出值为两个输入的异或非

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
3 [报告]
发表于 2011-06-07 16:49 |只看该作者
本帖最后由 cjaizss 于 2011-06-08 13:55 编辑

我们现在用一段式来写这个状态机,我这里用verilog编写,VHDL类似,我就不写了.
为了简单,在这里,我不过滤毛刺.

  1. module mytest1(clk,nrst,S,A,B,C);
  2. input clk,nrst,S,A,B;
  3. output C;
  4. reg [1:0]stat;
  5. reg S2;
  6. reg C;
  7. always@(negedge nrst or posedge clk)
  8. if(!nrst)
  9.         S2<=0;
  10. else
  11.         S2<=S;

  12. always@(negedge nrst or posedge clk)
  13. if(!nrst) begin
  14.        stat <= 0;
  15.        C<=0;
  16.        end
  17. else
  18.        case(stat)
  19.        0:
  20.               C<=A&B;
  21.               if(S&!S2)
  22.                    stat<=1;
  23.        1:
  24.               C<=A|B;
  25.               if(S&!S2)
  26.                    stat<=2;
  27.        2:
  28.               C<=A^B;
  29.               if(S&!S2)
  30.                    stat<=3;
  31.        3:
  32.               C<=A==B;
  33.               if(S&!S2)
  34.                    stat<=0;
  35.        default:
  36.               stat<=0;
  37.        endcase
  38. endmodule
复制代码

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
4 [报告]
发表于 2011-06-07 16:52 |只看该作者
上面就是一段式的写法,状态转换和状态机的输出写在一个进程里,下面我们再看看三段式的写法

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
5 [报告]
发表于 2011-06-08 13:40 |只看该作者
本帖最后由 cjaizss 于 2011-06-08 14:08 编辑

  1. module mytest2(clk,nrst,S,A,B,C);
  2. input clk,nrst,S,A,B;
  3. output C;
  4. reg [1:0]nx_stat,stat;
  5. reg S2;
  6. reg C;
  7. always@(negedge nrst or posedge clk)
  8. if(!nrst)
  9.         S2<=0;
  10. else
  11.         S2<=S;
  12. always@(negedge nrst or posedge clk)
  13. if(!nrst)
  14.         stat <= 0;
  15. else
  16.         stat <= nx_stat;
  17. always@(S2,S,stat)
  18. case(stat)
  19. 0:if(S&!S2)nx_stat<=1;else  nx_stat<=stat;
  20. 1:if(S&!S2)nx_stat<=2;else  nx_stat<=stat;
  21. 2:if(S&!S2)nx_stat<=3;else  nx_stat<=stat;
  22. 3:if(S&!S2)nx_stat<=0;else  nx_stat<=stat;
  23. endcase
  24. always@(negedge nrst or posedge clk)
  25. if(!nrst) begin
  26.        C<=0;
  27.        end
  28. else
  29.        case(nx_stat)
  30.        0:
  31.               C<=A&B;
  32.        1:
  33.               C<=A|B;
  34.        2:
  35.               C<=A^B;
  36.        3:
  37.               C<=A==B;
  38.        endcase
  39. endmodule
复制代码

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
6 [报告]
发表于 2011-06-09 15:24 |只看该作者
cjaizss 发表于 2011-06-08 13:40



    顾名思义,三段式就表示,描述一个状态机分三段,三个进程。
  上面verilog代码中,除了第一个之外,其他三个就是了。
  看上去,代码中要维护两个状态值,stat和nx_stat,stat表示状态机当前状态,nx_stat表示下一刻状态
  第一个进程,每到时钟上沿,nx_stat就要赋给stat.
   第二个进程,根据当时的状态、输入值为nx_stat赋值。
  第三个进程,产生输出。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
7 [报告]
发表于 2011-06-11 10:07 |只看该作者
第一个进程比较容易理解,第三个进程也很容易理解.
关键在于第二个进程
网上有很多的说法,比如有的说,这样的三段式写法性能上会好,但会使用更多的触发器,这是一种误解,因为它并不会导致使用更多的触发器.
这就涉及到编译(并非综合)是如何进行的,第二个进程的敏感表中有太多的值,那么把它综合成一个时序电路显然是不显示的,于是编译器会往组合电路的方向去想.
但如果要正确编译为组合逻辑,首先,必须所有的输入都在敏感表中,这是最基本的要求.
其次,任何情况下都必须有输出,else后面悬挂的部分不写的话,逻辑是有问题的,原因就在于这是组合电路,不是时序电路.
always@(S2,S,stat)
case(stat)
0:if(S&!S2)nx_stat<=1;else  nx_stat<=stat;
1:if(S&!S2)nx_stat<=2;else  nx_stat<=stat;
2:if(S&!S2)nx_stat<=3;else  nx_stat<=stat;
3:if(S&!S2)nx_stat<=0;else  nx_stat<=stat;
endcase
网上有人说,这一段的逻辑应该用=,而不应该用<=
一个是阻塞赋值,一个是非阻塞.
这又是一个误解,无所谓的.

我发这个帖子的关键之处,是要说明为什么写三段式,这里误解就更多了.
和一段式一样,三段式只是一种RTL的写法,两种本质并无区别.
但是,三段式的写法逻辑和组合分开,这样做至少人看着会舒服很多,编译器也会舒服.
人看着舒服,修改起来就方便一些.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP