0% found this document useful (0 votes)
13 views31 pages

Chap9_Useful Modeling Techniques

The document covers various useful modeling techniques in digital design, particularly focusing on procedural continuous assignments, overriding parameters, and conditional compilation in Verilog HDL. It explains concepts such as assign, deassign, force, and release statements, as well as the significance of logic synthesis and verification of gate-level netlists. Additionally, it discusses conditional execution and time scales for simulation, providing examples to illustrate these concepts.

Uploaded by

Nguyễn Huy Vũ
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views31 pages

Chap9_Useful Modeling Techniques

The document covers various useful modeling techniques in digital design, particularly focusing on procedural continuous assignments, overriding parameters, and conditional compilation in Verilog HDL. It explains concepts such as assign, deassign, force, and release statements, as well as the significance of logic synthesis and verification of gate-level netlists. Additionally, it discusses conditional execution and time scales for simulation, providing examples to illustrate these concepts.

Uploaded by

Nguyễn Huy Vũ
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 31

2024-12-26

Digital Design

L9: Useful Modeling Techniques


Duong Ngoc Phap, Ph.D
Faculty of Computer Engineering and Electronics

December 26, 2024

Content
Procedural continuous assignments
overriding parameters,
conditional compilation and execution
useful system tasks
Logic Synthesis
Impact of logic synthesis
Verilog HDL Synthesis
Synthesis design flow, Verification of Gate-Level
netlist

1
2024-12-26

Learning Objectives
 Describe procedural continuous assignment
statements assign, deassign, force, and release.
Explain their significance in modeling and
debugging.
 Understand how to override parameters by using the
defparam statement at the time of module
instantiation.
 Explain conditional compilation and execution of
parts of the Verilog description.
 Identify system tasks for file output, displaying
hierarchy, strobing, random number generation,
memory initialization, and value change dump

Procedural Continuous Assignments


 Procedural assignments assign a value to a register.
The value stays in the register until another
procedural assignment puts another value in that
register.
 Procedural continuous assignments behave
differently. They are procedural statements which
allow values of expressions to be driven continuously
onto registers or nets for limited periods of time.
 Procedural continuous assignments override existing
assignments to a register or net. They provide an
useful extension to the regular procedural assignment
statement.

2
2024-12-26

Assign and Deassign


 The keywords assign and deassign are used to express the
first type of procedural continuous assignment.
 The left-hand side of procedural continuous assignments
can be only be a register or a concatenation of registers.
 It cannot be a part or bit select of a net or an array of
registers.
 Procedural continuous assignments override the effect of
regular procedural assignments.
 Procedural continuous assignments are normally used for
controlled periods of time.

D-Flipflop with Procedural Continuous


Assignments
 // Negative edge-triggered D-flipflop with asynchronous
reset
 module edge_dff(q, qbar, d, clk, reset);
 // Inputs and outputs
 output q,qbar;
 input d, clk, reset;
 reg q, qbar; //declare q and qbar are registers
 always @(negedge clk) //assign value of q & qbar at active
edge of clock.
 begin
 q = d;
 qbar = ~d;
 end

3
2024-12-26

 always @(reset) //Override the regular assignments to q and qbar


 //whenever reset goes high. Use of procedural continuous
//assignments.
 if(reset)
 begin //if reset is high, override regular assignments to q with
 //the new values, using procedural continuous assignment.
 assign q = 1'b0;
 assign qbar = 1'b1;
 end
 else
 begin //If reset goes low, remove the overriding values by
//deassigning the registers. After this the regular
 //assignments q = d and qbar = ~d will be able to change
 //the registers on the next negative edge of clock.
 deassign q;
 deassign qbar;
 end
 endmodule

Force and Release


 Keywords force and release are used to express the
second form of the procedural continuous assignments.
 They can be used to override assignments on both
registers and nets.
 Force and release statements are typically used in the
interactive debugging process, where certain registers or
nets are forced to a value and the effect on other
registers and nets is noted.
 It is recommended that force and release statements not
be used inside design blocks. They should appear only
in stimulus or as debug statements.

4
2024-12-26

Force and Release on registers

 A force on a register overrides any procedural


assignments or procedural continuous assignments on
register until the register is released.
 The register variables will continue to store the forced
value after being released, but can then be changed
future procedural assignment.
 To override the values of q and qbar in Example 5-1 for
