This part focuses on synthesis considerations, testbench writing, and advanced Verilog concepts. These questions are common in senior design and verification roles.
Synthesizable constructs include: assign, always @(posedge clk), always @(*), if-else, case/casez, arithmetic/bitwise/logical operators, module instances, generate blocks, function (without timing), continuous assignments, and for loops with fixed bounds. Non-synthesizable constructs include: initial (except for reset), #delay, $display, $monitor, $readmemh/$readmemb, force/release, fork/join, wait, @(posedge ...) in testbenches, and while/forever loops without a fixed bound.
`timescale directive and how is it used?`timescale sets the time unit and precision for a module. The syntax is `timescale unit / precision, e.g., `timescale 1 ns / 1 ps means time values are in nanoseconds and fractional delays are rounded to picoseconds. It affects how #delay statements are interpreted. Each module should have its own `timescale directive before the module declaration. In SystemVerilog, timeunit and timeprecision keywords provide a more scoped alternative.
`default_nettype none?`default_nettype none instructs the compiler to not implicitly declare undeclared signals as wire (the default behavior in Verilog). This forces designers to explicitly declare every signal, catching typos and missing declarations at compile time rather than at synthesis or debug time. It is a best practice for RTL design, especially in larger teams and projects.
$stop and $finish.$stop pauses the simulation and returns control to the simulator command line, allowing the user to inspect signals and continue. $finish terminates the simulation entirely and exits back to the operating system. $stop is used for interactive debugging, while $finish is used at the end of a testbench. An optional argument (0, 1, 2) controls the verbosity of the exit message.
$signed and $unsigned do?$signed() casts a vector expression to be treated as a signed number during arithmetic operations, so sign-extension is applied. $unsigned() casts it back to unsigned. For example, $signed(4'b1111) is interpreted as -1, while 4'b1111 is 15. In modern code, it is cleaner to declare ports and regs as signed (e.g., input signed [7:0] a) rather than using these system functions.
force and release work in Verilog?force overrides the value of a net or variable regardless of its driver. It is used primarily in testbenches to inject stimulus or override internal signals for debugging. release removes the forced value and restores the original driver. For example, force top.u1.signal = 1'b1; will hold that signal at 1 until release top.u1.signal; is called. These constructs are not synthesizable.
$readmemh and $readmemb do?$readmemh and $readmemb read a file containing hexadecimal or binary values into an array (typically a memory). The syntax is $readmemh("filename", mem_array, start_addr, end_addr). They are commonly used in testbenches to load initialization data into ROM/RAM models. The file format is one value per line, with optional comments using // or /* */. These are not synthesizable.
generate blocks in Verilog.generate blocks allow conditional or iterative instantiation of modules, assignments, and always blocks at compile time. They use genvar for loop indices. Common use cases include parameterized instantiation, conditional inclusion of logic, and building regular structures like memories or adders.
module adder_tree #(parameter N = 4) (
input [N-1:0] a, b,
output [N:0] sum
);
wire [N:0] c;
genvar i;
generate
for (i = 0; i < N; i = i + 1) begin : bit
assign c[i] = a[i] & b[i];
end
endgenerate
endmodule
module nbit_adder #(parameter N = 8) (
input [N-1:0] a, b,
input cin,
output [N-1:0] sum,
output cout
);
assign {cout, sum} = a + b + cin;
endmodule
Inertial delay is the default delay mode in Verilog. It models the physical property that a pulse shorter than the delay is filtered out (not propagated). For example, assign #5 y = a; will reject glitches on a that are shorter than 5 time units. Transport delay propagates all pulses regardless of width, modeling transmission line effects. It is modeled using assign #a_transport_var with the transport path delay model or by using specify blocks with $setup/$hold. Transport delay is more common in gate-level simulations.
Understanding synthesis and testbench concepts is key to bridging the gap between simulation and real hardware. Explore SystemVerilog topics next for more advanced verification techniques.