Verilog HDL语言基础知识

news2024/11/28 15:54:42

目录

Verilog HDL语言基础知识 

6.1.2  Verilog HDL模块的结构

6.1.3 逻辑功能定义

6.2.1  常量

6.3 运算符及表达式

6.4.2 条件语句


Verilog HDL语言基础知识 

先来看两个Verilog HDL程序。

例6.1    一个8位全加器的 Verilog HDL源代码

module adder8(cout,sum,ina,inb,cin);

output[7:0] sum;

output cout;

input[7:0] ina,inb;

input cin;

assign {cout,sum}=ina+inb+cin; //全加

endmodule

【例6.2】一个8位计数器的Verilog HDL源代码

module counter8(out,cout,data,load,cin,clk);

output[7:0] out;

output cout;

input[7:0] data;

input load,cin,clk;

reg[7:0] out;

always @(posedge clk)

begin

if(load)

  out=data;

else

  out=out+cin;

end

assign cout=&out&cin;

endmodule

    从上面的例子可以看出:

    ① Verilog HDL程序是由模块构成的。每个模块的内容都是嵌在module 和endmodule 两个语句之间,每个模块实现特定的功能,模块是可以进行层次嵌套的。

    ②每个模块首先要进行端口定义,并说明输入(input)和输出(output),然后对模块的功能进行逻辑描述。

    ③Verilog HDL程序的书写格式自由,一行可以写几个语句,一个语句也可以分多行写。

④ 除了endmodule语句外,每个语句的最后必须有分号。

⑤ 可以用/*……*/和//…… 对Verilog HDL程序的任何部分作注释。

6.1.2  Verilog HDL模块的结构

    Verilog HDL的基本设计单元是"模块(block)"。一个模块是由两部分组成的,一部分描述接口;另一部分描述逻辑功能,即定义输入是如何影响输出的。下面举例说明,图6.1示出了一个"与-或-非"门电路。

图6.1"与-或-非"电路

该电路表示的逻辑函数可以写为:

                                F = AB + CD                                    

用Verlog HDL语言对该电路进行描述如下:

【例6.3】与-或-非门电路

module AOI(A,B,C,D,F);      // 模块名为AOI(端口列表A,B,C,D,F)

input A,B,C,D;             // 定义模块的输入端口A,B,C,D

output F;                       // 定义模块的输出端口F

assign F= ~((A&B)︱(C&D));       // 模块内的逻辑描述

endmodule

    从上面的例子可知,电路图符号的引脚也就是程序模块的端口,在程序模块内描述了电路图符号所实现的逻辑功能。在上面的Verilog HDL设计中,模块中的第2、第3行说明接口的信号流向,第4行说明了模块的逻辑功能。

    Verilog HDL结构完全嵌在module和endmodule声明语句之间,每个Verilog程序包括4个主要部分: 端口定义,I/0说明,信号类型声明和功能描述。

1. 模块的端口定义

模块的端口声明了模块的输人和输出口。其格式如下:

module 模块名(口1,口2,口3,口4,……);

2.模块内容

模块内容包括 I/O说明,信号类型声明和功能定义。

(1) I/O说明的格式如下:

输人口: input端口名1,端口名2,……端口名N;

输出口: output端口名l,端口名2,……端口名N;

I/O说明也可以写在端口声明语句里。其格式如下:

   module module_name(input portl,input port2,…output portl,output port2,…);

(2)信号类型声明:

它是说明逻辑描述中所用信号的数据类型及函数声明。如

reg[7:0] out;       //定义out的数据类型为reg(寄存器)型

对于端口信号的缺省定义类型为wire(连线)型。

6.1.3 逻辑功能定义

模块中最重要的部分是逻辑功能定义。有3种方法可在模块中描述逻辑。

  1. 用assign语句

如:assign F = ~((A&B)|(C&D));

这种方法的句法很简单,只须写一个“assign”,后面再加一个方程式即可。

"assign"语句一般适合于对组合逻辑进行赋值,称为连续赋值方式。

  1. 用元件例化(instantiate)

如: and myand3(f, a,b,c);

这个语句利用Verilog HDL提供的与门库,定义了一个三输人的与门。采用实例元件的方法同在电路图输入方式下调入库元件一样,键入元件的名字和引脚的名字即可。要求每个实例元件的名字必须是唯一的。

  1. 用always块语句

