cpld的verilog学习

  • 格式:docx
  • 大小:65.71 KB
  • 文档页数:56

cpld的verilog学习 2011-01-06 17:17 2842人阅读 评论(0) 收藏 举报 integer存储语言编译器moduleinput

以前浪费了太多机会了。以后就用这些来记录下自己到底学会了什么。用到了什么。做出了什么。

verilog的整体结构 模块的结构 verilog的基本设计单元是“模块”(block)。包括(接口描述、逻辑功能描述) 例子: module block(a, b, c, d); input a, b; output c, d;

assign c = a | b; 【连续赋值:assign,问号表达式(?:)】 assign d = a & b; endmodule 由例子可以看出,verilog结构位于在module和endmodule声明语句之间,每个verilog程序包括4个主要部分:端口定义、I/O说明、内部信号声明和功能定义。

1、 模块的端口定义 模块端口声明了模块的输入输出。格式: module 模块名(口1,口2,口3,口4,…..); 模块的端口表示模块的输入还是输出名。 引用模块时其端口可以用两种方法连接: (1) 在引用时,严格按照定义的端口顺序连接,不用标明原模块定义时规定的端口

(2) 在引用时用”.”符号,标明原模块是定义时规定的端口名。 2、 模块内容 模块的内容包括I/O说明、内部信号声明和功能定义。 (1) I/O说明的格式 输入口:input [信号位宽-1 : 0] 端口名1; 输出口:output [信号位宽-1 : 0] 端口名1; 输入输出口:inout [信号位宽-1 : 0] 断口名1; (2) 内部信号说明 在模块内用到的与端口有关的wire和reg类型变量的声明。

Reg [width-1 : 0] R变量1,R变量2…; 【reg不和实际的电路如寄存器对应,高层次的描述时用】

Wire [width-1 : 0]W变量1,W变量2…;【与实际的物理连接对应】 (3) 功能定义 模块中最重要的部分时逻辑功能定义。由3种方法可以在模块中产生逻辑。 1) 用assign声明语句 如assign a = b&c; 2) 用实例元件 and #2 u1(q, a, b); 3) 用always块【变量必须声明为reg,还有initial。】 always @(posedge clk or posedge clr) begin if(clr) q <= 0; else if(en) q <= d; end 采用assign是描述组合逻辑最常用的方法之一。而always既可用来描述组合逻辑电路也可以用来描述时序逻辑。

(4) 要点 1) 在verilog模块中所有过程块(initial, always)、连续赋值语句、实例引用都是并行的;

2) 他们表示的是一种通过变量名互相连接的关系 3) 在同一模块中这三者出现的先后顺序没有关系。 只有联系赋值的语句assign和实例引用语句可以独立与过程块而存在于模块功能定义部分

程序例子 偶数分频器的verilog实现(先学习偶数,我用的单片机用到分频器)

偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。这种方法可以实现任意的偶数分频。

module odd_division(clk,rst,count,clk_odd); input clk,rst; output clk_odd; output[3:0] count; reg clk_odd; reg[3:0] count; parameter N = 6; 【常数】

always @ (posedge clk) 【always模块:(敏感表可以为电平、沿信号posedge/negedge;通常和@连用)】 if(! rst) 【任务定义:task„„endtask】 begin count <= 1'b0; 【 赋值符号:= 和 <= (阻塞和非阻塞赋值,在具体设计中时很有讲究的)】 clk_odd <= 1'b0; end else if ( count < N/2-1) begin count <= count + 1'b1; end else begin count <= 1'b0; clk_odd <= ~clk_odd; end endmodule 注:数据结构详解

整数、实数和时间寄存器类型 整数是一种通用的寄存器数据类型,用于对数量进行操作,使用integer进行声明。 integer counter; //一般用途的变量用作计数器 initial counter = -1; //把-1存储到寄存器中 实数:实常量和实数寄存器数据类型使用关键字real来声明,可以用十进制或科学计数法来表示。实数声明不能带有范围,其默认值为0.如果将一个实数赋予一个整数,那么实数将会被取为最接近的整数。 real delta; //定义一个名为delta的实型变量 时间寄存器:仿真是按照仿真时间进行的,verilog使用一个特殊的时间寄存器数据类型来保存仿真时间。时间变量通过使用关键字time来声明,其宽度与具体实现无关,最小为64位。通过调用系统函数$time可以取得当前的仿真时间。 2 数组 Verilog中允许声明reg、integer、time、real、realtime及其向量类型的数组,对数组的维数没有限制,即可声明任意维数的数组。线网数组也可用于连接实例的端口,数组中的每个元素都可以作为一个标量或者向量,以同样的方式来使用,形如[]。 Integer count[0:7]; //由八位计数变量组成的数组 reg bool [31:0]; //由32个1位的布尔寄存器变量组成的数组 wire [7:0] w_array2 [5:0]; //声明8位向量的数组

注意:不要把数组和线网或寄存器向量混淆起来。向量是一个单独的元件,它的位宽是n,数组由多个元件组成,其中每个元件的位宽为n或1. 3 存储器【重点】 Verilog中使用寄存器一维数组来表示存储器。数字的每个元素成为一个元素或一个字(word),由一个数组索引来指定。每个字的位宽为1位或者多位。注意n个1位寄存器和一个n位寄存器是不同的。如果需要访问存储器中的一个特定的字,则可通过子的地址作为数组的下标来完成。 reg mem1bit[0:1023]; //1k的1位存储器 reg [7:0] membyte [0:1023]; //1k的字节(8位)存储器membyte membyet[511] //取出membyte中地址511所处的字节 4 参数 Verilog使用关键字parameter在模块内定义常数。参数代表常数,不能像变量那样赋值,但是每个模块实例的参数值可以在编译阶段被重载。通过参数重载使得用户可以对模块实例进行定制。除此之外还可以对参数的类型和范围进行定义。 parameter port_id = 5; //定义常数port_id 为5

5 字符串 字符串保存在reg类型的变量中,每个字符占用8位(一个字节),因此寄存器变量的宽度应足够大,以保证容纳全部字符。如果寄存器变量的宽度大于字符串的大小,则verilog用0来填充左边的空余位。如果寄存器变来那个的宽度小于字符串的大小,则verilog截去字符串最左边的位。

Verilog HDL是一种硬件描述语言,用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模。被建模的数字系统对象的复杂性可以介于简单的门和完整的电子数字系统之间。数字系统能够按层次描述,并可在相同描述中显式地进行时序建模。 Verilog HDL 语言具有下述描述能力:设计的行为特性、设计的数据流特性、设计的结构组成以及包含响应监控和设计验证方面的时延和波形产生机制。所有这些都使用同一种建模语言。此外,Verilog HDL语言提供了编程语言接口,通过该接口可以在模拟、验证期间从设计外部访问设计,包括模拟的具体控制和运行。 Verilog HDL语言不仅定义了语法,而且对每个语法结构都定义了清晰的模拟、仿真语义。因此,用这种语言编写的模型能够使用Verilog仿真器进行验证。语言从C编程语言中继承了多种操作符和结构。Verilog HDL提供了扩展的建模能力,其中许多扩展最初很难理解。但是,Verilog HDL语言的核心子集非常易于学习和使用,这对大多数建模应用来说已经足够。当然,完整的硬件描述语言足以对从最复杂的芯片到完整的电子系统进行描述。 =============================== 中文版Verilog HDL简明教程:第1章 简介

Verilog HDL是一种硬件描述语言,用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模。被建模的数字系统对象的复杂性可以介于