[笔记][原创]Verilog HDL语法分析笔记

 

     这篇帖子用于记录学习Verilog过程中的一些syntax的问题,会不断更新,有不正确的地方请各位帮忙指正:D
一.Verilog 语法中的可综合性
Verilog HDL 真的很强大,如果程序只用于仿真,那么几乎所有的语法和编程语句都可以使用。但如果程序是用于硬件实现,那么我们就必须保证程序的可综合性,即所编写的程序能被综合器 转化为相应的电路结构。不可综合的HDL语句在用综合工具综合时将被忽略或者报错。作为设计者,应该对可综合模型的结构有所了解。
虽然不同的综合工具对Verilog HDL语法结构的支持不尽相同,但Verilog HDL中某些典型的结构是很明确地被所有综合工具支持或不支持的。
(1)所有综合工具都支持的结构:
always,assign,begin,end,case,wire,tri,aupply0,supply1,reg,integer,default,for,
function,and,nand,or,nor,xor,xnor,buf,not,bufif0,bufif1,notif0,notif1,if,inout,
input,instantitation,module,negedge,posedge,operators,output,parameter。
(2)所有综合工具都不支持的结构:time,defparam,$finish,fork,join,initial,delays,UDP,wait。
(3)有些工具支持有些工具不支持的结构:casex,casez,wand,triand,wor,trior,real,disable,forever,arrays,memories,repeat,
task,while。
看到一些资料上说其实Verilog HDL的产生是为了写testbench,而编程设计只用到了其中的很少的部分。Verilog有人说很好学,很容易入手,但是我觉得仅仅入手是没有用的,充其量就鸡肋一根,一定要仔细深入研究语法和结构,这样才能写出高效率的代码,否则基本的代码一塌糊涂的话后面的功能仿真,时序仿真都是浮云。
|
|
二.避免锁存器
  在 always 块的 if..else 语句中如果所列的条件不完整,综合时则会产生锁存器。
example:
always @(action)
          if(action)  out1 <= 1'b1;

        没有考虑到 !action 的情况,默认out1保持不变,这就产生了锁存器。
优化方法:1.列出 !action 的情况,2.对out1赋初始值
1.always @(action)
          if(action)  out1 <= 1'b1;
else    out1 <= 1'b0;
|
2.always @(action)  begin
out <= 1'b0;
if(action)  out1 <= 1'b1;
end
但是,在描述时序逻辑的时候,也通常利用 if 语句的隐式条件对带时钟使能的 D 触发器建模
example:
always@(posedge clk, negedge rst_n)  begin
if(!rst_n)  sum <= 0;
else if(EN)  sum <= a+b;
表示在时钟正沿来临时,如果 EN 为 1 ,则将 a+b 的值赋给 sum, 言下之意是如果 EN 为 0, 那么 sum 保持原值不变。这里综合工具会把代码综合成一个带时钟使能的 D 触发器。
三.产生占空比不等于50%的波形 (状态机的巧用)
在面试的时候常常看到一些对verilog用得不熟的同学,在被要求写出可综合的RTL代码并产生占空比不同的输出脉冲时,选择用很多计数器来对输入的脉冲进行计数,而且还分别对输入脉冲的上升沿和下降沿进行计数,非常的糟糕,因为输入的脉冲一般只能保证一个触发沿是稳定的
如果要产生占空比相同的波形,那么计数器可以很简单的搞定。
例如:将一个200kHz的时钟做2分频,4分频,8分频,这时候你也许会想到用PLL,但是这里的时钟速率是kHz级别,很低,无法使用PLL。
可以这样设计:

    reg [2:0] cnt;
    always @(posedge clk_200k, negedge rst_n)
     if(!rst_n)
      cnt <= 3'b000;
     else 
      cnt <= cnt + 1'b1;
  
    assign clk_100k = cnt[0];
    assign clk_50k  = cnt[1];
    assign clk_25k  = cnt[2];
