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

Rev 1 → Rev 2

/trunk/rtl/verilog/forks/sd_mirror.v
0,0 → 1,104
//----------------------------------------------------------------------
// Srdy/drdy mirrored fork
//
// Used when a single item of data needs to be used by more than one
// block, and all blocks may finish at different times. This creates
// separate srdy/drdy signals for each block, and holds drdy to the
// sender until all blocks have individually asserted drdy.
//
// The input c_dst_vld allows the data to be selectively sent to some
// or all of the downstream endpoints. At least one bit in c_dst_vld
// must be asserted with c_srdy. If this functionality is not desired
// the input should be tied to 0.
//
// 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_mirror
#(parameter mirror=2,
parameter width=128)
(input clk,
input reset,
 
input c_srdy,
output reg c_drdy,
input [width-1:0] c_data,
input [mirror-1:0] c_dst_vld,
 
output reg [mirror-1:0] p_srdy,
input [mirror-1:0] p_drdy,
output reg [width-1:0] p_data
);
 
reg state, nxt_state;
reg [mirror-1:0] nxt_p_srdy;
reg load;
always @(posedge clk)
if (load)
p_data <= `SDLIB_DELAY c_data;
always @*
begin
nxt_p_srdy = p_srdy;
nxt_state = state;
c_drdy = 0;
load = 0;
case (state)
0 :
begin
c_drdy = 1'b1;
if (c_srdy)
begin
if (c_dst_vld == {mirror{1'b0}})
nxt_p_srdy = {mirror{1'b1}};
else
nxt_p_srdy = c_dst_vld;
nxt_state = 1;
load = 1;
end
end
 
1 :
begin
nxt_p_srdy = p_srdy & ~p_drdy;
if (p_srdy == {mirror{1'b0}})
begin
nxt_state = 1'b0;
end
end
endcase
end
 
always @(`SDLIB_CLOCKING)
begin
if (reset)
begin
p_srdy <= `SDLIB_DELAY {mirror{1'b0}};
state <= `SDLIB_DELAY 1'b0;
end
else
begin
p_srdy <= `SDLIB_DELAY nxt_p_srdy;
state <= `SDLIB_DELAY nxt_state;
end
end
 
endmodule // sd_mirror
/trunk/rtl/verilog/memory/behave1p_mem.v
0,0 → 1,41
//----------------------------------------------------------------------
// Author: Guy Hutchison
//
// This block is uncopyrighted and released into the public domain.
//----------------------------------------------------------------------
 
module behave1p_mem
#(parameter depth=256,
parameter width=8,
parameter addr_sz=$clog2(depth))
(/*AUTOARG*/
// Outputs
d_out,
// Inputs
wr_en, rd_en, clk, d_in, addr
);
input wr_en, rd_en, clk;
input [width-1:0] d_in;
input [addr_sz-1:0] addr;
 
output [width-1:0] d_out;
 
reg [addr_sz-1:0] r_addr;
 
reg [width-1:0] array[0:depth-1];
always @(posedge clk)
begin
if (wr_en)
begin
array[addr] <= #1 d_in;
end
else if (rd_en)
begin
r_addr <= #1 addr;
end
end // always @ (posedge clk)
 
assign d_out = array[r_addr];
 
endmodule
/trunk/rtl/verilog/memory/behave2p_mem.v
0,0 → 1,46
//----------------------------------------------------------------------
// Author: Guy Hutchison
//
// This block is uncopyrighted and released into the public domain.
//----------------------------------------------------------------------
 
module behave2p_mem
#(parameter depth=256,
parameter width=8,
parameter addr_sz=$clog2(depth))
(/*AUTOARG*/
// Outputs
d_out,
// Inputs
wr_en, rd_en, wr_clk, rd_clk, d_in, rd_addr, wr_addr
);
input wr_en, rd_en, wr_clk;
input rd_clk;
input [width-1:0] d_in;
input [addr_sz-1:0] rd_addr, wr_addr;
 
