Verilog 如何在RTL中使用时钟选通?

Verilog 如何在RTL中使用时钟选通?,verilog,system-verilog,register-transfer-level,vlsi,Verilog,System Verilog,Register Transfer Level,Vlsi,我正在设计一些锁存器和逻辑。我在合成、地点和路线方面没有太多经验。在RTL中实现时钟选通的正确方法是什么 例1: always_comb begin gated_clk = clk & latch_update_en; end always_latch begin if(gated_clk) begin latch_data <= new_data; end end 始终\u开始 门控时钟=时钟和闩锁更新; 结束 总是从一开始 如果(

我正在设计一些锁存器和逻辑。我在合成、地点和路线方面没有太多经验。在RTL中实现时钟选通的正确方法是什么

例1:

always_comb begin
    gated_clk  = clk & latch_update_en;
end

always_latch begin
    if(gated_clk) begin
         latch_data <= new_data;
    end
end
始终\u开始
门控时钟=时钟和闩锁更新;
结束
总是从一开始
如果(门控时钟)开始
在RTL中实现时钟选通的正确方法是什么?
时钟选通信号应仅在闩锁关闭时切换,否则可能出现故障和亚稳态问题。对于有源高锁存器,选通信号应在时钟下降沿上切换。主动低锁存器的上升沿

通常,您会使用边缘敏感触发器来保持
锁存更新\u en
,以防止选通信号出现噪声

always_ff @(negedge clk)
  latch_update_en <= next_latch_update_en;

always_comb
    gated_clk = (* clock_gating = "clk" *) clk & latch_update_en;

always_latch
    if(gated_clk)
         latch_data <= new_data;
如果没有引导,选通触发器可能会出现时钟延迟。这种倾斜会导致对错误的数据进行采样

                 _____       _____
IN -------------|D   Q|-----|D   Q|--- OUT
                |     |     |     |
                |     |     |     |
     +----------|>    |   +-|>    |
     |          |_____|   | |_____|
     |  ___               |
CLK -+-|   \    |\ |\     |
       | &  )---| >| >----+   UNBALANCED CLOCK : wrong data sampled
GATE --|___/    |/ |/
读一读,上面写着:

时钟选通电路的顺序等价性检查(SEC)是 必需的

此外,请尝试按如下方式粘贴代码:

//----------------------------------------------------------------------------
// Copyright (C) 2009 , Olivier Girard
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the authors nor the names of its contributors
//       may be used to endorse or promote products derived from this software
//       without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE
//
//----------------------------------------------------------------------------
//
// *File Name: omsp_clock_gate.v
// 
// *Module Description:
//                       Generic clock gate cell for the openMSP430
//
// *Author(s):
//              - Olivier Girard,    olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
//----------------------------------------------------------------------------

module  omsp_clock_gate (

// OUTPUTs
    gclk,                      // Gated clock

// INPUTs
    clk,                       // Clock
    enable,                    // Clock enable
    scan_enable                // Scan enable (active during scan shifting)
);

// OUTPUTs
//=========
output         gclk;           // Gated clock

// INPUTs
//=========
input          clk;            // Clock
input          enable;         // Clock enable
input          scan_enable;    // Scan enable (active during scan shifting)


//=============================================================================
// CLOCK GATE: LATCH + AND
//=============================================================================

// Enable clock gate during scan shift
// (the gate itself is checked with the scan capture cycle)
wire    enable_in =   (enable | scan_enable);

// LATCH the enable signal
reg     enable_latch;
always @(clk or enable_in)
  if (~clk)
    enable_latch <= enable_in;

// AND gate
assign  gclk      =  (clk & enable_latch);


