Intel® Hyperflex™ 体系结构高性能设计手册

ID 683353
日期 10/04/2021
Public
文档目录

2.2.1.1. 移除异步复位(Removing Asynchronous Resets)

如果当复位保持足够长的时间来达到一个相当于完整复位的稳定状态时,电路自然地复位,那么就要移除异步复位。

Verilog HDL和VHDL异步复位实例显示了异步复位是如何对流水线中的所有寄存器进行复位的(以粗体显示),从而防止Hyper-Register中的布局。

表 3.  Verilog HDL和VHDL异步复位实例
Verilog HDL VHDL
always @(posedge clk, aclr)
   if (aclr) begin
      reset_synch <= 1'b0;
      aclr_int <= 1’b0;
   end
   else begin
      reset_synch <= 1'b1;
      aclr_int <= reset_synch;
   end

always @(posedge clk, aclr_int)
// Asynchronous reset===============
   if (!aclr_int) begin
      a <= 1'b0;
      b <= 1'b0;
      c <= 1'b0;
      d <= 1'b0;
      out <= 1'b0;
   end
//===============
   else begin
      a <= in;
      b <= a;
      c <= b;
      d <= c;
      out <= d;
   end
PROCESS(clk, aclr) BEGIN
   IF (aclr = '0') THEN
      reset_synch <= '0';
      aclr_int <= '0';
   ELSIF rising_edge(clk) THEN
      reset_synch <= '1';
      aclr_int <= reset_synch;
   END IF;
END PROCESS;

PROCESS(clk, aclr_int) BEGIN
// Asynchronous reset===============
   IF (aclr_int = '0') THEN
      a <= '0';
      b <= '0';
      c <= '0';
      d <= '0';
      output <= '0';
//===============
   ELSIF rising_edge(clk) THEN
      a <= input;
      b <= a;
      c <= b;
      d <= c;
      output <= d;
   END IF;
END PROCESS;

完全异步复位的电路以示意图的形式显示了Verilog HDL和VHDL异步复位示例的逻辑。当aclr被置位时,触发器(flop)的所有输出都是零。释放aclr并应用两个时钟脉冲会使所有触发器都进入功能模式。

图 7. 完全异步复位的电路

部分异步复位显示了从电路中间移除异步复位。在部分复位之后,如果修改的电路与原始电路具有相同的稳定状态,那么此修改在功能上是等效的。

图 8. 部分异步复位(Partial Asynchronous Reset)


寄存器链中有逆变器的电路显示了包含反相逻辑的电路如何需要额外的同步复位以保留在流水线中。

图 9. 寄存器链中有逆变器(Inverter)的电路

在移除复位并应用时钟后,寄存器输出不会处于复位状态。如果从反相寄存器中移除异步复位,那么电路在退出复位后不能与寄存器链中有逆变器的电路保持等效。

图 10. 带异步复位的寄存器链中有逆变器(Inverter)的电路


为避免对由非自然反转功能导致的逻辑进行复位,请验证输出与复位移除同步,如验证输出以同步复位所示。如果当计算流水线实际有效时验证流水线能够使能输出,那么此行为与复位移除等效。即使电路的计算部分不自然复位,此方法也是适合的。

图 11. 验证输出以同步复位

使用最少或无异步复位的Verilog HDL实例显示了部分异步复位的Verilog HDL和VHDL示例。您可以将此示例应用到您的设计中,从而移除不必要的异步复位。

表 4.  使用最少或无异步复位的Verilog HDL实例
Verilog HDL VHDL
always @(posedge clk, aclr)
   if (aclr) begin
      reset_synch_1 <= 1'b0;
      reset_synch_2 <= 1'b0;
      aclr_int <= 1'b0;
   end
   else begin
      reset_synch_1 <= 1'b1;
      reset_synch_2 <= reset_synch_1;
      aclr_int <= reset_synch_2;
   end

// Asynchronous reset for output register=====
always @(posedge clk, posedge aclr_int)
   if (aclr_int)
      out <= 1'b0;
   else
      out <= d;
// Synchronous reset for input register=====
always @(posedge clk)
   if (reset_synch_2)
      a <= 1'b0;
   else
      a <= in;
// Naturally resetting registers=====
always @(posedge clk) begin
   b <= a;
   c <= b;
   d <= c;

end
PROCESS (clk, aclr) BEGIN
   IF (aclr = '1') THEN
      reset_synch_1 <= '0';
      reset_synch_2 <= '0';
      aclr_int <= '0';
   ELSIF rising_edge(clk) THEN
      reset_synch_1 <= '1';
      reset_synch_2 <= reset_synch_1;
      aclr_int <= reset_synch_2;
   END IF;
END PROCESS;

// Asynchronous reset for output register=====
PROCESS (clk, aclr_int) BEGIN
   IF (aclr_int = '1') THEN
      output <= '0';
   ELSIF rising_edge(clk) THEN
      output <= d;
   END IF;
END PROCESS;// Synchronous reset for input register=====
PROCESS (clk) BEGIN
   IF rising_edge(clk) THEN
      IF (reset_synch_2 = '1') THEN
         a <= '0';
      ELSE
         a <= input;
      END IF;
   END IF;
END PROCESS;// Naturally resetting registers=====
PROCESS (clk) BEGIN
   IF rising_edge(clk) THEN
      b <= a;
      c <= b;
      d <= c;
   END IF;
END PROCESS;