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
    from Rev 24 to Rev 25
    Reverse comparison

Rev 24 → Rev 25

/trunk/rtl/verilog/utility/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
/trunk/env/verilog/sync/sync_bench.v
0,0 → 1,105
module sync_bench;
 
parameter width = 16;
reg a_clk, a_reset;
reg b_clk, b_reset;
wire [width-1:0] a_data;
 
wire a_srdy, a_drdy;
wire b_srdy, b_drdy;
 
initial
begin
`ifdef VCS
$vcdpluson;
`else
$dumpfile ("sync.vcd");
$dumpvars;
`endif
a_clk = 0;
b_clk = 0;
a_reset = 1;
b_reset = 1;
#200;
a_reset = 0;
b_reset = 0;
#200;
 
seq_gen.send (25);
 
seq_gen.srdy_pat = 8'h01;
 
seq_gen.send (25);
 
seq_gen.srdy_pat = 8'hFF;
seq_chk.drdy_pat = 8'h01;
 
seq_gen.send (25);
 
seq_gen.srdy_pat = 8'h01;
seq_gen.send (25);
#2000;
 
if (seq_chk.last_seq == 100)
$display ("TEST PASSED");
else
$display ("TEST FAILED");
$finish;
end // initial begin
 
initial
begin
#50000; // timeout value
 
$display ("TEST FAILED");
$finish;
end
 
always a_clk = #5 ~a_clk;
always b_clk = #17 ~b_clk;
sd_seq_gen #(.width(width)) seq_gen
(
.clk (a_clk),
.reset (a_reset),
.p_srdy (a_srdy),
.p_data (a_data),
// Inputs
.p_drdy (a_drdy));
sd_sync sync0
(
// Outputs
.c_drdy (a_drdy),
.p_srdy (b_srdy),
// Inputs
.c_clk (a_clk),
.c_reset (a_reset),
.c_srdy (a_srdy),
.p_clk (b_clk),
.p_reset (b_reset),
.p_drdy (b_drdy));
 
sd_seq_check #(.width(width)) seq_chk
(
// Outputs
.c_drdy (b_drdy),
// Inputs
.clk (b_clk),
.reset (b_reset),
.c_srdy (b_srdy),
.c_data (a_data));
endmodule // sync_bench
// Local Variables:
// verilog-library-directories:("." "../../../rtl/verilog/utility" "../common")
// End:
 
 
/trunk/env/verilog/sync/sync.vf
0,0 → 1,4
../common/sd_seq_check.v
../common/sd_seq_gen.v
../../../rtl/verilog/utility/sd_sync.v
sync_bench.v

powered by: WebSVN 2.1.0

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