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 |