lcytms
发表于 2016-12-11 23:28:27
1109
现在我们写它的验证,新建verilog,另存为mux2_dataflow_tb.v。
写它的时标。
然后我们把它置入testbench其中,把它的例化头复制过来。
lcytms
发表于 2016-12-11 23:29:40
1110
这个时候我们还没有进入行为,进入行为的时候,我们会来解释,为什么要声明成reg?
现在我们只能说,接到信号发生器的是reg,输出的是线。
lcytms
发表于 2016-12-11 23:30:50
本帖最后由 lcytms 于 2016-12-11 23:31 编辑
1111
写激励,八种情况。
写停机。
设置仿真。
lcytms
发表于 2016-12-11 23:33:25
1112
查看仿真波形。
看到设计已经得到了验证。
这是数据流的描述。
lcytms
发表于 2016-12-11 23:34:45
1113
然后,我们就要描述它的行为了。
行为就是用人类的语言来处理,如果,怎么样。
我们自然而然会想到,如果s为高电平,我们让f输出b,如果s为低电平,让f输出a。
那么就是写一个if的语句,if的语句,类似的就是人类行为的语句。
行为语句,EDA又该如何处理呢?
怎么样才能够描述这种行为的语句,能够被EDA接收,并且它又有哪些约定呢?
就诞生出reg这种定义来。
休息
lcytms
发表于 2016-12-11 23:37:56
1119
这个数据流的语句,描述的是what to do,还是how to do呢?
how to do也就是如何实现,如何实现是站在电路设计的角度上,用布尔表达式来实现。
所以说,现在数据流显然描述的只是what to do,在某种意义上,它有一定的how to do的描述,但是呢,是介于其中的。
现在呢,我们来看看行为,行为真正的只描述了what to do,而没有描述how to do,它这个电路结构跟我们的布尔表达式没有任何的关系。
我们只需要描述一个事实,如果怎么样,结果怎么样。
现在我们来做这种描述,我仍然选mux2的代码上,然后另存为mux2_behaviour.v,行为。
1120
交换顶层为mux2_behaviour.v。
我希望EDA能够支持它,因为马上要做仿真。
修改代码,现在我们来写行为。
行为嘛,就是if嘛,if语句,如果s为真值,我们让f输出b,相对的条件,让f输出a。
这个语句的描述,是真正意义上的what to do。
lcytms
发表于 2016-12-11 23:39:38
1121
我怎么描述呢?
就是根据事实来描述,根据电路处理的事实。
而电路究竟是如何实现,跟这个布尔表达式没有任何的关联。
它如何变成对应的电路实现,完全交给综合器去做,所以说这就体现出它的behaviour,它的行为。
Case也是行为,if也是行为。
可是这段行为语句呢,EDA却无法识别,因为EDA并不知道行为在什么时候出现。
EDA要是知道行为在什么时候出现,要理解这个行为语句,只有一种方法,就是必须把特定的行为语句置于一个特定的框架之中。
置于一个框架之中,EDA才能认为它是行为,才会执行对行为的处理。
lcytms
发表于 2016-12-11 23:42:47
1122
马上我们来看行为语句的三件事情。
行为语句,第一就是框架,置于一个框架之中,这个框架在verilog里面只有两个,一个是初始化的行为框架,就是initial,第二个就是称为循环行为框架,always。
Always的这个框架,当然它们都是行结构,多行要begin…end起来。
虽然if语句是一行,但是我现在还是用begin…end括起来,这是第一件事。
就是行为语句,if也好,case也好,必须置于特定的框架之中。
现在我们要把它置在循环行为框架,这个循环行为框架写成always,你从字面上理解,永远、一直、总在执行。
啥叫总在执行呢?
并不是执行的概念,在这个里面就是一种约定。
当你把行为语句,置于这个框架之中,EDA就会知道,这是一段行为,根据这段行为它就会得到对应的电路。
1123
但是仅仅这样还不够,第一件事要做的,就是框架。
第二件事,是什么呢?
如果我们这样写了以后,EDA还是无法识别。
它无法识别什么呢?
无法识别f这个值,这个时候f这个值是在循环行为体的框架里面,出现在赋值号的左侧的信号,是它的输出信号。
输出信号,这个时候,verilog有一种约定,行为语句的输出,置于循环行为体里面的肯定是循环行为语句。
行为语句的输出,这个行为语句赋值号的左侧,这个信号必须声明成reg。
至于它是否真的会变成寄存器呢?
不一定。
那完全由综合器决定,Moorby的团队,当时的编译器的团队,就是这么制定的,就是行为语句的输出就必须声明成reg。
lcytms
发表于 2016-12-11 23:45:27
1124
想到这一点,我们就可以理解了,为什么verilog在它的testbench里面,会把原本接入到信号发生器的部分声明成reg呢?
现在我们理解了,并不是由于它接信号发生器,要把它声明成reg。
而是这个信号会出现在行为语句的左侧。
什么是行为语句呢?
我们会放在初始化行为语句,initial语句里面,initial语句是一个初始化行为的框架。
这是第二件事。
就是行为语句的输出,要声明成reg。
然后还有第三件事。就是这样做了以后,EDA还是无法工作,早期就是这么做的。
为什么EDA还是无法工作呢?
由于这段行为语句,它是由输入关联到输出的,EDA怎么知道什么时候要做这件关联呢?
1125
因此上,它必须时时刻刻来做,每一个时间单位都来做。
每一个时间单位,我们在后仿的时候都涉及到,设置到ps的阶段,每一个ps都要处理时,EDA的开销异常的巨大,非常大。
这个呢,会引起用户管理器里面,我们就会看到CPU的占用率非常大了,而且会非常的卡。
为了解决这个问题,解决EDA的开销的问题,EDA的效率的问题,在米德体系下面,VHDL体系下面,就引入了信号敏感表。
什么是信号敏感表呢?
就是这个时候,有数据者通知EDA,@表明有哪些信号,发生变更的时候,EDA才处理这些行为,才处理对应的循环行为体,使得效率提升。
所以说这一段在VHDL里面,循环行为体的信号敏感表,是与综合无关的。
lcytms
发表于 2016-12-11 23:47:10
本帖最后由 lcytms 于 2016-12-18 22:26 编辑
1126
跟综合,不管什么电路,都没有关系,你做不做它,都得到完全相同的电路。
但是呢,非综合目的的时候,仿真验证的时候,在电脑里面运行的时候,由信号敏感表来通知EDA,什么时候做呢?
信号敏感表里面列出的信号发生变更的时候,行为语句才来处理,哪些信号会列到信号敏感表里面呢?
它发生了变更以后如何来处理呢?
显然输入的信号,s发生变化的时候,a发生变化的时候,b发生变化的时候,我们需要处理这段行为。
或者说,我们需要EDA处理这段行为。
所以说,信号敏感表,它的职能,就是哪些信号变化了以后,必须要EDA来处理,用于非综合目的。
但是在verilog里面,Moorby的团队下面呢,做了一个小小的修改,因为在他的团队的商业化运作里面,并没有精确地理解米德体系下信号敏感表的含义。
1127
在稍后我们会说到,信号敏感表里面出现的时钟沿,会影响到综合。
VHDL信号敏感表,不影响综合,和综合无关。
但verilog有关。
所以说,这三件事,我再重复一下。
第一件事,行为语句,要置于行为语句的框架之中。
verilog的框架有两个,第一是always循环行为框架,第二是initial,初始化行为框架,这是第一件事。
第二件事,行为语句的输出,必须声明成reg,这是第二件事。
第三件事,你需要EDA来处理行为的时候,通常用于非综合目的,verilog是跟综合有关,行为语句什么时候处理它的时候,你必须通知它,通知EDA.
有些信号变化的时候,你希望EDA来处理它,这是信号敏感表。
1128
第一,框架,行为体的框架。
第二,行为语句的输出声明成reg。
第三,你必须标注出信号敏感表。
当有些信号发生变化的时候,行为语句才来处理它。
这三件事,完成了以后,我们才正确的描述了what to do。
它要做什么,并没有描述它是如何实现的,如何实现我们交给EDA来去做。
现在,Ctrl+S、Ctrl+K。
现在我们顶层是行为,行为已经做成了,就是用这种方式来描述的。
现在呢,我们就来写验证。
新建verilog,另存为mux2_behaviour_tb.v文件,这是写行为的Testbench,我们不从头写了,将数据流复制过来,修改名字。