在【例6.2】的计数器模块中

always @(posedge clk) //每当时钟上升沿到来时执行一遍块内语句

begin

if(load)

  out=data;

else

  out=out+cin;

end

always块可用于产生各种逻辑,常用于描述时序逻辑。这个例子用always块生成了一个带有同步置数的计数器。always块可用很多种描述手段来表达逻辑,如此例中就用了if-else语句来表达逻辑关系。

综上所述,可给出Verilog HDL模块的模板如下:

Verilog HDL模块的模板(仅考虑用于逻辑综合的部分,不考虑用于逻辑模拟的部分)。

module <顶层模块名>,(<输入输出端口列表>);

output输出端口列表; //输出端口声明

input输入端口列表; //输入端口声明

/* 定义数据,信号的类型,函数声明,用关键字wire,reg,funtion等定义 */

//使用assign语句定义逻辑功能

wire 结果信号名;

assign <结果信号名> = <表达式>;

//使用 always块描述逻辑功能

always @ (<敏感信号表达式>)

  begin

// 过程赋值

  // if语句,

// case语句

  // while,for,repeat循环语句

  // function调用

end

// 模块元件例化

< module_name模块名>,<instance_name例化元件名>,(<port_list端口列表>);

// 门元件例化

gate_type_keyword <instance_name例化元件名>  (<port_list>);

endmodule

6.2 数据类型及常量、变量

   Verilog HDL中共有19种数据类型。数据类型是用来表示数字电路中的数据存储和传送单元的。在此介绍4个最基本的数据类型:  integer型、parameter型、reg型和wire型。

Verilog HDL中也有常量和变量之分,他们分属以上这些类型。

6.2.1  常量

   在程序运行过程中,其值不能被改变的量称为常量。

1. 数字

   (1)整数

   在Verilog HDL中,整数型常量(即整常数)有以下4种进制表示形式:

   ◇二进制整数(b或B);

   ◇十进制整数(d或D);

   ◇十六进制整数(h或H);

   ◇八进制整数(o或O)。

    完整的数字表达式为:

    <位宽>'<进制> <数字>,

    位宽为对应二迸制数的宽度,如:

8'b11000101    //位宽为8位的二进制数11000101;

    8'hc5          //位宽为8位的十六进制数c5;

    十进制的数可以缺省位宽和进制说明,如:

    197            //代表十进制数197

    (2)x和z值

    x表示不定值,z表示高阻值。每个字符代表的宽度取决于所用的进制,例如:

    8'b1001xxxx;   等价于8'h9x;

    8'b1010zzzz;   等价于8'haz;

当常量不说明位数时,默认值为32位。此外,“?”是高阻态的z的另一种表示符号。

2.常量

    在Verilog HDL中,用parameter来定义常量,即用parameter来定义一个标志符,代表一个常量,称为符号常量。其定义格式如下:

parameter 参数名1=表达式,参数名2=表达式,参数名3=表达式……;

例如:

parameter sel=8,code=8'ha3;

//分别定义参数sel为常数8(十进制),参数code为常数a3(十六进制)

6.2.2 变量

    变量是在程序运行过程中其值可以改变的量。变量分为两种:一种为网络型(nets type),另一种为寄存器型(register type)。

1. nets型变量 wire

nets型变量指输出始终根据输入的变化而更新其值的变量,它一般指的是硬件电路中的各种物理连接。Verilog HDL中提供了多种nets型变量,具体见表6.1。

表6.1  常用的nets型变量及说明

类型

功能说明

wire,tri

连线类型(wire和tri功能完全相同)

wor,trior

具有线或特性的连线(两者功能一致)

wand,triand

具有线与特性的连线(两者功能一致)

tri1,tri0

分别为上拉电阻和下拉电阻

supply1,supply0

分别为电源(逻辑1)和地(逻辑0)

这里着重介绍wire型变量。wire是一种常用的nets型变量,wire型数据常用来表示assign语句赋值的组合逻辑信号。Verilog HDL模块中的输入/输出信号类型缺省时自动定义为wire型。Wire型信号可以用作任何方程式的输入,也可以用作assign语句和实例元件的输出,其取值为0,1,x,z。

wire型变量格式如下 :

⑴.定义宽度为1位的变量:

wire 数据名1,数据名2,……数据名n;

例如: wire a,b; //定义了两个宽度为1位wire型变量a,b

