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
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/buffers/sd_fifo_s.v
0,0 → 1,121
//----------------------------------------------------------------------
// Srdy/Drdy FIFO "S"
//
// Building block for FIFOs. The "S" (small or synchronizer) FIFO is
// designed for smaller FIFOs based around memories or flops, with
// sizes that are a power of 2.
//
// The "S" FIFO can be used as a two-clock asynchronous FIFO. When the
// async parameter is set to 1, the pointers will be converted from
// binary to grey code and double-synchronized.
//
// Naming convention: c = consumer, p = producer, i = internal interface
//----------------------------------------------------------------------
// 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_fifo_s
#(parameter width=8,
parameter depth=16,
parameter async=0
)
(
input c_clk,
input c_reset,
input c_srdy,
output c_drdy,
input [width-1:0] c_data,
 
input p_clk,
input p_reset,
output p_srdy,
input p_drdy,
output [width-1:0] p_data
);
 
localparam asz = $clog2(depth);
 
reg [width-1:0] mem [0:depth-1];
wire [width-1:0] mem_rddata;
wire rd_en;
wire [asz:0] rdptr_tail, rdptr_tail_sync;
wire wr_en;
wire [asz:0] wrptr_head, wrptr_head_sync;
reg [width-1:0] p_data;
reg dly_rd_en;
wire [asz-1:0] rd_addr, wr_addr;
 
always @(posedge c_clk)
if (wr_en)
mem[wr_addr] <= `SDLIB_DELAY c_data;
 
assign mem_rddata = mem[rd_addr];
 
sd_fifo_head_s #(depth, async) head
(
// Outputs
.c_drdy (c_drdy),
.wrptr_head (wrptr_head),
.wr_en (wr_en),
.wr_addr (wr_addr),
// Inputs
.clk (c_clk),
.reset (c_reset),
.c_srdy (c_srdy),
.rdptr_tail (rdptr_tail_sync));
 
sd_fifo_tail_s #(depth, async) tail
(
// Outputs
.rdptr_tail (rdptr_tail),
.rd_en (rd_en),
.rd_addr (rd_addr),
.p_srdy (p_srdy),
// Inputs
.clk (p_clk),
.reset (p_reset),
.wrptr_head (wrptr_head_sync),
.p_drdy (p_drdy));
 
always @(posedge p_clk)
begin
if (rd_en)
p_data <= `SDLIB_DELAY mem_rddata;
end
 
generate
if (async)
begin : gen_sync
reg [asz:0] r_sync1, r_sync2;
reg [asz:0] w_sync1, w_sync2;
 
always @(posedge p_clk)
begin
w_sync1 <= `SDLIB_DELAY wrptr_head;
w_sync2 <= `SDLIB_DELAY w_sync1;
end
 
always @(posedge c_clk)
begin
r_sync1 <= `SDLIB_DELAY rdptr_tail;
r_sync2 <= `SDLIB_DELAY r_sync1;
end
 
assign wrptr_head_sync = w_sync2;
assign rdptr_tail_sync = r_sync2;
end
else
begin : gen_nosync
assign wrptr_head_sync = wrptr_head;
assign rdptr_tail_sync = rdptr_tail;
end
endgenerate
 
endmodule // sd_fifo_s
/buffers/sd_fifo_head_s.v
0,0 → 1,103
//----------------------------------------------------------------------
// Srdy/Drdy FIFO Head "S"
//
// Building block for FIFOs. The "S" (big) FIFO is design for smaller
// FIFOs based around memories or flops, with sizes that are a power of 2.
//
// The "S" FIFO can be used as a two-clock asynchronous FIFO.
//
// Naming convention: c = consumer, p = producer, i = internal interface
//----------------------------------------------------------------------
// Author: Guy Hutchison
//
// This block is uncopyrighted and released into the public domain.
//----------------------------------------------------------------------
 
// Clocking statement for synchronous blocks. Default is for
// posedge clocking and positive async reset
`ifndef SDLIB_CLOCKING
`define SDLIB_CLOCKING posedge clk or posedge reset
`endif
 
// delay unit for nonblocking assigns, default is to #1
`ifndef SDLIB_DELAY
`define SDLIB_DELAY #1
`endif
 
module sd_fifo_head_s
#(parameter depth=16,
parameter async=0,
parameter asz=$clog2(depth)
)
(
input clk,
input reset,
input c_srdy,
output c_drdy,
 
output [asz:0] wrptr_head,
output [asz-1:0] wr_addr,
output reg wr_en,
input [asz:0] rdptr_tail
 
);
 
reg [asz:0] wrptr, nxt_wrptr;
reg [asz:0] wrptr_p1;
reg empty, full;
wire [asz:0] rdptr;
 