limited period of time, we could do the following:

 module stimulus;
 ...
 //instantiate the d-flipflop
 edge_dff dff(Q, Qbar, D, CLK, RESET);
 ...
 initial
 begin
 //these statements force value of 1 on dff.q between time 50
and
 //100, regardless of the actual output of the edge_dff.
 #50 force dff.q = 1'b1; //force value of q to 1 at time 50.
 #50 release dff.q; //release the value of q at time 100.
 end
 ...
 endmodule

5
2024-12-26

Force and Release on nets


 Force on nets overrides any continuous assignments until the
net is released. The net will immediately return to its normal
driven value when it is released. A net can be forced to an
expression or a value.
 module top;
 ...
 assign out = a & b & c; //continuous assignment on net out
 ...
 initial
 #50 force out = a | b & c;
 #50 release out;
 end
 ...
 endmodule

 In the example above, a new expression is forced on the


net from time 50 to time 100.
 From time 50 to time 100, when the force statement is
active, the expression a | b & c will be re-evaluated and
assigned to out whenever values of signals a or b or c
change.
 Thus, the force statement behaves like a continuous
assignment except that it is active for only a limited
period of time.

6
2024-12-26

Overriding Parameters
 Parameters can be defined in a module definition, as
was discussed earlier in Section 3.2.8, Parameters.
 However, during compilation of Verilog modules,
parameter values can be altered separately for each
module instance.
 This allows us to pass a distinct set of parameter values
to each module during compilation regardless of
predefined parameter values.
 There are two ways to override parameter values:
through the defparam statement or through module
instance parameter value assignment.

Defparam Statement
 Example 5-2. Defparam Statement
 //Define a module hello_world
 module hello_world;
 parameter id_num = 0; //define a module
identification number = 0
 initial //display the module identification
