../src/lowrisc_prim_all_0.1/rtl/prim_pulse_sync.sv Cov: 100%

   1: // Copyright lowRISC contributors.
   2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
   3: // SPDX-License-Identifier: Apache-2.0
   4: //
   5: // Pulse synchronizer: synchronizes a pulse from source clock domain (clk_src)
   6: // to destination clock domain (clk_dst). Each pulse has the length of one clock
   7: // cycle of its respective clock domain. Consecutive pulses need to be spaced
   8: // appropriately apart from each other depending on the clock frequency ratio
   9: // of the two clock domains.
  10: 
  11: module prim_pulse_sync (
  12:   // source clock domain
  13:   input  logic clk_src_i,
  14:   input  logic rst_src_ni,
  15:   input  logic src_pulse_i,
  16:   // destination clock domain
  17:   input  logic clk_dst_i,
  18:   input  logic rst_dst_ni,
  19:   output logic dst_pulse_o
  20: );
  21: 
  22:   ////////////////////////////////////////////////////////////////////////////////
  23:   // convert src_pulse to a level signal so we can use double-flop synchronizer //
  24:   ////////////////////////////////////////////////////////////////////////////////
  25:   logic src_level;
  26: 
  27:   always_ff @(posedge clk_src_i or negedge rst_src_ni) begin
  28:     if (!rst_src_ni) begin
  29:       src_level <= 1'b0;
  30:     end else begin
  31:       src_level <= src_level ^ src_pulse_i;
  32:     end
  33:   end
  34: 
  35:   //////////////////////////////////////////////////////////
  36:   // synchronize level signal to destination clock domain //
  37:   //////////////////////////////////////////////////////////
  38:   logic dst_level;
  39: 
  40:   prim_flop_2sync #(.Width(1)) prim_flop_2sync (
  41:     // source clock domain
  42:     .d      (src_level),
  43:     // destination clock domain
  44:     .clk_i  (clk_dst_i),
  45:     .rst_ni (rst_dst_ni),
  46:     .q      (dst_level)
  47:   );
  48: 
  49:   ////////////////////////////////////////
  50:   // convert level signal back to pulse //
  51:   ////////////////////////////////////////
  52:   logic dst_level_q;
  53: 
  54:   // delay dst_level by 1 cycle
  55:   always_ff @(posedge clk_dst_i or negedge rst_dst_ni) begin
  56:     if (!rst_dst_ni) begin
  57:       dst_level_q <= 1'b0;
  58:     end else begin
  59:       dst_level_q <= dst_level;
  60:     end
  61:   end
  62: 
  63:   // edge detection
  64:   assign dst_pulse_o = dst_level_q ^ dst_level;
  65: 
  66: endmodule
  67: