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 |