B = 'b0100; 那么: |B 结果为1 & B 结果为0 ~ A 结果为1
归约异或操作符用于决定向量中是否有位为x。假定, MyReg = 4'b01x0; 那么:
^MyReg 结果为x
上述功能使用如下的if语句检测: if (^MyReg = = = 1'bx)
$ display (\ 注意逻辑相等(==)操作符不能用于比较;逻辑相等操作符比较将只会产生结果x。全等操作符期望的结果为值1。 4.2.7 移位操作符 移位操作符有: * << (左移) * >> (右移)
移位操作符左侧操作数移动右侧操作数表示的次数,它是一个逻辑移位。空闲位添0补位。如果右侧操作数的值为x或z, 移位操作的结果为x。假定:
reg [0:7] Qreg; . . .
Qreg = 4'b0111; 那么:
Qreg >> 2 是 8'b0000_0001 Verilog
HDL中没有指数操作符。但是,移位操作符可用于支持部分指数操作。例如,如果要计算ZNumBits的值,可以使用移位操作实现,例如: 32'b1 << NumBits //NumBits必须小于32。 同理,可使用移位操作为2-4解码器建模,如 wire [0:3] DecodeOut = 4'b1 << Address [0:1]; Address[0:1]
可取值0,1,2和3。与之相应,DecodeOut可以取值4'b0001、4'b0010、4'b0100和4'b1000,从而为解码器建模。
4.2.8 条件操作符
条件操作符根据条件表达式的值选择表达式,形式如下: cond_expr ? expr1 : expr2
如果cond_expr 为真(即值为1),选择expr1;如果cond_expr为假(值为0),选择expr2。 如果cond_expr
为x或z,结果将是按以下逻辑expr1和expr2按位操作的值: 0与0得0,1与1得1,其余情况为x。 如下所示:
wire [0:2] Student = Marks > 18 ? Grade_A : Grade_C; 计算表达式Marks > 18; 如果真, Grade_A 赋值为Student; 如果Marks < =18, Grade_C
赋值为Student。下面为另一实例: always
#5 Ctr = (Ctr != 25) ? (Ctr + 1) : 5;
过程赋值中的表达式表明如果Ctr不等于25, 则加1;否则如果Ctr值为25时, 将Ctr值重新置为5。 4.2.9 连接和复制操作
连接操作是将小表达式合并形成大表达式的操作。形式如下: {expr1, expr2, . . .,exprN} 实例如下所示: wire [7:0] Dbus; wire [11:0] Abus;
assign Dbus [7:4] = {Dbus [0], Dbus [1], Dbus[2], Dbus[3]}; //以反转的顺序将低端4位赋给高端4位。 assign Dbus = {Dbus [3:0], Dbus [7:4]}; //高4位与低4位交换。
由于非定长常数的长度未知, 不允许连接非定长常数。例如, 下列式子非法:
{Dbus,5} //不允许连接操作非定长常数。 复制通过指定重复次数来执行操作。形式如下: {repetition_number {expr1, expr2, ...,exprN}} 以下是一些实例:
Abus = {3{4'b1011}}; //位向量12'b1011_1011_1011) Abus = {{4{Dbus[7]}}, Dbus}; /*符号扩展*/
{3{1'b1}} 结果为111
{3{Ack}} 结果与{Ack, Ack, Ack}相同。 4.3 表达式种类
常量表达式是在编译时就计算出常数值的表达式。通常,常量表达式可由下列要素构成:
1) 表示常量文字, 如'b10和326。 2) 参数名,如RED的参数表明: parameter RED = 4'b1110;
标量表达式是计算结果为1位的表达式。如果希望产生标量结果, 但是表达式产生的结果为向量, 则最终结果为向量最右侧的位值。 习题
1. 说明参数GATE_DELAY, 参数值为5。
2. 假定长度为64个字的存储器, 每个字8位,编写Verilog 代码,按逆序交换存储器的内容。即将第0个字与第63个字交换,第1个字与第62个字交换,依此类推。
3. 假定32位总线Address_Bus, 编写一个表达式,计算从第11位到第20位的归约与非。
4. 假定一条总线Control_Bus [15:0],编写赋值语句将总线分为两条总线:Abus [0:9]和Bbus [6:1]。
5. 编写一个表达式,执行算术移位,将Qparity 中包含的8位有符号数算术移位。
6. 使用条件操作符, 编写赋值语句选择NextState的值。如果CurrentState的值为RESET,
那么NextState的值为GO;如果CurrentState的值为GO,则NextState
的值为BUSY;如果CurrentState的值为BUSY;则NextState的值为RESET。
7. 如何从标量变量A,B,C和D中产生总线BusQ[0:3]? 如何从两条总线BusA [0:3]和BusY
[20:15]形成新的总线BusR[10:1]?
本章讲述Verilog HDL为门级电路建模的能力,包括可以使用的内置基本门和如何使用它们来进行硬件描述。 5.1 内置基本门
Verilog HDL中提供下列内置基本门: 1) 多输入门:
and, nand,or, nor,xor,xnor 2) 多输出门: buf, not 3) 三态门:
bufif0, bufif1, notif0,notif1 4) 上拉、下拉电阻: pullup, pulldown 5) MOS开关:
cmos, nmos, pmos, rcmos, rnmos, rpmos 6) 双向开关:
tran,tranif0, tranif1, rtran, rtranif0, rtranif1
门级逻辑设计描述中可使用具体的门实例语句。下面是简单的门实例语句的格式。
gate_type[instance_name] (term1, term2, . . . ,termN);
注意,instance_name是可选的;gate_type为前面列出的某种门类型。各term用于表示与门的输入/输出端口相连的线网或寄存器。 同一门类型的多个实例能够在一个结构形式中定义。语法如下: gate_type
[instance_name1] (term11, term12, . . .,term1N), [instance_name2] (term21, term22, . . .,term2N), . . .
[instance_nameM] (termM1, termM2, . . .,termMN); 5.2 多输入门
内置的多输入门如下: and nand nor or xor xnor
这些逻辑门只有单个输出,1个或多个输入。多输入门实例语句的语法如下:
multiple_input_gate_type
[instance_name] (OutputA, Input1, Input2, . . .,InputN); 第一个端口是输出,其它端口是输入。 下面是几个具体实例。 and A1(Out1, In1, In2);
and RBX (Sty, Rib, Bro, Qit, Fix);
xor (Bar, Bud[0],Bud[1], Bud[2]), (Car, Cut[0], Cut[1]),
(Sar, Sut[2], Sut[1], Sut[0], Sut[3]);
第一个门实例语句是单元名为A1、输出为Out1、并带有两个输入In1和In2的两输入与门。第二个门实例语句是四输入与门,单元名为RBX,输出为Sty,4个输入为Rib、Bro、Qit和Fix。第三个门实例语句是异或门的具体实例,没有单元名。它的输出是Bar,三个输入分别为Bud[0]、Bud[1]和Bud[2]。同时,这一个实例语句中还有两个相同类型的单元。 5.3 多输出门 多输出门有: buf not
这些门都只有单个输入,一个或多个输出。这些门的实例语句的基本语法如下:
multiple_output_gate_type
[instance_name] (Out1, Out2, . . . OutN ,InputA); 最后的端口是输入端口,其余的所有端口为输出端口。 例如:
buf B1 (Fan [0],Fan [1],Fan [2],Fan [3],Clk); not N1 (PhA,PhB,Ready);
在第一个门实例语句中,Clk是缓冲门的输入。门B1有4个输出:Fan[0]到Fan[3]。在第二个门实例语句中,Ready是非门的唯一输入端口。门N1有两个输出:PhA和PhB。 5.4 三态门 三态门有:
bufif0 bufif1 notif0 notif1
这些门用于对三态驱动器建模。这些门有一个输出、一个数据输入和一个控制输入。三态门实例语句的基本语法如下:
tristate_gate[instance_name] (OutputA, InputB,ControlC); 第一个端口OutputA是输出端口,第二个端口InputB是数据输入,ControlC是控制输入。根据控制输入,输出可被驱动到高阻状态,即值z。对于bufif0,若通过控制输入为1,则输出为z;否则数据被传输至输出端。对于bufif1,若控制输入为0,则输出为z。对于notif0,如果控制输出为1,那么输出为z;否则输入数据值的非传输到输出端。对于notif1,若控制输入为0;则输出为z。 例如: