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

Subversion Repositories srdydrdy_lib

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /srdydrdy_lib/trunk/rtl/verilog/utility
    from Rev 24 to Rev 25
    Reverse comparison

Rev 24 → Rev 25

/sd_sync.v
0,0 → 1,155
//----------------------------------------------------------------------
// 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

powered by: WebSVN 2.1.0

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