三、12【Verilog HDL】用户自定义原语(UDP)

目录

前言

一、基础知识

1.1 UDP定义的组成

1.2 UDP的定义规则

二、组合逻辑的UDP

2.1 组合逻辑的UDP定义

2.2 状态表项

2.3 实例化引用(举例)

 三、时序逻辑的UDP

3.1 电平敏感的时序逻辑UDP

3.2 边沿敏感的时序逻辑UDP

四、UDP表中的缩写符号

五、UDP设计指南


前言

参考书籍:《Verilog HDL 数字设计与综合》第二版,本文档为第12章的学习笔记。

用户自定义原语(User-Defined Primitive,UDP),在UDP中不能调用(实例引用)其他模块或者其他原语,其调用方式和门级原语调用方式相同。

UDP的类型:

  • 组合逻辑的UDP:输出仅取决于输入信号的逻辑,如四选一多路选择器。
  • 时序逻辑的UDP:下一个输出值不但取决于当前的组合逻辑,还取决于当前的内部状态,如锁存器和触发器。

一、基础知识

1.1 UDP定义的组成

定义关键字:primitive开始,原语名称、输出输入端口,initial语句(用于初始化时许逻辑UDP的输出端口)。UDP状态表是UDP最终要的部分,以关键字table开始,endtable结束,状态表定义了输入状态和当前状态得到的输出值,可以是一个查找表,也可类似于逻辑真值表。原语最终endprimitive结束。

//定义一个原语
primitive <udp_name>(<输出端口>,<输入端口1>,<输入端口2>,...<输入端口n>)  //第一个必须为输出
    oupput <输出端口名>;
    input  <输入端口名>;
    reg    <输出端口名>; //可选,只有表示时许逻辑的UDP才需要

    initial <端口名> = <值>;
//UDP状态表
    table
        <状态表>
    endtable
endprimitive

1.2 UDP的定义规则

  • UDP只能有一个1位输出端口,输出列表的第一个必须是输出端口,不允许多个或多位输出。
    output a,b;       //不合法:输出只能有一个
    output [2:0] a;   //不合法:输出只能有一位
  • UDP只能采用标量(1位)输入端口 ,但是允许多个输入端口
input a,b;       //合法:输入可以有多个
input [2:0] a;   //不合法:输入只能有一位
  • 端口声明部分:输入端口声明input;输出端口声明output;不支持输入输出端口声明inout。因为表示时许逻辑的UDP需要保持状态,所以输出端口必须声明位reg类型。
  • 时序逻辑的UDP中,可以使用initial语句对reg类型变量(输出)进行赋初值。、
  • 状态表项可以包含值0,1或x。UDP不能处理z值,输入UDP的z值被当作x值处理。
  • UDP与模块同级,因此UDP不能在模块内部定义,但可以在模块内部调用,调用方法和调用原语相同。

二、组合逻辑的UDP

2.1 组合逻辑的UDP定义

primitive udp_and(out, a, b);
    output out;
    inutput a,b;
    table
    //a  b : out;
      0  0 : 0;
      0  1 : 0;
      1  0 : 0;
      1  1 : 1;
    endtable
endprimitive

ANSI C语言风格

primitive udp_and(output out, input a, output b);
...
endprimitive

2.2 状态表项

语法形式:

<input1> <input2>......<inputn> : <output>

注意:

  • 状态表每一行的输入端口的顺序一定要和端口列表相同
  • 输入输出<:>隔开,<;>结束
  • 能够出现的输入项出现的组合必须全部列出。否则,如果在状态表各行中找不到与这组输入对应项,相对应的输出就是x。
  • 注意输入的值也最好为确定值,如果输入都非确定值即(x),那么输出也必然是x,那么就会出现x值传播下去。
  • 无关项可以用“?”来表示

2.3 实例化引用(举例)

由于UDP限制过多且当输入增加时,状态表将成几何倍数增加,因此定义的UDO原语仅仅使用在基本的逻辑功能。

这里我们UDP一个:四选一多路选择器进行举例,这里加入了使能端EN

  •  程序代码
