7.1 The `include Directive: Code Organization and Reusability
What is `include?
The `include directive inserts the contents of another file directly into the current file at the point where the directive appears. It's analogous to #include in C/C++.
​
`include "filename.v"
`include "path/to/file.vh"
`include "/absolute/path/to/definitions.svh"
​
Syntax Rules:
​
-
Filename must be in double quotes
-
Can use relative or absolute paths
-
File is inserted textually at directive location
-
Typically used for header files with .vh or .svh extension
-
Can include any valid Verilog code
7.1.1. Common Use Cases
7.1.1.1. Use Case 1: Shared Parameter Definitions
​
File: system_params.vh
Verilog
// System-wide parameters
`ifndef SYSTEM_PARAMS_VH
`define SYSTEM_PARAMS_VH
// Clock frequencies
`define SYS_CLK_FREQ_MHZ 100
`define UART_CLK_FREQ_MHZ 50
`define DDR_CLK_FREQ_MHZ 800
// Bus widths
`define AXI_DATA_WIDTH 64
`define AXI_ADDR_WIDTH 32
`define AXI_ID_WIDTH 4
// Memory configuration
`define CACHE_LINE_SIZE 64
`define CACHE_NUM_LINES 512
`define ROM_SIZE_BYTES 65536
`endif // SYSTEM_PARAMS_VH
File: axi_master.v
`include "system_params.vh"
module axi_master #(
parameter DATA_WIDTH = `AXI_DATA_WIDTH,
parameter ADDR_WIDTH = `AXI_ADDR_WIDTH,
parameter ID_WIDTH = `AXI_ID_WIDTH
)(
input wire clk,
input wire rst_n,
// AXI interface
output reg [ID_WIDTH-1:0] awid,
output reg [ADDR_WIDTH-1:0] awaddr,
output reg [DATA_WIDTH-1:0] wdata,
// ... other ports
);
// Use system-wide definitions
localparam CLOCK_FREQ = `SYS_CLK_FREQ_MHZ;
// Implementation
endmodul
7.1.1.2. Use Case 2: Common Package Definitions
​
File: protocol_pkg.vh
Verilog
`ifndef PROTOCOL_PKG_VH
`define PROTOCOL_PKG_VH
// AXI Protocol Constants
`define AXI_BURST_FIXED 2'b00
`define AXI_BURST_INCR 2'b01
`define AXI_BURST_WRAP 2'b10
`define AXI_SIZE_1_BYTE 3'b000
`define AXI_SIZE_2_BYTES 3'b001
`define AXI_SIZE_4_BYTES 3'b010
`define AXI_SIZE_8_BYTES 3'b011
`define AXI_SIZE_16_BYTES 3'b100
`define AXI_RESP_OKAY 2'b00
`define AXI_RESP_EXOKAY 2'b01
`define AXI_RESP_SLVERR 2'b10
`define AXI_RESP_DECERR 2'b11
// AMBA AHB Constants
`define AHB_TRANS_IDLE 2'b00
`define AHB_TRANS_BUSY 2'b01
`define AHB_TRANS_NONSEQ 2'b10
`define AHB_TRANS_SEQ 2'b11
`define AHB_BURST_SINGLE 3'b000
`define AHB_BURST_INCR 3'b001
`define AHB_BURST_WRAP4 3'b010
`endif // PROTOCOL_PKG_VH
Usage in Design:
Verilog
`include "protocol_pkg.vh"
module axi_to_ahb_bridge (
// ports
);
always @(posedge clk) begin
case (axi_burst_type)
`AXI_BURST_FIXED: begin
ahb_trans <= `AHB_TRANS_NONSEQ;
end
`AXI_BURST_INCR: begin
ahb_burst <= `AHB_BURST_INCR;
end
endcase
end
endmodule
7.1.1.3. Use Case 3: Register Map Definitions
​
File: register_map.vh
Verilog
`ifndef REGISTER_MAP_VH
`define REGISTER_MAP_VH
// Control and Status Registers
`define REG_CTRL_ADDR 32'h0000_0000
`define REG_STATUS_ADDR 32'h0000_0004
`define REG_INT_ENABLE_ADDR 32'h0000_0008
`define REG_INT_STATUS_ADDR 32'h0000_000C
// Configuration Registers
`define REG_CLK_DIV_ADDR 32'h0000_0010
`define REG_TIMEOUT_ADDR 32'h0000_0014
`define REG_MODE_ADDR 32'h0000_0018
// Data Registers
`define REG_TX_DATA_ADDR 32'h0000_0020
`define REG_RX_DATA_ADDR 32'h0000_0024
// Control Register Bit Fields
`define CTRL_ENABLE_BIT 0
`define CTRL_RESET_BIT 1
`define CTRL_INT_EN_BIT 2
`define CTRL_MODE_BIT_START 4
`define CTRL_MODE_BIT_END 6
// Status Register Bit Fields
`define STATUS_BUSY_BIT 0
`define STATUS_ERROR_BIT 1
`define STATUS_READY_BIT 2
`define STATUS_OVERFLOW_BIT 3
`endif // REGISTER_MAP_VH
Usage in Register Block:
`include "register_map.vh"
module register_block (
input wire [31:0] addr,
input wire [31:0] wdata,
input wire write_en,
output reg [31:0] rdata
);
reg [31:0] ctrl_reg;
reg [31:0] status_reg;
reg [31:0] config_reg;
// Write logic
always @(posedge clk) begin
if (write_en) begin
case (addr)
`REG_CTRL_ADDR: begin
ctrl_reg <= wdata;
end
`REG_CLK_DIV_ADDR: begin
config_reg <= wdata;
end
// ... other registers
endcase
end
end
// Read logic
always @(*) begin
case (addr)
`REG_CTRL_ADDR: rdata = ctrl_reg;
`REG_STATUS_ADDR: rdata = status_reg;
`REG_CLK_DIV_ADDR: rdata = config_reg;
default: rdata = 32'h0;
endcase
end
// Extract control fields
wire enable = ctrl_reg[`CTRL_ENABLE_BIT];
wire reset_req = ctrl_reg[`CTRL_RESET_BIT];
wire [2:0] mode = ctrl_reg[`CTRL_MODE_BIT_END:`CTRL_MODE_BIT_START];
endmodule
7.1.2. Best Practices for `include
7.1.2.1. Use Include Guards
​
Always protect header files with include guards to prevent multiple inclusion:
Verilog
// Good practice - with include guard
`ifndef MY_HEADER_VH
`define MY_HEADER_VH
// Header content here
`endif // MY_HEADER_VH
​
Why? Without guards, including the same file twice causes redefinition errors:
​
// File: defs.vh (without guard)
`define BUS_WIDTH 32
// File: top.v
`include "defs.vh"
`include "defs.vh" // ERROR: BUS_WIDTH already defined!
7.1.2.2. Organize include Files by Purpose

7.1.2.3. Use Relative Paths When Possible
Verilog
// Good - relative path
`include "../includes/system_params.vh"
// Avoid - absolute path (not portable)
`include "/home/user/project/includes/system_params.vh"
7.1.2.4. Document Dependencies
Verilog
/**
* Module: axi_master
* Dependencies:
* - system_params.vh : System-wide parameters
* - axi_defs.vh : AXI protocol constants
*/
`include "system_params.vh"
`include "axi_defs.vh"
module axi_master (...);
7.1.2.5. Minimize Include Depth
Verilog
// Avoid - deep nesting
// file_a.vh includes file_b.vh
// file_b.vh includes file_c.vh
// file_c.vh includes file_d.vh
// Hard to track dependencies!
// Better - flat structure
// Each file includes only what it needs directly
7.1.3. Hidden Challenges with `include
7.1.3.1. Circular Dependencies
Verilog
// File: module_a.vh
`include "module_b.vh"
`define A_CONSTANT 10
// File: module_b.vh
`include "module_a.vh" // ERROR: Circular dependency!
`define B_CONSTANT 20
Solution: Use include guards and restructure dependencies.
​
7.1.3.2. Search Path Issues
Verilog
// If compiler can't find file
`include "my_header.vh" // ERROR: File not found
Solution: Configure compiler include paths:
# For Vivado
vlog +incdir+./includes module.v
# For ModelSim
vlog -incdir ./includes module.v
# For VCS
vcs +incdir+./includes module.v
7.1.3.3. Including Modules
Verilog
// Bad practice - don't include modules
`include "uart.v" // Avoid this!
// Good practice - compile separately and link
// Compile: uart.v
// Compile: top.v (instantiates uart)
