OpenCores
URL https://opencores.org/ocsvn/srdydrdy_lib/srdydrdy_lib/trunk

Subversion Repositories srdydrdy_lib

[/] [srdydrdy_lib/] [trunk/] [rtl/] [verilog/] [utility/] [sd_sync.v] - Rev 25

Compare with Previous | Blame | View Log

//----------------------------------------------------------------------
// Srdy/Drdy Sync Block
//
// Provides synchronization across clock domains for an srdy/drdy
// pair.  Assumes low utilization; for high utilization see sd_fifo_a.
//
// Only syncs control signals, data can be passed directly to the
// receiver.
//
// Naming convention: c = consumer, p = producer
//----------------------------------------------------------------------
//  Author: Guy Hutchison
//
// This block is uncopyrighted and released into the public domain.
//----------------------------------------------------------------------
 
// delay unit for nonblocking assigns, default is to #1
`ifndef SDLIB_DELAY 
 `define SDLIB_DELAY #1 
`endif
 
module sd_sync
  #(parameter edge_det = 0)
  (
   input       c_clk,
   input       c_reset,
   input       c_srdy,
   output reg  c_drdy,
 
   input       p_clk,
   input       p_reset,
   output reg  p_srdy,
   input       p_drdy
   );
 
  reg          launch_a, nxt_launch_a;
 
  reg          sync_ack_b, ack_b;
  reg [1:0]    psync_b; // pulse sync A to B
  reg          p_ack;
  reg          p_state, nxt_p_state;
  reg [1:0]    c_state, nxt_c_state;
 
  localparam ps_idle = 0, ps_ack = 1;
  localparam cs_idle = 0, cs_req = 1, cs_clear = 2;
 
  //------------------------------------------------------------
  // Consumer Clock Domain
  //------------------------------------------------------------
 
  always @*
    begin
      nxt_launch_a = 0;
      c_drdy = 0;
      nxt_c_state = c_state;
 
      case (c_state)
        cs_idle :
          begin
            if (c_srdy)
              begin
                nxt_launch_a = 1;
                nxt_c_state  = cs_req;
              end
          end
 
        cs_req :
          begin
            nxt_launch_a = 1;
 
            if (ack_b)
              begin
                c_drdy = 1;
                nxt_c_state = cs_clear;
              end
          end
 
        cs_clear :
          begin
            if (!ack_b)
              nxt_c_state = cs_idle;
          end
 
        default : nxt_c_state = cs_idle;
      endcase
    end // always @ *
 
 
  always @(posedge c_clk or posedge c_reset)
    begin
      if (c_reset)
        begin
          launch_a <= `SDLIB_DELAY 1'b0;
          c_state  <= `SDLIB_DELAY cs_idle;
        end
      else
        begin
          launch_a <= `SDLIB_DELAY nxt_launch_a;
          c_state  <= `SDLIB_DELAY nxt_c_state;
        end
    end
 
  always @(posedge c_clk)
    begin
      ack_b      <= `SDLIB_DELAY sync_ack_b;
      sync_ack_b <= `SDLIB_DELAY p_ack;
    end
 
  //------------------------------------------------------------
  // Producer Clock Domain
  //------------------------------------------------------------
 
  always @(posedge p_clk or posedge p_reset)
    begin
      if (p_reset)
        p_state <= `SDLIB_DELAY ps_idle;
      else
        p_state <= `SDLIB_DELAY nxt_p_state;
    end
 
  always @(posedge p_clk)
    begin
      psync_b   <= `SDLIB_DELAY { launch_a, psync_b[1] };
    end
 
  always @*
    begin
      p_ack = 0;
      p_srdy = 0;
      nxt_p_state = p_state;
 
      case (p_state)
        ps_idle :
          begin
            p_srdy = psync_b[0];
 
            if (psync_b[0] & p_drdy)
              begin
                nxt_p_state = ps_ack;
              end
          end
 
        ps_ack :
          begin
            p_srdy = 0;
            p_ack  = 1;
 
            if (!psync_b[0])
              nxt_p_state = ps_idle;
          end
 
      endcase // case (p_state)
    end // always @ *
 
endmodule // sd_sync
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.