assign c_drdy = !full;
assign wr_addr = wrptr[asz-1:0];
always @*
begin
wrptr_p1 = wrptr + 1;
full = ((wrptr[asz-1:0] == rdptr[asz-1:0]) &&
(wrptr[asz] == ~rdptr[asz]));
if (c_srdy & !full)
nxt_wrptr = wrptr_p1;
else
nxt_wrptr = wrptr;
 
wr_en = (c_srdy & !full);
end
always @(`SDLIB_CLOCKING)
begin
if (reset)
begin
wrptr <= `SDLIB_DELAY 0;
end
else
begin
wrptr <= `SDLIB_DELAY nxt_wrptr;
end // else: !if(reset)
end // always @ (posedge clk)
 
function [asz:0] bin2grey;
input [asz:0] bin_in;
integer b;
begin
bin2grey[asz] = bin_in[asz];
for (b=0; b<asz; b=b+1)
bin2grey[b] = bin_in[b] ^ bin_in[b+1];
end
endfunction // for
 
function [asz:0] grey2bin;
input [asz:0] grey_in;
integer b;
begin
grey2bin[asz] = grey_in[asz];
for (b=asz-1; b>=0; b=b-1)
grey2bin[b] = grey_in[b] ^ grey2bin[b+1];
end
endfunction
 
assign wrptr_head = (async) ? bin2grey(wrptr) : wrptr;
assign rdptr = (async)? grey2bin(rdptr_tail) : rdptr_tail;
endmodule
/buffers/sd_fifo_tail_s.v
0,0 → 1,107
//----------------------------------------------------------------------
// Srdy/Drdy FIFO Head "S"
//
// Building block for FIFOs. The "S" (big) FIFO is design for smaller
// FIFOs based around memories or flops, with sizes that are a power of 2.
//
// The "S" FIFO can be used as a two-clock asynchronous FIFO.
//
// Naming convention: c = consumer, p = producer, i = internal interface
//----------------------------------------------------------------------
// Author: Guy Hutchison
//
// This block is uncopyrighted and released into the public domain.
//----------------------------------------------------------------------
 
// Clocking statement for synchronous blocks. Default is for
// posedge clocking and positive async reset
`ifndef SDLIB_CLOCKING
`define SDLIB_CLOCKING posedge clk or posedge reset
`endif
 
// delay unit for nonblocking assigns, default is to #1
`ifndef SDLIB_DELAY
`define SDLIB_DELAY #1
`endif
 
module sd_fifo_tail_s
#(parameter depth=16,
parameter async=0,
parameter asz=$clog2(depth)
)
(
input clk,
input reset,
 
input [asz:0] wrptr_head,
output [asz:0] rdptr_tail,
 
output reg rd_en,
output [asz-1:0] rd_addr,
 
output reg p_srdy,
input p_drdy
);
 
reg [asz:0] rdptr;
reg [asz:0] nxt_rdptr;
reg [asz:0] rdptr_p1;
reg empty;
reg nxt_p_srdy;
wire [asz:0] wrptr;
 
assign rd_addr = nxt_rdptr[asz-1:0];
 
always @*
begin
rdptr_p1 = rdptr + 1;
empty = (wrptr == rdptr);
 
if (p_drdy & p_srdy)
nxt_rdptr = rdptr_p1;
else
nxt_rdptr = rdptr;
nxt_p_srdy = (wrptr != nxt_rdptr);
rd_en = (p_drdy & p_srdy) | (!empty & !p_srdy);
end
always @(`SDLIB_CLOCKING)
begin
if (reset)
begin
rdptr <= `SDLIB_DELAY 0;
p_srdy <= `SDLIB_DELAY 0;
end
else
begin
rdptr <= `SDLIB_DELAY nxt_rdptr;
p_srdy <= `SDLIB_DELAY nxt_p_srdy;
end // else: !if(reset)
end // always @ (posedge clk)
 
function [asz:0] bin2grey;
input [asz:0] bin_in;
integer b;
begin
bin2grey[asz] = bin_in[asz];
for (b=0; b<asz; b=b+1)
bin2grey[b] = bin_in[b] ^ bin_in[b+1];
end
endfunction // for
 
function [asz:0] grey2bin;
input [asz:0] grey_in;
integer b;
begin
grey2bin[asz] = grey_in[asz];
for (b=asz-1; b>=0; b=b-1)
grey2bin[b] = grey_in[b] ^ grey2bin[b+1];
end
endfunction
 
assign rdptr_tail = (async) ? bin2grey(rdptr) : rdptr;
assign wrptr = (async)? grey2bin(wrptr_head) : wrptr_head;
endmodule // sd_fifo_head_s

powered by: WebSVN 2.1.0

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