作者sasako (只想把你留在心中)
看板Electronics
标题Re: [问题] 关於verilog signal&varieble问题
时间Sun Apr 12 09:55:09 2009
※ 引述《zxvc (修行)》之铭言:
: ※ 引述《sasako (只想把你留在心中)》之铭言:
: : 我这样分,是希望在coding style大家能保持良好的习惯,
: : 把sequential和combinational作分开,这样在debug的时候
: : 会比较容易..
: : 至於你上面写的这个例子,个人认为就是一个bad example,
: : c可以知道会合出DFF,且会是一个简单的conuter..
: : 至於d他是一个combinational的电路,你将sequential和combinational
: : 混在同一个always底下,的确还是可以合成,只是当在写大电路时,
: 我是习惯这种coding style。
: 或许你以为这样就是分开sequential circuit与combinational circuit,
: module Test(c, d, Clock, Reset1);
: output reg [2:0] c;
: output reg d;
: input Clock, Reset1;
: reg d2;
: always@(posedge Clock)
: if(Reset1)
: c = 0;
: else
: begin
: c = c+1;
: d = d2;
: end
: always@(*)
: if(c == 2)
: d2 = 1;
: else
: d2 = 0;
: endmodule
: 但其实c = c+1;会合出加法器(combinational circuit)。
: 所以这种叙述也是bad style!?:
: always@(posedge Clock)
: if(Reset1)
: a = 0;
: else
: begin
: if(b)
: a = 1;
: else
: a = 0;
: end
: 因为if(b)会合出多工器。
: 如果这真是你们实验室的coding style,我也认了。
: 不过我没有轻视任何coding style的意思,只是习惯的差异。
: 至於debug的容易与否我想跟你自己习惯的coding style有关。
: 你自己习惯哪种coding style,你就觉得它容易debug。
: 不过如果大多数人的coding style跟我不一样,
: 我想我也只好习惯别人的coding style。
: 题外话:这个世界不是最好的东西就是最好,还要大家说最好才算数。
: : 这就会造成debug上的困扰,至少我在初学者的时候,我曾经也是这样
: : ,後来当程式写得越多越大时,就会发现这样的style实在是不好的...
: : 或许刚开始大家可能为了交作业,只想function对就行了,但往後
: : 程式开始复杂时,学长、老师的要求就会是整齐,把每个讯号分清楚,
: : 加上注解,这样以後再回头看,自己还记得当初在写什麽,交接学弟
: : 时,至少不会让人阅读起来很痛苦...
: : 而回到原作者一开始的问题,我觉得可以去参考一下CIC design compiler
: : 那本教科书,他甚至举完例子,还画出了合成的示意图,非常容易了解..
: : 而坊间的书多半都是解释"<=" 就是在同时间一起动作,"="则是有次序的
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
: 很多人喜欢这样看,但其实是错的。例如(我没说可合成):
: initial
: begin
: a = 0; (1)
: a <= 1; (2)
: b = 0; (3)
: c <= a; (4)
: end
: (2)跟(4)如果视为同时动作,所以最後a = 1, c = 0!?就错了。
: 硬要用"同时"、"不同时"去解释也解释不通这initial怎麽跑。
: blocking assignment中block作动词解释为"阻挡",不是"方块"。
: 阻挡什麽?答案是执行的控制权。
: 也就是当assignment的update动作还没完成,它是不会执行下一行的。
: begin...end在Verilog中叫sequential block,
: 也就它里面的叙述是一行一行(sequential)执行的(IEEE 1364-2005 Sec. 9.8.1)。
: fork...join在Verilog中叫parallel block,
: 它里面的各叙述才是同时(concurrent)执行的(IEEE 1364-2005 Sec. 9.8.2)。
: 所以上面的initial要怎麽跑?答案就是,initial後面接sequential block,
: 所以它会先执行(1)。(1)是blocking assignment,
: 所以它会先对等号右手端求值(evaluation),然後更新(update)完a才继续执行下一行。
: 所以现在a = 0,然後执行(2)。(2)是non-blocking assignment,它会先evaluation,
: 但不会立即update就执行下一行(3)。
: non-blocking assignment update的动作是当
: 遇到blocking assignment或sequential block的end才会update。
: (3)是blocking assignment,所以a会被强制update。所以(3)执行完後
: a = 1, b = 0。
: 接着执行(4),但a此时=1,所以最後a = 1, b = 0, c = 1。
: 有兴趣可以用ModelSim验证看看。
: 另外请勿使用parallel block(fork...join)设计硬体,
: 因为大多合成器不能合成。
首先,我绝对不会写initial这种语法在我的code里,我不知道大部分的人是
否一样,这种东西我只会写在test.v档里...
另外假如真的要区分non-blocking和blocking,我真的比较认同CIC的举例,
用图说明真的是最简单的,毕竟设计者要了解,你写出什麽东西,大概就会
知道合成的电路,讲这些的先例的可不是我,我也是从CIC上课,在写程式和
欣赏别人程式的过程中慢慢体会一种"感觉"..
这也是为什麽coding style这麽重要,因为数位电路图,可以用区块表示,每
个讯号的功用都会区分清楚,在我们实验室学长大概都是这样训练学弟..
不需要把spec的东西摆在台面上来跟我说明,那些参考资料,说真的我很懒得看
,不是没看过,是看到不想看,你不知道学长多重视每个人的coding style,以
前老是从公司印一堆资料叫我看,再加上CIC上课的东西,真的很足够了!
verilog的语法并不难,难在如何写出来让人看得懂,难在逻辑上,难在想法,
在写一个大型的程式前,其实就需要作很多前制的纸上作业,将整个细节都要想
清楚,而不是马上在电脑上硬干,还记得我毕业前是写LDPC,光是纸上作业,就
弄了两个月,将每个环节会碰到的问题要先想办法解决,但是通常都会有所遗漏
,他们工程师都称之为surprise,另外RD有个有趣的讲法"research & debug",
个人认为非常贴切,在这个板上,有很多强者的存在,我也曾经在此请教过很多
问题,我也不想关公面前耍大刀...闲聊於此罗!
--
军人的假期是宝贵的压!!哈哈..
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.135.103.42
1F:推 zxvc:最後一段我满认同的,不止是做硬体、写软体也一样。没有规化 04/12 10:39
2F:→ zxvc:好,code最後会写不下去,自己都不知道自己在写什麽。 04/12 10:40
3F:→ zxvc:但我觉得Verilog的语法其实有点难懂。 04/12 10:41
4F:→ zxvc:有很多似是而非的解释、与观念。这些观念在某一些情形下就会 04/12 10:43
5F:→ zxvc:出错。像non-blocking与blocking解释成同时不同时就是一个例 04/12 10:44
6F:→ zxvc:子。基本上standard是最严谨的,follow它是不太会出错的。 04/12 10:47
7F:→ zxvc:不过也难以保证一个simulator 100%相容某个标准。 04/12 10:48
8F:→ zxvc:不只是硬体的simulator,就我所知目前也只有一个C++ compiler 04/12 10:50
9F:→ zxvc:是可以100%相容於standard。 04/12 10:50
10F:→ zerocustom00:知道自己在干什麽的话就一点也不难懂了. 04/12 16:22