1//
2// LRM 22. Compiler Directives
3//  `define should have its own kind other than constant (c)
4
5//
6// 22.4 `include
7//
8`include "parts/count.v"
9`include "fileB" // including fileB
10`include <List.vh>
11
12//
13// 22.5 `define, `undef, and `undefineall
14//
15module directive;
16`define D(x,y) initial $display("start", x , y, "end");
17`D( "msg1" , "msg2" )
18// expands to 'initial $display("start", "msg1" , "msg2", "end");'
19`D( " msg1", )
20// expands to 'initial $display("start", " msg1" , , "end");'
21`D(, "msg2 ")
22// expands to 'initial $display("start", , "msg2 ", "end");'
23`D(,)
24// expands to 'initial $display("start", , , "end");'
25`D( , )
26// expands to 'initial $display("start", , , "end");'
27//`D("msg1")
28// illegal, only one argument
29//`D()
30// illegal, only one empty argument
31//`D(,,)
32// illegal, more actual than formal arguments
33
34`define MACRO1(a=5,b="B",c) $display(a,,b,,c);
35`MACRO1 ( , 2, 3 ) // argument a omitted, replaced by default
36// expands to '$display(5,,2,,3);'
37`MACRO1 ( 1 , , 3 ) // argument b omitted, replaced by default
38// expands to '$display(1,,"B",,3);'
39`MACRO1 ( , 2, ) // argument c omitted, replaced by nothing
40// expands to '$display(5,,2,,);'
41//`MACRO1 ( 1 ) // ILLEGAL: b and c omitted, no default for c
42
43`define MACRO2(a=5, b, c="C") $display(a,,b,,c);
44`MACRO2 (1, , 3) // argument b omitted, replaced by nothing
45// expands to '$display(1,,,,3);'
46`MACRO2 (, 2, ) // a and c omitted, replaced by defaults
47// expands to '$display(5,,2,,"C");'
48`MACRO2 (, 2) // a and c omitted, replaced by defaults
49// expands to '$display(5,,2,,"C");'
50
51`define MACRO3(a=5, b=0, c="C") $display(a,,b,,c);
52`MACRO3 ( 1 ) // b and c omitted, replaced by defaults
53// expands to '$display(1,,0,,"C");'
54`MACRO3 ( ) // all arguments replaced by defaults
55// expands to '$display(5,,0,,"C");'
56//`MACRO3 // ILLEGAL: parentheses required
57
58`define wordsize 8
59logic [1:`wordsize] data;
60
61//define a nand with variable delay
62`define var_nand(dly) nand #dly
63`var_nand(2) g121 (q21, n10, n11);
64`var_nand(5) g122 (q22, n10, n11);
65
66// illegal
67//`define first_half "start of string
68//$display(`first_half end of string");
69
70`define max(a,b)((a) > (b) ? (a) : (b))
71n = `max(p+q, r+s) ;
72
73`define TOP(a,b) a + b
74`TOP( `TOP(b,1), `TOP(42,a) )
75
76endmodule
77
78module main;
79`define HI Hello
80`define LO "`HI, world"
81`define H(x) "Hello, x"
82
83    initial begin
84        $display("`HI, world");
85        $display(`LO);
86        $display(`H(world));
87    end
88endmodule
89
90module directive2;
91`define msg(x,y) `"x: `\`"y`\`"`"
92`define append(f) f``_master
93
94    initial begin
95        $display(`msg(left side,right side));
96        `append(clock) = 1'b0;
97    end
98
99`define home(filename) `"/home/mydir/filename`"
100`include `home(myfile)
101
102endmodule
103
104//
105// 22.6 `ifdef, `else, `elsif, `endif, `ifndef
106//
107module and_op (a, b, c);
108    output a;
109    input b, c;
110    `ifdef behavioral
111        wire a = b & c;
112    `else
113        and a1 (a,b,c);
114    `endif
115endmodule
116
117module test(out);
118    output out;
119    `define wow
120    `define nest_one
121    `define second_nest
122    `define nest_two
123    `ifdef wow
124        initial $display("wow is defined");
125        `ifdef nest_one
126            initial $display("nest_one is defined");
127            `ifdef nest_two
128                initial $display("nest_two is defined");
129            `else
130                initial $display("nest_two is not defined");
131            `endif
132        `else
133            initial $display("nest_one is not defined");
134        `endif
135    `else
136        initial $display("wow is not defined");
137        `ifdef second_nest
138            initial $display("second_nest is defined");
139        `else
140            initial $display("second_nest is not defined");
141        `endif
142    `endif
143endmodule
144
145module test;
146    `ifdef first_block
147        `ifndef second_nest
148            initial $display("first_block is defined");
149        `else
150            initial $display("first_block and second_nest defined");
151        `endif
152    `elsif second_block
153        initial $display("second_block defined, first_block is not");
154    `else
155        `ifndef last_result
156            initial $display("first_block, second_block,",
157                " last_result not defined.");
158        `elsif real_last
159            initial $display("first_block, second_block not defined,",
160                " last_result and real_last defined.");
161        `else
162            initial $display("Only last_result defined!");
163        `endif
164    `endif
165endmodule
166
167// orignal tests
168module ifdef_in_port (
169    input logic a,
170    `ifdef FOO// comment w/o white space
171        input logic b1,
172    `elsif BAR  // coment w/ white space
173        input logic b2,
174    `else/* old C comment */ // foo
175        input logic b3,
176    `endif /* old C comment */ // foo
177    input logic c
178);
179
180endmodule
181
182typedef logic user_t;
183module define_in_port (
184    input user_t a,
185`define FOO
186    input user_t b,
187`define BAR
188`ifdef FOO
189        input user_t c1,
190`elsif BAZ
191        input user_t c2,
192`else
193        input user_t c3,c4,
194`endif
195`ifdef FOO
196        output user_t d1 ,
197`else
198        output user_t d2
199`endif
200);
201
202endmodule
203
204module define_in_port_messy (
205    input user_t a
206`define FOO
207    ,input user_t b
208`define BAR
209`ifdef FOO
210        ,input user_t c1
211`elsif BAZ
212        ,input user_t c2
213`else
214        ,input user_t c3 , c4
215`endif
216`ifdef FOO
217        , output user_t d1
218`else
219        , output user_t d2
220`endif
221);
222
223endmodule
224
225`undef  MY_UNDEF
226`define MY_DEFINE
227
228`define assert_clk(arg, __clk=clk, __rst_n=rst_n) \
229 assert property (@(posedge __clk) disable iff (!__rst_n) arg)
230
231module forSkipMacro;
232`define add_t(f) f``_t
233    var `add_t(foo) = '0;
234
235    `macro({e},FOO)
236    `macro("string",FOO)
237    `macro(bar)
238    `macro(int)
239    `macro(int,bar)
240endmodule
241