output [width-1:0] d_out;
 
reg [addr_sz-1:0] r_addr;
 
reg [width-1:0] array[0:depth-1];
always @(posedge wr_clk)
begin
if (wr_en)
begin
array[wr_addr] <= #1 d_in;
end
end
 
always @(posedge rd_clk)
begin
if (rd_en)
begin
r_addr <= #1 rd_addr;
end
end // always @ (posedge clk)
 
assign d_out = array[r_addr];
 
endmodule
/trunk/rtl/verilog/buffers/sd_fifo_head_b.v
0,0 → 1,123
//----------------------------------------------------------------------
// Srdy/Drdy FIFO Head "B"
//
// Building block for FIFOs. The "B" (big) FIFO is design for larger FIFOs
// based around memories, with sizes that may not be a power of 2.
//
// The bound inputs allow multiple FIFO controllers to share a single
// memory. The enable input is for arbitration between multiple FIFO
// controllers, or between the fifo head and tail controllers on a
// single port memory.
//
// The commit parameter enables write/commit behavior. This creates
// two write pointers, one which is used for writing to memory and
// a commit pointer which is sent to the tail block.
//
// 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_head_b
#(parameter depth=16,
parameter commit=0,
parameter asz=$clog2(depth)
)
(
input clk,
input reset,
input enable,
input c_commit,
input c_abort, // should be asserted when c_srdy == 0
input c_srdy,
output c_drdy,
 
input [asz-1:0] bound_low,
input [asz-1:0] bound_high,
 
input [asz-1:0] rdptr,
output reg [asz-1:0] cur_wrptr,
output reg [asz-1:0] com_wrptr,
output reg mem_we
);
reg [asz-1:0] nxt_wrptr;
reg [asz-1:0] wrptr_p1;
reg empty;
reg full, nxt_full;
reg [asz-1:0] nxt_com_wrptr;
generate if (!commit)
always @* com_wrptr = cur_wrptr;
endgenerate
 
assign c_drdy = !full & enable;
always @*
begin
if (cur_wrptr[asz-1:0] == bound_high)
begin
wrptr_p1[asz-1:0] = bound_low;
end
else
wrptr_p1 = cur_wrptr + 1;
empty = (cur_wrptr == rdptr) & !full;
nxt_full = (wrptr_p1 == rdptr);
 
if ((commit == 1) && c_abort)
begin
nxt_wrptr = com_wrptr;
end
else if (enable & c_srdy & !full)
begin
nxt_wrptr = wrptr_p1;
mem_we = 1;
end
else
begin
nxt_wrptr = cur_wrptr;
mem_we = 0;
end
end
 
always @(posedge clk)
begin
if (reset)
begin
cur_wrptr <= `SDLIB_DELAY bound_low;
full <= `SDLIB_DELAY 0;
end
else
begin
cur_wrptr <= `SDLIB_DELAY nxt_wrptr;
full <= `SDLIB_DELAY nxt_full;
end // else: !if(reset)
end // always @ (posedge clk)
 
generate if (commit)
always @*
begin
if (enable & c_commit & !c_abort & c_srdy & !full)
nxt_com_wrptr = wrptr_p1;
else
nxt_com_wrptr = com_wrptr;
end
always @(posedge clk)
begin
if (reset)
com_wrptr <= `SDLIB_DELAY bound_low;
else
com_wrptr <= `SDLIB_DELAY nxt_com_wrptr;
end
endgenerate
 
endmodule // fifo_head
 