如要要求产生一个占空比为1:4的波形,用计数器实现的话就很麻烦了,在这种时候就可以用一个简单的状态机来实现。
000->001->110->100->010->
|               |
<----<----<----<----<----<-
利用状态机就很简单的实现了占空比不同的波形的产生。
代码如下:
1   reg [2:0] state;
2
3   always @(posedge clk, negedge rst_n)
4   if(!rst_n)
5    state <=3'b000;
6    else
7    case (state)
8    3'b000: state <= 3'b001;
9    3'b001: state <= 3'b110;
10    3'b110: state <= 3'b100;
11    3'b100: state <= 3'b010;
12    3'b010: state <= 3'b000;
13    default : state <=3'b000;
14    endcase
15
16   assign clk_out = state[0];
17

    仿真波形:

  

  状态机的设计水平直接反映了工程师的逻辑功底,要写好状态机就一定要多练习。
 
                    

转载于:https://www.cnblogs.com/semiok/archive/2010/10/13/1849730.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/462872.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SRV记录注册不成功的可能的原因

1.1.1 SRV记录注册不成功的可能的原因 默认情况&#xff0c;安装完活动目录就会DNS中的SRV记录就注册成功了&#xff0c;如果您在域控制器上重启Netlogon服务&#xff0c;有可能还是不能注册SRV记录到DNS服务器上&#xff0c;以下是总结的需要检查的几点。 DNS区域名字是否正确…

cast()函数

cast()函数用于将某种数据类型的表达式显式转换为另一种数据类型。 CAST()函数的参数是一个表达式&#xff0c;它包括用as关键字分隔的源值和目标数据类型。 语法&#xff1a;CAST (expression AS data_type) expression&#xff1a;任何有效的SQL Server表达式。 AS&#x…

组建内存双通道的条件

双通道要分以下两种情况&#xff1a; 1.对称双通道&#xff1a;这是最传统的双通道模式&#xff0c;需要尽量完全相同的成对内存组建&#xff0c;性能为双通道中最强&#xff0c;要求也最苛刻&#xff0c;即使不能保证内存完全相同也至少应该保证容量、速度、延时、版型相同&am…

ABAP很厉害是怎么一种体验?

知乎上偶然看到这个问题&#xff0c;觉得很有意思&#xff0c;我也来回答一发。 我本科和研究生学的是计算机专业&#xff0c;做项目用C/C&#xff0c;研究生三年项目的代码量大概在三到四万行左右。2007年大学毕业加入SAP成都研究院一直工作到现在&#xff0c;工作中用的最熟练…

vector内存扩容

vector底层实现的机制是一个动态数组&#xff0c;当其占用的内存不足时&#xff0c;就会自动分配时原来内存大小2倍的空间&#xff0c;并将原来内存中的数据拷贝到新开辟的内存中。vector扩容时&#xff0c;并不是在原有内存的基础上再分配一块内存&#xff0c;而是在其他的地方…

C语言:为什么用fprintf(stderr,Error);比printf(Error);更好?

C语言:为什么用fprintf(stderr,"Error");比printf("Error");更好?_百度知道C语言:为什么用fprintf(stderr,"Error");比printf("Error");更好?2009-05-27 17:03 提问者&#xff1a; Wave_Dan |浏览次数&#xff1a;2855次请问:当文件…

w3m 使用总结

安装 sudo apt install w3m终端 w3m www.baidu.com 即可打开w3m是个开放源代码的命令行下面的网页浏览器。一般的linux系统都会自带这个工具&#xff0c;可以通过它在命令行下面浏览网页。本文介绍这个工具的使用方法。 [功能] w3m是个开放源代码的命令行下面的网页浏览器。 它…

set_error_handler自定义错误处理

刚看到了App.class.php&#xff0c;里面有个自定义错误的函数appError 刚还在怀疑。咋这么多参数&#xff0c;虽然看起来都是有用的&#xff0c;不过有些头晕。 继续往下看&#xff0c;看到了init()里的第一句话set_error_handler(array(&$this,”appError”)); 于是好好搜…

vector查找、插入、删除时效率对比