⑵.定义宽度位n位的向量(vectors):

wire[n-1:0] 数据名1,数据名2,……数据名n;

    wire[n:1] 数据名1,数据名2,……数据名n;

例如: wire[7:0] databus; //定义一个8位wire型向量

或 wire[8:1] databus;

wire型向量可按以下方式使用:

wire[7:0] in,out; //定义两个8位wire型向量in,out

assign out=in;

若只使用其中某几位,可直接指明,注意宽度要一致。如:

wire[7:0] out;

wire[3:0] in;

assign out[5:2]=in; //out向量的第二位到第5位与in向量相等

2. register型变量 reg

register型变量对应的是具有状态保持作用的电路元件,如触发器、寄存器等。register型变量与nets变量的根本区别在于:register需要被明确地赋值,并在被重新赋值前一直保持原值。在设计中必须将寄存器型变量放在过程块语句(如initial,always)中,通过过程赋值语句赋值。另外,在always过程块内被赋值的每一个信号都必须定义成寄存器型。

Verilog HDL中,有4种寄存器型变量,见表6.2

表6.2常用的register型变量及说明

类型

功能说明

reg

常用的寄存器型变量

integer

32位带符号整数型变量

real

64位带符号整数型变量

time

无符号时间变量

Integer、real、time等3种寄存器型变量都是纯数学的抽象描述,不对应任何具体的硬件电路。reg型变量是最常用的一种寄存器型变量,下面介绍reg型变量。

   reg型变量格式如下:

   reg 数据名1,数据名2,……数据名n;

例如: reg a,b;       //定义了两个宽度为1位的reg型变量a,b

若定义一个向量,则按以下格式:

reg[n-l:0]数据名1,数据名2,……数据名n;

reg[n:l]数据名1,数据名2,……数据名n;

它们定义了数据的宽度为n位。如下面的语句定义了8位宽的数据

例如:

reg[7:0] data;              //定义data为8位宽的reg型向量

或:

reg[8:1] data;

3. 数组

    若干个相同宽度的向量构成数组,reg型数组变量即为memory型变量,即可定义存储器型数据。如:

    reg[7:0] mymem[l023:0];

上面的语句定义了一个1024个字节、每个字节宽度为8位的存储器。通常,存储器采用如下方式定义:

parameter wordwidth=8,memsize = l024;

reg[wordwidth-l:0] mymem[memsize-l:0];

上面的语句定义了一个宽度为8位、1024个存储单元的存储器,该存储器的名字是mymem,若对该存储器中的某一单元赋值的话,采用如下方式:

mymem[8]=1;      //mymem存储器中的第8个单元赋值为1

注意: Verilog HDL中的变量名、参数名等标记符是对大小写字母敏感的。

6.3 运算符及表达式

6.3.1 运算符

1. 算术运算符

+ 加

- 减

* 乘

/ 除

% 求模

算术运算符都是双目运算符。

2. 逻辑运算符

&&            逻辑与

||            逻辑或

!             逻辑非

3. 位运算符

位运算是将两个操作数按对应位进行逻辑运算。位运算符包括

-             按位取反

&             按位与

|             按位或

^             按位异或

^~,~ ^       按位同或

当两个不同长度的数据进行位运算时,会自动地将两个操作数按右端对齐,位数少的操作数会在高位用0补齐。

4. 关系运算符

< 小于

< = 小于或等于

> 大于

> = 大于或等于

在进行关系运算时,如果声明的关系是假,则返问值是0;如果声明的关系是真,则返回值是1;如果某个操作数的值不定,则其结果是模糊的,返回值是不定值。

5. 等式运算符

= =  等于

!=  不等于

= = =  全等

!= =  不全等

这4种运算符都是双目运算符,得到的结果是1位的逻辑值。如果得到1,说明声明的关系为真;如得到0,说明声明的关系为假。

相等运算符(= =)和全等运算符(= = =)的区别是参与比较的两个操作数必须逐位相等,其相等比较的结果才为l,如果某些位是不定态或高阻值,其相等比较得到的结果就会是不定值。而全等比较(= = =)是对这些不定态或高阻值的位也进行比较,两个操作数必须完全一致,其结果才为1。否则结果是0。

如:设寄存器变量a=5'b110x01,b=5'11x01,则“a= = b”得到的结果为不定值x,而“a= = =b”得到的结果为l。