/trunk/rtl/verilog/buffers/sd_fifo_tail_b.v
0,0 → 1,240
//----------------------------------------------------------------------
// Srdy/Drdy FIFO Tail "B"
//
// Building block for FIFOs. The "B" (big) FIFO is design for larger FIFOs
// based around memories, with sizes that may not be a power of 2.
//
// The bound inputs allow multiple FIFO controllers to share a single
// memory. The enable input is for arbitration between multiple FIFO
// controllers, or between the fifo head and tail controllers on a
// single port memory.
//
// The commit parameter enables read/commit behavior. This creates
// two read pointers, one which is used for reading from memory and
// a commit pointer which is sent to the head block. The abort behavior
// has a 3-cycle performance penalty due to pipeline flush.
//
// The FIFO tail assumes a memory with one-cycle read latency, and
// has output buffering to compensate for this.
//
// 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_b
#(parameter width=8,
parameter depth=16,
parameter commit=0,
parameter asz=$clog2(depth))
(
input clk,
input reset,
input enable,
 
input [asz-1:0] bound_low,
input [asz-1:0] bound_high,
 
output reg [asz-1:0] cur_rdptr,
output reg [asz-1:0] com_rdptr,
input [asz-1:0] wrptr,
output reg mem_re,
 
output reg [asz:0] usage,
output p_srdy,
input p_drdy,
input p_commit,
input p_abort,
input [width-1:0] mem_rd_data,
output [width-1:0] p_data
);
 
reg [asz-1:0] cur_rdptr;
reg [asz-1:0] nxt_cur_rdptr;
reg [asz-1:0] cur_rdptr_p1;
reg [asz-1:0] com_rdptr;
reg empty, full;
 
reg p_srdy;
reg nxt_irdy;
 
reg [width-1:0] hold_a, hold_b;
reg valid_a, valid_b;
reg prev_re;
reg [asz:0] tmp_usage;
reg [asz:0] fifo_size;
 
// Stage 1 -- Read pipeline
// issue a read if:
// 1) we are enabled
// 2) valid_a is 0, OR
// 3) valid_b is 0, OR
// 4) valid_a && valid_b && trdy
always @*
begin
if (cur_rdptr[asz-1:0] == (bound_high))
begin
cur_rdptr_p1[asz-1:0] = bound_low;
end
else
cur_rdptr_p1 = cur_rdptr + 1;
empty = (wrptr == cur_rdptr);
 
if (commit && p_abort)
begin
nxt_cur_rdptr = com_rdptr;
mem_re = 0;
end
else if (enable & !empty & (!valid_a | (!prev_re & !valid_b) |
(valid_a & valid_b & p_drdy)))
begin
nxt_cur_rdptr = cur_rdptr_p1;
mem_re = 1;
end
else
begin
nxt_cur_rdptr = cur_rdptr;
mem_re = 0;
end // else: !if(enable & !empty & (!valid_a | !valid_b |...
 
fifo_size = (bound_high - bound_low + 1);
tmp_usage = wrptr[asz-1:0] - cur_rdptr[asz-1:0];
if (~tmp_usage[asz])
usage = tmp_usage[asz-1:0];
else
usage = fifo_size - (cur_rdptr[asz-1:0] - wrptr[asz-1:0]);
end
 
always @(posedge clk)
begin
if (reset)
cur_rdptr <= `SDLIB_DELAY bound_low;
else
cur_rdptr <= `SDLIB_DELAY nxt_cur_rdptr;
end
 
generate
if (commit == 1)
begin : gen_s0
reg [asz-1:0] rdaddr_s0, rdaddr_a, rdaddr_b;
reg [asz-1:0] nxt_com_rdptr;
 
always @(posedge clk)
begin
if (reset)
com_rdptr <= `SDLIB_DELAY bound_low;
else
com_rdptr <= `SDLIB_DELAY nxt_com_rdptr;
 
if (mem_re)
rdaddr_s0 <= `SDLIB_DELAY cur_rdptr;
end
end
else
begin : gen_ns0
always @*
com_rdptr = cur_rdptr;
end
endgenerate
 
// Stage 2 -- read buffering
always @(`SDLIB_CLOCKING)
begin
if (reset)
begin
valid_a <= `SDLIB_DELAY 0;
hold_a <= `SDLIB_DELAY 0;
prev_re <= `SDLIB_DELAY 0;
end
else
begin
if (commit && p_abort)
prev_re <= `SDLIB_DELAY 0;
else
prev_re <= `SDLIB_DELAY mem_re;
 
if (commit && p_abort)
valid_a <= `SDLIB_DELAY 0;
else if (prev_re)
begin
valid_a <= `SDLIB_DELAY 1;
hold_a <= `SDLIB_DELAY mem_rd_data;
end
else if (!valid_b | p_drdy)
valid_a <= `SDLIB_DELAY 0;
end
end // always @ (posedge clk or posedge reset)
generate
if (commit == 1)
begin : gen_s2
always @(posedge clk)
begin
if (prev_re)
rdaddr_a <= `SDLIB_DELAY rdaddr_s0;
end
end
endgenerate
 
// Stage 3 -- output irdy/trdy
always @(`SDLIB_CLOCKING)
begin
if (reset)
begin
valid_b <= `SDLIB_DELAY 0;
hold_b <= `SDLIB_DELAY 0;
end
else
begin
if (commit && p_abort)
valid_b <= `SDLIB_DELAY 0;
else if (valid_a & (!valid_b | p_drdy))
begin
valid_b <= `SDLIB_DELAY 1;
hold_b <= `SDLIB_DELAY hold_a;
end
else if (valid_b & p_drdy)
valid_b <= `SDLIB_DELAY 0;
end
end // always @ (posedge clk or posedge reset)
 
generate
if (commit == 1)
begin : gen_s3
always @(posedge clk)
begin
if (valid_a & (!valid_b | p_drdy))
rdaddr_b <= `SDLIB_DELAY rdaddr_a;
end
 
always @*
begin
if (p_commit)
nxt_com_rdptr = rdaddr_b;
else
nxt_com_rdptr = com_rdptr;
end
end
endgenerate
 
assign p_srdy = valid_b;
assign p_data = hold_b;
endmodule // it_fifo
/trunk/rtl/verilog/closure/sd_iofull.v
0,0 → 1,53
//----------------------------------------------------------------------
// Srdy/Drdy input/output block
//
// Halts timing on all signals with efficiency of 1.0. Note that this
// block is simply a combination of sd_input and sd_output.
//
// Naming convention: c = consumer, p = producer, i = internal interface
//----------------------------------------------------------------------
// Author: Guy Hutchison
//
// This block is uncopyrighted and released into the public domain.
//----------------------------------------------------------------------
 
module sd_iofull
#(parameter width = 8)
(
input clk,
input reset,
input c_srdy,
output c_drdy,
input [width-1:0] c_data,
 
output p_srdy,
input p_drdy,
output [width-1:0] p_data
);
 
wire i_irdy, i_drdy;
wire [width-1:0] i_data;
 
sd_input #(width) in
(
.c_drdy (c_drdy),
.ip_srdy (i_srdy),
.ip_data (i_data),
.clk (clk),
.reset (reset),
.c_srdy (c_srdy),
.c_data (c_data),
.ip_drdy (i_drdy));
 
sd_output #(width) out
(
.ic_drdy (i_drdy),
.p_srdy (p_srdy),
.p_data (p_data),
.clk (clk),
.reset (reset),
.ic_srdy (i_srdy),
.ic_data (i_data),
.p_drdy (p_drdy));
 
endmodule
/trunk/rtl/verilog/closure/sd_input.v
0,0 → 1,87
//----------------------------------------------------------------------
// Srdy/Drdy input block
//
// Halts timing on c_drdy. Intended to be used on the input side of
// a design block.
//
// 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_input
#(parameter width = 8)
(
input clk,
input reset,
input c_srdy,
output reg c_drdy,
input [width-1:0] c_data,
 
output reg ip_srdy,
input ip_drdy,
output reg [width-1:0] ip_data
);
 
reg load;
reg drain;
reg occupied, nxt_occupied;
reg [width-1:0] hold, nxt_hold;
reg nxt_c_drdy;
 
always @*
begin
nxt_hold = hold;
nxt_occupied = occupied;
 
drain = occupied & ip_drdy;
load = c_srdy & c_drdy & (!ip_drdy | drain);
if (occupied)
ip_data = hold;
else
ip_data = c_data;
 
ip_srdy = (c_srdy & c_drdy) | occupied;
 
if (load)
begin
nxt_hold = c_data;
nxt_occupied = 1;
end
else if (drain)
nxt_occupied = 0;
 
nxt_c_drdy = (!occupied & !load) | (drain & !load);
end
 
always @(`SDLIB_CLOCKING)
begin
if (reset)
begin
hold <= `SDLIB_DELAY 0;
occupied <= `SDLIB_DELAY 0;
c_drdy <= `SDLIB_DELAY 0;
end
else
begin
hold <= `SDLIB_DELAY nxt_hold;
occupied <= `SDLIB_DELAY nxt_occupied;
c_drdy <= `SDLIB_DELAY nxt_c_drdy;
end // else: !if(reset)
end // always @ (posedge clk)
endmodule
/trunk/rtl/verilog/closure/sd_output.v
0,0 → 1,69
//----------------------------------------------------------------------
// Srdy/Drdy output block
//
// Halts timing on all signals except ic_drdy
// ic_drdy is a combinatorial path from p_drdy
//
// 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_output
#(parameter width = 8)
(
input clk,
input reset,
input ic_srdy,
output reg ic_drdy,
input [width-1:0] ic_data,
 
output reg p_srdy,
input p_drdy,
output reg [width-1:0] p_data
);
 
reg load; // true when data will be loaded into p_data
reg drain; // true when data will be emptied from p_data
reg hold; // true when data will be held in p_data
reg nxt_p_srdy;
 
always @*
begin
drain = p_srdy & p_drdy;
hold = p_srdy & !p_drdy;
ic_drdy = drain | !p_srdy;
load = ic_srdy & ic_drdy;
nxt_p_srdy = load | hold;
end
always @(`SDLIB_CLOCKING)
begin
if (reset)
begin
p_srdy <= `SDLIB_DELAY 0;
end
else
begin
p_srdy <= `SDLIB_DELAY nxt_p_srdy;
end // else: !if(reset)
end // always @ (posedge clk)
 
always @(posedge clk)
if (load)
p_data <= `SDLIB_DELAY ic_data;
 
endmodule // it_output
/trunk/rtl/verilog/closure/sd_iohalf.v
0,0 → 1,65
//----------------------------------------------------------------------
// Srdy/Drdy input/output block
//
// Halts timing on all signals. Efficiency of block is only 0.5, so
// it can produce data at most on every other cycle.
//
// 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_iohalf
#(parameter width = 8)
(
input clk,
input reset,
input c_srdy,
output c_drdy,
input [width-1:0] c_data,
 
output reg p_srdy,
input p_drdy,
output reg [width-1:0] p_data
);
 
reg load; // true when data will be loaded into p_data
reg nxt_p_srdy;
 
always @*
begin
load = c_srdy & !p_srdy;
nxt_p_srdy = (p_srdy & !p_drdy) | (!p_srdy & c_srdy);
end
assign c_drdy = ~p_srdy;
always @(`SDLIB_CLOCKING)
begin
if (reset)
begin
p_srdy <= `SDLIB_DELAY 0;
end
else
begin
p_srdy <= `SDLIB_DELAY nxt_p_srdy;
end // else: !if(reset)
end // always @ (posedge clk)
 
always @(posedge clk)
if (load)
p_data <= `SDLIB_DELAY c_data;
 
endmodule // it_output

powered by: WebSVN 2.1.0

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