Verilog语言基础知识_第1页
Verilog语言基础知识_第2页
Verilog语言基础知识_第3页
Verilog语言基础知识_第4页
Verilog语言基础知识_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

精品文档 1欢迎下载 VerilogVerilog HDLHDL 语言基础知识语言基础知识 先来看两个 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 endmodule 从上面的例子可以看出 Verilog HDL 程序是由模块构成的 每个模块的内容都是嵌在 module 和 endmodule 两个语句之间 每个模块实现特定的功能 模块是可以进行层次嵌套的 每个模块首先要进行端口定义 并说明输入 input 和输出 output 然后对模块 的功能进行逻辑描述 Verilog HDL 程序的书写格式自由 一行可以写几个语句 一个语句也可以分多行 写 除了 endmodule 语句外 每个语句的最后必须有分号 可以用 和 对 Verilog HDL 程序的任何部分作注释 精品文档 2欢迎下载 6 1 26 1 2 VerilogVerilog HDLHDL 模块的结构模块的结构 Verilog HDL 的基本设计单元是 模块 block 一个模块是由两部分组成的 一部 分描述接口 另一部分描述逻辑功能 即定义输入是如何影响输出的 下面举例说明 图 6 1 示出了一个 与 或 非 门电路 1 2 3 1 2 3 A B C D F 图 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 模块内的逻辑描述 endmodule 从上面的例子可知 电路图符号的引脚也就是程序模块的端口 在程序模块内描述 了电路图符号所实现的逻辑功能 在上面的 Verilog HDL 设计中 模块中的第 2 第 3 行 说明接口的信号流向 第 4 行说明了模块的逻辑功能 Verilog HDL 结构完全嵌在 module 和 endmodule 声明语句之间 每个 Verilog 程序 包括 4 个主要部分 端口定义 I 0 说明 信号类型声明和功能描述 1 1 模块的端口定义模块的端口定义 模块的端口声明了模块的输人和输出口 其格式如下 modulemodule 模块名模块名 口口 1 1 口 口 2 2 口 口 3 3 口 口 4 4 2 2 模块内容 模块内容 模块内容包括 I O 说明 信号类型声明和功能定义 1 1 I OI O 说明的格式如下说明的格式如下 输人口输人口 inputinput 端口名端口名 1 1 端口名 端口名 2 2 端口名端口名 N N 输出口输出口 outputoutput 端口名端口名 l l 端口名 端口名 2 2 端口名端口名 N N I O 说明也可以写在端口声明语句里 其格式如下 module module name input portl input port2 output portl output 精品文档 3欢迎下载 port2 2 2 信号类型声明信号类型声明 它是说明逻辑描述中所用信号的数据类型及函数声明 如 reg 7 0 out 定义 out 的数据类型为 reg 寄存器 型 对于端口信号的缺省定义类型为 wire 连线 型 6 1 36 1 3 逻辑功能定义逻辑功能定义 模块中最重要的部分是逻辑功能定义 有 3 种方法可在模块中描述逻辑 1 1 用用 assignassign 语句语句 如 assign F A 这种方法的句法很简单 只须写一个 assign 后面再加一个方程式即可 assign 语句一般适合于对组合逻辑进行赋值 称为连续赋值方式 2 用元件例化 用元件例化 instantiateinstantiate 如 and myand3 f a b c 这个语句利用 Verilog HDL 提供的与门库 定义了一个三输人的与门 采用实例元 件的方法同在电路图输入方式下调入库元件一样 键入元件的名字和引脚的名字即可 要求每个实例元件的名字必须是唯一的 3 3 用用 alwaysalways 块语句块语句 在 例 6 2 的计数器模块中 always posedge clk 每当时钟上升沿到来时执行一遍块内语句 begin if load out data else out out cin end always 块可用于产生各种逻辑 常用于描述时序逻辑 这个例子用 always 块生成 了一个带有同步置数的计数器 always 块可用很多种描述手段来表达逻辑 如此例中就 用了 if else 语句来表达逻辑关系 综上所述 可给出 Verilog HDL 模块的模板如下 VerilogVerilog HDLHDL 模块的模板模块的模板 仅考虑用于逻辑综合的部分 不考虑用于逻辑模拟的部分 modulemodule outputoutput 输出端口列表输出端口列表 输出端口声明输出端口声明 inputinput 输入端口列表输入端口列表 输入端口声明输入端口声明 定义数据 信号的类型 函数声明 用关键字 wire reg funtion 等定义 精品文档 4欢迎下载 使用使用 assignassign 语句定义逻辑功能语句定义逻辑功能 wirewire 结果信号名结果信号名 assignassign 使用使用 alwaysalways 块描述逻辑功能块描述逻辑功能 alwaysalways beginbegin 过程赋值过程赋值 ifif 语句 语句 casecase 语句语句 whilewhile for repeatfor repeat 循环语句循环语句 functionfunction 调用调用 endend 模块元件例化模块元件例化 instance name port list 门元件例化门元件例化 gate type keywordgate type keyword instance name endmoduleendmodule 6 26 2 数据类型及常量 变量数据类型及常量 变量 Verilog HDL 中共有 19 种数据类型 数据类型是用来表示数字电路中的数据存储和 传送单元的 在此介绍 4 个最基本的数据类型 integer 型 parameter 型 reg 型和 wire 型 Verilog HDL 中也有常量和变量之分 他们分属以上这些类型 6 2 16 2 1 常量常量 在程序运行过程中 其值不能被改变的量称为常量 1 1 数字数字 1 整数 在 Verilog HDL 中 整数型常量 即整常数 有以下 4 种进制表示形式 二进制整数 b 或 B 十进制整数 d 或 D 十六进制整数 h 或 H 八进制整数 o 或 O 完整的数字表达式为 位宽为对应二迸制数的宽度 如 8 b11000101 位宽为 8 位的二进制数 11000101 8 hc5 位宽为 8 位的十六进制数 c5 精品文档 5欢迎下载 十进制的数可以缺省位宽和进制说明 如 197 代表十进制数 197 2 x 和 z 值 x 表示不定值 z 表示高阻值 每个字符代表的宽度取决于所用的进制 例如 8 b1001xxxx 等价于 8 h9x 8 b1010zzzz 等价于 8 haz 当常量不说明位数时 默认值为 32 位 此外 是高阻态的 z 的另一种表示符号 2 2 常量 常量 在 Verilog HDL 中 用 parameter 来定义常量 即用 parameter 来定义一个标志符 代表一个常量 称为符号常量 其定义格式如下 parameterparameter 参数名参数名 1 1 表达式 参数名表达式 参数名 2 2 表达式 参数名表达式 参数名 3 3 表达式表达式 例如 parameter sel 8 code 8 ha3 分别定义参数 sel 为常数 8 十进制 参数 code 为常数 a3 十六进制 6 2 26 2 2 变量变量 变量是在程序运行过程中其值可以改变的量 变量分为两种 一种为网络型 nets type 另一种为寄存器型 register type 1 1 netsnets 型变量型变量 wirewire nets 型变量指输出始终根据输入的变化而更新其值的变量 它一般指的是硬件电路 中的各种物理连接 Verilog HDL 中提供了多种 nets 型变量 具体见表 6 1 表表 6 16 1 常用的常用的 netsnets 型变量及说明型变量及说明 类型功能说明 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 位的变量 精品文档 6欢迎下载 wirewire 数据名数据名 1 1 数据名 数据名 2 2 数据名数据名 n n 例如 wire a b 定义了两个宽度为 1 位 wire 型变量 a b 定义宽度位 n 位的向量 vectors wire n 1 0 wire n 1 0 数据名数据名 1 1 数据名 数据名 2 2 数据名数据名 n n 或 wire n 1 wire n 1 数据名数据名 1 1 数据名 数据名 2 2 数据名数据名 n 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 2 registerregister 型变量型变量 regreg register 型变量对应的是具有状态保持作用的电路元件 如触发器 寄存器等 register 型变量与 nets 变量的根本区别在于 register 需要被明确地赋值 并在被重 新赋值前一直保持原值 在设计中必须将寄存器型变量放在过程块语句 如 initial always 中 通过过程赋值语句赋值 另外 在 always 过程块内被赋值的每一 个信号都必须定义成寄存器型 Verilog HDL 中 有 4 种寄存器型变量 见表 6 2 表表 6 26 2 常用的常用的 registerregister 型变量及说明型变量及说明 类型功能说明 reg 常用的寄存器型变量 integer 32 位带符号整数型变量 real 64 位带符号整数型变量 time 无符号时间变量 Integer real time 等 3 种寄存器型变量都是纯数学的抽象描述 不对应任何具 体的硬件电路 reg 型变量是最常用的一种寄存器型变量 下面介绍 reg 型变量 reg 型变量格式如下 regreg 数据名数据名 1 1 数据名 数据名 2 2 数据名数据名 n n 精品文档 7欢迎下载 例如 reg a b 定义了两个宽度为 1 位的 reg 型变量 a b 若定义一个向量 则按以下格式 reg n l 0 reg n l 0 数据名数据名 1 1 数据名 数据名 2 2 数据名数据名 n n 或 reg n l reg n l 数据名数据名 1 1 数据名 数据名 2 2 数据名数据名 n n 它们定义了数据的宽度为 n 位 如下面的语句定义了 8 位宽的数据 例如 reg 7 0 data 定义 data 为 8 位宽的 reg 型向量 或 reg 8 1 data 3 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 36 3 运算符及表达式运算符及表达式 6 3 16 3 1 运算符运算符 1 1 算术运算符算术运算符 加 减 乘 除 求模 算术运算符都是双目运算符 2 2 逻辑运算符逻辑运算符 如果声明的关系是真 则 返回值是 1 如果某个操作数的值不定 则其结果是模糊的 返回值是不定值 5 5 等式运算符等式运算符 等于 不等于 全等 不全等 这 4 种运算符都是双目运算符 得到的结果是 1 位的逻辑值 如果得到 1 说明声 明的关系为真 如得到 0 说明声明的关系为假 相等运算符 和全等运算符 的区别是参与比较的两个操作数必须逐位相 等 其相等比较的结果才为 l 如果某些位是不定态或高阻值 其相等比较得到的结果就 会是不定值 而全等比较 是对这些不定态或高阻值的位也进行比较 两个操作数 必须完全一致 其结果才为 1 否则结果是 0 如 设寄存器变量 a 5 b110 x01 b 5 11x01 则 a b 得到的结果为不定值 x 而 a b 得到的结果为 l 6 6 缩减运算符缩减运算符 单目运算 等效于 b a 0 例 若 A 5 b11001 则 只有 A 的各位都为 0 时 其或缩减运算的值才为 0 7 7 移位运算符移位运算符 右移 n 或 A n 表示把操作数 A 右移或左移 n 位 并用 0 填补移出位 8 8 条件运算符 三目运算符 条件运算符 三目运算符 格式 信号信号 条件条件 表达式表达式 1 1 表达式 表达式 2 2 当条件成立时 信号取表达式 1 的值 反之取表达式 2 的值 9 9 位拼接运算符位拼接运算符 将两个或多个信号的某些位拼接起来 用法 信号信号 1 1 的某几位 信号的某几位 信号 2 2 的某几位 的某几位 信号信号 n 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 3 2 运算符的优先级运算符的优先级 以上运算符的优先级如下 高优先级 在上面的赋值中 a 和 b 信号的任何变化 都将随时反映到 c 上来 因此称为连续 赋值方式 2 2 过程赋值语句过程赋值语句 过程赋值语句用于对寄存器类型 reg 的变量进行赋值 过程赋值有以下两种方式 精品文档 11欢迎下载 1 1 非阻塞非阻塞 non blocking non blocking 赋值方式赋值方式 赋值号为赋值号为 如 b a 非阻塞赋值在块结束时才完成赋值操作 即 b 的值并不是立刻就改变的 2 2 阻塞阻塞 blocking blocking 赋值方式赋值方式 赋值号为赋值号为 如 b a 阻塞赋值在该语句结束时就完成赋值操作 即 b 的值在该赋值语句结束后立刻改变 如果在一个块语句中 有多条阻塞赋值语句 那么在前面的赋值语句没有完成之前 后 面的语句就不能执行 就像被阻塞 blocking 一样 因此称为阻塞赋值方式 3 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 精品文档 12欢迎下载 b a end always posedge clk begin c b end endmodule 6 4 26 4 2 条件语句条件语句 条件语句是顺序语句 应放在 always 块内 1 1 if elseif else 语句语句 使用方法有以下 3 种 if if 表达式表达式 语句 语句 if if 表达式表达式 1 1 语句语句 1 1 elseelse 语句语句 2 2 if if 表达式表达式 1 1 语句语句 1 1 elseelse if if 表达式表达式 2 2 语句语句 2 2 elseelse if if 表达式表达式 3 3 语句语句 3 3 elseelse if if 表达式表达式 n n 语句语句 n n elseelse 语句语句 n 1 n 1 这三种方式中 表达式 一般为逻辑表达式或关系表达式 也可能是一位变量 若 表达式的值为 0 x z 视为 假 若为 1 视为 真 语句可以是单句 也可以是多句 多句时用 begin end 括起来 2 2 casecase 语句语句 多用于多条件译码电路 如描述译码器 数据选择器 状态机及微处理器的指令译 码等 casecase 语句语句 格式 casecase 敏感表达式敏感表达式 值值 1 1 语句 语句 1 1 值值 2 2 语句 语句 2 2 值值 n n 语句 语句 n n default default 语句语句 n 1 n 1 endcaseendcase casezcasez 和和 casexcasex 语句语句 case 语句中 敏感表达式与值 1 值 n 之间的比较是一种全等比较 必须保证两者 精品文档 13欢迎下载 的 对应位全等 casez 与 casex 语 句是 case 语句的两种变体 三者的表示形式中唯一的 区别是 3 个关键词 case casez casex 的不同 在 casez 语句中 如果分支表达式某些位 的值为高阻 z 那么对这些位的比较就不予考虑 因此 只需关注其他位的比较结果 而 在 casex 语句中 则把这种处理方式进一步扩展到对 x 的处理 即如果比较的双方有一 方的某些位的值是 x 或 z 那么这些位的比较就不予考虑 此外 还有另外一种标识 x 或 z 的方式 即用表示无关值的 来表示 6 4 36 4 3 循环语句循环语句 Verilog HDL 中存在 4 种类型的循环语句 用来控制语句的执行次数 这 4 种语句 分别为 foreve 连续地执行语句 多用在 initial 块中 以生成周期性输入波形 repeat 连续执行一条语句 n 次 while 执行一条语句 直到循环条件不满足 for 语句 由于 MAX PLUS 软件不支持 repeat 语句 forever 语句一般用在 initial 语句块中 而 MAX PLUS 软件不支持 initial 语句块 因此这里只介绍 for 和 while 两种语句 1 1 forfor 语句语句 格式 for for 表达式表达式 1 1 表达式表达式 2 2 表达式表达式 3 3 语句 语句 即 forfor 循环变量初值 循环结束条件 循环变量增值 执行语句 2 2 whilewhile 语句语句 格式 while while 循环执行条件表达式循环执行条件表达式 语句 语句 while 语句执行时 首先判断循环执行表达式是否为真 若为真 执行循环体中语句 然后 再判断循环执行条件表达式是否为真 直至条件表达式不为真为止 循环 体中语句可以是单句 也可以是多句 多句时用 begin end 括起来 6 4 46 4 4 结构说明语句结构说明语句 Verilog HDL 中的任何过程模块都从属于以下 4 种结构说明语句 initial always task function inital 说明语句一般用于仿真中的初始化 仅执行一次 always 块内的语句则是不 精品文档 14欢迎下载 断重复执行的 task 和 function 语句可以在程序模块中的一处或多处调用 由于 MAX PLUS 软件不支持 task initial 语句 因此这里只介绍 always 和 function 两种结构说明语句 1 1 alwaysalways 块语句块语句 always 块语句模板如下 always always beginbegin 过程赋值过程赋值 if if 语句语句 case case 语句语句 while repeat for while repeat for 循环循环 task function task function 调用调用 endend 在一个模块 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 精品文档 15欢迎下载 endmodule posedgeposedge 与 negedgenegedge 关键字 对于时序电路 事件是由时钟边沿触发的 为表达边沿这个概念 Verilog HDL 提 供 了 posedge 和 negedge 两个关键字来描述 比如在例 6 2 的 8 位计数器中有块语句 always posedge clk 上升沿时刻计数 posedge clk 表示时钟信号 clk 的上升沿 negedge clk 表示时钟信号 clk 的下降沿 2 2 函数函数 functionfunction 函数的目的是返回一个用于表达式的值 函数的定义格式为 functionfunction 函数名 函数名 端口声明 端口声明 局部变量定义 局部变量定义 其他语句 其他语句 endfunctionendfunction 例 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 的个数 并返回一个适当的值 是一个可选项 如果缺省 则返回值为一位关于寄存器类 型的数据 函数的定义中蕴含了一个与函数同名的 函数内部的寄存器 在函数定义时 将函 数返回值所使用的寄存器设为与函数同名的内部变量 因此函数名被赋予的值就是函数 精品文档 16欢迎下载 的返回值 例如在上例中 gefun 最终赋予的值即为函数的返回值 函数的调用是通过将函数作为表达式中的操作数来实现的 调用格式如下 比如使用连续赋值语句调用函数 gefun 时 可以采用如下语句 assign out is legal gefun in 1 b0 注意 在函数中不能包含有任何的时间控制语句 并且定义函数时至少要有一个输人 参量 6 56 5 语句的顺序执行和并行执行语句的顺序执行和并行执行 用 Verilog HDL 模块来设计电路 首先应该清楚哪些操作是同时发生的 哪些是顺 序发生的 在 always 模块内 逻辑是按照指定的顺序执行的 always 块内的语句 称为顺序语句

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论