Functional Overview
The always and assign constructs serve as fundamental building blocks for describing hardware behavior in Verilog. Each statement type maps to specific digital circuitry, making them essential for implementing complete digital systems.
Circuit Representation
Understanding the hardware mapping of these statements is critical for efficient FPGA and ASIC design. The following example demonstrates how these constructs translate to physical hadrware:
reg r_counter;
wire w_output;
always@(posedge sys_clock)
begin
if(!sys_reset_n)
begin
r_counter <= 8'h00;
end
else
begin
r_counter <= r_counter + 1'b1;
end
end
assign w_output = r_counter[7];
Synthesis Mapping
Sequential Logic via always Block
The always@(posedge clk) construct generates flip-flop (FF) or latch elements in synthesized hardware. Control signals fall into three primary categories:
- Synchronous Reset: Reset signal is not part of the sensitivity list; it takes effect on the next clock edge
- Asynchronous Reset: Reset must be included in the sensitivity list for immediate response
- Clock Enable: Logic maintains current state when disabled
These three control mechanisms collectively form control sets within the device fabric. To FPGA implementations, grouping logic with shared control sets optimizes resource utilization and improves timing closure.
Combinational Logic via always Block
The always@(*) construct synthesizes pure combinational logic without any storage elements. This approach is particularly useful when implementing state machines with case statements or complex conditional logic that requires no memory.
Continuous Assignment via assign Statement
The assign statement creates wire interconnections and combinational logic networks. The synthesized hardware encompasses:
- Level translation and buffering
- Combinational datapath operations
- Comparison and arithmetic functions
Combining always with generate
When always blocks are instantiated within generate loops, they create cascaded register arrays or replicated logic structures. The synthesis tool applies the following principles:
- Matching bit widths result in straightforward duplication
- Width mismatches trigger automatic zero or sign extension
- The underlying hardware consists of paralel register banks connected in a configurable pattern
This technique enables the construction of flexible logic groups suitable for implementing memory structures, data parsing engines, and bit manipulation operations.
localparam PATTERN = "testing";
reg [7:0] r_buffer [0:7];
generate genvar idx;
for(idx = 0; idx < 8; idx = idx + 1)
begin: BUFFER_LOOP
always@(posedge clock)
begin
r_buffer[idx] <= PATTERN[8*(idx+1)-1:8*idx];
end
end
endgenerate
This example illustrates storing a string constant into a two-dimensional register array. Adding conditional logic within the loop enables string analysis, pattern matching, and bit-position identification. For instance, locating the most significant set bit in a 128-bit vector becomes straightforward with nested loops, yielding concise and maintainable code.