number
 $display("Displaying hello_world id number =
%d", id_num);
 endmodule

7
2024-12-26

 //define top-level module


 module top;
 //change parameter values in the instantiated
modules
 //Use defparam statement
 defparam w1.id_num = 1, w2.id_num = 2;
 //instantiate two hello_world modules
 hello_world w1();
 hello_world w2();
 endmodule

 In Example 5-2, the module hello_world was defined with a


default id_num = 0. However, when the module instances w1
and w2 of the type hello_world are created, their id_num
values are modified with the defparam statement. If we
simulate the above design, we would get the following output
 Displaying hello_world id number = 1
 Displaying hello_world id number = 2
 Multiple defparam statements can appear in a module. Any
parameter can be overridden with the defparam statement.
The defparam construct is now considered to be a bad coding
style and it is recommended that alternative styles be used in
Verilog HDL code.
 Note that the module hello_world can also be defined using
an ANSI C style parameter declaration. Figure 5-3 shows the
ANSI C style parameter declaration for the module
hello_world.

8
2024-12-26

Conditional Compilation and


Execution
 A portion of Verilog might be suitable for one
environment but not for another.
 The designer does not wish to create two versions of
Verilog design for the two environments.
 Instead, the designer can specify that the particular
portion of the code be compiled only if a certain flag is
set.This is called conditional compilation.
 A designer might also want to execute certain parts of
the Verilog design only when a flag is set at run time.
This is called conditional execution.

Conditional Compilation
 Conditional compilation can be accomplished by using
compiler directives
 `ifdef, `ifndef, `else, `elsif, and `endif. Example 5-5
contains Verilog source code to be compiled
conditionally.
 Example 5-5. Conditional Compilation
 //Conditional Compilation
 //Example 1
 'ifdef TEST //compile module test only if text macro TEST is
defined
 module test;
 ...
 endmodule

9
2024-12-26

 'else //compile the module stimulus as default


 module stimulus;
 ...
 ...
 endmodule
 'endif //completion of 'ifdef directive

 //Example 2
 module top;
 bus_master b1(); //instantiate module unconditionally
 'ifdef ADD_B2
 bus_master b2(); //b2 is instantiated conditionally if text macro
 //ADD_B2 is defined
 'elsif ADD_B3
 bus_master b3(); //b3 is instantiated conditionally if text macro
 //ADD_B3 is defined
 'else
 bus_master b4(); //b4 is instantiate by default
 'endif
 'ifndef IGNORE_B5
 bus_master b5(); //b5 is instantiated conditionally if text macro
 //IGNORE_B5 is not defined
 'endif
 endmodule

10
2024-12-26

 The `ifdef and `ifndef directives can appear


anywhere in the design.
 A designer can conditionally compile
statements, modules, blocks, declarations,
and other compiler directives.
 The `else directive is optional.
 A maximum of one `else directive can
accompany an `ifdef or `ifndef.
 Any number of `elsif directives can
accompany an `ifdef or `ifndef. An `ifdef or
`ifndef is always closed by a corresponding
`endif.

 The conditional compile flag can be set by


using the `define statement inside the Verilog
file.
 In the example above, we could define the
flags by defining text macros TEST and
ADD_B2 at compile time by using the `define
statement.
 The Verilog compiler simply skips the portion
if the conditional compile flag is not set. A
Boolean expression, such as TEST &&
ADD_B2, is not allowed with the `ifdef
statement.

11
2024-12-26

Conditional Execution
 Conditional execution flags allow the
designer to control statement execution flow
at run time.
 All statements are compiled but executed
conditionally.
 Conditional execution flags can be used only
for behavioral statements.
 The system task keyword $test$plusargs is
used for conditional execution.

 Example 5-6. Conditional Execution with $test$plusargs


 //Conditional execution
 module test;
 ...
 ...
 initial
 begin
 if($test$plusargs("DISPLAY_VAR"))
 $display("Display = %b ", {a,b,c} ); //display only if flag is set
 else
 //Conditional execution
 $display("No Display"); //otherwise no display
 end
 endmodule

12
2024-12-26

 Conditional execution can be further controlled by using


the system task keyword $value$plusargs.
 This system task allows testing for arguments to an
invocation option.
 $value$plusargs returns a 0 if a matching invocation was
not found and non-zero if a matching option was found.
 Example 5-7 shows an example of $value$plusargs.
 Example 5-7. Conditional Execution with
$value$plusargs
 //Conditional execution with $value$plusargs
 module test;
 reg [8*128-1:0] test_string;
 integer clk_period;
 ...
 ...

 initial
 begin
 if($value$plusargs("testname=%s", test_string))
 $readmemh(test_string, vectors); //Read test vectors
 else
 //otherwise display error message
 $display("Test name option not specified");
 if($value$plusargs("clk_t=%d", clk_period))
 forever #(clk_period/2) clk = ~clk; //Set up clock
 else
 //otherwise display error message
 $display("Clock period option name not specified");
 end
 //For example, to invoke the above options invoke simulator with
 //+testname=test1.vec +clk_t=10
 //Test name = "test1.vec" and clk_period = 10
 endmodule

13
2024-12-26

Time Scales
 Often, in a single simulation, delay values in
one module need to be defined by using
certain time unit, e.g., 1 μs, and delay values
in another module need to be defined by
using a different time unit, e.g. 100 ns.
 Verilog HDL allows the reference time unit for
modules to be specified with the `timescale
compiler directive.

 Usage: `timescale <reference_time_unit> /


<time_precision>
 The <reference_time_unit> specifies the unit
of measurement for times and delays.
 The <time_precision> specifies the precision
to which the delays are rounded off during
simulation.
 Only 1, 10, and 100 are valid integers for
specifying time unit and time precision.
Consider the two modules, dummy1 and
dummy2, in Example 5-8.

14
2024-12-26

 //Define a time scale for the module dummy1


 //Reference time unit is 100 nanoseconds
and precision is 1 ns
 `timescale 100 ns / 1 ns
 module dummy1;
 reg toggle;
 //initialize toggle
 initial
 toggle = 1'b0;
 //Flip the toggle register every 5 time units

 //In this module 5 time units = 500 ns = .5 μs


 always #5
 begin
 toggle = ~toggle;
 $display("%d , In %m toggle = %b ", $time,
toggle);
 end
 endmodule

15
2024-12-26

 //Define a time scale for the module dummy2


 //Reference time unit is 1 microsecond and precision is 10 ns
 `timescale 1 us / 10 ns
 module dummy2;
 reg toggle;
 //initialize toggle
 initial
 toggle = 1'b0;
 //Flip the toggle register every 5 time units
 //In this module 5 time units = 5 μs = 5000 ns
 always #5
 begin
 toggle = ~toggle;
 $display("%d , In %m toggle = %b ", $time, toggle);
 end
 endmodule

 The two modules dummy1 and dummy2 are


identical in all respects, except that the time unit for
dummy1 is 100 ns and the time unit for dummy2 is 1
μs.
 Thus the $display statement in dummy1 will be
executed 10 times for each $display executed in
dummy2.
 The $time task reports the simulation time in terms
of the reference time unit for the module in which it
is invoked.
 The first few $display statements are shown in the
simulation output below to illustrate the effect of the
`timescale directive.

16
2024-12-26

 5 , In dummy1 toggle = 1
 10 , In dummy1 toggle = 0
 15 , In dummy1 toggle = 1
 20 , In dummy1 toggle = 0
 25 , In dummy1 toggle = 1
 30 , In dummy1 toggle = 0
 35 , In dummy1 toggle = 1
 40 , In dummy1 toggle = 0
 45 , In dummy1 toggle = 1
 --> 5 , In dummy2 toggle = 1
 50 , In dummy1 toggle = 0
 55 , In dummy1 toggle = 1
 Notice that the $display statement in dummy2
executes once for every ten $display statements in
dummy1.

Useful System Tasks


 We discuss system tasks [1] for file output, displaying
hierarchy, strobing, random number generation, memory
initialization, and value change dump.
 File Output
 Output from Verilog normally goes to the standard output
the file verilog.log. It is possible to redirect the output
Verilog to a chosen file.
 Opening a file
 A file can be opened with the system task $fopen.
 Usage: $fopen("<name_of_file>"); [2]
 Usage: <file_handle> = $fopen("<name_of_file>");

17
2024-12-26

 The task $fopen returns a 32-bit value called a


multichannel descriptor.[3]
 Only one bit is set in a multichannel descriptor.
 The standard output has a multichannel descriptor with
the least significant bit (bit 0) set.
 Standard output is also called channel 0. The standard
output is always open.
 Each successive call to $fopen opens a new channel
and returns a 32-bit descriptor with bit 1 set, bit 2 set,
and so on, up to bit 30 set.
 Bit 31 is reserved. The channel number corresponds to
the individual bit set in the multichannel descriptor.
Example 9-9 illustrates the use of file descriptors.

File Descriptors
 //Multichannel descriptor
 integer handle1, handle2, handle3; //integers are 32-bit
values
 //standard output is open; descriptor = 32'h0000_0001 (bit 0
set)
 initial
 begin
 handle1 = $fopen("file1.out"); //handle1 = 32'h0000_0002
(bit 1 set)
 handle2 = $fopen("file2.out"); //handle2 = 32'h0000_0004
(bit 2 set)
 handle3 = $fopen("file3.out"); //handle3 = 32'h0000_0008
(bit 3 set)
 end

18
2024-12-26

Writing to files
 The system tasks $fdisplay, $fmonitor, $fwrite, and $fstrobe
are used to write to files.
 Note that these tasks are similar in syntax to regular system
tasks $display, $monitor, etc., but they provide the
additional capability of writing to file We will consider only
$fdisplay and $fmonitor tasks.
 Usage: $fdisplay(<file_descriptor>, p1, p2 ..., pn);
$fmonitor(<file_descriptor>, p1, p2,..., pn);
 p1, p2, … , pn can be variables, signal names, or quoted
strings.
 A file_descriptor is a multichannel descriptor that can be a
file handle or a bitwise combination of file handles. Verilog
will write the output to all files that have a 1 associated with
them in the file descriptor.

 //All handles defined in Example 9-9


 //Writing to files
 integer desc1, desc2, desc3; //three file descriptors
 initial
 begin
 desc1 = handle1 | 1; //bitwise or; desc1 = 32'h0000_0003
 $fdisplay(desc1, "Display 1");//write to files file1.out & stdout
 desc2 = handle2 | handle1; //desc2 = 32'h0000_0006
 $fdisplay(desc2, "Display 2");//write to files file1.out &
file2.out
 desc3 = handle3 ; //desc3 = 32'h0000_0008
 $fdisplay(desc3, "Display 3");//write to file file3.out only
 end

19
2024-12-26

 Closing files
 Files can be closed with the system task
$fclose.
 Usage: $fclose(<file_handle>);
 //Closing Files
 $fclose(handle1);
 A file cannot be written to once it is closed.
The corresponding bit in the multichannel
descriptor is set to 0. The next $fopen call
can reuse the bit.

Displaying Hierarchy
 Hierarchy at any level can be displayed by means of
the %m option in any of the display tasks, $display,
$write task, $monitor, or $strobe task, as discussed
briefly in Section 4.3, Hierarchical Names.
 This is a very useful option. For example, when
multiple instances of a module execute the same
Verilog code, the %m option will distinguish from
which module instance the output is coming.
 No argument is needed for the %m option in the
display tasks. See Example 9-10.

20
2024-12-26

Displaying Hierarchy
 //Displaying hierarchy information
 module M;
 ...
 initial
 $display("Displaying in %m");
 endmodule
 //instantiate module M
 module top;
 ...
 M m1();
 M m2();
 //Displaying hierarchy information
 M m3();
 endmodule

 The output from the simulation will look like


the following:
 Displaying in top.m1
 Displaying in top.m2
 Displaying in top.m3
 This feature can display full hierarchical
names, including module instances, tasks,
functions, and named blocks.

21
2024-12-26

Strobing
 Strobing is done with the system task keyword $strobe.
This task is very similar to the $display task except for a
slight difference.
 If many other statements are executed in the same time
unit as the $display task, the order in which the
statements and the $display task are executed is
nondeterministic.
 If $strobe is used, it is always executed after all other
assignment statements in the same time unit have
executed.
 Thus, $strobe provides a synchronization mechanism to
ensure that data is displayed only after all other
assignment statements, which change the data in that
time step, have executed.

 Example 5-11. Strobing


 //Strobing
 always @(posedge clock)
 begin
 a = b;
 c = d;
 end
 always @(posedge clock)
 $strobe("Displaying a = %b, c = %b", a, c); // display
values at posedge
 In Example 9-11, the values at positive edge of clock will
be displayed only after statements a = b and c = d
execute.
 If $display was used, $display might execute before
statements a = b and c = d, thus displaying different
values.

22
2024-12-26

Random Number Generation


 Random number generation capabilities are required for
generating a random set of test vectors.
 Random testing is important because it often catches hidden
bugs in the design.
 Random vector generation is also used in performance
analysis of chip architectures.
 The system task $random is used for generating a random
number.
 Usage: $random;
 $random(<seed>);
 The value of <seed> is optional and is used to ensure the
same random number sequence each time the test is run.
The <seed> parameter can either be a reg, integer, or time
variable. The task $random returns a 32-bit signed
integer.

Random Number Generation


 //Generate random numbers and apply them to a simple ROM
 module test;
 integer r_seed;
 reg [31:0] addr;//input to ROM
 wire [31:0] data;//output from ROM
 ...
 ROM rom1(data, addr);
 initial
 r_seed = 2; //arbitrarily define the seed as 2.
 always @(posedge clock)
 addr = $random(r_seed); //generates random numbers
 ...
 <check output of ROM against expected results>
 ...
 endmodule

23
2024-12-26

 Generation of Positive and Negative Numbers by


$random Task
 reg [23:0] rand1, rand2;
 rand1 = $random % 60; //Generates a random
number between -59 and 59
 rand2 = {$random} % 60; //Addition of concatenation
operator to
 //$random generates a positive value between //0
and 59.

 Initializing Memory from File


 We discussed how to declare memories in Section 3.2.7, Memories.
 Verilog provides a very useful system task to initialize memories
from a data file.
 Two tasks are provided to read numbers in binary or hexadecimal
format.
 Keywords $readmemb and $readmemh are used to initialize
memories.
 Usage: $readmemb("<file_name>", <memory_name>);
$readmemb("<file_name>", <memory_name>, <start_addr>);
 $readmemb("<file_name>", <memory_name>, <start_addr>,
 <finish_addr>);
 Identical syntax for $readmemh.
 The <file_name> and <memory_name> are mandatory;
<start_addr> and <finish_addr> are optional.
 Defaults are start index of memory array for <start_addr> and end of
the data file or memory for <finish_addr>.

24
2024-12-26

Initializing Memory
 module test;
 reg [7:0] memory[0:7]; //declare an 8-byte memory
 integer i;
 initial
 begin
 //read memory file init.dat. address locations given in memory
 $readmemb("init.dat", memory);
 module test;
 //display contents of initialized memory
 for(i=0; i < 8; i = i + 1)
 $display("Memory [%0d] = %b", i, memory[i]);
 end
 endmodule

 The file init.dat contains the initialization data.


Addresses are specified in the data file with
@<address>. Addresses are specified as
hexadecimal numbers. Data is separated by
whitespaces. Data can contain x or z.
Uninitialized locations default to x. A
sample file, init.dat, is shown below.
 @002
 11111111 01010101
 00000000 10101010
 @006
 1111zzzz 00001111

25
2024-12-26

 When the test module is simulated, we will


get the following output:
 Memory [0] = xxxxxxxx
 Memory [1] = xxxxxxxx
 Memory [2] = 11111111
 Memory [3] = 01010101
 Memory [4] = 00000000
 Memory [5] = 10101010
 Memory [6] = 1111zzzz
 Memory [7] = 00001111

Value Change Dump File (VCD)


 A value change dump (VCD) is an ASCII file that contains
information about simulation time, scope and signal
definitions, and signal value changes in the simulation run.
 All signals or a selected set of signals in a design can be
written to a VCD file during simulation.
 Postprocessing tools can take the VCD file as input and
visually display hierarchical information, signal values, and
signal waveforms.
 Many postprocessing tools as well as tools integrated into the
simulator are now commercially available.
 For simulation of large designs, designers dump selected
signals to a VCD file and use a postprocessing tool to debug,
analyze, and verify the simulation output.

26
2024-12-26

Debugging and Analysis of Simulation with


VCD File
 System tasks are provided for selecting module
instances or module instance signals to dump
($dumpvars), name of VCD file ($dumpfile), starting and
stopping the dump process ($dumpon, $dumpoff), and
generating checkpoints ($dumpall).
 The uses of each task are shown in Example 9-15.
 //specify name of VCD file. Otherwise,default name is
 //assigned by the simulator.

 initial
 $dumpfile("myfile.dmp"); //Simulation info
dumped to myfile.dmp
 //Dump signals in a module
 initial
 $dumpvars; //no arguments, dump all signals
in the design
 initial
 $dumpvars(1, top); //dump variables in
module instance top.

27
2024-12-26

 //Number 1 indicates levels of hierarchy.


Dump one
 //hierarchy level below top, i.e., dump
variables in top,
 //but not signals in modules instantiated by
top.
 initial
 $dumpvars(2, top.m1);//dump up to 2 levels
of hierarchy below top.m1
 initial
 $dumpvars(0, top.m1);//Number 0 means
dump the entire hierarchy

 // below top.m1
 //Start and stop dump process
 initial
 begin
 $dumpon; //start the dump process.
 #100000 $dumpoff; //stop the dump process after 100,000
time units
 end
//Create a checkpoint. Dump current value of all VCD
variables
 initial
 $dumpall;
 The $dumpfile and $dumpvars tasks are normally specified at
the beginning of the simulation. The $dumpon, $dumpoff, and
$dumpall control the dump process during the simulation.[5]

28
2024-12-26

Questions

 1) Using assign and deassign statements, design a


positive edge-triggered D-flipflop with asynchronous
clear (q=0) and preset (q=1).
 2) Using primitive gates, design a 1-bit full adder FA.
Instantiate the full adder inside a stimulus module. Force
the sum output to a & b & c_in for the time between 15
and 35 units.

Questions
 What will be the output of the $display statement
shown below?
 module top;
 A a1();
 endmodule
 module A;
 B b1();
 endmodule
 module B;
 initial
 $display("I am inside instance %m");
 endmodule

29
2024-12-26

Questions
 Identify the files to which the following display
statements will write:
 //File output with multi-channel descriptor
 module test;
 integer handle1,handle2,handle3; //file handles
 //open files
 initial
 begin
 handle1 = $fopen("f1.out");
 handle2 = $fopen("f2.out");
 handle3 = $fopen("f3.out");
 end

Questions
 //Display statements to files
 initial
 begin
 //File output with multi-channel descriptor
 #5;
 $fdisplay(4, "Display Statement # 1");
 $fdisplay(15, "Display Statement # 2");
 $fdisplay(6, "Display Statement # 3");
 $fdisplay(10, "Display Statement # 4");
 $fdisplay(0, "Display Statement # 5");
 end
 endmodule

30
2024-12-26

Q&A

December 26, 2024

31

You might also like