AN 917: Reset Design Techniques for Intel® Hyperflex™ Architecture FPGAs

ID 683539
Date 1/05/2021
Public
Document Table of Contents

1.4.2.2. Coding Reset-Related Optimizations

As mentioned, you can implement the following reset related coding changes to fully enable Hyper-Retiming optimization across your design:

  • Convert asynchronous resets to synchronous resets.
  • Remove resets on datapath registers or pipeline registers when the functionality allows, to lessen routing congestion in areas where the data registers are involved.

However, if applied incorrectly, these reset related optimization can actually cause retiming restrictions.

For example, consider the following initial code with a mix of control signals and data registers:

always @(posedge clk or negedge rstb)
begin
	if (!rstb)
		begin
			any_control <= 1’b0;
			data[31:0] <= 32‘d0;
			data_d1[31:0] <= 32‘d0;
			data_d2[31:0] <= 32‘d0;
		end
	else
		begin
			any_control <= s_valid & s_ok;
			data[31:0] <= sdata[31:0];
			data_d1[31:0] <= data[31:0];
			data_d2[31:0] <= data_d1[31:0];
		end
end

After converting the code to use synchronous reset, the code may appear as follows:

always @(posedge clk)
begin
	if (!rstb)
		begin
			any_control <= 1’b0;
			data[31:0] <= 32‘d0;
			data_d1[31:0] <= 32‘d0;
			data_d2[31:0] <= 32‘d0;
		end
	else
		begin
			any_control <= s_valid & s_ok;
			data[31:0] <= sdata[31:0];
			data_d1[31:0] <= data[31:0];
			data_d2[31:0] <= data_d1[31:0];
		end
end

However, if you decide to only remove the resets on data pipelines data_d1[31:0] and data_d2[31:0], the result mixes registers with and without reset in the same if-else procedure. The following example code shares characteristics with the example in Coding Synchronous Reset with Follower Registers:

always @(posedge clk)
begin
	if (!rstb)
		begin
			any_control <= 1’b0;
			data[31:0] <= 32‘d0;
		end
	else
		begin
			any_control <= s_valid & s_ok;
			data[31:0] <= sdata[31:0];
			data_d1[31:0] <= data[31:0];
			data_d2[31:0] <= data_d1[31:0];
		end
end

data_d1[31:0] and data_d2[31:0] use rstb as a condition, whether to update or retain their previous values. This coding creates unnecessary logic and 32-bit loopbacks on the registers.

The following example shows a more effective method for code with mixed control signals and data pipelines:

always @(posedge clk)
begin

	any_control <= s_valid & s_ok;
	data[31:0] <= sdata[31:0];
	data_d1[31:0] <= data[31:0];
	data_d2[31:0] <= data_d1[31:0];

	if (!rstb)
	begin
		any_control <= 1’b0;
		data[31:0] <= 32‘d0;
		data_d1[31:0] <= 32‘d0;
		data_d2[31:0] <= 32‘d0;
	end
end

Removing resets on data_d1[31:0] and data_d2[31:0] in this code is safe. This method also avoids creating unnecessary loopbacks and does not introduce any retiming restrictions.

Signals any_control and data[31:0] have multiple assignments when rstb is ‘0’. The Verilog HDL standard defines the Verilog HDL coding of multiple non-blocking assignments to the same variable, in the same always block. The last non-blocking assignment to the same variable takes precedence.