endmodule // omsp_clock_gate
//----------------------------------------------------------------------------
//版权所有(C)2009,Olivier Girard
//
//以源代码和二进制形式重新分发和使用,带或不带
//如果满足以下条件,则允许进行修改
//满足以下条件:
//*源代码的重新分发必须保留上述版权
//请注意,此条件列表和以下免责声明。
//*二进制形式的重新分发必须复制上述版权
//请注意,此条件列表和中的以下免责声明
//随分发提供的文件和/或其他材料。
//*作者姓名及其贡献者姓名
//可用于认可或推广源自本软件的产品
//未经事先书面许可。
//
//本软件由版权所有者和贡献者“按原样”提供
//以及任何明示或暗示的保证,包括但不限于
//对适销性和特定用途适用性的默示保证
//拒绝承认。在任何情况下,版权持有人或贡献者均不得
//对任何直接、间接、附带、特殊、示范性、,
//或间接损害(包括但不限于采购
//替代商品或服务;使用、数据或利润的损失;或业务
//中断)无论是何种原因造成的,且基于任何责任理论,无论是在
//合同、严格责任或侵权行为(包括疏忽或其他)
//因使用本软件而产生的任何后果,即使
//这种损害的可能性
//
//----------------------------------------------------------------------------
//
//*文件名:omsp\u clock\u gate.v
// 
//*模块说明:
//openMSP430的通用时钟门单元
//
//*作者:
//-奥利维尔·吉拉德,olgirard@gmail.com
//
//----------------------------------------------------------------------------
//$Rev:103$
//$LastChangedBy:olivier.girard$
//$LastChangedDate:2011-03-05 15:44:48+0100(2011年3月5日星期六)$
//----------------------------------------------------------------------------
模块omsp_时钟_门(
//输出
gclk,//选通时钟
//投入
时钟,//时钟
启用,//时钟启用
扫描\ U启用//扫描启用(扫描移位期间激活)
);
//输出
//=========
输出gclk;//门控时钟
//投入
//=========
输入时钟;//钟
输入启用;//时钟使能
输入扫描_启用;//扫描启用(扫描切换期间激活)
//=============================================================================
//时钟门:闩锁+和
//=============================================================================
//在扫描移位期间启用时钟门
//(通过扫描捕获周期检查闸门本身)
导线启用_in=(启用|扫描_启用);
//锁定启用信号
reg启用_闩锁;
始终@(clk或enable_in)
如果(~clk)

启用闩锁要使时钟正确选通,寄存器必须仅在选通高的情况下在时钟上升沿上接受新值(假设激活高启用)。简单地将时钟和enable相加是不够的,因为如果时钟高,这将在门的上升沿上产生一个假时钟。我做了一些编辑。我实际上并没有对寄存器使用时钟启用。我的设计中有一些插销。因此,我们的想法是在闩锁启用较高时捕获闩锁中的数据。因此,我正在使用时钟启用以创建半周期正时钟,并使用它捕获电平敏感(正)锁存器中的数据。
clock\u gator
不是标准的Verilog模块;它被你的代码拉到了某个地方。如果你想让我们理解它,你必须向我们展示它是如何实现的。我认为
clock\u gator
单元应该是一个无故障的实现。在您的示例1中,使用时钟选通是最基本的想法。但是,它会产生故障并导致错误行为。旁注:时钟选通应用于选通需要动态暂停或关闭/打开的大型模块的时钟;不适用于少数失败。时钟选通很少有利于小边缘触发器设计。通常使用enable引脚或Q-to-D反馈可以节省足够的电源/面积。我很困惑这里没有寄存器,工具如何识别时钟选通?Carter抱歉,但我没有理解reddit回答的要点,即使有关于无故障选通的解释。@Carter主要有。另请参见@Carter是否看到
                 _____       _____
IN -------------|D   Q|-----|D   Q|--- OUT
                |     |     |     |
       |\ |\    |     |     |     |
     +-| >| >---|>    |   +-|>    |
     | |/ |/    |_____|   | |_____|
     |  ___               |
CLK -+-|   \              |
       | &  )-------------+   BALANCED CLOCK : correct data sampled
GATE --|___/
                 _____       _____
IN -------------|D   Q|-----|D   Q|--- OUT
                |     |     |     |
                |     |     |     |
     +----------|>    |   +-|>    |
     |          |_____|   | |_____|
     |  ___               |
CLK -+-|   \    |\ |\     |
       | &  )---| >| >----+   UNBALANCED CLOCK : wrong data sampled
GATE --|___/    |/ |/
//----------------------------------------------------------------------------
// Copyright (C) 2009 , Olivier Girard
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the authors nor the names of its contributors
//       may be used to endorse or promote products derived from this software
//       without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE
//
//----------------------------------------------------------------------------
//
// *File Name: omsp_clock_gate.v
// 
// *Module Description:
//                       Generic clock gate cell for the openMSP430
//
// *Author(s):
//              - Olivier Girard,    olgirard@gmail.com
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
//----------------------------------------------------------------------------

module  omsp_clock_gate (

// OUTPUTs
    gclk,                      // Gated clock

// INPUTs
    clk,                       // Clock
    enable,                    // Clock enable
    scan_enable                // Scan enable (active during scan shifting)
);

// OUTPUTs
//=========
output         gclk;           // Gated clock

// INPUTs
//=========
input          clk;            // Clock
input          enable;         // Clock enable
input          scan_enable;    // Scan enable (active during scan shifting)


//=============================================================================
// CLOCK GATE: LATCH + AND
//=============================================================================

// Enable clock gate during scan shift
// (the gate itself is checked with the scan capture cycle)
wire    enable_in =   (enable | scan_enable);

// LATCH the enable signal
reg     enable_latch;
always @(clk or enable_in)
  if (~clk)
    enable_latch <= enable_in;

// AND gate
assign  gclk      =  (clk & enable_latch);


endmodule // omsp_clock_gate