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

Rev 2 → Rev 3

/trunk/rtl/verilog/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
/trunk/rtl/verilog/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
/trunk/rtl/verilog/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
/trunk/env/verilog/sd_seq_check.v
0,0 → 1,99
//----------------------------------------------------------------------
// Srdy/Drdy sequence checker
//
// Simplistic traffic checker for srdy/drdy blocks. Checks for an
// incrementing data sequence.
//
// 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_seq_check
#(parameter width=8)
(input clk,
input reset,
input c_srdy,
output reg c_drdy,
input [width-1:0] c_data);
 
parameter pat_dep = 8;
 
reg [width-1:0] last_seq;
reg first;
reg [pat_dep-1:0] drdy_pat;
integer dpp;
reg nxt_c_drdy;
 
initial
begin
drdy_pat = {pat_dep{1'b1}};
dpp = 0;
end
 
initial
begin
first = 1;
c_drdy = 0;
end
 
always @*
begin
nxt_c_drdy = c_drdy;
 
if (c_srdy & c_drdy)
begin
if (drdy_pat[dpp])
begin
nxt_c_drdy = 1;
end
else
nxt_c_drdy = 0;
end
else if (!c_drdy)
begin
if (drdy_pat[dpp])
begin
nxt_c_drdy = 1;
end
else
nxt_c_drdy = 0;
end
end
always @(posedge clk)
begin
if ((c_srdy & c_drdy) | !c_drdy)
dpp = (dpp + 1) % pat_dep;
end
 
always @(posedge clk)
begin
if (reset)
begin
c_drdy <= `SDLIB_DELAY 0;
end
else
begin
c_drdy <= `SDLIB_DELAY nxt_c_drdy;
if (c_srdy & c_drdy)
begin
if (!first && (c_data !== (last_seq + 1)))
$display ("%t: ERROR : %m: Sequence miscompare rcv=%x exp=%x",
$time, c_data, last_seq+1);
else
begin
last_seq = c_data;
first = 0;
end
end // if (c_srdy & c_drdy)
end // else: !if(reset)
end
 
endmodule // sd_seq_check
/trunk/env/verilog/bench_fifo_s.v
0,0 → 1,109
`timescale 1ns/1ns
 
module bench_fifo_s;
 
reg clk, reset;
 
localparam width = 8;
 
initial clk = 0;
always #10 clk = ~clk;
 
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [width-1:0] chk_data; // From fifo_s of sd_fifo_s.v
wire chk_drdy; // From chk of sd_seq_check.v
wire chk_srdy; // From fifo_s of sd_fifo_s.v
wire [width-1:0] gen_data; // From gen of sd_seq_gen.v
wire gen_drdy; // From fifo_s of sd_fifo_s.v
wire gen_srdy; // From gen of sd_seq_gen.v
// End of automatics
 
/* sd_seq_gen AUTO_TEMPLATE
(
.p_\(.*\) (gen_\1[]),
);
*/
sd_seq_gen gen
(/*AUTOINST*/
// Outputs
.p_srdy (gen_srdy), // Templated
.p_data (gen_data[width-1:0]), // Templated
// Inputs
.clk (clk),
.reset (reset),
.p_drdy (gen_drdy)); // Templated
 
/* sd_seq_check AUTO_TEMPLATE
(
.c_\(.*\) (chk_\1[]),
);
*/
sd_seq_check chk
(/*AUTOINST*/
// Outputs
.c_drdy (chk_drdy), // Templated
// Inputs
.clk (clk),
.reset (reset),
.c_srdy (chk_srdy), // Templated
.c_data (chk_data[width-1:0])); // Templated
 
/* sd_fifo_s AUTO_TEMPLATE
(
.c_clk (clk),
.c_reset (reset),
.p_clk (clk),
.p_reset (reset),
.p_\(.*\) (chk_\1[]),
.c_\(.*\) (gen_\1[]),
);
*/
sd_fifo_s #(8, 32, 1) fifo_s
(/*AUTOINST*/
// Outputs
.c_drdy (gen_drdy), // Templated
.p_srdy (chk_srdy), // Templated
.p_data (chk_data[width-1:0]), // Templated
// Inputs
.c_clk (clk), // Templated
.c_reset (reset), // Templated
.c_srdy (gen_srdy), // Templated
.c_data (gen_data[width-1:0]), // Templated
.p_clk (clk), // Templated
.p_reset (reset), // Templated
.p_drdy (chk_drdy)); // Templated
 
initial
begin
$dumpfile("fifo_s.vcd");
$dumpvars;
reset = 1;
#100;
reset = 0;
 
// burst normal data for 20 cycles
repeat (20) @(posedge clk);
 
gen.srdy_pat = 8'h5A;
repeat (20) @(posedge clk);
 
chk.drdy_pat = 8'hA5;
repeat (40) @(posedge clk);
 
// check FIFO overflow
gen.srdy_pat = 8'hFD;
repeat (100) @(posedge clk);
 
// check FIFO underflow
gen.srdy_pat = 8'h11;
repeat (100) @(posedge clk);
 
#5000;
$finish;
end
 
endmodule // bench_fifo_s
// Local Variables:
// verilog-library-directories:("." "../../rtl/verilog/buffers")
// End:
/trunk/env/verilog/sd_seq_gen.v
0,0 → 1,94
//----------------------------------------------------------------------
// Srdy/Drdy sequence generator
//
// Simplistic traffic generator for srdy/drdy blocks. Generates an
// incrementing data sequence.
//
// 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_seq_gen
#(parameter width=8)
(input clk,
input reset,
output reg p_srdy,
input p_drdy,
output reg [width-1:0] p_data);
 
reg nxt_p_srdy;
reg [width-1:0] nxt_p_data;
 
parameter pat_dep = 8;
 
reg [pat_dep-1:0] srdy_pat;
integer spp, startup;
 
initial
begin
srdy_pat = {pat_dep{1'b1}};
spp = 0;
startup = 0;
end
 
always @*
begin
nxt_p_data = p_data;
nxt_p_srdy = p_srdy;
 
if (startup < 10)
begin
end
else if (p_srdy & p_drdy)
begin
if (srdy_pat[spp])
begin
nxt_p_data = p_data + 1;
nxt_p_srdy = 1;
end
else
nxt_p_srdy = 0;
end
else if (!p_srdy)
begin
if (srdy_pat[spp])
begin
nxt_p_data = p_data + 1;
nxt_p_srdy = 1;
end
else
nxt_p_srdy = 0;
end
end // always @ *
 
always @(posedge clk)
begin
if ((p_srdy & p_drdy) | !p_srdy)
spp = (spp + 1) % pat_dep;
end
 
always @(posedge clk)
begin
if (reset)
begin
p_srdy <= `SDLIB_DELAY 0;
p_data <= `SDLIB_DELAY 0;
end
else
begin
p_srdy <= `SDLIB_DELAY nxt_p_srdy;
p_data <= `SDLIB_DELAY nxt_p_data;
if (startup < 10)
startup = startup + 1;
end
end
 
endmodule // sd_seq_gen
/trunk/env/verilog/bench_fifo_s.vf
0,0 → 1,6
bench_fifo_s.v
sd_seq_check.v
sd_seq_gen.v
../../rtl/verilog/buffers/sd_fifo_s.v
../../rtl/verilog/buffers/sd_fifo_head_s.v
../../rtl/verilog/buffers/sd_fifo_tail_s.v

powered by: WebSVN 2.1.0

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