6. 缩减运算符(单目运算)

& 与

~ & 与非

| 或

~ | 或非

^ 异或

^ ~ ,~ ^ 同或

缩减运算符与位运算符的逻辑运算法则一样,但缩减运算是对单个操作数进行与、或、非递推运算的。如:

reg[3:0] a;

b=&a; //等效于b=((a[0]&a[1])&a[2])&a[3];  

例:若A=5'b11001,则:

&A=0; //只有A的各位都为1时,其与缩减运算的值才为l。

|A=l; //只有A的各位都为0时,其或缩减运算的值才为0。

7. 移位运算符

>> 右移

<< 左移

移位运算符用法:

A >> n或 A<< n

表示把操作数A右移或左移n位,并用0填补移出位。

8. 条件运算符(三目运算符)

?:

格式: 信号 = 条件 ? 表达式1:表达式2;

当条件成立时,信号取表达式1的值,反之取表达式2的值.

9.位拼接运算符

{ }                  //将两个或多个信号的某些位拼接起来。

用法:

{信号1的某几位,信号2的某几位,……,信号n的某几位}

例如,在进行加法运算时,可将输出与和拼接在一起使用。

output[3:0] sum;                 //sum代表和

output cout;                     //cout为进位输出

input[3:0] ina,inb;

input cin;

assign {cout,sum}=ina+inb+cin;  //进位与和拼接在一起

位拼接可以嵌套使用,还可以用重复法来减化书写,如:

{3{a,b}}等同于{{a,b},{a,b},{a,b}},也等同于{a,b,a,b,a,b}。

6.3.2. 运算符的优先级

以上运算符的优先级如下:

!,~ 高优先级

*,/,%

+,-

<< , >>

< , < = , > , > =

= = , != , = = = , != =

& ,  ~&

^  ,  ^ ~

| , ~ |

&&

||

? :  低优先级

6.4 语句

Verilog HDL支持许多语句,从而成为结构化和过程性的语言。Verilog HDL的语句包括:赋值语句、条件语句、循环语句、结构说明语句和编译预处理语句等。每一类又包括几种不同的语句,具体如表6.3所示。

表6.3 Verilog HDL语句

赋值语句

连续赋值语句

过程赋值语句

条件语句

if-else语句

case语句

循环语句

forever语句

repeat语句

while语句

for语句

结构说明语句

initial语句

always语句

function语句

编译预处理语句

'define语句

'include 语句

'timescale语句

6.4.1 赋 值 语 句

1. 连续赋值语句 assign

assign为连续赋值语句,它用来对wire型变量进行赋值。

格式:

assign 变量 = 表达式;

如:  assign c = a & b;

在上面的赋值中,a和b信号的任何变化,都将随时反映到c上来,因此称为连续赋值方式。

2. 过程赋值语句

过程赋值语句用于对寄存器类型(reg)的变量进行赋值。过程赋值有以下两种方式。

(1)非阻塞(non_blocking)赋值方式

赋值号为 <= ,如 b<=a;

 非阻塞赋值在块结束时才完成赋值操作,即b的值并不是立刻就改变的。

(2)阻塞(blocking)赋值方式

赋值号为 = ,如 b=a;

阻塞赋值在该语句结束时就完成赋值操作,即b的值在该赋值语句结束后立刻改变。如果在一个块语句中,有多条阻塞赋值语句,那么在前面的赋值语句没有完成之前,后面的语句就不能执行,就像被阻塞(blocking)一样,因此称为阻塞赋值方式

(3)阻塞赋值方式和非阻塞赋值方式的区别

阻塞赋值方式和非阻塞赋值方式的区别常给设计人员带来问题。问题主要是对“always”模块内的reg型变量得赋值不易把握。为区分阻塞赋值与非阻塞赋值的不同,可看下面两例。

【例6.4】非阻塞赋值               【例6.5】阻塞赋值

module non_block(c,b,a,clk);       module block(c,b,a,clk);

output c,b;                        output c,b;

input clk,a;                      input clk,a;

reg c,b;                           reg c,b;

always @ (posedge clk)             always @ (posedge clk)

  begin                              begin

    b<=a;                              b=a;

    c<=b;                              c=b;

  end                                end

endmodule                          endmodule

将上面两段代码用MAX+PLUSⅡ进行综合,并进行仿真,可看到二者的区别:

