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 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

powered by: WebSVN 2.1.0

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