首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

可综合的verilog语法子集

可综合的verilog语法子集

常用的RTL语法结构如下:



模块声明: module……endmodule
端口声明:input,output,inoutinout的用法比较特殊,需要注意)

信号类型:wire,reg,tri等,integer常用语for语句中(reg,wire时最常用的,一般triinteger不用)

参数定义:parameter
运算操作符:各种逻辑操作符、移位操作符、算术操作符大多时可综合的(注:===与!==是不可综合的)

比较判断:if……else,case(casex,casez)……default
endcase

连续赋值:assign,问号表达式(?:)

always模块:(敏感表可以为电平、沿信号posedge/negedge;通常和@连用)

begin……end(通俗的说,它就是C语言里的 “{ }”

任务定义:task……endtask
循环语句:for(用的也比较少,但是在一些特定的设计中使用它会起到事半功倍的效果)

☆ 赋值符号:= 和 <= (阻塞和非阻塞赋值,在具体设计中时很有讲究的)



      可综合的语法时verilog可用语法里很小的一个子集,用最精简的语句描述最复杂的硬件,这也正是硬件描述语言的本质。对于做RTL级设计来说,掌握好上面这些基本语法是很重要。
     本文来自   特权's BLOG:http://blog.ednchina.com/ilove314/157717/message.aspx
      相信大家在看了这么多了verilog语法书籍以后一定有点烦了,那么现在我告诉大家一个好消息,对于一个RTL级的设计来说,掌握了上面的语法就已经足够了,无论多么牛逼的工程师,在他的代码里无非也就是上面一些语法而已。当然了,对于一个能够进行很好的仿真验证的代码,一般还需要在RTL级的设计代码中添加一些延时之类的语句,比如大家一定知道#10的作用,就是延时10个单位时间,这个语句虽然在仿真的时候是实实在在的延时,但是这个语句在综合后是会被忽略的,也就是说在我们综合并且布局布线最后烧进FPGA里,这个#10的延时是不会在硬件上实现的。所以说,上面给出的这些语法才是可以最后在硬件上实现的,其它的语法大多会在综合后被忽略。这么一来大家就要问了,为什么语法书里又要给出这么多的语法呢?呵呵,它们大都是为仿真验证是写testbench准备的,先点到为止,下集继续!


Verilog语法需要注意的一些要点

1. Testbench中时钟和数据比特流的简单设计方法

always clock = ~clock;

always @(posedge clock)

begin

data_in_a = {$radom} % 2; // 产生-1到1之间随机的比特流

data_in_b = 16’b1101_1011_1110_0011; // 产生固定的比特流

$display(“a= %d\n”, a); // 与C语言类似

end

2. Verilog语法中的并行与顺序模块

(1) 连续赋值语句、always模块之间、实例模块之间都是并行语句

(2) always模块内部是分情况而定,对于if…else…而言,总是有优先级的顺序的,对于case而言,无优先级,是完全顺序执行的,此外,还要对阻塞语句和非阻塞语句具体分析。

3. Verilog中四种最常见的变量

(1) wire,即线网形变量,它不能存储值,必须受到驱动器或者连续赋值语句的驱动,如果没有驱动,那么它将会是高阻态

(2) reg是数据存储单元的抽象,通过赋值语句可以改变寄存器存储的值,其作用与改变触发器存储的值相当。寄存器变量的初时值为不确定态。在always内部用到的变量必须是reg型的。

(3) prarmeter相当与VHDL中的constant

4. 注意区分集中容易混淆的运算符

(1) 位运算符,按位操作,~,|,&,^,其输出与输出一样位宽

(2) 逻辑运算符,输出0或者1,&&,||,!

(3) 缩减运算符,按位递归运算,&,|,!,其输出仅仅是1或者0

5. 阻塞语句(blocking)与非阻塞赋值语句(non-blocking)

(1) 非连续赋值语句(non-blocking)(b <= a)

在always块结束后才完成赋值操作,并且赋值后b不是立即就改变,在时序逻辑或者既有时序逻辑也有组合逻辑中一定要用这种赋值方式

(2) 阻塞语句(blocking)(b = a)

赋值之后,b就立即改变,也就是在赋值语句完成以后,always才结束,在综合时,如果不注意,将产生意想不到的结果

一个非常典型的例子:




always @(clock)

begin

b = a;

c = b;

end

always @(clock)

begin

c = b;

b = a;

end

always @(clock)

begin

b <= a;

c <= b;

end




6. 使用if或者是case进行综合时,一定要覆盖所有可能的情况,防止锁存器的综合

7. 写testbench一些常见的保留字

$display(“print_word_value = %d”, print_word_value); // 与C语言类似

$display(“%h, %o”, 12’b1101_0100_0111); // 结果是 0xD47和o6507

$monitoron; // 监控开始

$mointor($time, “rxd = %b”, “txd = %b”, rxd, txd); // 打印当前时刻的监控值

$monitoroff;

$finish; // 仿真结束

$readmemb(“数据文件名”, 存储器名); // 把数据读入到当前指定的存储器内

rand_data = {random} % 60; // 产生-59到59之间的随机数
继承事业,薪火相传
返回列表