User Defined Primitives Part-I (of Verilog HDL)

 ../images/main/bullet_green_ball.gifIntroduction // 简介
  

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)的支持,我们可以使用用户自定义原语来构建更为复杂原语。

  

space.gif

  
  • Combinational Logic //组合逻辑
  • Sequential Logic //时序逻辑
  

space.gif

  

We can include timing information along with these UDP to model complete ASIC library models.

我们可以将时间信息添加到UDP中来构建一个完整的ASIC库模型。

  

space.gif

 ../images/main/bulllet_4dots_orange.gifSyntax //语法
  

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 语句块的外部。

  

space.gif

  

  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 endprimitive
You could download file udp_syntax.v here
  

space.gif

  

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;

  

space.gif

  

The formal syntax of the UDP definition is as follows:

//用户自定义原语语法格式如下:

  

space.gif

  
<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>
   ||= -    
  

space.gif

 ../images/main/bulllet_4dots_orange.gifUDP ports rules //UDP的端口规则
  

space.gif

  
  • An UDP can contain only one output and up to 10 inputs. //UDP只能有一个输出,最多有10个输入。
  • Output port should be the first port followed by one or more input ports. //输出端口必须是第一个端口,后面可以有一到多个输入端口
  • All UDP ports are scalar, i.e. Vector ports are not allowed.  //所有的UDP端口都是标量,矢量端口是不允许的。
  • UDPs can not have bidirectional ports. //UDP中不能有双向端口
  • The output terminal of a sequential UDP requires an additional declaration as type reg. //时序逻辑的UDP输出端口需要声明为reg类型
  • It is illegal to declare a reg for the output terminal of a combinational UDP //为一个组合逻辑的UDP的输出端口声明为reg类型是非法的。
  

space.gif

  
  

space.gif

 ../images/main/bulllet_4dots_orange.gifBody //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,可以使用初始化语句为输出赋个初始值。

  

space.gif

  

  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 endprimitive
You could download file udp_body.v here
  

space.gif

  

Note: An UDP cannot use 'z' in the input table

注意:UDP中不能使用在真值表的输入中使用Z,即高阻态。

  

space.gif

  

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 endmodule
You could download file udp_body_tb.v here
  

space.gif

  

Simulator Output

  

space.gif

  
  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
  

space.gif

 ../images/main/bullet_star_pink.gifTable // 真值表
  

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结束。

  

space.gif

  

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.

真值表中的每一行都是一个条件,当输入发生变化时,与相应的输入条件匹配的行的输出作为输入变化的反馈。

  

space.gif

 ../images/main/bullet_star_pink.gifInitial //初始化语句
  

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。

  

space.gif

  

  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 endprimitive
You could download file udp_initial.v here
  

space.gif

 ../images/main/bulllet_4dots_orange.gifSymbols //符号
  

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中使用的符号。

  

space.gif

  

Symbol

Interpretation

Explanation

? (三值,0,1,x)

0 or 1 or X

? means the variable can be 0 or 1 or x

b  (二值,0, 1)

0 or 1

Same as ?, but x is not included

f  (falling edage )

(10)

Falling edge on an input

r  (rising edge)

(01)

Rising edge on an input

p (正沿)

(01) or (0x) or (x1) or (1z) or (z1)

Rising edge including x and z

n  (负沿)

(10) or (1x) or (x0) or (0z) or (z0)

Falling edge including x and z

* (所有可能变化)

(??)

All transitions

- (不变)

no change

No Change

the above original link:http://www.asic-world.com/verilog/udp1.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值