From sandi@cadence.com Tue Feb 25 14:18:55 1992 Return-Path: Received: from relay1.UU.NET by im (4.1/TOC-1.1S) id AA18688; Tue, 25 Feb 92 14:18:32 EST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA29663; Tue, 25 Feb 92 14:18:28 -0500 Received: from cadence.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 141730.24252; Tue, 25 Feb 1992 14:17:30 EST Received: from gda by cadence.Cadence.COM (5.61/3.14) id AA07954; Tue, 25 Feb 92 08:59:18 -0800 Received: from acae240.gda by gda (3.2/GDA-90/10/18) id AA04358; Tue, 25 Feb 92 12:01:33 EST Received: by acae240.gda (4.1/SMI-4.0-gda) id AA00633; Tue, 25 Feb 92 11:57:05 EST Date: Tue, 25 Feb 92 11:57:05 EST From: sandi@cadence.com (Sandi McGrade) Message-Id: <9202251657.AA00633@acae240.gda> To: faust@im.lcs.mit.edu Subject: dtran info Status: RO Resolution: In order to use specify block path delays in a given model, Verilog requires that the outputs of the model in question be acceleratable by the XL-algorithm. A net is acceleratable as long as there are no decelerating, or non-acceleratable, elements connected to that net. If the output of the path delay cannot be accelerated, the user must remove the non-acceleratable element from the node in question. This can be done by buffering the node from the rest of the circuit with a gate primative that is acceleratable. Most Verilog primatives are acceleratable by default. However, it is possible to use a primative in a way that will cause it to be decelerated. For instance, if the primative input is driven by a bit of a vectored register, that primative will be decelerated. reg [7:0] driver; This example will yield the PDOMBA . error because out1 is not an . acceleratable net. . buf b1 (out1, driver[1]); The reason is that the buffer, b1, . has been decelerated by the vectored . register bit on it's input, driver[1]. . specify Any net that touches a decelerated (in1 *> out1) = 2:3:4; primative is a non-acceleratable net. We can solve this problem by adding another buffer between b1 and out1, like so: buf b1 (out1b, driver[1]); buf b2 (out1,out1b); One common cause of this problem that cannot be solved by buffering the output is when the "tran" primative, which is non-acceleratable, is used on bidirectional module ports. The tran will decelerate any node that it touches, which means one cannot use that node as the output of a path delay. Since the net is bidirectional, a buffer cannot be used to isolate it from the tran. One way to correct this problem is to remove the tran primatives from the model in question. If this cannot be done without adversely affecting the operation of that model, the "dtran" construct can be used. Dtran is a PLI application that will operate like the tran primative, except that its outputs are acceleratable. This PLI code must be linked into the Verilog executeable before it can be used. A complete description of how to obtain and use the "dtran" is shown below, under the title "Using the DTRAN". Page 26-4 of the Verilog Reference Manual lists several items that are not supported by the XL-algorithm. Using any of these items on the output of a path delay will cause the PDOMBA error. When searching for the cause of a PDOMBA error, remember that deceleration of nets DOES cross module boundries. It is quite possible to have a module that uses path delays and compiles successfully, stand-alone, but then fails when it is instanciated in a higher level module. If there is a non-acceleratable element in a module that has been connected to the output of a path delay of another module, that path delay output is decelerated, causing the subsequent error. USING THE DTRAN --------------- The DTRAN software is available from a Cadence AE, and the details of it's operation are as follows: The Verilog tran gate has two problems in Verilog-XL: 1. The user cannot assign a delay to a tran gate. 2. The user cannot attach the output of a specify block to a net that touches a tran gate. This makes it impossible for us to use the tran gate to model wire delays on boards or in chips. It is also impossible to back-annotate a new delay onto a tran gate. The dtran is a hybrid Verilog/PLI model which implements a tran gate with a delay. The model can be attached to the output net of a specify block, and can be backannotated with the PLI or $update_timing (though $update_timing is frowned upon.) There are two restrictions to the dtran: 1. It can only be It will not handle behavioral models, or continuous assignments. *** Warning: This program can crash if you use an unnamed primitive and don't accellerate your model. *** 2. It doesn't handle drivers of different strengths. It only looks at the values that primitives want to drive onto a bus. THE DESIGN Long Description: Path delays and specify blocks requre that the output nodes of a device be accelerated. There are certain constructs within Verilog that are non-accelerateable. This message typically means that the output of a path delay has been connected to a non-accelerateable construct. For instance, if the output of a path delay is connected to a "tran" element on the port of another module, you will get this message. Many times a customer will develop a device model, compile and test it and it works just fine. Then when they connect it in the board environment, it fails compile with this error message. This is usually because something else is connected to that node in the board which causes the problem. THE DESIGN The dtran has two parts: a Verilog module, and a PLI system task. The Verilog Model ----------------- The verilog model is in dtran.v. It looks like this: +-------------------------------+ |delbuf +-------+ | | abuf +-| a_reg | | | /| | +-------+ |\ | +----+ +--+ +--+ +----+ | \| | |/ | | +-------+ | delbuf | | | b_reg |-+ bbuf | | +-------+ | | initial | | $delay_transport(a_reg, | | +-------------------------------+ The buffers in this drawing are modules that contain an nmos transistor and a specify block. The nmos transistor will pass a Z value from the input, and the specify block provides the timing. There is a specparam in the specify block called delay that indicates the delay. You can use the PLI or $update_timing to backannotate the delbufs. The system task $delay_transport is the guts of the dtran. It monitors the terminals that drive the dtran inputs and decides what value to drive on the output. Then it places this value in the appropriate register. For example, consider the following circuit. There are 4 drivers driving this dtran. A and B are driving 1's onto net N1. C and D are driving Z's onto n2. Given this situation, this dtran should drive a 1 onto N2 and a Z onto N1. The 1's would overpower the Z's and the entire network would have 1's. $delay_transport monitors the terminals of A and B, and uses this information to drive the correct value onto N2. It also monitors the terminals of C and D and drives the correct information onto N1. Verilog-XL's internal contention handling determines who will win the struggle. |\ /| | \ 1 Z / | |a +------+ +------+ c| | / | | \ | |/| | n1 +-------+ n2 | |\| |------| dtran |------| | +-------+ | |\ | | /| | \ 1 | | Z / | |b +------+ +-------+ d| | / \ | |/| |\| Now, what if we have the following situation: |\ | \ 1 Z / | |a +------+ +------+ c| | / | | \ | |/| | n1 +-------+ n2 | |\| |------| dtran |------| | +-------+ | |\ | | /| | \ 0 | | Z / | |b +------+ +-------+ d| | / \ | |/| |\| A is driving a 1 but B is driving a 0. This will cause N1 to become an X. $delay_transport will monitor the terminals of A and B and drive an X onto N2. The dtran still drives a Z onto N1, but this loses its contention battle to the X's. N1 and N2 therefore currently have a value of X. Some people have tried to model tran gates by placing two buffers back to back like this: |\ /| | \ 1 Z / | |a +------+ b1 +------+ c| | / | /| | \ | |/| | n1 +- + |--+ n2 | |\| |------| \| |------| | | | | |\ | | |\ | | /| | \ 0 | +--| +--+ | Z / | |b +------+ |/ +-------+ d| | / b2 \ | |/| |\| This setup won't work in this situation. Here is the order of events that will break it: 1. A = 1 B = 0 2. Therefore N1 = X 3. This causes B1 to drive X onto N2 4. This causes B2 to drive X onto N1 5. B = 1 This should settle the network back to all 1, but it doesn't. N1 has three objects driving it: A = 1 B1 = X This results in N1 being equal to X. The 1 was unable to drive the X away. With the dtran we have a different set of events: 1. A = 1 B = 0 2. Therefore N1 = X. The DTRAN is monitoring the terminals of A and B and recognizes the clash between A and B, so it drives X onto N2. This X defeats the Z's, so N2 settles at X. 3. The DTRAN continues to drive Z onto N1 because it ignores N2 and looks at the C and D terminals directly. However A and B are clashing and cause N1 to stay at X. 4. B = 1 N1 now changes to a 1 because it has the following objects driving it: A = 1 B = 1 DTRAN = Z The DTRAN drives a 1 onto N2 because it is monitoring B and sees that A and B no longer conflict. So N2 goes to 1 and the entire network settles at 1. We needed the PLI to create the dtran so we could handle the X situation. DTRAN FILES $delay_transport is implemented with four files: dtran_checktf.c - This routine creates the data structures and begins monitoring the terminals that drive the dtran. dtran_calltf.c - This routine starts the dtran by calling tf_synchronize. dtran_misctf.c - This routine does most of the work. It figures out the new values for both ports of the dtran and applies them at the end of the timestep. It is only called when one of the driving terminals changes value. dtran_consumer.c - This routine modifies the dtran data structure each time a driving terminal changes logical va It also calls tf_synchronize to call the dtran_misctf routine. You also have a file that contains the dtran module: dtran.v - This module calls $delay_transport and should be included on your command line or in your libraries. USING THE DTRAN To use the DTRAN model, you must link the dtran_*.c files with Verilog 1.6 or later. Use the following veriusertfs entry in veriuser.c: {usertask, 0, dtran_checktf, 0, dtran_calltf, dtran_misctf, "$delay_transport", 1}, Once you have the $delay_transport function loaded into Verilog-XL, you can start using the dtran verilog model. You should include dtran.v on the command line or in your libraries, then use dtran in your verilog models wherever you need a tran gate. You can set delays in the dtran by changing the delay specparam in the delbuf module in dtran.v. Or you can backannotate the specify blocks in the delbufs.