对于非阻塞赋值,c的值落后b的值一个时钟周期,这是因为该“always”块每一个时钟周期执行一次,因此信号的值每一个时钟周期更新一次,c的值是上一时钟周期的b值。

对于阻塞赋值,c的值和b的值一样,这是因为b的值是立即更新的。

为避免对这两种赋值语句的应用错误,建议在初学时刻只是用一种,比如采用阻塞赋值“=”,因为它类似C语言的赋值方式。为避免出错,在同一块内,不要将输出重新作为输入使用。而为实现上述非阻塞赋值功能,可采用两个“always”块来实现,代码如下:

module non_block(c,b,a,clk);  

output c,b;

input clk,a;

reg c,b;

 always @ (posedge clk)

  begin

     b=a;

  end  

always @ (posedge clk)

  begin

    c=b;

  end

endmodule  

6.4.2 条件语句

条件语句是顺序语句,应放在“always”块内。

1. if-else语句

使用方法有以下3种

 if(表达式) 语句;

  if(表达式1) 语句1;

else 语句2;

③  if(表达式1) 语句1;

else if(表达式2) 语句2;

else if(表达式3) 语句3;

……

else if(表达式n) 语句n;

else 语句n+1;

这三种方式中,“表达式”一般为逻辑表达式或关系表达式,也可能是一位变量。若

表达式的值为0,x,z,视为“假”;若为1,视为“真”。语句可以是单句,也可以是多句,多句时用“begin-end”括起来。

2. case语句

多用于多条件译码电路,如描述译码器、数据选择器、状态机及微处理器的指令译

码等。

⑴. case语句

格式:

case (敏感表达式)

值1:语句1;

值2:语句2;

……

值n:语句n;

default: 语句n+1;

endcase

⑵. casez和casex语句

case 语句中,敏感表达式与值1~值n之间的比较是一种全等比较,必须保证两者的

对应位全等。 casez与 casex语 句是case语句的两种变体,三者的表示形式中唯一的区别是3个关键词case,casez,casex的不同。在casez语句中,如果分支表达式某些位的值为高阻z,那么对这些位的比较就不予考虑,因此,只需关注其他位的比较结果。而在casex语句中,则把这种处理方式进一步扩展到对x的处理,即如果比较的双方有一方的某些位的值是x或z,那么这些位的比较就不予考虑。

此外,还有另外一种标识x或z的方式,即用表示无关值的“?”来表示。

6.4.3 循环语句

Verilog HDL中存在4种类型的循环语句,用来控制语句的执行次数。这4种语句分别为:

  • foreve 连续地执行语句,多用在"initial"块中,以生成周期性输入波形。
  • repeat 连续执行一条语句n次。
  • while 执行一条语句,直到循环条件不满足。
  • for 语句

由于MAX+PLUS 软件不支持repeat语句。forever语句一般用在initial语句块中,而MAX+PLUS 软件不支持initial语句块,因此这里只介绍for和while两种语句。

1.for语句

格式:

for(表达式1;表达式2;表达式3)语句;

即:for (循环变量初值;循环结束条件;循环变量增值) 执行语句;

2.while语句

格式:

while(循环执行条件表达式) 语句;

while语句执行时,首先判断循环执行表达式是否为真,若为真,执行循环体中语句,

然后,再判断循环执行条件表达式是否为真,……,直至条件表达式不为真为止。循环体中语句可以是单句,也可以是多句,多句时用“begin-end”括起来。

6.4.4 结构说明语句

Verilog HDL中的任何过程模块都从属于以下4种结构说明语句:

◇initial

◇always

◇task

◇function

inital说明语句一般用于仿真中的初始化,仅执行一次;always块内的语句则是不断重复执行的;task和function语句可以在程序模块中的一处或多处调用。

由于MAX+PLUS 软件不支持task,initial语句, 因此这里只介绍always和function两种结构说明语句

1.always块语句

always块语句模板如下:

always@(<敏感信号表达式>)

begin

//过程赋值

//if语句

//case语句

//while,repeat,for循环

//task,function调用

end

在一个模块(module)中,使用always语句的次数是不受限制的。always块内的语句

是不断重复执行的。

说明:

⑴敏感信号表达式

