Generally speaking, a makefile is a file that defines one or more execution rules and methods and is executed by the make command. This section will provide a simple and direct explanation of makefile and illustrate its application in the IC design simulation process.
The rules for writing a makefile are as follows:
target ... :prerequisites ... command ......
(1) target indicates the goal of the rule, referring to the target file or the necessary intermediate files for generating this target file, or it can be a custom command specified during the execution of make. It cannot be omitted.
(2) prerequisites indicate the preconditions of the rule, referring to the list of targets (intermediate target files or custom commands) that the target file depends on. It can be omitted.
(3) command indicates the command line of the rule, referring to the command line that needs to be executed to generate the target file. It is important to note that the command line must start with a TAB character and cannot use spaces or other characters. It can be omitted.
(4) The name of the makefile can only be “makefile” or “Makefile”.
◆ Example of Compiling with Makefile
When converting C language source files into executable files, generally, two processes are required: compilation and linking.
The compilation process mainly checks the syntax of the source files and then generates intermediate target files (O files or OBJ files).
The linking process mainly organizes and merges the intermediate target files, determines various dependencies, and finally generates the executable file.
For example, if a project contains three C files: main.c, source1.c, source2.c and two header files: source1.h, source2.h, the makefile with compilation and linking functions can be written as follows:
main.exe: main.o source1.o source2.o gcc -o main.exe main.o source1.o source2.o
main.o: main.c gcc -c main.c
source1.o: source1.c source1.h gcc -c source1.c
source2.o: source2.c source2.h gcc -c source2.c
In the current path, enter the make command, and the execution process is as follows:
(1) make will look for a file named “makefile” or “Makefile” in the current directory.
(2) If not found, it will report an error and exit; if found, it will take the first target in the makefile as the final target file, for example, in this case, main.exe is the final target file.
(3) If the target file main.exe does not exist, or the modification time of its dependent .o files is later than main.exe, the command line corresponding to generating the main.exe target file will be executed; otherwise, the corresponding command line will not be executed.
(4) Similarly, if the .o files that generate the target file main.exe do not exist, or the modification time of the .c and .h files that generate the .o files is later than the .o files, the command line for generating the .o files will also be executed; otherwise, the corresponding command line will not be executed.
(5) Likewise, all intermediate target files required to generate the final target file will also be determined whether to execute the corresponding command line based on the modification time of their dependency files. If the modification time of the dependency files is later than the target file, the target file will be regenerated; if the modification time of the dependency files is earlier than the target file, the corresponding command line will not be executed.
(6) Finally, based on the dependency relationships between the files, the corresponding command lines will be executed to generate the corresponding target files, completing the compilation and linking process.
From the execution process of the makefile, it can be seen that when there are too many source files to compile, only the files that have been modified will have their corresponding compilation or linking command lines executed. This automated compilation process greatly improves the efficiency of software development.
◆ General Example of Makefile
More generally, a makefile defines the execution rules of commands and generates target files through the make command, rather than just being used for compilation and linking.
For example, if two text files a.txt and b.txt have the following contents:

Now, if you need to merge the two files into one file c.txt, the rules of the makefile can be written as:
c.txt: a.txt b.txt cat a.txt b.txt > c.txt
By executing the make command in the current path, the file c.txt can be obtained, with the following content:

Makefile also has the effect of simplifying commands, and the following explains the application of makefile in the VCS simulation process.
Using Makefile for Simulation Process
In the section “1.3 VCS+Verdi Simulation Process”, the run_vcs.sh script can start the VCS compilation, the run_simv.sh script can start the simv simulation process, and the run_verdi.sh script can start Verdi to view the waveform.
Still using the simulation environment from “1.3 VCS+Verdi Simulation Process”, move the file.list and macro.list files from the path vcs to the sim path, and delete the folder vcs. Switch to the sim path and create a makefile file, then the execution commands corresponding to each stage in the simulation process can be represented in the makefile as:
all: clean vcs sim
# compiling, corresponding to run_vcs.sh
vcs: vcs -full64 -notice -debug_all -j8 -timescale=1ns/1ps \
+plusargs_save +libext+.v+.V+.sv+.svh -sverilog +memcbk \
-P ${Verdi_HOME}/share/PLI/VCS/LINUX64/novas.tab \
${Verdi_HOME}/share/PLI/VCS/LINUX64/pli.a \
-cpp /usr/bin/g++-4.4 -cc /usr/bin/gcc-4.4 \
-f file.list -f macro.list -top test \
-l compile.log
# simulation, corresponding to run_simv.sh
sim: ./simv -ucli -i wave_gen.tcl -l sim.log
# start verdi, corresponding to run_verdi.sh
verdi: verdi -f file.list -f macro.list \
-top test -ssf dump.fsdb -nologo &
# delete useless files
clean: rm -rf simv* *.log *.fsdb novas* *.key csrc verdiLog
At this point, in the sim path:
◆ Execute the command make vcs to complete the VCS compilation process;
◆ Execute the command make sim to complete the simv simulation process;
◆ Execute the command make verdi to start Verdi to view the waveform, and be careful not to omit the symbol “&” when writing the command line;
◆ Execute the command make clean to delete the intermediate files generated during the compilation and simulation processes to avoid mutual influence during multiple simulations when the design is modified multiple times;
◆ Execute the command make all to automatically complete the deletion of intermediate files, VCS compilation, and simv simulation process. In the makefile, the target all depends on the targets clean, vcs, and sim.