We use synthesizable constructs to create hardware circuits from code. Non-synthesizable constructs help us test and simulate designs but cannot become hardware.
Synthesizable vs non-synthesizable constructs in Verilog
// Synthesizable example always @(posedge clk) begin q <= d; end // Non-synthesizable example initial begin $display("Hello, simulation!"); #10 $finish; end
Synthesizable code describes hardware circuits and uses constructs like always blocks triggered by signals.
Non-synthesizable code often uses initial blocks and system tasks like $display for simulation only.
d to output q on clock's rising edge.always @(posedge clk) begin q <= d; end
initial begin $display("Start simulation"); #5 $finish; end
assign y = a & b;
always @(posedge clk) begin if (reset) q <= 0; else q <= q + 1; end
This module shows synthesizable code for a flip-flop and non-synthesizable code to print a message and stop simulation.
`timescale 1ns/1ps
module example(input clk, input reset, input d, output reg q);
// Synthesizable: flip-flop behavior
always @(posedge clk) begin
if (reset) q <= 0;
else q <= d;
end
// Non-synthesizable: simulation message
initial begin
$display("Simulation started");
#20 $finish;
end
endmoduleOnly synthesizable constructs can be turned into real hardware by synthesis tools.
Non-synthesizable constructs are useful for testing and debugging but are ignored by synthesis.
Common non-synthesizable features include initial blocks, delays (#), and system tasks like $display.
Synthesizable constructs describe hardware and run on real devices.
Non-synthesizable constructs help simulate and test designs but do not become hardware.
Use synthesizable code for design, non-synthesizable code for simulation and debugging.
Practice
non-synthesizable and used only for simulation?Solution
Step 1: Understand the role of
initialblocksinitialblocks run once at simulation start and are not synthesizable into hardware.Step 2: Compare with synthesizable constructs
alwaysblocks,assignstatements, and module instantiations describe hardware and are synthesizable.Final Answer:
Initial blocks (initial) -> Option BQuick Check:
initial= Non-synthesizable [OK]
initial blocks only simulate, never synthesize [OK]- Confusing
alwayswithinitial - Thinking
assignis non-synthesizable - Assuming module instantiations are simulation-only
always block sensitive to the positive edge of clock clk?Solution
Step 1: Identify correct edge sensitivity
Synthesizable clocked logic usesposedge clkornegedge clkto trigger on clock edges.Step 2: Check syntax correctness
always @(posedge clk)is correct;always @(clk)triggers on any change, which is not typical for clocked logic.Final Answer:
always @(posedge clk) begin ... end -> Option DQuick Check:
Useposedge clkfor clock edge sensitivity [OK]
posedge or negedge for clock edges [OK]- Using level sensitivity instead of edge sensitivity
- Mixing clock and reset signals incorrectly
- Omitting
beginandendfor multiple statements
reg [3:0] count; initial begin count = 0; #5 count = 4'b1010; end always @(posedge clk) begin count <= count + 1; end
Assuming
clk toggles every 1 time unit starting at 0.Solution
Step 1: Analyze
Theinitialblock effectinitialblock setscountto 0 at time 0, then to 10 at time 5 (delay #5).Step 2: Analyze
Thealwaysblock behavioralwaysblock incrementscounton every positive clock edge, but the non-blocking assignment means the update happens after the clock edge, so the delayed assignment at time 5 overrides the count value at that time.Final Answer:
Count stays 0 until time 5, then becomes 10 and increments every clock cycle -> Option AQuick Check:
initial#delay executes after clock edges [OK]
initial affects count after clock increments [OK]- Ignoring the
initialblock's delayed assignment - Assuming
countincrements from 10 immediately - Confusing blocking and non-blocking assignments
always @(posedge clk) begin
integer i;
for (i = 0; i < 4; i = i + 1) begin
data[i] = i;
end
endSolution
Step 1: Check variable declarations and loop usage
Declaringinteger iinside thealwaysblock is allowed for synthesis as loop variable.Step 2: Identify assignment type issue
Using blocking assignment=inside clockedalwaysblock causes unintended behavior; non-blocking<=is required for registers.Final Answer:
Using blocking assignment (=) instead of non-blocking (<=) inside always block -> Option CQuick Check:
Use non-blocking (<=) in clocked always blocks [OK]
- Thinking loop variables cannot be declared inside always blocks
- Believing for loops are non-synthesizable
- Ignoring difference between blocking and non-blocking assignments
sig is high during clock cycles, but also print the count value for debugging during simulation. Which approach correctly separates synthesizable and non-synthesizable constructs?Solution
Step 1: Identify synthesizable counting logic
Counting on clock edges must be in analways @(posedge clk)block using non-blocking assignments.Step 2: Identify non-synthesizable debugging code
Printing with$displayis simulation-only and must be placed in aninitialor separate simulation-only block.Final Answer:
Use analways @(posedge clk)block to increment count and aninitialblock with$displayto print count -> Option AQuick Check:
Separate hardware logic and simulation prints [OK]
initial, counting in clocked always [OK]- Trying to print inside synthesizable
alwaysblock - Using continuous assignment for counting
- Confusing tasks/functions for simulation prints
Ready to prove it?
Pass the test and this pattern moves unknown
