Verilog HDL语言总结(全)

目录

1 、Verilog HDL基本结构

2 、数据类型

(1)寄存器型

(2)线型

(3)符号常量

(4)寄存器数组

3 、 运算符

(1)算术运算符

(2)逻辑运算符

 (3)按位运算符

(4)关系运算符

(5)等式运算符

(6)移位运算符

(7)条件运算符

(8)拼位运算符

 4 、语句

(1)赋值语句

 (2)结构说明语句(always+initial)

(3)if语句 

 (4)case语句

 (5)循环语句(repeat+forever+while+for)


1 、Verilog HDL基本结构

1. Verilog HDL程序是由模块构成的。每个模块嵌套在module和endmodule声明语句中。

2 每个Verilog HDL源文件中只有一个顶层模块,其他为子模块。可以每个模块写一个文件。

3.每个模块要进行端口定义,并说明输入输出端口,然后对模块的功能进行行为逻辑描述。

4.模块中的时序逻辑部分在always块的内部,在always块中只能对寄存器变量赋值。

5.模块中对端口或其他wire型变量的赋值,必须在always块的外部使用assign语句,通常是将寄存器的值送出

6.程序书写格式自由,一行可以写几个语句,一个语句也可以分多行写。

7. 除了endmodule语句、begin_end语句和fork_join语句外,每个语句和数据定义的最后都要加分号

8.可用/*.....*/和//...对程序的任何部分作注释。加上必要的注释,可以增强程序的可读性

2 、数据类型

首先对数的表示方式进行讲解,Verilog只能表示二进制的逻辑值,可以为0,1,高阻,未知

如下图所示, 数在Verilog里面有3种表示

Verilog的数据类型分为 寄存器型(reg) 线型(wire) 符号常量(parameter) 寄存器数组

(1)寄存器型

之所以reg叫做寄存器型,是因为数字电路中的触发器只在时钟有效边沿到来的时候,保存的值才能够发生改变。

reg型信号的定义格式如下:
定义一个n位的寄存器变量 : reg [n-1:0]变量名;
定义m个n位的寄存器变量 : reg [n-1:0]变量名1,变量名2,....变量名m;

下面给出2个例子:
reg [7:0] a, b, c;    //a, b, c都是位宽为8位的寄存器
reg d;   //1位的寄存器d
 

(2)线型

wire型信号的定义格式如下:

定义一个n位的wire变量 : wire [n-1:0]变量名;

定义m个n位的wire变量 : wire [n-1:0]变量名1,变量名2,.变量名m;

下面给出2个例子:

wire [7:0] a, b, c;   // a, b, c都是位宽为8位的wire

wire d;    //d是1位的wire

(3)符号常量

如果用关键词parameter来定义一个标识符,代表一个常量,这个常量就被称为符号常量。

例如: parameter width=3;//符号常量width的值是3,如果未进行重定义,当在程序中出现width时就用3代替。

同样的,可以一次性定义多个符号常量,parameter idle=1,one=2,two=3,stop=4;//定义了4个符号常量。如果未进行重定义,当代码中出现idle就用1代替,出现one就用2代替,出现tow就用3代替,出现stop就用4代替。

但是符号常量可以被重定义,使用#即可

如下图,一开始time_delay=5  time_count=10,重定义之后time_delay=4  time_count=8

 

(4)寄存器数组

存储器实际上是一个寄存器数组。

存储器使用如下方式定义reg [ msb: lsb] memory1 [ upper: lower] 

(upper:lower)代表寄存器个数,(msb是最高有效位,lsb是最低有效位)代表每个寄存器的位数 

例如:

reg[3:0] mymem1[63:0];       //mymem1为64个4位寄存器的数组。

reg dog [1:5];         //dog为5个1位寄存器的数组。

dog[4]= 1;            //合法赋值语句,对其中一个1位寄存器赋值。

dog[1:51]= 0;      //合法赋值语句,对存储器大范围赋值。

3 、 运算符

(1)算术运算符

算术运算符说明
+
-
*
/
%取模(余数)

在进行整数的除法运算时,结果要略去小数部分,只取整数部分;

进行取模运算时( %) 结果的符号位采用模运算符中第一个操作数的符号。例如,-10%3结果-1,11%-3 结果为2。

在进行算术运算时,如果某一个操作数有不确定的值x,则整个结果也为不确定值x。

(2)逻辑运算符

逻辑运算符说明
&&逻辑与
||逻辑或
逻辑非

逻辑运算最常用于条件判断语句。逻辑运算只区分真假,而不管是什么数值。逻辑运算的输入4'ha1和4'h01是没有区别的,都是逻辑真,而0为逻辑假。一般来说,逻辑运算的结果要么为真(1)要么为假(0)

特例是如果有一个输入为未知X,那么结果也是X。

例如,4'ha1&&4h01是1,4'ha1&&4h00是0。

■对于逻辑与或:只有两个输入都是0的时候,逻辑或的结果才是0。
■对于逻辑非:当输入为非0值,输出就是0。

 (3)按位运算符

按位运算符说明
&按位与
|按位或
~按位取反
^按位异或
~^   ^~按位同或

按位运算符是对照数据的每一位进行运算, 例如0101&1100=0100,0101|1100=1101

ps:异或是指如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

同或是指如果a、b两个值不相同,则同或结果为0。如果a、b两个值相同,同或结果为1。

(4)关系运算符

关系运算符说明
<小于
<=小于等于
>大于
>=大于等于

关系运算符和逻辑运算符一般用于条件判断语句。

关系运算结果为1位的逻辑值1(真)或0(假),但也可能是x(未知)。关系运算符根据关系运算的结果是真还是假,用于条件判断。

