1verilog特点:    区分大小写,所有关键字都要求小写
      不是强类型语言,不同类型数据之间可以赋值和运算
    //是单行注释  可以跨行注释
    描述风格有系统级描述、行为级描述、RTL级描述、门级描述,其中RTL级和门级别与具体电路结构有关,行为级描述要遵守可综合原
    门级描述使用门级模型或者用户自定义模型UDP来代替具体基本元件,在IDE中针对不同FPGA器件已经有对应的基本元件原语
verlog语法要点
2语句组成:★ module endmodule之间由两部分构成:接口描述和逻辑功能描述 
  IO端口种类: input  output  inout   
相同位宽的输入输出信号可以一起声明, input[3:0] a,b; 不同位宽的必须分开写
  内部信号为reg类型,内部信号信号的状态: 0  1  x  z  3bx1=3bxx1 x/z会往左扩展  3b1=3b001 数字不往左扩展
  逻辑功能描述中常用assign描述组合逻辑电路,always既可以描述组合逻辑电路又可以描述时序逻辑电路,还可以用元件调用方法描述逻辑功能
    always之间、assign之间、实例引用之间以及它们之间都是并行执行,always内部是顺序执行
3  常量格式 <二进制位宽><><进制><该进制的数值>
          默认进制为10进制
          默认位宽为32
          位宽是从二进制宽度角度而言的
          由位宽决定从低位截取二进制数2hFF=2b11,通常由被赋值的reg变量位宽决定
parameter字符串截取的语法格式常用于定义延迟和变量位宽,可用常量或常量表达式定义
4变量种类: wire  reg  memory
    IO信号默认为wire类型,除非指定为reg类型(regwire的区别
  wire可以用作任何输入输出端口
wire包括input output inout
  wire不带寄存功能
  assign赋值语句中,被赋值的信号都是wire类型
  assign之所以称为连续赋值,是因为不断检测表达式的变化
reg类型可以被赋值后再使用,而不是向wire一样只能输出     
reg类型变量初始值为x
   always模块里被赋值的信号都必须定义为reg类型,因为always可以反复执行,而reg表示信号的寄存,可以保留上次执行的值
 reg类型变量与integer变量不同,即使赋负值,实质上也是按二进制无符号数存储的,integer是有符号数
verilog中所有内部信号都是静态变量,因为它们的值都在reg中存储起来 
  memory型只有一维数组,由reg型变量组成
memory初始化只能按地址赋值,不能一次性赋值
          1*256memory写法: reg mema[255:0]    mema[3]=0;
不同位宽的变量之间赋值,处理之前都以被赋值的变量位宽为准扩展或截取
A[a:b] 无论a b谁大,a总是实际电路的信号高位,b总是实际电路的信号低位
算术运算中如果有X值则结果为X
for循环中的变量另外定义成integer,因为它不是实际信号,有正负;reg则以无符号数存在
5、运算符(其他简单的书上有自己看)
== !=只比较01,遇到zx时结果都为x (xif中算做假条件),结果可能是10x
===!==比较更加苛刻,包括xz的精确比较,结果可能是01
&&的结果只有1b11b0两种, A&A的结果位宽则是与A相同的
{1,0} 64h100000000,所以拼接运算中各信号一定要指定位宽
移位运算左移将保留 4'b1000<<1等于5'b10000,右移则舍弃 4'b0011等于4'b0001
数字电路里位运算应用普遍,包括按位逻辑运算、移位运算、拼接运算、缩减运算
6、非阻塞式赋值<=与阻塞式赋值=(比较)
        阻塞:在同一个always过程中,后面的赋值语句要等待前一个赋值语句执行完,后面的语句被该赋值语句阻塞
        非阻塞:在同一个always过程中,非阻塞赋值语句是同时进行的,排在后面的语句不会被该赋值语句阻塞
        <=
            块结束后才能完成赋值
            块内所有<=语句在always块结束时刻同时赋值
            <=右边各变量的值是上一次时钟边沿时,这些变量当时的值
            用于描述可综合的时序电路
        =
            =语句结束之后过程always才可能结束
            always过程中,begin end块内按先后顺序立即赋值,在fork join内同时赋值(可能造成冲突)
            assign连用描述组合电路
            begin end中阻塞的含义:begin  ...@(A) ;  end  如果A事件不发生则永远不能执行下去,被阻塞了
        由于时钟的延时(往往在ps),多个always(posedge)之间究竟谁先执行是个未知数
  使用八原则 1)时序电路建模时,采用非阻塞赋值
