- What are a few considerations while partitioning large designs?
- How can I reliably convey control information across clock domains?
- What is a safe strategy to transfer data of different buswidths and across different clock domains?
- What are a few considerations while using FIFOs for posted writes or prefetched reads that influence the speed of the design?
- What will be synthesized of a module with only inputs and no outputs?
- Why do I see latches in my synthesized logic?
- What are combinatorial timing loops? Why should they be avoided?
- How does the sensitivity list of a combinatorial always block affect pre- and post- synthesis simulation?
- How do the `ifdef, `ifndef, `elsif, `endif constructs aid in minimizing area?
- What is constant propagation? How can I use constant propagation to minimize area?
What are a few considerations while partitioning large designs?
- Size and complexity of the design: A large design will need to be partitioned into a number of smaller designs. This can affect how the design is divided into different sections and the size of each partition.
- Clock Domains: It is recommended to group logic belonging to same clock domain in a single block, and clock domain crossings done thorugh a synchronizer.
- Specific design requirements: Specific design requirements, such as timing or power constraints, will affect how the design is partitioned.
- Vendor's requirements: The vendor's requirements must also be considered as the partitioning of designs will be determined largely by their manufacturing capabilities.
How can I reliably convey control information across clock domains?
- Use a two-flop synchronizer: A two-flop synchronizer is a common technique used to safely transfer data between clock domains. It consists of two registers placed in series, one in each clock domain, to ensure reliable transfer of data across domains.
- Be aware of clock skew: Clock skew can occur between different clock domains and can adversely affect the timing of the control signal. To mitigate this, compensate for the clock skew by adding a delay buffer.
- Consider using asynchronous FIFOs: Asynchronous FIFOs are used to transfer data between clock domains that have different clock frequencies. By implementing flow control and arbitration logic, asynchronous FIFOs can help avoid data loss, blocking, or lock-up.
- Simulate and verify: Always simulate and verify the design with all possible corner-case scenarios to ensure that control information is reliably transferred across different clock domains.
What is a safe strategy to transfer data of different buswidths and across different clock domains?
An asymmetrical FIFO is an ideal component for this purpose where the bus width between the write side and the read sides are different.
Read more on Synchronous FIFO.
What are a few considerations while using FIFOs for posted writes or prefetched reads that influence the speed of the design?
When the write and read sides are running on different clock frequencies, a FIFO acts as a buffer thereby allowing the write side to simply push the transfer into the buffer instead of waiting for the slave to respond and the transfer to complete. This allows better utilization of the bus.
However, assume that the master posted data into the FIFO and assumed it to have completed. If the slave now issues an error, this condition will have to be routed back to the master somehow like an interrupt so it can resend the same transfer.
If the master aborts a read transaction late in the cyle when read prefetch has already taken place, then it is possible to get stale data from the FIFO, and contents may need to be flushed.
What will be synthesized of a module with only inputs and no outputs?
If a module has only inputs and no outputs, then the synthesis tool may throw empty modules with no logic or little logic.
Why do I see latches in my synthesized logic?
Latches usually result when the tool cannot determine a unique value for a signal during synthesis. If the sequential logic in your RTL code is incomplete, contains uninitialized values, or does not have a defined output value for some input combination, the synthesis tool may generate latches to store the input signals' present values. If there are incomplete case
or if else
statements in the RTL code, the synthesis tool may generate latches to hold intermediate states until a valid condition is met.
Read more on Latch.
What are combinatorial timing loops? Why should they be avoided?
Combinatorial timing loops, also known as combinational feedback loops, are a type of timing issue that can occur in digital circuits. They happen when a logic path's output is fed back to its input without passing through any registers or flip-flops, creating an infinite loop that prevents the circuit from settling to a stable state. This means that the output of the circuit is undefined.
// A simple example shown below has output depedent on itself
// However, it can be complex with more logic in between but ultimately
// feeding back to the same signal without any flops in between
assign out = out & in;
Combinatorial timing loops should be avoided in digital circuits for a few reasons:
- They can cause glitches: When a combinational loop exists, it creates a race condition where the output of the loop is dependent on the delays of the logic gates. Any small variation in these delays may cause the output of the circuit to glitch, leading to unpredictable behavior.
- They increase power consumption: When a combinational loop exists, the logic gates are continuously toggling outputs without settling to a stable state. This results in a high switching activity, which can increase the power consumption of the circuit.
- They increase the propagation delay: Combinatorial loops can lead to an increase in the circuit's propagation delay since the output of the loop depends on the previous output.
How does the sensitivity list of a combinatorial always block affect pre- and post- synthesis simulation?
The sensitivity list of a combinatorial always block specifies the input signals to the block that trigger its execution. The sensitivity list informs the simulation tool which input signals to monitor for changes that would require an update in the output.
Verilog and SystemVerilog languages have evolved to allow designers represent their intentions more easily with new constructs.
// A normal sensitivity list should include all signals that affect output
always @ (a, b, c, d) begin
out = (a & b) ^ (c | d);
end
// Use * to let tool automatically add such signals into the sensitivity list
always @ (*) begin
out = (a & b) ^ (c | d);
end
// SystemVerilog has another keyword
always_comb begin
out = (a & b) ^ (c | d);
end
How do the `ifdef, `ifndef, `elsif, `endif constructs aid in minimizing area?
The conditional compilation constructs, such as `ifdef, `ifndef, `elsif, and `endif, allow the designer to choose which part of the design is included in the synthesis process. This is useful when certain parts of the design are not necessary for the final implementation, and including them can result in an unnecessarily large area. By selectively including parts of the design, the synthesis tool can optimize the output circuit for a smaller size.
Read more on Verilog `ifdef Conditional Compilation.
What is constant propagation? How can I use constant propagation to minimize area?
Constant propagation is a compiler optimization technique that replaces the usage of variables with their constant values which helps reduce area and improve the performance of the synthesized circuit.
parameter zero = 0;
assign out = (zero == 1) ? in1 : in2;
In Verilog, constant propagation optimizes the circuit by replacing the values of variables that remain constant throughout the simulation with their final values. If a variable has a constant value, the synthesis tool optimizes the logic by replacing the variable with a wire that has the same constant value. This can help reduce the size of the synthesized circuit since fewer resources are required to implement the design.