敏感信号表达式又称事件表达式或敏感表,当该表达式的值改变时,就会执行一遍块内语句。因此在敏感信号表达式中应列出影响块内取值的所有信号(一般为所有输入信号)。若有两个或两个以上信号时,它们之间用"or"连接。

    例如,下面用case语句描述的4选1数据选择器,只要输入信号in0,inl,in2,in3或选择信号sel[1:0]改变则输出改变,所以敏感信号表达式写为:

in0 or in1 or in2 or in3 or sel   

【例6.6】用case语句描述的4选1数据选择器

module mux4_1(out,in0,in1,in2,in3,sel);

output out;

input in0,in1,in2,in3;

input[1:0] sel;

reg out;

always @ (in0 or in1 or in2 or in3 or sel)

case(sel)

2’b00: out=in0;

2’b01: out=in1;

2’b10: out=in2;

2’b11: out=in3;

default: out=2’bx;

endcase

endmodule

 posedgenegedge关键字

对于时序电路,事件是由时钟边沿触发的。为表达边沿这个概念,Verilog HDL提供

了posedge和negedge两个关键字来描述。比如在例6.2的8位计数器中有块语句:

always @ (posedge  clk)          //上升沿时刻计数

posedge clk表示时钟信号clk的上升沿,negedge clk表示时钟信号clk的下降沿。

2. 函数 function

函数的目的是返回一个用于表达式的值。函数的定义格式为:

function <返回值位宽或类型说明> 函数名;

端口声明;

局部变量定义;

其他语句;

endfunction

【例6.7】函数举例

function[7:0] gefun;

input[7:0] x;

reg[7:0] count;

integer i;

begin

count=0;

for(i=0;i<=7;i=i+1)

if(x[i]=1’b0) count=count+1;

gefun=count;

end

endfunction

上面的gefun函数循环核对输人的每一位,计算出0的个数,并返回一个适当的值。

<返回值位宽或类型说明>是一个可选项,如果缺省,则返回值为一位关于寄存器类型的数据。

函数的定义中蕴含了一个与函数同名的、函数内部的寄存器。在函数定义时,将函数返回值所使用的寄存器设为与函数同名的内部变量,因此函数名被赋予的值就是函数的返回值。例如在上例中,gefun最终赋予的值即为函数的返回值。

函数的调用是通过将函数作为表达式中的操作数来实现的。调用格式如下:

<函数名>,(<表达式> <表达式>);

比如使用连续赋值语句调用函数gefun时,可以采用如下语句:

assign out=is_legal ? gefun(in) : 1'b0;

注意,在函数中不能包含有任何的时间控制语句,并且定义函数时至少要有一个输人

参量。

6.5 语句的顺序执行和并行执行

    用Verilog HDL模块来设计电路,首先应该清楚哪些操作是同时发生的,哪些是顺序发生的。在“always”模块内,逻辑是按照指定的顺序执行的,"always"块内的语句称为顺序语句因为这些语句完全按照书写的顺序来执行。"always"模块之间,是同时执行的,或者说是并行执行的。两个或更多个"always"模块、“assign”语句、实例元件等都是同时执行的。通过下面的例子,可以清楚地看到"always"模块内的语句是顺序执行的,而always"模块之间是并行执行的。

   【例6.8】顺序执行模块1    【例6.9】顺序执行模块2

module serial(q,a,clk)                     module seria2(q,a,clk)

output q,a;                               output q,a;

input cIk;                                input cIk;

reg q,a;                                   reg q,a;

always @ (posedge clk);                     always @ (posedge clk);     begin                                       begin

      q= ~ q;                                     a= ~ q;  

a= ~ q;                                     q= ~ q;

end                                         end

endmodule                                   endmodule

    上面的两个例子,其区别只是在"always"模块内,把两个赋值语句的顺序相互颠倒。

分别对上面的两个模块用MAX+PLUSII软件进行模拟仿真,从得到的波形可以看到:在模块1中q先取反,然后再取反给a,a和q的波形是相反的;在模块2中,q取反后赋值给q和a,a和q的波形是相同的。如果将上述两句赋值语句分别放在两个"always"模块中,如下面例6.8和例6.9两个程序所示,经过仿真可以发现:这两个"always" 模块放置的顺序对结果并没有影响,因为这两个模块是并行执行的。

【例6.10】并行模块1                      【例6.11】并行模块2

moduleparal(q,a,clk);                moduleparal2(q,a,clk);

output q,a;                          output q,a;

lnput cIk;                           lnput cIk;

reg q,a;                              reg q,a;

