目录
前言
一、基础知识
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的类型:
定义关键字:primitive开始,原语名称、输出输入端口,initial语句(用于初始化时许逻辑UDP的输出端口)。UDP状态表是UDP最终要的部分,以关键字table开始,endtable结束,状态表定义了输入状态和当前状态得到的输出值,可以是一个查找表,也可类似于逻辑真值表。原语最终endprimitive结束。
//定义一个原语
primitive (<输出端口>,<输入端口1>,<输入端口2>,...<输入端口n>) //第一个必须为输出
oupput <输出端口名>;
input <输入端口名>;
reg <输出端口名>; //可选,只有表示时许逻辑的UDP才需要
initial <端口名> = <值>;
//UDP状态表
table
<状态表>
endtable
endprimitive
output a,b; //不合法:输出只能有一个
output [2:0] a; //不合法:输出只能有一位
input a,b; //合法:输入可以有多个
input [2:0] a; //不合法:输入只能有一位
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
语法形式:
注意:
由于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的区别:
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
//带清零的时钟下降沿触发的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
设计功能模块时,是使用module还是使用UDP来实现模块功能,下面给出选择的指导原则: