24 September 2013

近期没有更新什么博客,总觉得写出一篇博客需要深入的思考,待成熟后再发表出来。所以,回首过往学习过的知识才发现,积累的很少,思考的很少,不得不一点点重新积累,所以一时写不出什么好的文字自然也就不足为奇了。

我觉得Martin Fowler这篇《仍无法衡量软件开发的生产效率》说的非常有道理,打个比方,也许你写了一天的代码,但只要没有出结果,老板不会觉得你工作量有多大,尽管也许你在这一天的编程中解决了数个问题。所以,“持续编程”的过程积累了经验,却不易轻易表现出来,也就没什么“新”东西可以写到博客里了。

近期关于研究方向问题思前想后,花费了不少时间。自己是喜欢软件的,可团队是做硬件的,之前倒是想做视频编码,但终究考虑后选择放弃,学习了一阵子verilog改了一些模块。直到今天与老师的交流,发现自己仍然不适合做硬件,可能要做一些软件的东西,更适合自己的兴趣和特点吧。

所以,明天也许就不再使用verilog了,今天在此写下这些天的感想。好了,废话打住。


不得不说,verilog与C很相似,很多语法基本相同。if、for、case这些语句在verilog中随处可见,但我认为硬件编程语言与软件编程语言最大的不同就在于“时序”与“并行”。

1.时序

说到时序不得不说数字逻辑电路的两大种类:

  • 组合逻辑:输出只是当前输入逻辑电平的函数,与电路的原始状态无关。就是任何一个信号变化,输出都可能随之变化,无记忆性。
  • 时序逻辑:输出不只是当前输入的逻辑电平的函数,还与电路目前所处的状态有关。

组合逻辑好理解,举时序逻辑的例子。

always @(posedge clk) begin
     cnt <= cnt + 1;
     tmp <= cnt;

首先cnt、tmp也定义为reg(寄存器类型)型(还要注意位宽),表示可以存储数值,组合逻辑中不能使用reg,而要使用wire(无记忆性)。每个时钟上升沿到来时,cnt自加1,但是cnt并不马上加1,而要等整个always结束后才变化。也就是说假设cnt原来为1,上升沿到来时,cnt还是1,而tmp被赋给1(结束前还是保持原值),当always结束后cnt才变为2,tmp变为1。这也是verilog特殊的阻塞与非阻塞赋值。

所以,我们看到这一切都和时钟有关,没错,时钟的概念在硬件语言中具有举足轻重的意义。经常使用时序逻辑,就要考虑什么时候这些reg变化成了什么数,而绝不像C(软件语言)中那样立刻赋值。所以你会经常看到类似这样的仿真图,数据没对上是常有的事情,慢慢调吧。

2.并行

看起来并行在软件语言中也可以实现,多进程多线程啊等等,其实我们可以看到硬件本身为硬件提供了极大的便利,让并行更易实现。比如verilog那重要的always语句(上文提到),如果一段代码中有多个always语句,这些语句是一起执行的,敏感条件(@后面括号里的信号)一旦被满足always就开始执行,若同时满足多个always语句,则这些语句一同开始执行。其实还有fork。。。join语句,生成块等并行方法,在此不一一介绍。当然这里的语句执行也要符合时序(时钟)。

3.测试仿真

每写好一段代码,要想看到输出就要仿真,就要写测试仿真代码。这些测试仿真给你的代码输入,包括时钟等等,并输出结果。所以好不容易写好了一段代码,验证时又要写测试文件(与软件的测试单元相区别),工作量那是倍增啊(其实也不会特别难写,大同小异)。

说了这么多,基本上把我认为重要的特性简要介绍了一番,硬件编程语言最大的特点即可以描述硬件的很多特性,比如寄存器、延时、并行等,由于自己也刚学不久,终究会有所不足之处,就算作阶段总结吧。



blog comments powered by Disqus