(2)锁存器电路建模时,采用非阻塞赋值。
(3)always块来建立组合逻辑模型时,要用阻塞赋值。
(4)在同一个always块内建立时序和组合逻辑电路时,用非阻塞赋值。
(5)在同一个always块中不要既要用非阻塞赋值又用阻塞方式赋值
(6)不要在一个以上的always块中为同一个变量赋值
(7)$srobe系统任务来显示用非阻塞赋值的变量值
(8)复制时不要使用#0延迟     
    7 if else的三种形式( ),  第三种形式适合描述优先编码器
    if条件中0/x/z当成假,1当成真,非0的数值也当成真
    8case语句的三种 case(四种状态的比较)  casez(忽略z)  casex(忽略xz,只看哪些位的信号有用)
    case语句中所有表达式值的位宽必须相等,default中不能将n'bx'bx代替
    避免生成锁存器的方法: 电平触发时if后加else  case中加default   
    使用casex会将不必要的状态视为无关项,使得综合出来的电路最简单
    9、两种特殊的括号: begin 顺序语句... end    fork 并行语句... join,其差别在于块内语句的起止时间、执行顺序、相对延时
 
    10、块被命名后,其内部变量可以被调用,因为变量都是静态的(调用信号:对应电路中的一个信号线被引到另一处)
    initial块只无条件执行一次  always块在满足条件时不断执行
    initial常用来写测试文件, always块常用来写电路描述
    always既可以描述组合逻辑电路又可以描述时序逻辑电路
    always如果后面有敏感信号列表则不能用wait语句
    always既可以描述电平触发又可以描述边沿触发,wait只能描述电平触发
    assign常用于描述组合逻辑电路
    测试文件中一般都是现initial always

    11生成语句:生成快的本质是使用循环内的一条语句代替多条重复的verilog语句,简化了用户的编程
              genvar用于声明生成变量,生成变量只能用在生成快之间
              仿真时,仿真器会将生成块中的代码展平,在确立后的方针代码中,生成变量是不存在的
              最好是先想象出来循环生成语句被展平后的电路样子,再写相关的描述语句
    12 taskfunction的区别:
              task可以定义自己的仿真时间单位,function与主模块共用同一个仿真时间单位
              函数不能启动任务,任务能够启动函数
              函数至少要有一个输入变量,任务没有输入变量
              函数返回一个值,任务不返回值
 
    13一个模块的设计包括3个部分: 电路模块的设计  测试模块的设计  设计文档的编写
    设计者通过布局布线工具生成具有布线延迟的电路,再进行后仿真,得到时序分析报告
    从时序分析报告中可以知道电路的实际延迟t,同步电路内每个时钟周期要大于t,从而可确定该运算逻辑的最高频率
    综合器之所以能够实现加法器、乘法器是因为库中已经存在可配置的参数化器件模型
    FPGA内总线宽度容易自定义,以便实现高速数据流,三态数据总线相当于数据流的控制阀门
    14、数字系统内数据流的控制: 开关(或三态数据总线)、数据暂存部件(寄存器) 同步状态机控制(整个系统在一个时钟域内)
 
    15流水线操作pipe line
        K级流水线就是从组合逻辑的输入到输出恰好有K个寄存器组,上一级的输出是下一级