always @ (posedge clk)                 always @ (posedge clk)

begin                                  begin

        q= ~ q;                                a= ~ q;  

end                                    end

always @ (posedge clk)                 always @ (posedge clk)

begin                                  begin

        a= ~ q;                                q= ~ q;

end                                    end

endmodule                              endmodule

例6.10和例6.11的仿真波形与例6.9的仿真波形是完全相同的。

6.6  小结

本章介绍Verilog HDL的语法结构,包括变量、语句、模块和不同抽象级别的电路的

设计和描述。

    需要注意的是,所有的Verilog HDL编译软件都只支恃该语言的某一个子集。所以,在使用Verilog HDL 进行编译时,必须弄清楚所用编译软件的功能,用编译软件支持的语句来描述所设计的系统。

七.参考资料

《数字系统设计与Verilog HDL》电子工业出版社 王金明等编著。

《CPLD逻辑电路设计与实习》 捷太出版社     萧如宣 著

以上就是本期的内容,我们下一次见! 

 分享一张壁纸:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1174926.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何用 GPT-4 全模式(All Tools)帮你高效学习和工作?

「十项全能」的 ChatGPT &#xff0c;用起来感受如何&#xff1f; 之前&#xff0c;作为 ChatGPT Plus 用户&#xff0c;如果你集齐下面这五个模式&#xff0c;就会成为别人羡慕的对象。 但现在&#xff0c;人们更加期盼的&#xff0c;是下面这个提示的出现&#xff1a; 这个提…

Python---字符串中的count()方法

count()方法 主要功能&#xff1a;求子串在字符串中出现的次数 count 英 /kaʊnt/ v. &#xff08;按顺序&#xff09;数数&#xff1b;计数&#xff0c;点数目&#xff1b;把……算入&#xff0c;包括&#xff1b;重要&#xff1b;被允许&#xff0c;被接受&#xff1b;…

项目实战:新增@RequestMapping和@GetMapping和@PostMapping三个注解

1、RequestMapping package com.csdn.mymvc.annotation; import java.lang.annotation.*; Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Inherited public interface RequestMapping {String value(); }2、PostMapping package com.csdn.mymvc.annotation; im…

Java自学第5课:Java web开发环境概述,更换Eclipse版本

1 Java web开发环境 前面我们讲了java基本开发环境&#xff0c;但最终还是要转到web来的&#xff0c;先看下怎么搭建开发环境。 这个图就是大概讲了下开发和应用环境&#xff0c;其实很简单&#xff0c;对于一台裸机&#xff0c;win7 系统的&#xff0c;首先第1步&#xff0c;…

Makefile初识

目录 0.前期准备0.1、程序编译链接&#xff1a; 1.Makefile基础1.1、认识Makefile1.2、Makefile定义模式&#xff1a;(1) 定义模式&#xff1a;(2) 执行Makefile&#xff1a; 1.3、Makefile的变量(1) 变量定义&#xff1a;(2) **变量的赋值符**:(3) 自动化变量 1.4 伪目标1.5 文…

【C++】特殊类设计+类型转换+IO流

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;命运给你一个低的起点&#xff0c;是想看你精彩的翻盘&#xff0c;而不是让你自甘堕落&#xff0c;脚下的路虽然难走&#xff0c;但我还能走&#xff0c;比起向阳而生&#xff0c;我更想尝试逆风…

【QT5之QFtp模块】编译及使用

下载 传送门&#xff1a;https://github.com/qt/qtftp 或者 git clone https://github.com/qt/qtftp.git 下载ZIP&#xff0c;解压待用。 编辑 使用QtCreator打开qtftp.pro; 修改如下&#xff1a; qtftp.pro中&#xff0c;将第21行注释; src/qftp.pro中&#xff0c;将第4行…

JavaEE-博客系统3(功能设计)

本部分内容为&#xff1a;实现登录功能&#xff1b;强制要求用户登录&#xff1b;实现显示用户信息&#xff1b;退出登录&#xff1b;发布博客 该部分的后端代码如下&#xff1a; Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws Ser…

微服务之初始微服务

文章目录 一、服务架构演变1.单体架构2.分布式架构 二、认识微服务三、总结四、微服务技术对比五、SpringCloud注意 一、服务架构演变 1.单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署。 优点&#xff1a; 架构简单部署成本…

【强化学习】17 ——DDPG(Deep Deterministic Policy Gradient)