primitive mux4_to_1( output i0, i1, i2, i3, s1 s0, EN,
                     input i0, i1, i2, i3, s1 s0, EN );
table
//  i0  i1  i2  i3  s1 s0 EN : output;
     ?   ?   ?   ?   ?  ?  1 :  0;
     1   ?   ?   ?   0  0  0 : 1;
     0   ?   ?   ?   0  0  0 : 0;
     ?   1   ?   ?   0  1  0 : 1;
     ?   0   ?   ?   0  1  0 : 0;
     ?   ?   1   ?   1  0  0 : 1;
     ?   ?   0   ?   1  0  0 : 0;
     ?   ?   ?   1   1  1  0 : 1;
     ?   ?   ?   0   1  1  0 : 0;
     ?   ?   ?   ?   x  ?  0 :  x;
     ?   ?   ?   ?   ?  x  0 : x;
endtable
endprimitive
  • 仿真代码
module stimulus();
    reg i0, i1, i2, i3, s1, s0, EN;
    wire output;
    initial begin
        i0 = 1; i1 = 0; i2 = 1; i3 = 0; 
        #1 $display("i0 = %b, i1 = %b, i2 = %b, i3 = %b", i0, i1, i2, i3);
        #5 EN = 0;   $display("output = %b, output);                 
        #5 s1 = 0 s0 = 0; $display("output = %b, output);
        #5 s1 = 0 s0 = 1; $display("output = %b, output);
    end
    mux4_to_1 mux_inst(output, i0, i1, i2, i3, s1, s0, EN);
endmodule

 三、时序逻辑的UDP

时序逻辑与组合逻辑UDP的区别:

  1. 表示时序逻辑的UDP的输出必须声明为reg类型,并且可以使用initial进行初始化。
  2. 表示时序逻辑的UDP,状态表:<输入1><输入2>...<输入N> : <当前状态> : <下一状态>
  3. 表示时序逻辑的UDP,状态表的输入项可以是电平或者跳变沿的形式。
  4. 当前状态是寄存器的当前值,下一状态是计算得到值会被存到寄存器中成为新值。

3.1 电平敏感的时序逻辑UDP

primitive latch(output reg q = 0
                input d, clock, clear);
initial q = 0; 
table  
    // d   clock   clear  :  q : q+;
       ?     ?       1    :  ? : 0;
//clock = 1时将d值锁存到q中
       1     1       0    :  ? :1;
       0     1       0    :  ? : 0;

       ?     0       0    :  ? : -;
endtable
endprimitive

3.2 边沿敏感的时序逻辑UDP

//带清零的时钟下降沿触发的D触发器
primitive edge_dff(output reg q=0
                    input d, clock, clear);
table
//  d  clock clear : q : q+;
    ?    ?    1    : ? : 0 ;
    ?    ?    (10) : ? : - ;    //(10) 由1向0跳变
    1    (10) 0    : ? : 1 ;
    0    (10) 0    : ? : 0 ;
    ?    (1x) 0    : ? : - ;    //(1x)由1向不确定状态跳变
    ?    (0?) 0    : ? : - ;    
    ?    (x1) 0    : ? : - ;
    (??) ?    0    : ? : - :    //(??)信号值再0,1,x三者之间任意跳变
endtable
endprimitive

四、UDP表中的缩写符号

五、UDP设计指南

设计功能模块时,是使用module还是使用UDP来实现模块功能,下面给出选择的指导原则:

  • UDP只能进行功能建模,不能对电路时序和制造工艺(CMOS/TTL/ECL)进行建模。UDP是对模块功能的模型,而module是对于完整的模块模型。
  • UDP只能有一个一位输出,且UDP的输入端口数由仿真器决定。
  • UDP的描述方式是使用状态表,所以不适合输入参数太多的描述。
  • 尽可能完整的列出UDP中的状态表
  • 尽可能使用缩写符来表示状态表输入项
  • 当电平敏感的与边沿敏感的同时作用是,下一状态先由电平敏感的决定,即电平敏感的优先级高于边沿敏感。
  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐者-桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值