关系运算时,若关系为真,则返回值为1;若声明的关系为假,则返回值为0;若某操作数为不定值x,则返回值也一定为x。

(5)等式运算符

等式运算符说明
==等于
!=不等于
===全等于
!==全不等于

"=="和"!="称作逻辑等式运算符,其结果由两个操作数的值决定。由于操作数可能是x或z,其结果可能为x。

"==="和"!=="常用于case表达式的判别,又称作case等式运算符。其结果只能为0和1。如果操作数中存在x和z,那么操作数必须完全相同结果才为1,否则为0。

注意"=="和"="是完全不同的,"="是对寄存器赋值使用的。

(6)移位运算符

移位运算符说明
<<左移
>>右移

a>>n中a代表要进行向右移位的操作数,n代表要移几位。a<<n表示将a逻辑左移n位。

这两种移位运算都用0来填补移出的空位。

例如a是一个5位的寄存器,那么a=4'b1001<<1,a的结果就是5'b10010。但是当a是一个4位的寄存器,那么a=4'b1001<<1,a的结果就是4'b0010。

(7)条件运算符

用法: assign wire类型变量=条件?表达式1:表达式2;

如果满足条件,变量=表达式1,否则,变量=表达式2

(8)拼位运算符

使用拼接运算符可以将变量任意组合后输出或送给另一个变量。

用法:{信号1的某几位,信号2的某几位,......信号n的某几位}

{m,-a,b[3:0],w,3'b101}等同于{a,b[3],b[2],b[1],b[0],w,1b'[1],1'b[0],1'b[1]}

{4{w}}等同于{w,w,w,w}

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

 4 、语句

(1)赋值语句

 (2)结构说明语句(always+initial)

 

 ps:

 

(3)if语句 

 

 

 (4)case语句

 

 

 (5)循环语句(repeat+forever+while+for)

 

 

 

 

 

 

 

  • 35
    点赞
  • 277
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Verilog HDL是一种用于描述数字电路的硬件描述语言,可以用来编写FM产生器。以下是一个基本的FM产生器示例: ``` module FM_generator (clk, reset, mod_signal, carrier, output); input clk, reset; input mod_signal; input carrier; output output; reg mod_accum; reg carrier_accum; // 更新累加器的值 always @ (posedge clk or posedge reset) begin if (reset) begin mod_accum <= 0; carrier_accum <= 0; end else begin mod_accum <= mod_accum + mod_signal; carrier_accum <= carrier_accum + carrier; end end // 计算FM信号 assign output = cos(mod_accum + carrier_accum); endmodule ``` 在这个示例中,`clk` 和 `reset` 是控制累加器更新的输入信号,`mod_signal` 和 `carrier` 是控制FM信号频率的输入信号,`output` 是计算出的FM信号。 需要注意的是,这仅是一个简单的示例,在实际的应用中可能需要根据具体需求进行更多的调整和优化。 ### 回答2: 编写一个FM(调频)产生器,可以使用Verilog HDL(硬件描述语言)编程语言来实现。FM产生器通过改变信号频率的方式来产生声音。 首先,我们需要定义所需的输入和输出接口。输入接口通常是一个用于控制频率的信号,输出接口是所产生的音频信号。 接下来,我们需要实现一个模块,该模块将接收输入频率信号,并根据该信号改变输出信号的频率。这可以通过改变输出信号的每个周期内的频率来实现。可以使用一个正弦波发生器作为基本音频产生器,并且通过改变每个周期内的时间步长来改变频率。时间步长越小,频率就越高,时间步长越大,频率就越低。我们可以使用一个计数器来计算和控制时间步长。 在模块中,我们可以定义一个计数器,根据输入的频率信号来控制时间步长,并计算要在该时间步长内产生的周期数。以每个周期的时间步长为基础,我们可以计算出每个周期内的角度改变量,并通过正弦波表来产生音频信号。通过不断增加角度改变量,我们可以生成连续的音频信号。 最后,我们需要将产生的音频信号连接到输出接口,以便将其传输到音频输出设备。这可以通过将音频信号赋值给输出接口的变量来实现。 总结起来,使用Verilog HDL语言编写FM产生器需要定义输入和输出接口,实现一个模块来接收和处理频率信号,以及一个计数器来控制时间步长,产生连续的音频信号,并将其连接到输出接口。通过调整时间步长可以改变频率,从而产生不同的声音。 ### 回答3: 编写一个FM(频率调制)产生器时,可以使用Verilog HDL(硬件描述语言)来描述其行为和功能。 首先,需要定义输入和输出端口,以及任何其他所需的模块或信号。对于FM产生器,通常有一个包括频率控制信号的输入端口和一个产生调制信号的输出端口。 然后,可以定义一个计数器来计算每个时钟周期的相位。这个计数器可以根据输入的频率控制信号来增加或减少。例如,可以使用一个加法器来将频率控制信号加到计数器的当前值上。 接下来,可以使用计数器的当前值来计算调制信号的幅度。这可以通过应用一个数学函数(例如正弦)来实现。频率控制信号的改变将导致计数器的值改变,因此调制信号的幅度也将相应地改变。 最后,可以使用输出端口来输出调制信号。根据实际需求,可能需要添加额外的模块或逻辑来对输出进行调整或处理。 通过将上述步骤组合在一起,就可以编写一个基本的FM产生器。这个FM产生器将根据输入的频率控制信号生成一个调制信号,并将其输出到指定的输出端口。 当然,这只是一个简单的例子。在实践中,FM产生器可能需要更多的功能和模块,如振荡器、相位调整器、滤波器等。 总结起来,使用Verilog HDL编写FM产生器需要定义输入和输出端口,计数器来计算相位,使用一个函数来计算调制信号的幅度,最后使用输出端口输出调制信号。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值