的输入
        流水线操作获得第一个结果的时间要比不用流水线操作的时间长,但以后结果获得时间都只需要一个时钟周期,提高了数据吞吐量
        流水线操作的保证:Tclk>K*(组合逻辑延迟+触发器的建立保持时间/触发时间),即时间片段要长于最大路径延迟
        体现了面积换速度的思想,在综合时考虑的是以面积小为主还是以速度为主
        本质上是一种同步逻辑
 
  16 同步时序逻辑和异步时序逻辑:
        同步时序逻辑指所有寄存器组由唯一时钟触发  always@(posedge clk)  always@(negedage clk)
        异步时序逻辑指触发条件不唯一,任意一个条件都会引起触发  always@(posedge clk or posedage reset)
        目前的综合器是以同步时序逻辑综合的,因为同步时序逻辑较异步时序逻辑可靠
        严格的同步要求时钟信号传递速度远远大于各部分的延迟,实际中clk要单独用线,而
不要经过反相器等部件
        always @(posedge.. )  begin ...<=... end  表示同步时序逻辑(同时刻赋值)
        不同速率数据接口的处理方法(异步数据的处理方法):帧同步    FIFO  双端口RAM
 
    17 同步状态机:
        包括mooremealy型两种,及其反馈模型(是一种反馈控制系统,当前状态就是其内部状态变量)
        状态机的开发步骤:
            根据实际问题列出输入输出变量和状态数
            画出状态图并化简
            写出状态转移真值表得到逻辑表达式
            D触发器或JK触发器构建电路(目前用D触发器多)
        verilog描述时只需要得到简化的状态图就可以描述
        状态编码方式: 独热码  格雷码
        状态机主体程序有单always描述方式和多always描述方式
        采用case/casez/casex建立模型最好,因为x是无关态,生成的电路最简单
        default: state='bx与实际情况更一致,效果等同于 default: state<=idle
        只有同步状态机才能被目前的综合
18、语法注意细节:
有优先级的if else结构会消耗更多资源,建议用无优先级的case替代
模块的复用往往比代码上修改节省的资源多
PLL的分频、倍频、移相操作会增加设计精度
同步时序电路的延时:#x通常用于仿真测试,实际硬件延时是:长延迟用计数器,小延迟用D触发器,此方法用来取代延迟链
同步电路中,稳定的数据采用必须满足采样寄存器的建立和保持时间
reg类型在always中不一定综合成时序电路,也可能是组合逻辑电路
乒乓操作与作用  异步时钟域同步问题
延迟包括门延迟和线延迟
组合逻辑产生的时钟仅能应用在时钟频率较低、精度要求不高的情况下
增减敏感信号得到的结果一样
补充部分:
verilog HDL起初是作为写testbench而产生的
verilog 1995进入IEEE标准,为IEEE-1364, 2001年进行了扩展,为IEEE 1364-2001
verilog AMS可用于模拟电路和数字电路的综合,目前正在不断发展和完善中;
verilog的标识符区分大小写,关键字使用小写;
\\来进行单行注释,用\* *\来进行跨行注释;
标识符由字母、数字、下划线构成,并以字母开头;
关键字又叫保留字,只有小写的关键字才是保留字;
信号的状态有4种: 0 1 x z
xz在描述电路时不区分大小写,在仿真时大小写有不同意义;
常量表达式中:
x z不区分大小写;
进制符号h o d bH O D B不区分大小写;
十六进制中a~f不区分大小写;
下划线_用于提高可读性;
?在数中可以代替z
xz的左端补位;
字符和字符串都以ASICII码形式存在,也可以当成电路内的信号;
字符串必须包含在同一行,不能分成多行书写;
如果表达式或者赋值语句中将字符串当成操作数,则字符串中的每个字符都被看成8位的ASCII值序列;
可综合的信号类型:wire reg memory 它们用来描述数字电路
不可综合的数据类型:integer real 它们只用仿真,位于testbench

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。