vector底层实现的机制时动态数组&#xff0c;因此适用于查找比较频繁的场景。那么在vector的中push_back()一个元素时或者在尾部删除一个元素时&#xff0c;效率是不是就高&#xff1f; 结果&#xff1a;不是。无论在任何位置插入或者删除元素时&#xff0c;都会进行内存的分配…

jquery如何获取checkbox的值

jquery如何获取checkbox的值 一、总结 一句话总结&#xff1a;就是通过jquery获取哪些对应name的checkbox&#xff0c;然后找出:check&#xff08;被选中的&#xff09;&#xff0c;然后通过jquery的each遍历获取这些的值即可 $(input[namecheckboxName]:checked).each遍历取值…

Linux文件查找命令find,xargs详述

Linux文件查找命令find,xargs详述 总结&#xff1a;zhy2111314来自&#xff1a;LinuxSir.Org整理&#xff1a;北南南北摘要&#xff1a; 本文是find 命令的详细说明&#xff0c;可贵的是针对参数举了很多的实例&#xff0c;大量的例证&#xff0c;让初学者更为容易理解&#xf…

WTL 学习博文地址

http://blog.chinaunix.net/u/884/showart_148905.html转载于:https://www.cnblogs.com/changping/archive/2010/11/09/1873078.html

git命令:修改已经commit的注释

在使用git命令时&#xff0c;有时commit后&#xff0c;突然想起来忘记修改commit的注释。修改commit的注释使用下面的命令&#xff1a; git commit --amend 本人也是最近2周才开始使用git&#xff0c;有些也理解不到位&#xff0c;在工作中实操之后记录下来&#xff0c;工作环…

当前读与快照读

概念 快照读 读取的是记录数据的可见版本&#xff08;可能是过期的数据&#xff09;&#xff0c;不用加锁 当前读 读取的是记录数据的最新版本&#xff0c;并且当前读返回的记录都会加上锁&#xff0c;保证其他事务不会再并发的修改这条记录   概念说的比较虚&#xff0c;也不…

误删表数据,如何恢复过来

/* 真实案例:在执行语句的时候错误的把系统中的一个表的数据全部删除 在删除之前&#xff0c;我做过一次完整的数据库备份&#xff0c;再删除之后&#xff0c;我第一时 间做了尾日志备份 也就是说 我手上现在有一份最新的完整备份 和删除数据之后的尾 日…

git命令:将多个commit提交记录修改为1条

本人也是最近2周才开始使用git&#xff0c;有些也理解不到位&#xff0c;在工作中实操之后记录下来&#xff0c;工作环境linux ubuntu。 变基时有六个命令可用&#xff1a; pick pick只是意味着包括提交。重新进行命令时&#xff0c;重新安排pick命令的顺序会更改提交的顺序…

随手笔记

import turtleturtle.bgcolor("red")turtle.fillcolor("yellow")turtle.color(yellow)turtle.speed(10)#主星turtle.begin_fill()turtle.up()turtle.goto(-600,220) turtle.down()for i in range (5): turtle.forward(150)turtle.right(144)turtle.end_…

修改、读取txt文档

1、使用FileStream读写文件文件头&#xff1a;using System;using System.Collections.Generic;using System.Text;using System.IO;读文件核心代码&#xff1a;byte[] byData new byte[100];char[] charData new char[1000];try{FileStream sFile new FileStream("文件…

详解AST抽象语法树

浅谈 AST 先来看一下把一个简单的函数转换成AST之后的样子。 // 简单函数 function square(n) {return n * n; }// 转换后的AST {type: "FunctionDeclaration",id: {type: "Identifier",name: "square"},params: [{type: "Identifier&quo…

struct linger

TCP连接断开的时候调用close socket函数&#xff0c;已经讨论过有优雅的断开和强制断开&#xff0c;那么如何设置断开连接的方式呢&#xff1f; 是通过设置socket描述符一个linger结构体属性。 linger结构体数据结构如下&#xff1a; struct linger { int l_onoff; int l_linge…