![]() | Introduction // 简介 | ||||||||||||||||||||||||||||
Verilog has built-in primitives like gates, transmission gates, and switches. This is a rather small number of primitives; if we need more complex primitives, then Verilog provides UDP, or simply User Defined Primitives. Using UDP we can model Verilog HDL 已经内建了一些原语如门,传输门、开关等。这只是原语中的一小部分,同样Verilog HDL也提供了对用户自定义原语(UDP)的支持,我们可以使用用户自定义原语来构建更为复杂原语。 | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
We can include timing information along with these UDP to model complete ASIC library models. 我们可以将时间信息添加到UDP中来构建一个完整的ASIC库模型。 | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
![]() | Syntax //语法 | ||||||||||||||||||||||||||||
UDP begins with reserve word primitive and ends withendprimitive. Ports/terminals of primitive should follow. This is similar to what we do for module definition. UDPs should be defined outside module and endmodule UDP(用户自定义原语)以保留字 primitive开始以endprimitive结束。接着是原语的端口。 这和我们定义的模块的做法是相似的。 UDP的定义必须出现在 module 和endmodule 语句块的外部。 | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
1 //This code shows how input/output ports 2 // and primitve is declared 3 primitive udp_syntax ( 4 a, // Port a 5 b, // Port b 6 c, // Port c 7 d // Port d 8 ); 9 output a; 10 input b,c,d; 11 12 // UDP function code here 13 14 endprimitiveYou could download file udp_syntax.v here | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
In the above code, udp_syntax is the primitive name, it contains ports a, b,c,d. 在上面的代码中, udp_syntax 是primitive name它端口a,b, c, d; | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
The formal syntax of the UDP definition is as follows: //用户自定义原语语法格式如下: | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
<UDP>
::= primitive <name_of_UDP> ( <output_terminal_name>,
<input_terminal_name> <,<input_terminal_name>>* ) ;
<UDP_declaration>+
<UDP_initial_statement>?
<table_definition>
endprimitive
<name_of_UDP>
::= <IDENTIFIER>
<UDP_declaration>
::= <UDP_output_declaration>
||= <reg_declaration>
||= <UDP_input_declaration>
<UDP_output_declaration>
::= output <output_terminal _name>;
<reg_declaration>
::= reg <output_terminal_name> ;
<UDP_input_declaration>
::= input <input_terminal_name> <,<input_terminal_name>>* ;
<UDP_initial_statement>
::= initial <output_terminal_name> = <init_val> ;
<init_val>
::= 1'b0
||= 1'b1
||= 1'bx
||= 1
||= 0
<table_definition>
::= table
<table_entries>
endtable
<table_entries>
::= <combinational_entry>+
||= <sequential_entry>+
<combinational_entry>
::= <level_input_list> : <OUTPUT_SYMBOL> ;
<sequential_entry>
::= <input_list> : <state> : <next_state> ;
<input_list>
::= <level_input_list>
||= <edge_input_list>
<level_input_list>
::= <LEVEL_SYMBOL>+
<edge_input_list>
::= <LEVEL_SYMBOL>* <edge> <LEVEL_SYMBOL>*
<edge>
::= ( <LEVEL_SYMBOL> <LEVEL_SYMBOL> )
||= <EDGE_SYMBOL>
<state>
::= <LEVEL_SYMBOL>
<next_state>
::= <OUTPUT_SYMBOL>
||= -
| |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
![]() | UDP ports rules //UDP的端口规则 | ||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
![]() | Body //udp原语的功能体 | ||||||||||||||||||||||||||||
Functionality of primitive (both combinational and sequential) is described inside a table, and it ends with reserved word 'endtable' as shown in the code below. For sequential UDP, we can use initial to assign an initial value to output. (组合逻辑和时序逻辑的)原语功能在真值表中描述。真值表以保留字table开始,以endtable结尾,像下面的代码所示。 对于时序逻辑的UDP,可以使用初始化语句为输出赋个初始值。 | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
1 // This code shows how UDP body looks like 2 primitive udp_body ( 3 a, // Port a 4 b, // Port b 5 c // Port c 6 ); 7 output a; 8 input b,c; 9 10 // UDP function code here 11 // A = B | C; 12 table 13 // B C : A 14 ? 1 : 1; 15 1 ? : 1; 16 0 0 : 0; 17 endtable 18 19 endprimitiveYou could download file udp_body.v here | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
Note: An UDP cannot use 'z' in the input table 注意:UDP中不能使用在真值表的输入中使用Z,即高阻态。 | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
TestBench to check the above UDP | |||||||||||||||||||||||||||||
1 `include "udp_body.v" 2 module udp_body_tb(); 3 4 reg b,c; 5 wire a; 6 7 udp_body udp (a,b,c); 8 9 initial begin 10 $monitor(" B = %b C = %b A = %b",b,c,a); 11 b = 0; 12 c = 0; 13 #1 b = 1; 14 #1 b = 0; 15 #1 c = 1; 16 #1 b = 1'bx; 17 #1 c = 0; 18 #1 b = 1; 19 #1 c = 1'bx; 20 #1 b = 0; 21 #1 $finish; 22 end 23 24 endmoduleYou could download file udp_body_tb.v here | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
Simulator Output | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
B = 0 C = 0 A = 0
B = 1 C = 0 A = 1
B = 0 C = 0 A = 0
B = 0 C = 1 A = 1
B = x C = 1 A = 1
B = x C = 0 A = x
B = 1 C = 0 A = 1
B = 1 C = x A = 1
B = 0 C = x A = x
| |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
![]() | Table // 真值表 | ||||||||||||||||||||||||||||
Table is used for describing the function of UDP. Verilog reserved word table marks the start of table and reserved word endtablemarks the end of table. 真值表是用来描述UDP的功能。Verilog中使用保留字table开头,以保留字endtable结束。 | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
Each line inside a table is one condition; when an input changes, the input condition is matched and the output is evaluated to reflect the new change in input. 真值表中的每一行都是一个条件,当输入发生变化时,与相应的输入条件匹配的行的输出作为输入变化的反馈。 | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
![]() | Initial //初始化语句 | ||||||||||||||||||||||||||||
Initial statement is used for initialization of sequential UDPs. This statement begins with the keyword 'initial'. The statement that follows must be an assignment statement that assigns a single bit literal value to the output terminal reg. 初始化语句,用来完成时序逻辑UDP的初始化。初始化语句以initial关键字开始,接着是一个赋值语句,其将一位的常量值(字面值)赋值给输出端口的reg。 | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
1 primitive udp_initial (a,b,c); 2 output a; 3 input b,c; 4 reg a; 5 // a has value of 1 at start of sim 6 initial a = 1'b1; 7 8 table 9 // udp_initial behaviour 10 endtable 11 12 endprimitiveYou could download file udp_initial.v here | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
![]() | Symbols //符号 | ||||||||||||||||||||||||||||
UDP uses special symbols to describe functions like rising edge, don't care and so on. The table below shows the symbols that are used in UDPs: UDP使用特殊的符号来声明特殊的功能如上升沿,忽略的功能和其他一些功能。 下面这个表格中是一些在UDP中使用的符号。 | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
|
the above original link:http://www.asic-world.com/verilog/udp1.html