行为级建模
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Page 20
OR事件控制 有时,多个信号或者事件中发生的任意一个变化都能够触发语句或语句块 的执行。在Verilog语言中,可以使用“或”表达式来表示这种情况。由关 键词“or”连接的多个事件名或者信号名组成的列表称为敏感列表。
在跳变沿敏感的触发器中,也可以使用关键词“,” 来代替“or” 。
注意:不要在同一个always块中混合使用阻塞和非阻塞赋值语句。
Page 10
wenku.baidu.com
非阻塞赋值语句的应用
对程序:
如下的特点:
1.在每个时钟上升沿到来时读取in1,in2,in3和reg1,计算右侧表达式的值,该值 由仿真器临时保存。
2.对左值的赋值由仿真器调度到相应的仿真时刻,延迟时间由语句中内嵌的延迟值 确定。在本例中,对reg1的赋值需要等一个时间单位,对reg2的赋值需要等到时钟 信号下降沿到来的时刻,对reg3的赋值需要等一个时间单位; 3.每个赋值操作在被调度的仿真时刻完成。注意,对左侧变量的赋值使用的是由仿 真器保存的表达式“旧值”。在本例中,对reg3赋值使用的是reg1的“旧值”,而 不是在此之前对reg1赋予的新值,reg1的“旧值”是在赋值事件调度时由仿真器保 存的。
采用阻塞赋值完成
Page 12
always @( posedge clk ) begin
b<=a;
c<=b; end
a clk
D Q
b
D
Q
c
CLK
CLK
Page 13
always @(posedge clk) begin b=a; c=b; end
a b
D Q
clk
CLK
c
Page 14
由于initial块语句在整个仿真期间只能执行一次,因此它一般被用于初始化、 信号监视、生成仿真波形等目的。
Page 3
Page 4
initial begin areg=0; //初始化寄存器areg for(index=0;index<size;index=index+1) memory[index]=0; //初始化一个memory end
HDL语言硬件设计
第七章 行为级建模
7.1 结构化过程语句
在Verilog中有两种结构化的过程语句:initial语句和always语句,它们是 行为级建模的两种基本语句。其他所有的行为语句只能出现在这两种结构 化过程语句里。
与C语言不同,Verilog在本质上是并发而非顺序的。Verilog中的各个执行 流程(进程)并发执行,而不是顺序执行的。
Page 5
7.1.2 always语句
always语句包括的所有行为语句构成了一个always语句块。该always语句 块从仿真0时刻开始顺序执行其中的行为语句;在最后一条执行完成后,再 次开始执行其中的第一条语句,如此循环往复,直至整个仿真结束。
always语句通常用于对数字电路中一组反复执行的活动进行建模。例如时 钟信号发生器,每半个时钟周期时钟信号翻转一次。在现实电路中只要电 源接通,时钟信号发生器从时刻0就有效,一直工作下去。
7.3时序控制
7.3.1 基于延迟的时序控制 Verilog提供了三种时序控制方法:基于延迟的时序控制、基于事件的时序 控制和电平敏感的时序控制。
基于延迟的时序控制出现在表达式中,它指定了语句开始执行到执行完成 之间的时间间隔。
延迟值可以是数字、标识符或表达式,需要在延迟值前加上关键字#。对于 过程赋值,Verilog提供了三种类型的延迟控制:常规延迟控制、赋值内嵌 延迟控制和零延迟控制。
Page 9
7.2.2 非阻塞赋值语句
非阻塞赋值使用“<=”作为赋值符。
非阻塞(Non_Blocking)赋值方式( 如 b <= a; )。在语句块中,上面语句 所赋的变量并不能立即为下面的赋值语句使用;所赋变量值为上一次赋值得 到的。
仿真0时刻执行 仿真时刻15执行 仿真时刻10执行 仿真0时刻执行 reg_a[2]<= #15 1’b1; reg_b[15:13]<= #10 {x,y,z};
Page 21
如果组合逻辑块语句的输入变量很多,那么编写敏感列表会很繁琐并且容 易出错。针对这种情况,Verilog提供了另外两个特殊的符号:@*和@(*), 它们都表示对其后语句块中的所有输入变量的变化是敏感的。
Page 22
7.3.3 电平敏感时序控制
Verilog同时也允许使用另外一种形式表示的电平敏感时序控制(即后面的 语句和语句块需要等待某个条件为真才能执行)。Verilog语言用关键字 wait来表示等待电平敏感的条件为真。
阻塞(Blocking)赋值方式( 如 b = a; ) ,其中b的值在赋值语句执行完后立刻 就改变的。
x = 0执行完成之后,才会执行y = 1 仿真0时刻执行 仿真时刻15执行 仿真时刻25执行
1.如果右侧表达式的位宽较宽,则将保留从最低位开始的右侧值,把 超过左侧位宽的高位丢弃; 2.如果左侧位宽大于右侧位宽,则不足的高位补0;
尽量不要使用零延迟控制
具有零延迟,语句被最后执行,仿 真0时刻结束时,x和y的值都为1, 但它们的执行顺序是不确定的。
Page 18
7.3.2 基于事件的时序控制
在Verilog中,事件是指某一个寄存器或线网变量的值发生了变化。Verilog 提供了4种类型的事件控制:常规事件控制、命名事件控制、OR(或)事 件控制和电平敏感时序控制。
Page 24
Page 25
7.5 多路分支语句— —case
当条件语句中选项的数目很多时,使用if-else语句就会很不方便,这时可以 使用case语句来解决这个问题。case语句使用关键字case,endcase和 default来表示。语法如下:
case语句中的每一条分支语句都可以是一条语句或一组语句。多条语句需 要使用关键字begin和end组合为一个块语句。在执行时,首先计算条件表 达式的值,然后按顺序将它和各个候选项进行比较,如果和全部候选项都 不相等,则执行default_statement语句。注意,default_statement语句是 可选的,而且在一条case语句中不允许有多条default_statement。另外, case语句可以嵌套使用。
在这个例子中用initial语句在仿真开始时对各变量进行初始化。 initial begin inputs = 'b000000; //初始时刻为0 #10 inputs = 'b011001; #10 inputs = 'b011011; #10 inputs = 'b011000; #10 inputs = 'b001000; end 从这个例子中,我们可以看到用initial语句来生成激励波形作为 电路的测试仿真信号。
2. 上述各种类型的位选(例如,addr [ 0 ])。
3. 上述各种类型的域选(例如,addr [ 31 : 16 ])。 上面三种类型的拼接。
Verilog包括两种类型的过程赋值语句:阻塞赋值和非阻塞赋值语句
Page 8
7.2.1 阻塞赋值语句
阻塞赋值语句使用“=”作为赋值符,在一个begin-end块中表现为串行行 为。
Page 28
7.5 多路分支语句— — casex/casez
case语句还有两个变形:casex和casez。 casez语句将条件表达式或候选项表达式中的z作为无关值,所有值为z的位 也可以用“?”来代表,即对非x的位置
casex语句将条件表达式或候选项表达式中的x作为无关值。
always #half_period areg = ~areg; 这个例子生成了一个周期为:period(=2*half_period) 的无限延续的信号 波形,常用这种方法来描述时钟信号,作为激励信号来测试所设计的电路。
Page 7
7.2 过程赋值语句
过程赋值语句的更新对象是寄存器、整数、实数或时间变量。这些类型的 变量在被赋值后,其值将保持不变,直到被其他过程赋值语句赋予新值。 用法: 过程赋值语句的左侧值可以是: 1. reg,整型数、实型数、时间寄存器变量或存储器单元。
仿真器连续监视count_enable的值。如果其值为0,则不执行后面的语句, 仿真会停顿下来;如果其值为1,则在20个时间单位之后执行这条语句。如 果count_enable始终为1,那么count将每20个时间单位加1。
Page 23
7.4 条件语句
条件语句用于根据某个条件来确定是否执行其后的语句,关键字if和else用 于表示条件语句。Verilog语言共有三种类型的条件语句,用法如下:
always语句声明格式如下:
always <时序控制> <语句>
Page 6
如果一个always语句没有时序控制,则这个always语句将会发成一个 仿真死锁。见下例: always areg = ~areg;
这个always语句将会生成一个0延迟的无限循环跳变过程,这时会发生 仿真死锁。如果加上时序控制,则这个always语句将变为一条非常有用的 描述语句。见下例:
Page 15
常规延迟控制 常规延迟控制位于赋值语句的左边,用于指定一个非零延迟值。
Page 16
内嵌赋值延迟控制 除了可以将延迟控制置于赋值语句之前,还可以将它嵌入到赋值语句中, 放在赋值符的右边。这种延迟方式的效果与常规延迟赋值是完全不同的。
Page 17
零延迟控制 在同一仿真时刻,位于不同always和initial块中的过程语句有可能被同时计 算,但是执行(赋值)顺序是不确定的,与使用的仿真器类型有关。在这 种情况下,零延迟控制可以保证带零延迟控制的语句将在执行时刻相同的 多条语句中最后执行,从而避免发生竞争。但需要注意的是,如果存在多 条带有零延迟的语句,则它们之间的执行顺序也将是不确定的。
常规事件控制
事件控制使用符号@来说明,语句继续执行的条件是信号的值发生变化、 发生正向跳变和负向跳变。关键字posedge用于指明正向跳变,negedge用 于指明负向跳变。
Page 19
命名事件控制 Verilog语言提供了命名事件控制机制。用户可以在程序中声明event(事件) 类型的变量,触发该变量,并且识别该事件是否已经发生。命名事件由关 键字event声明,它不能保存任何值。事件的触发用符号-> 表示;判断事件 是否发生使用符号@来识别。
每个initial语句和always语句代表一个独立的执行过程,每个执行过程从仿 真时间0开始执行,并且这两种语句不能嵌套使用。
Page 2
7.1.1 initial语句
所有在initial语句内的语句构成了一个initial块。initial块从仿真0时刻开始执 行,在整个仿真过程中只执行一次。 如果一个模块中包括了若干个initial块,则这些initial块从仿真0时刻开始并 发执行,且每个块的执行是各自独立的。 如果在块内包含了多条行为语句,那么需要将这些语句组成一组,一般是 使用关键字begin和end将它们组合为一个块语句;如果块内只有一条语句, 则不必使用begin和end。
Page 11
使用非阻塞赋值来避免竞争
产生了竞争的情况:a = b和b = a,具体执行顺序的先后取决于 所使用的仿真器,因此这段代 码达不到交换a和b值的目的 。 在每个时钟上升沿到来的时候, 仿真器读取每个操作数的值, 进而计算表达式的值并保存在 临时变量中;当赋值的时候, 仿真器将这些保存的值赋予非 阻塞赋值语句的左侧变量。
casex和casez的使用可以让我们在case表达式中只对非x或非z的位置进行 比较。casez的使用与casex的使用类似。
Page 26
case语句类似于多路选择器,下面使用case语句实现四选一多路选择器。
Page 27
case语句逐位比较表达式的值和候选项的值,每一位的值可能是0,1,x或 z。上例中只考虑0和1的情况,将x和z的情况归结为default。我们也可以将 这部分进行单独的说明,如下: