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 29 to Rev 30
- ↔ Reverse comparison
Rev 29 → Rev 30
/trunk/rtl/verilog/utility/llmanager.v
0,0 → 1,403
//---------------------------------------------------------------------- |
// Linked List Manager |
// |
//---------------------------------------------------------------------- |
// Author: Guy Hutchison |
// |
// This block is uncopyrighted and released into the public domain. |
//---------------------------------------------------------------------- |
|
module llmanager |
(/*AUTOARG*/ |
// Outputs |
par_drdy, parr_srdy, parr_page, lnp_drdy, rlp_drdy, rlpr_srdy, |
rlpr_data, drf_drdy, refup_drdy, pgmem_wr_en, pgmem_wr_addr, |
pgmem_wr_data, pgmem_rd_addr, pgmem_rd_en, ref_wr_en, ref_wr_addr, |
ref_wr_data, ref_rd_addr, ref_rd_en, free_count, |
// Inputs |
clk, reset, par_srdy, parr_drdy, lnp_srdy, lnp_pnp, rlp_srdy, |
rlp_rd_page, rlpr_drdy, drf_srdy, drf_page_list, refup_srdy, |
refup_page, refup_count, pgmem_rd_data, ref_rd_data |
); |
|
parameter lpsz = 8; // link list page size, in bits |
parameter lpdsz = lpsz+1; // link page data size, must be at least size of address |
parameter pages = 256; // number of pages |
//parameter sidsz = 2; // source ID size, in bits |
parameter sources = 4; // number of sources |
parameter sinks = 4; // number of sinks |
parameter sksz = 2; // number of sink address bits |
parameter maxref = 7; // maximum reference count, disable with maxref = 0 |
parameter refsz = 3; // size of reference count bits |
|
input clk; |
input reset; |
|
// page allocation request i/f |
input [sources-1:0] par_srdy; |
output [sources-1:0] par_drdy; |
|
// page allocation request reply i/f |
output [sources-1:0] parr_srdy; |
input [sources-1:0] parr_drdy; |
output [lpsz-1:0] parr_page; |
|
// link to next page i/f |
input [sources-1:0] lnp_srdy; |
output [sources-1:0] lnp_drdy; |
input [sources*(lpsz+lpdsz)-1:0] lnp_pnp; |
|
// read link page i/f |
input [sinks-1:0] rlp_srdy; |
output [sinks-1:0] rlp_drdy; |
input [sinks*lpsz-1:0] rlp_rd_page; |
|
// read link page reply i/f |
output [sinks-1:0] rlpr_srdy; |
input [sinks-1:0] rlpr_drdy; |
output [lpdsz-1:0] rlpr_data; |
|
// page dereference interface |
input [sinks-1:0] drf_srdy; |
output [sinks-1:0] drf_drdy; |
input [sinks*lpsz*2-1:0] drf_page_list; |
|
// reference count update interface |
input refup_srdy; |
output refup_drdy; |
input [lpsz-1:0] refup_page; |
input [refsz-1:0] refup_count; |
|
// link memory interface |
output pgmem_wr_en; |
output [lpsz-1:0] pgmem_wr_addr; |
output [lpdsz-1:0] pgmem_wr_data; |
output [lpsz-1:0] pgmem_rd_addr; |
output pgmem_rd_en; |
input [lpdsz-1:0] pgmem_rd_data; |
|
// reference count memory interface |
output ref_wr_en; |
output [lpsz-1:0] ref_wr_addr; |
output [refsz-1:0] ref_wr_data; |
output [lpsz-1:0] ref_rd_addr; |
output ref_rd_en; |
input [refsz-1:0] ref_rd_data; |
|
|
output [lpsz:0] free_count; |
|
reg [lpsz-1:0] r_free_head_ptr, free_tail_ptr; |
wire [lpsz-1:0] free_head_ptr; |
|
reg pmstate; |
integer i; |
wire [sources-1:0] req_src_id; |
reg [sources-1:0] iparr_src_id; |
wire req_srdy; |
|
wire reclaim_srdy; |
reg reclaim_drdy; |
wire [lpsz-1:0] reclaim_start_page, reclaim_end_page; |
|
reg [lpdsz-1:0] pgmem_wr_data; |
reg pgmem_wr_en; |
reg [lpsz-1:0] pgmem_wr_addr; |
reg [lpsz-1:0] pgmem_rd_addr; |
reg pgmem_rd_en; |
|
reg init; |
reg [lpsz:0] init_count; |
reg [lpsz:0] free_count; |
wire free_empty; |
reg req_drdy; |
|
wire irlp_srdy; |
reg irlp_drdy; |
wire [lpsz-1:0] irlp_rd_page; |
wire [sinks-1:0] irlp_grant; |
|
reg irlpr_srdy; |
wire irlpr_drdy; |
reg [sinks-1:0] irlpr_grant, nxt_irlpr_grant; |
reg load_head_ptr, nxt_load_head_ptr; |
reg load_lp_data, nxt_load_lp_data; |
|
wire ilnp_srdy; |
reg ilnp_drdy; |
wire [lpsz-1:0] ilnp_page; |
wire [lpdsz-1:0] ilnp_nxt_page; |
|
wire dsbuf_srdy, dsbuf_drdy; |
wire [sources-1:0] dsbuf_source; |
wire [lpsz-1:0] dsbuf_data; |
wire iparr_drdy; |
|
assign free_empty = (free_head_ptr == free_tail_ptr); |
assign free_head_ptr = (load_head_ptr) ? pgmem_rd_data : r_free_head_ptr; |
|
sd_rrmux #(.mode(0), .fast_arb(1), |
.width(1), .inputs(sources)) req_mux |
( |
.clk (clk), |
.reset (reset), |
|
.c_srdy (par_srdy), |
.c_drdy (par_drdy), |
.c_data ({sources{1'b0}}), |
.c_rearb (1'b1), |
|
.p_srdy (req_srdy), |
.p_drdy (req_drdy), |
.p_data (), |
.p_grant (req_src_id) |
); |
|
sd_rrmux #(.mode(0), .fast_arb(1), |
.width(lpsz+lpdsz), .inputs(sources)) lnp_mux |
( |
.clk (clk), |
.reset (reset), |
|
.c_srdy (lnp_srdy), |
.c_drdy (lnp_drdy), |
.c_data (lnp_pnp), |
.c_rearb (1'b1), |
|
.p_srdy (ilnp_srdy), |
.p_drdy (ilnp_drdy), |
.p_data ({ilnp_page,ilnp_nxt_page}), |
.p_grant () |
); |
|
sd_rrmux #(.mode(0), .fast_arb(1), |
.width(lpsz), .inputs(sources)) rlp_mux |
( |
.clk (clk), |
.reset (reset), |
|
.c_srdy (rlp_srdy), |
.c_drdy (rlp_drdy), |
.c_data (rlp_rd_page), |
.c_rearb (1'b1), |
|
.p_srdy (irlp_srdy), |
.p_drdy (irlp_drdy), |
.p_data (irlp_rd_page), |
.p_grant (irlp_grant) |
); |
|
always @(posedge clk) |
begin |
if (reset) |
begin |
init <= 1; |
init_count <= 0; |
r_free_head_ptr <= 0; |
free_tail_ptr <= pages - 1; |
free_count <= pages; |
load_head_ptr <= 0; |
load_lp_data <= 0; |
irlpr_grant <= 0; |
iparr_src_id <= 0; |
end |
else |
begin |
load_head_ptr <= nxt_load_head_ptr; |
load_lp_data <= nxt_load_lp_data; |
irlpr_grant <= nxt_irlpr_grant; |
|
if (init) |
begin |
init_count <= init_count + 1; |
if (init_count == (pages-1)) |
init <= 0; |
end |
else |
begin |
if (load_head_ptr) |
r_free_head_ptr <= pgmem_rd_data; |
|
if (req_drdy) |
iparr_src_id <= req_src_id; |
|
if (reclaim_srdy & reclaim_drdy) |
free_tail_ptr <= reclaim_end_page; |
|
if (pgmem_rd_en & !pgmem_wr_en) |
free_count <= free_count - 1; |
else if (pgmem_wr_en & !pgmem_rd_en) |
free_count <= free_count + 1; |
end |
end // else: !if(reset) |
end // always @ (posedge clk) |
|
always @* |
begin |
pgmem_wr_data = 0; |
pgmem_wr_en = 0; |
pgmem_wr_addr = 0; |
pgmem_rd_addr = 0; |
pgmem_rd_en = 0; |
ilnp_drdy = 0; |
nxt_load_head_ptr = 0; |
nxt_load_lp_data = 0; |
nxt_irlpr_grant = irlpr_grant; |
irlp_drdy = 0; |
req_drdy = 0; |
|
if (init) |
begin |
pgmem_wr_en = 1; |
pgmem_wr_addr = init_count; |
pgmem_wr_data[lpsz-1:0] = init_count + 1; |
pgmem_wr_data[lpdsz-1:lpsz] = 0; |
reclaim_drdy = 0; |
end |
else |
begin |
reclaim_drdy = 1; |
// load_lp check is to predict flow control on next cycle, |
// prevents back-to-pack Read Link Page requests |
if (irlp_srdy & irlpr_drdy & !load_lp_data) |
begin |
pgmem_rd_en = 1; |
pgmem_rd_addr = irlp_rd_page; |
nxt_load_lp_data = 1; |
nxt_irlpr_grant = irlp_grant; |
irlp_drdy = 1; |
end |
else if (req_srdy & (iparr_drdy & dsbuf_drdy) & !free_empty) |
begin |
pgmem_rd_en = 1; |
pgmem_rd_addr = free_head_ptr; |
nxt_load_head_ptr = 1; |
req_drdy = 1; |
end |
|
if (reclaim_srdy) |
begin |
pgmem_wr_en = 1; |
pgmem_wr_addr = free_tail_ptr; |
pgmem_wr_data = reclaim_start_page; |
end |
else if (ilnp_srdy) |
begin |
ilnp_drdy = 1; |
pgmem_wr_en = 1; |
pgmem_wr_addr = ilnp_page; |
pgmem_wr_data = ilnp_nxt_page; |
end |
end |
end |
|
sd_input #(.width(lpsz+sources)) lp_disp_buf |
(.clk (clk), .reset (reset), |
.c_srdy (load_head_ptr), |
.c_drdy (iparr_drdy), |
.c_data ({iparr_src_id,r_free_head_ptr}), |
.ip_srdy (dsbuf_srdy), |
.ip_drdy (dsbuf_drdy), |
.ip_data ({dsbuf_source,dsbuf_data})); |
|
sd_mirror #(.mirror(sources), .width(lpsz)) lp_dispatch |
(.clk (clk), |
.reset (reset), |
|
.c_srdy (dsbuf_srdy), |
.c_drdy (dsbuf_drdy), |
.c_data (dsbuf_data), |
.c_dst_vld (dsbuf_source), |
|
.p_srdy (parr_srdy), |
.p_drdy (parr_drdy), |
.p_data (parr_page) |
); |
|
// output reflector for read link page interface |
sd_mirror #(.mirror(sinks), .width(lpdsz)) read_link_return |
(.clk (clk), |
.reset (reset), |
|
.c_srdy (load_lp_data), |
.c_drdy (irlpr_drdy), |
.c_data (pgmem_rd_data), |
.c_dst_vld (irlpr_grant), |
|
.p_srdy (rlpr_srdy), |
.p_drdy (rlpr_drdy), |
.p_data (rlpr_data) |
); |
|
generate if (maxref == 0) |
begin : no_ref_count |
sd_rrmux #(.mode(0), .fast_arb(1), |
.width(lpsz*2), .inputs(sinks)) reclaim_mux |
( |
.clk (clk), |
.reset (reset), |
|
.c_srdy (drf_srdy), |
.c_drdy (drf_drdy), |
.c_data (drf_page_list), |
.c_rearb (1'b1), |
|
.p_srdy (reclaim_srdy), |
.p_drdy (reclaim_drdy), |
.p_data ({reclaim_start_page,reclaim_end_page}), |
.p_grant () |
); |
end // block: no_ref_count |
else |
begin : enable_ref_count |
wire drq_srdy, drq_drdy; |
wire [lpsz-1:0] drq_start_page, drq_end_page; |
|
sd_rrmux #(.mode(0), .fast_arb(1), |
.width(lpsz*2), .inputs(sinks)) reclaim_mux |
( |
.clk (clk), |
.reset (reset), |
|
.c_srdy (drf_srdy), |
.c_drdy (drf_drdy), |
.c_data (drf_page_list), |
.c_rearb (1'b1), |
|
.p_srdy (drq_srdy), |
.p_drdy (drq_drdy), |
.p_data ({drq_start_page,drq_end_page}), |
.p_grant () |
); |
|
llmanager_refcount #(/*AUTOINSTPARAM*/ |
// Parameters |
.lpsz (lpsz), |
.refsz (refsz)) llref |
(/*AUTOINST*/ |
// Outputs |
.drq_drdy (drq_drdy), |
.reclaim_srdy (reclaim_srdy), |
.reclaim_start_page (reclaim_start_page[(lpsz)-1:0]), |
.reclaim_end_page (reclaim_end_page[(lpsz)-1:0]), |
.refup_drdy (refup_drdy), |
.ref_wr_en (ref_wr_en), |
.ref_wr_addr (ref_wr_addr[(lpsz)-1:0]), |
.ref_wr_data (ref_wr_data[(refsz)-1:0]), |
.ref_rd_addr (ref_rd_addr[(lpsz)-1:0]), |
.ref_rd_en (ref_rd_en), |
// Inputs |
.clk (clk), |
.reset (reset), |
.drq_srdy (drq_srdy), |
.drq_start_page (drq_start_page[(lpsz)-1:0]), |
.drq_end_page (drq_end_page[(lpsz)-1:0]), |
.reclaim_drdy (reclaim_drdy), |
.refup_srdy (refup_srdy), |
.refup_page (refup_page[(lpsz)-1:0]), |
.refup_count (refup_count[(refsz)-1:0]), |
.ref_rd_data (ref_rd_data[(refsz)-1:0])); |
end |
endgenerate |
|
endmodule // llmanager |
/trunk/rtl/verilog/utility/llmanager_refcount.v
0,0 → 1,116
module llmanager_refcount |
#(parameter lpsz = 8, |
parameter refsz = 3) |
( |
input clk, |
input reset, |
|
input drq_srdy, |
output reg drq_drdy, |
input [lpsz-1:0] drq_start_page, |
input [lpsz-1:0] drq_end_page, |
|
output reg reclaim_srdy, |
input reclaim_drdy, |
output reg [lpsz-1:0] reclaim_start_page, |
output reg [lpsz-1:0] reclaim_end_page, |
|
// reference count update interface |
input refup_srdy, |
output reg refup_drdy, |
input [lpsz-1:0] refup_page, |
input [refsz-1:0] refup_count, |
|
// reference count memory interface |
output reg ref_wr_en, |
output reg [lpsz-1:0] ref_wr_addr, |
output reg [refsz-1:0] ref_wr_data, |
output reg [lpsz-1:0] ref_rd_addr, |
output reg ref_rd_en, |
input [refsz-1:0] ref_rd_data |
); |
|
reg [lpsz-1:0] dref_start_addr, nxt_dref_start_addr; |
reg [lpsz-1:0] dref_end_addr, nxt_dref_end_addr; |
reg [2:0] state, nxt_state; |
|
localparam s_idle = 0, s_dreq = 1, s_reclaim = 2; |
|
always @* |
begin |
reclaim_srdy = 0; |
reclaim_start_page = 0; |
reclaim_end_page = 0; |
ref_wr_en = 0; |
ref_wr_addr = 0; |
ref_wr_data = 0; |
ref_rd_addr = 0; |
ref_rd_en = 0; |
drq_drdy = 0; |
refup_drdy = 0; |
nxt_state = state; |
nxt_dref_start_addr = dref_start_addr; |
nxt_dref_end_addr = dref_end_addr; |
|
case (1'b1) |
state[s_idle] : |
begin |
refup_drdy = 1; |
if (refup_srdy) |
begin |
ref_wr_en = 1; |
ref_wr_addr = refup_page; |
ref_wr_data = refup_count; |
end |
else if (drq_srdy) |
begin |
ref_rd_en = 1; |
ref_rd_addr = drq_start_page; |
nxt_state = 1 << s_dreq; |
nxt_dref_start_addr = drq_start_page; |
nxt_dref_end_addr = drq_end_page; |
end |
end // case: s_idle |
|
state[s_dreq] : |
begin |
drq_drdy = 1; |
ref_wr_en = 1; |
ref_wr_addr = dref_start_addr; |
ref_wr_data = ref_rd_data - 1; |
if (ref_rd_data == 1) |
nxt_state = 1 << s_reclaim; |
else |
nxt_state = 1 << s_idle; |
end |
|
state[s_reclaim] : |
begin |
reclaim_srdy = 1; |
reclaim_start_page = dref_start_addr; |
reclaim_end_page = dref_end_addr; |
if (reclaim_drdy) |
nxt_state = 1 << s_idle; |
end |
endcase // case (1'b1) |
end // always @ * |
|
always @(posedge clk) |
begin |
if (reset) |
begin |
state <= 1 << s_idle; |
end |
else |
begin |
state <= nxt_state; |
end |
end |
|
always @(posedge clk) |
begin |
dref_start_addr <= nxt_dref_start_addr; |
dref_end_addr <= nxt_dref_end_addr; |
end |
|
endmodule // llmanager_refcount |
/trunk/rtl/verilog/utility/sd_scoreboard.v
72,13 → 72,13
begin : no_txid_and_mask |
assign c_hold_data = {c_req_type,c_itemid,c_mask,c_data}; |
assign {ip_req_type,ip_itemid,ip_mask,ip_data} = p_hold_data; |
assign ip_mask = 0; |
assign ip_txid = 0; |
end |
else if ((use_txid == 1) && (use_mask == 0)) |
begin : txid_and_no_mask |
assign c_hold_data = {c_txid,c_req_type,c_itemid,c_data}; |
assign {ip_txid,ip_req_type,ip_itemid,ip_data} = p_hold_data; |
assign ip_txid = 0; |
assign ip_mask = 0; |
end |
else if ((use_txid == 0) && (use_mask == 0)) |
begin : no_txid_no_mask |
/trunk/rtl/verilog/forks/sd_rrmux.v
10,6 → 10,13
// demultiplexer. Output flow control will cause the |
// component to stall, so that inputs do not miss their |
// turn due to flow control. |
// Mode 0 fast arb : Each input gets a single grant. If the |
// output is not ready (p_drdy deasserted), then the |
// machine will hold on that particular input until it |
// receives a grant. Once a single token has been |
// accepted the machine will round-robin arbitrate. |
// When there are no requests the machine returns to |
// its default state. |
// Mode 1 : Each input can transmit for as long as it has data. |
// When input deasserts, device will begin to hunt for a |
// new input with data. |
62,9 → 69,9
output [inputs-1:0] c_drdy, |
input c_rearb, // for use with mode 2 only |
|
output reg [width-1:0] p_data, |
output [width-1:0] p_data, |
output [inputs-1:0] p_grant, |
output reg p_srdy, |
output p_srdy, |
input p_drdy |
); |
|
71,9 → 78,9
reg [inputs-1:0] rr_state; |
reg [inputs-1:0] nxt_rr_state; |
|
wire [width-1:0] rr_mux_grid [0:inputs-1]; |
//wire [width-1:0] rr_mux_grid [0:inputs-1]; |
reg rr_locked; |
genvar i; |
//genvar i; |
integer j; |
|
assign c_drdy = rr_state & {inputs{p_drdy}}; |
95,11 → 102,23
end |
endfunction |
|
always @* |
begin |
data_ind = 0; |
for (j=0; j<inputs; j=j+1) |
if (rr_state[j]) |
data_ind = j; |
end |
|
generate |
/* -----\/----- EXCLUDED -----\/----- |
for (i=0; i<inputs; i=i+1) |
begin : grid_assign |
wire [width-1:0] temp; |
assign temp = c_data >> (i*width); |
assign rr_mux_grid[i] = c_data >> (i*width); |
end |
-----/\----- EXCLUDED -----/\----- */ |
|
if (mode == 2) |
begin : tp_gen |
108,7 → 127,18
|
always @* |
begin |
if (c_rearb) |
/* -----\/----- EXCLUDED -----\/----- |
data_ind = 0; |
for (j=0; j<inputs; j=j+1) |
if (rr_state[j]) |
data_ind = j; |
-----/\----- EXCLUDED -----/\----- */ |
|
nxt_rr_locked = rr_locked; |
|
if ((c_srdy & rr_state) & (!rr_locked)) |
nxt_rr_locked = 1; |
else if ((c_srdy & rr_state & c_rearb) & p_drdy ) |
nxt_rr_locked = 0; |
else if ((nxt_rr_state != rr_state) && (nxt_rr_state != 0)) |
nxt_rr_locked = 1; |
126,24 → 156,17
end // block: tp_gen |
endgenerate |
|
always @* |
begin |
p_data = 0; |
p_srdy = 0; |
for (j=0; j<inputs; j=j+1) |
if (rr_state[j]) |
begin |
p_data = rr_mux_grid[j]; |
p_srdy = c_srdy[j]; |
end |
end |
assign p_srdy = |(rr_state & c_srdy); |
assign p_data = c_data[data_ind*width +: width]; |
|
always @* |
begin |
if ((mode == 1) & (c_srdy & rr_state)) |
nxt_rr_state = rr_state; |
else if ((mode == 0) & !p_drdy) |
else if ((mode == 0) && !p_drdy && !fast_arb) |
nxt_rr_state = rr_state; |
else if ((mode == 0) && |(rr_state & c_srdy) && !p_drdy && fast_arb) |
nxt_rr_state = rr_state; |
else if ((mode == 2) & (rr_locked | (c_srdy & rr_state))) |
nxt_rr_state = rr_state; |
else if (fast_arb) |
155,7 → 178,7
always @(`SDLIB_CLOCKING) |
begin |
if (reset) |
rr_state <= `SDLIB_DELAY 1; |
rr_state <= `SDLIB_DELAY (fast_arb)? 0 : 1; |
else |
rr_state <= `SDLIB_DELAY nxt_rr_state; |
end |
/trunk/rtl/verilog/forks/sd_ajoin2.v
26,7 → 26,7
#(parameter c1_width=8, |
parameter c2_width=8) |
( |
input clk; |
input clk, |
input reset, |
|
input c1_srdy, |
/trunk/rtl/verilog/memory/behave1p_mem.v
38,6 → 38,7
|
assign d_out = array[r_addr]; |
|
`ifndef verilator |
genvar g; |
|
generate |
48,5 → 49,6
assign brk=array[g]; |
end |
endgenerate |
`endif |
|
endmodule |
/trunk/rtl/verilog/closure/sd_output.v
37,17 → 37,13
); |
|
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; |
ic_drdy = p_drdy | !p_srdy; |
load = ic_srdy & ic_drdy; |
nxt_p_srdy = load | hold; |
nxt_p_srdy = load | (p_srdy & !p_drdy); |
end |
|
always @(`SDLIB_CLOCKING) |
/trunk/examples/bridge/env/gmii_driver.v
43,6 → 43,7
end |
|
icrc = nxt_icrc; |
$display ("DEBUG: byte %02d data=%x crc=%x", len, rxbuf[len], icrc); |
end // for (len=0; len<length; len=len+1) |
|
icrc = ~icrc; |
123,7 → 124,7
rxbuf[p] = $random; |
|
//gencrc32 (length); |
gencrc32 (length, crc32_result); |
gencrc32 (length-4, crc32_result); |
{ rxbuf[length-1], rxbuf[length-2], |
rxbuf[length-3], rxbuf[length-4] } = crc32_result; |
|
/trunk/examples/bridge/env/run
7,7 → 7,7
if [ "$?" == "0" ]; then |
rm -f a.out |
iverilog -f bridge.vf tests/$TESTNAME.v $* | tee compile.log |
./a.out -lxt | tee run.log |
./a.out | tee run.log |
else |
vcs -full64 +v2k -R -I -f bridge.vf tests/$TESTNAME.v $* |
fi |