完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
数据类型
常量 整数:整数可以用二进制b或B,八进制o或O,十进制d或D,十六进制h或H表示,例如,8’b00001111表示8位位宽的二进制整数,4’ha表示4位位宽的十六进制整数。 X和Z:X代表不定值,z代表高阻值,例如,5’b00x11,第三位不定值,3’b00z表示最低位为高阻值。 下划线:在位数过长时可以用来分割位数,提高程序可读性,如8’b0000_1111 参数parameter:parameter可以用标识符定义常量,运用时只使用标识符即可,提高可读性及维护性,如定义parameterwidth=8;定义寄存器reg[width-1:0]a;即定义了8位宽度的寄存器。 参数的传递:在一个模块中如果有定义参数,在其他模块调用此模块时可以传递参数,并可以修改参数,如下所示,在module后用#()表示。 例如定义模块如下调用模块 modulerom #( parameterdepth=15, parameterwidth=8 ) ( input[depth-1:0]addr, input[width-1:0]data, outputresult ); endmodule moduletop(); wire[31:0]addr; wire[15:0]data; wireresult; rom #( .depth(32), .width(16) ) r1 ( .addr(addr), .data(data), .result(result) ); endmodule Parameter可以用于模块间的参数传递,而localparam仅用于本模块内使用,不能用于参数传递。Localparam多用于状态机状态的定义。 |
|
|
|
变量
变量是指程序运行时可以改变其值的量,下面主要介绍几个常用了变量类型 1.Wire 型 Wire 类型变量,也叫网络类型变量,用于结构实体之间的物理连接,如门与门之间,不能储存值,用连续赋值语句assign赋值,定义为wire [n-1:0] a ; 其中n代表位宽,如定义wire a ; assign a = b ; 是将b的结点连接到连线a上。如下图所示,两个实体之间的连线即是wire类型变量。 |
|
|
|
Reg 型
Reg 类型变量,也称为寄存器变量,可用来储存值,必须在always语句里使用。其定义为 reg [n-1:0] a ; 表示n位位宽的寄存器,如reg [7:0] a; 表示定义8位位宽的寄存器a。如下所示定义了寄存器q,生成的电路为时序逻辑,右图为其结构,为D触发器。 moduletop(d,clk,q); inputd; inputclk; outputregq; always@(posedgeclk) begin q《=d; end endmodule 也可以生成组合逻辑,如数据选择器,敏感信号没有时钟,定义了reg Mux,最终生成电路为组合逻辑。 moduletop(a,b,c,d,sel,Mux); inputa; inputb; inputc; inputd; input[1:0]sel; outputregMux; always@(seloraorborcord) begin case(sel) 2‘b00:Mux=a; 2’b01:Mux=b; 2‘b10:Mux=c; 2’b11:Mux=d; endcase end endmodule Memory型 可以用memory类型来定义RAM,ROM等存储器,其结构为reg [n-1:0] 存储器名[m-1:0],意义为m个n位宽度的寄存器。例如,reg [7:0] ram [255:0]表示定义了256个8位寄存器,256也即是存储器的深度,8为数据宽度。 |
|
|
|
运算符
运算符可分为以下几类: 算术运算符(+,-,*,/,%) 赋值运算符(=,《=) 关系运算符(》,《,》=,《=,==,!=) 逻辑运算符(&&,||,!) 条件运算符(?:) 位运算符(~,|,^,&,^~) 移位运算符(《《,》》) 拼接运算符({ }) 算术运算符 “+”(加法运算符),”-“(减法运算符),”*”(乘法运算符),”/”(除法运算符,如7/3 =2),“%”(取模运算符,也即求余数,如7%3=1,余数为1) |
|
|
|
赋值运算符
“=”阻塞赋值,”《=”非阻塞赋值。阻塞赋值为执行完一条赋值语句,再执行下一条,可理解为顺序执行,而且赋值是立即执行;非阻塞赋值可理解为并行执行,不考虑顺序,在always块语句执行完成后,才进行赋值。如下面的阻塞赋值: 代码如下:激励文件如下 moduletop(din,a,b,c,clk); inputdin; inputclk; outputrega,b,c; always@(posedgeclk) begin a=din; b=a; c=b; end endmodule `timescale1ns/1ns moduletop_tb(); regdin; regclk; wirea,b,c; initial begin din=0; clk=0; forever begin #({$random}%100) din=~din; end end always#10clk=~clk; topt0(.din(din),.a(a),.b(b),.c(c),.clk(clk)); endmodule 可以从仿真结果看到,在clk的上升沿,a的值等于din,并立即赋给b,b的值赋给c。 如果改为非阻塞赋值,仿真结果如下,在clk上升沿,a的值没有立即赋值给b,b为a原来的值,同样,c为b原来的值 可以从两者的RTL图看出明显不同: 阻塞赋值RTL图非阻塞赋值RTL图 一般情况下,在时序逻辑电路中使用非阻塞赋值,可避免仿真时出现竞争冒险现象;在组合逻辑中使用阻塞赋值,执行赋值语句后立即改变;在assign语句中必须用阻塞赋值。 |
|
|
|
关系运算符
用于表示两个操作数之间的关系,如a》b,a《b,多用于判断条件,例如: If (a》=b) q 《=1’b1 ; else q 《= 1’b0 ;表示如果a的值大于等于b的值,则q的值为1,否则q的值为0 逻辑运算符 “&&”(两个操作数逻辑与),”||”(两个操作数逻辑或),”!”(单个操作数逻辑非)例如: If (a》b && c 《d) 表示条件为a》b并且c《d; if (!a)表示条件为a的值不为1,也就是0。 条件运算符 “?:”为条件判断,类似于if else,例如assign a = (i》8)?1’b1:1’b0 ;判断i的值是否大于8,如果大于8则a的值为1,否则为0。 位运算符 “~”按位取反,”|”按位或,”^”按位异或,”&”按位与,”^”按位同或,除了”~”只需要一个操作数外,其他几个都需要两个操作数,如a&b,a|b。具体应用在后面的组合逻辑一节中有讲解。 移位运算符 “《《”左移位运算符,”》》”右移位运算符,如a《《1表示,向左移1位,a》》2,向右移两位。 拼接运算符 “{ }”拼接运算符,将多个信号按位拼接,如{a[3:0], b[1:0]},将a的低4位,b的低2位拼接成6位数据。另外,{n{a[3:0]}}表示将n个a[3:0]拼接,{n{1’b0}}表示n位的0拼接。如{8{1’b0}}表示为8’b0000_0000. 优先级别 各种运算符的优先级别如下: |
|
|
|
组合逻辑
本节主要介绍组合逻辑,组合逻辑电路的特点是任意时刻的输出仅仅取决于输入信号,输入信号变化,输出立即变化,不依赖于时钟。 与门 在verilog中以“&”表示按位与,如c=a&b,真值表如下,在a和b都等于1时结果才为1,RTL表示如右图 代码实现如下:激励文件如下: moduletop(a,b,c); inputa; inputb; outputc; assignc=a&b; endmodule `timescale1ns/1ns moduletop_tb(); rega; regb; wirec; initial begin a=0; b=0; forever begin #({$random}%100) a=~a; #({$random}%100) b=~b; end end topt0(.a(a),.b(b),.c(c)); endmodule 仿真结果如下: 如果a和b的位宽大于1,例如定义input [3:0] a, input [3:0]b,那么a&b则指a与b的对应位相与。如a[0]&b[0],a[1]&b[1]。 |
|
|
|
或门
在verilog中以“|”表示按位或,如c = a|b , 真值表如下,在a和b都为0时结果才为0。 代码实现如下:激励文件如下 moduletop(a,b,c); inputa; inputb; outputc; assignc=a|b; endmodule `timescale1ns/1ns moduletop_tb(); rega; regb; wirec; initial begin a=0; b=0; forever begin #({$random}%100) a=~a; #({$random}%100) b=~b; end end topt0(.a(a),.b(b),.c(c)); endmodule 仿真结果如下: 同理,位宽大于1,则是按位或。 |
|
|
|
非门
在verilog中以“~”表示按位取反,如b=~a,真值表如下,b等于a的相反数。 代码实现如下:激励文件如下: moduletop(a,b); inputa; outputb; assignb=~a; endmodule `timescale1ns/1ns moduletop_tb(); rega; wireb; initial begin a=0; forever begin #({$random}%100) a=~a; end end topt0(.a(a),.b(b)); endmodule 仿真结果如如下: |
|
|
|
只有小组成员才能发言,加入小组>>
2389 浏览 7 评论
2805 浏览 4 评论
Spartan 3-AN时钟和VHDL让ISE合成时出现错误该怎么办?
2272 浏览 9 评论
3346 浏览 0 评论
如何在RTL或xilinx spartan fpga的约束文件中插入1.56ns延迟缓冲区?
2440 浏览 15 评论
有输入,但是LVDS_25的FPGA内部接收不到数据,为什么?
770浏览 1评论
请问vc707的电源线是如何连接的,我这边可能出现了缺失元件的情况导致无法供电
552浏览 1评论
求一块XILINX开发板KC705,VC707,KC105和KCU1500
393浏览 1评论
1977浏览 0评论
694浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-1 19:00 , Processed in 1.512651 second(s), Total 95, Slave 78 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号