文章目录 前言DDPG特点 随机策略与确定性策略DDPG&#xff1a;深度确定性策略梯度伪代码代码实践 前言 之前的章节介绍了基于策略梯度的算法 REINFORCE、Actor-Critic 以及两个改进算法——TRPO 和 PPO。这类算法有一个共同的特点&#xff1a;它们都是在线策略算法&#xff0c…

C++ map 的使用

下面的是关于 map 的介绍。来自 map - C Reference (cplusplus.com) 的翻译&#xff0c;您可以看也可以不看哈&#xff01; map 是关联容器&#xff0c;它按照特定的次序(按照 key 来比较)存储由键值 key 和值 value组合而成的元素。在 map 中&#xff0c;键值 key 通常用于排序…

使用腾讯云轻量服务器安装AList

新人有免费两个月试用轻量服务器&#xff0c;使用云服务器商自带的webshell登录&#xff1b; 我这儿用docker安装Alist&#xff0c;因为服务器没自带docker&#xff0c;所以具体安装docker centos7.0最快速安装docker的方法 通过 Docker 部署 Alist 命令&#xff1a; docke…

多元共进|2023 Google 开发者大会现场全回顾

多元共进&#xff5c;2023 Google 开发者大会现场全回顾 作为 Google I/O Connect 环球之旅的收官之站 五湖四海的开发者在此相聚 共度无数个精彩瞬间 两天时光&#xff0c;现场有哪些闪耀时刻&#xff1f; 快来一起盘点&#xff01; 持续关注大会官网 回看更多大会精彩…

JavaScript_Date对象_实例方法_set类

设置一年后的今天&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Document</…

win10 + cmake3.17 + vs2017编译osgearth2.7.0遇到的坑

坑1&#xff1a;debug模式下生成osgEarthAnnotation时 错误&#xff1a;xmemory0(881): error C2440: “初始化”: 无法从“std::pair<const _Kty,_Ty>”转换为 to _Objty 出错位置&#xff1a;src/osgEarthFeatures/FeatureSourceIndexNode.cpp 解决办法&#xff1a; …

S4.2.4.7 Start of Data Stream Ordered Set (SDS)

一 本章节主讲知识点 1.1 xxx 1.2 sss 1.3 ddd 二 本章节原文翻译 2.1 SDS 数据流开始有序集 SDS 代表传输的数据类型从有序集转为数据流。它会在 Configuration.Idle&#xff0c;Recovery.Idle 和 Tx 的 L0s.FTS 状态发送。Loopback 模式下&#xff0c;主机允许发送 SDS。…

【项目源码】反编译Java字节码生成源码

【项目源码】反编译Java字节码生成源码 文章目录 【项目源码】反编译Java字节码生成源码参考资料一、什么是反编译&#xff1f;二、反编译Java字节码文件1. &#xff08;不一定有效&#xff09; 使用IDEA提供的插件 - Java Bytecode Decomplier2. &#xff08;推荐&#xff09;…

网络性能瓶颈分析,让我来说给你听!

在性能测试中&#xff0c;谈到网络问题&#xff0c;其实&#xff0c;在没有特别说明的情况下&#xff0c;我们一般讲的都是 HTTP 协议下的网络瓶颈问题&#xff0c;那&#xff0c;对于这个问题&#xff0c;我们如何来分析呢&#xff1f;计算机中的网络&#xff0c;跟我们现实生…

ESP32S3入手体验测试

ESP32S3入手体验测试 &#x1f516;所入手的型号是YD-ESP32-S3 N16R8,该款和乐鑫官方推出的ESP32-S3-DevKitC-1配置差不多。 &#x1f388;乐鑫官方介绍&#xff1a;ESP32-S3-DevKitC-1 v1.1 &#x1f530;两者采用的模组&#xff1a;ESP32-S3-WROOM-1 和ESP32-S3-WROOM-1U模组…

再见了,提示~ 谷歌发布自适应提示方法,从此告别提示工程!

夕小瑶科技说 原创 作者 | 谢年年、ZenMoore 大模型虽好&#xff0c;但却存在着一个恼人的问题&#xff1a;大模型回答得好不好&#xff0c;取决于我们问题问得怎么样。一个好的、详细的问题往往可以产生惊人的效果... 所以... ChatGPT 问世之后&#xff0c;最火的书可能不是…