打印

由“组合电路描述与时序电路描述分开写”想到的

[复制链接]
2182|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dong_dt|  楼主 | 2012-3-19 14:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.很多资料中,在将coding style时,会提到组合电路与时序电路要分开设计。
我本人觉得这个区分没有必要搞得太严格,某些简单的设计可以将组合部分与时序部分合起来。如果分开写,反而显得很笨拙。

比如有这样的两段代码:

///例1_1
always @ (A,B)
begin
  C <= A + B;
end

always @ (posedge clk)
begin
  D <= C;
end

///例1_2
always @ (posedge clk)
begin
  D <= A+ B;
end

综合工具不至于笨得非得让我们按照例1_2中的写法才能综合出比较好的电路吧。

我不知道各位同仁在实际使用中,这一点是不是严格区分的。如果不严格区分,有没有一个衡量的标准,就是什么时候需要分开,什么时候必须合并。这个真有点困惑啊。

2.然后,我想到另外一个问题,就是关于状态机的写法。在描述状态跳转时,一般是一个组合逻辑块+一个时序块。如下:

always @ ( * )
begin
   case(cur_state)
      .........;
      .........;
      next_state <= .....;
   endcase  
end

always @ (posedge clk)
begin
  cur_state <= next_state ;
end

上面的这个两个always块合并起来感觉也无大碍啊,为什么不合并起来写呢?分开写,具体能好在哪里?


3.我感觉平时在些电路时,应当综合考虑FF前的数据端D和时钟使能端E的因素,使我们的设计最优化。如果决定FF的输出Q的信号,一部分综合到D,另一部分巧妙地综合到E端,不仅可以提高电路的速度,还可以提高资源的利用率。
比如这样的两段代码:

///例3_1
always @ (A,B,C,D,E,RES_BUF)
begin
  if(E)
     RES_BUF <= (A&B) | (C&D);
  else
     RES_BUF <= RES_BUF;
end

always @ (posedge clk)
begin
    RES <= RES_BUF;
end

///例3_2
always @ (posedge clk)
begin
   if(E)//E 会被综合到FF的时钟使能端
      RES <= (A&B) | (C&D);
end

例3_2的电路是否要比例3_1的要好些?请高人指教。

相关帖子

沙发
Backkom80| | 2012-3-19 15:01 | 只看该作者
1,首先说下,你对赋值方式的应用有错,时序逻辑用什么方式,组合逻辑用什么方式需理解及分清楚。
2,例1-2和例1-1功能是一样的,结构也基本相同,只是代码的输写风格不同,例1-2确实比例1-1要简洁。

使用特权

评论回复
板凳
dong_dt|  楼主 | 2012-3-19 17:30 | 只看该作者
2# Backkom80

我在组合逻辑里面用非阻塞式的赋值,不是对于错的问题,要看场合的。
对于“组合逻辑里面必须使用阻塞赋值”的观点,我不敢苟同。
对电路的综合性而言,在组合逻辑里使用阻塞与非阻塞赋值,效果是一样的。区别仅在于仿真。

阻塞式赋值,能比较好地的实现组合逻辑的建模,这一点无可厚非。请注意这里说的是“建模”,而不是综合后的实现效果。从效果上看,在组合逻辑里使用阻塞与非阻塞赋值,结果一样。我们在写HDL代码时,首先应该建立起“并行”的思想,这也是硬件电路的特性,而不是C模式下的顺序执行。很多初学者在理解阻塞赋值时,很容易产生误解,认为电路是在顺序执行的,然后接下来会以C的思路来理解HDL。

在仿真的行为建模时,用阻塞赋值能达到非阻塞赋值无法达到的效果。但对于最终实现的电路而言,阻塞赋值能达到的效果,非阻塞赋值也能达到。

使用特权

评论回复
地板
Backkom80| | 2012-3-19 18:07 | 只看该作者
本帖最后由 Backkom80 于 2012-3-19 18:15 编辑

嘻嘻,不敢同意你的说法,
1,难道你写完代码不仿真吗?(小型可能可以,复杂的还是需要的吧,至少功能仿真还是要的)
2,不同的综合器对你说的这点识别不同,综合器没有你说的那么智能。如:

always @ ( posedge clk )
begin
     b <= a;
     c  = b;
     d <= c;
end
结果不是很一样,有些会智能些,有些不一定

使用特权

评论回复
5
GoldSunMonkey| | 2012-3-19 18:33 | 只看该作者
1.很多资料中,在将coding style时,会提到组合电路与时序电路要分开设计。
我本人觉得这个区分没有必要搞得太严格,某些简单的设计可以将组合部分与时序部分合起来。如果分开写,反而显得很笨拙。

比如有这样的两 ...
dong_dt 发表于 2012-3-19 14:52
1, 我觉得您的理解可能有一点偏差。您的这两种写法,其实都是我们统称的时序的写法。
    至少我会用1.2的方式。
2. 组合逻辑和时序逻辑分开,更多的是指比方说放在这个模块里面对这个模块根本
   没什么作用的组合逻辑,只是放在那里和这个module影响可读性。
    如果用VHDL可能你更好理解一点。

使用特权

评论回复
6
GoldSunMonkey| | 2012-3-19 18:35 | 只看该作者
状态机,的确可以写在一起。
但是可读性上肯定不好。

使用特权

评论回复
7
GoldSunMonkey| | 2012-3-19 18:36 | 只看该作者
并行思想是对的,但是呢?为仿真后写点语法很重要。万一需要仿真怎么办?
另外,万一不是每一个综合器认识你说的这种语法,毕竟这个和VERILOG的标准有点不一样。

使用特权

评论回复
8
GoldSunMonkey| | 2012-3-19 18:36 | 只看该作者
以上为个人观点。

使用特权

评论回复
9
lwq030736| | 2012-3-19 20:40 | 只看该作者
我觉得组合逻辑电路和时序电路分开写,
主要是能够让整个电路的逻辑看起来更清晰
调整时序和调试的时候更方便

使用特权

评论回复
10
GoldSunMonkey| | 2012-3-19 21:32 | 只看该作者
:)和我说的一样:)

使用特权

评论回复
11
Backkom80| | 2012-3-20 09:06 | 只看该作者
支持猴哥。:lol

使用特权

评论回复
12
yxf236| | 2012-3-20 09:23 | 只看该作者
1和3,我都是用第二种用法,感觉两种用法是一样的,只不过第二种看着直观
2,我一般都是将两个always块合并(当然一般规模都不太复杂),可能不合并更好一些,但是我习惯了合并的写法了,我感觉这个其实也没有严格的要求,记得看过说是不太复杂的可以只用一个always块,复杂的话建议分开。

使用特权

评论回复
13
dong_dt|  楼主 | 2012-3-21 11:55 | 只看该作者
嘻嘻,不敢同意你的说法,
1,难道你写完代码不仿真吗?(小型可能可以,复杂的还是需要的吧,至少功能仿真还是要的)
2,不同的综合器对你说的这点识别不同,综合器没有你说的那么智能。如:

always @ ( posedge cl ...
Backkom80 发表于 2012-3-19 18:07


呵呵,有点意思。由一个话题不经意间引到另外一个话题。

你举得这个例子,是在时序逻辑中。在时序电路中,本来就是不推荐使用阻塞赋值的。
而我的写法,是在组合逻辑中全部采用非阻塞赋值。请注意这个前提,是“在组合逻辑中”。

在组合逻辑里面全部用非阻塞赋值,照样也可以达到仿真的目的。不清楚你是否了解VHDL,VHDL里没有阻塞与非阻塞之说,进程里面的赋值过程都是并行的,同样可以写出很好的代码,也能仿真。

但是我感觉在些test_bench时,用verilog来对激励信号做建模更方便一些。在这样的场合,verilog的阻塞赋值能发挥巨大的优势。

使用特权

评论回复
14
Backkom80| | 2012-3-21 14:07 | 只看该作者
13# dong_dt
呵呵,看清楚了在回哈,我给的例子恰恰是反例,我可没说那个例子是推荐的例子。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

29

帖子

0

粉丝