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
/
- from Rev 20 to Rev 21
- ↔ Reverse comparison
Rev 20 → Rev 21
/srdydrdy_lib/trunk/rtl/verilog/forks/sd_rrslow.v
File deleted
/srdydrdy_lib/trunk/rtl/verilog/forks/sd_rrmux.v
0,0 → 1,175
//---------------------------------------------------------------------- |
// Srdy/drdy round-robin arbiter |
// |
// Asserts drdy for an input and then moves to the next input. |
// |
// This component supports multiple round-robin modes: |
// |
// Mode 0 : Each input gets a single cycle, regardless of data |
// availability. This mode functions like a TDM |
// demultiplexer. Output flow control will cause the |
// component to stall, so that inputs do not miss their |
// turn due to flow control. |
// 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. |
// Mode 2 : Continue to accept input until the incoming data |
// matches a particular "end pattern". The trigger pattern |
// is when (c_data & eod_mask) == eod_pattern. Once |
// trigger pattern is seen, begin hunting for new input. |
// |
// This component also supports two arbitration modes: slow and fast. |
// slow rotates the grant from requestor to requestor cycle by cycle, |
// so each requestor gets serviced at most once every #inputs cycles. |
// This can be useful for producing a TDM-type interface, however |
// requestors may be delayed waiting for the grant to come around even |
// if there are no other requestors. |
// |
// Fast mode immediately grants the highest-priority requestor, however |
// it is drdy-noncompliant (drdy will not be asserted until srdy is |
// asserted). |
// |
// 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_rrmux |
#(parameter width=8, |
parameter inputs=2, |
parameter mode=0, |
parameter eod_pattern=0, |
parameter eod_mask=0, |
parameter fast_arb=0) |
( |
input clk, |
input reset, |
|
input [(width*inputs)-1:0] c_data, |
input [inputs-1:0] c_srdy, |
output [inputs-1:0] c_drdy, |
|
output reg [width-1:0] p_data, |
output [inputs-1:0] p_grant, |
output reg p_srdy, |
input p_drdy |
); |
|
reg [inputs-1:0] rr_state; |
reg [inputs-1:0] nxt_rr_state; |
|
reg [$clog2(inputs)-1:0] data_ind; |
|
wire [width-1:0] rr_mux_grid [0:inputs-1]; |
reg rr_locked; |
genvar i; |
integer j; |
wire trig_pattern; |
|
assign c_drdy = rr_state & {inputs{p_drdy}}; |
assign p_grant = rr_state; |
|
function [inputs-1:0] nxt_grant; |
input [inputs-1:0] cur_grant; |
input [inputs-1:0] cur_req; |
reg [inputs-1:0] msk_req; |
reg [inputs-1:0] tmp_grant; |
begin |
msk_req = cur_req & ~((cur_grant - 1) | cur_grant); |
tmp_grant = msk_req & (~msk_req + 1); |
|
if (msk_req != 0) |
nxt_grant = tmp_grant; |
else |
nxt_grant = cur_req & (~cur_req + 1); |
end |
endfunction |
|
generate |
for (i=0; i<inputs; i=i+1) |
begin : grid_assign |
assign rr_mux_grid[i] = c_data >> (i*width); |
end |
|
if (mode == 2) |
begin : tp_gen |
reg nxt_rr_locked; |
|
assign trig_pattern = (rr_mux_grid[data_ind] & eod_mask) == eod_pattern; |
always @* |
begin |
data_ind = 0; |
for (j=0; j<inputs; j=j+1) |
if (rr_state[j]) |
data_ind = j; |
|
nxt_rr_locked = rr_locked; |
|
if ((c_srdy & rr_state) & (!rr_locked)) |
nxt_rr_locked = 1; |
else if ((c_srdy & rr_state) & p_drdy & trig_pattern ) |
nxt_rr_locked = 0; |
end |
|
always @(`SDLIB_CLOCKING) |
begin |
if (reset) |
rr_locked <= `SDLIB_DELAY 0; |
else |
rr_locked <= `SDLIB_DELAY nxt_rr_locked; |
end |
end // block: tp_gen |
else |
begin : ntp_gen |
assign trig_pattern = 1'b0; |
end |
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 |
|
always @* |
begin |
if ((mode == 1) & (c_srdy & rr_state)) |
nxt_rr_state = rr_state; |
else if ((mode == 0) & !p_drdy) |
nxt_rr_state = rr_state; |
else if ((mode == 2) & (rr_locked | (c_srdy & rr_state))) |
nxt_rr_state = rr_state; |
else if (fast_arb) |
nxt_rr_state = nxt_grant (rr_state, c_srdy); |
else |
nxt_rr_state = { rr_state[0], rr_state[inputs-1:1] }; |
end |
|
always @(`SDLIB_CLOCKING) |
begin |
if (reset) |
rr_state <= `SDLIB_DELAY 1; |
else |
rr_state <= `SDLIB_DELAY nxt_rr_state; |
end |
|
endmodule // sd_rrmux |
/srdydrdy_lib/trunk/doc/component_descriptions.txt
90,9 → 90,9
Note that sd_mirror is low-throughput, as it waits until all downstream blocks have |
acknoweldged before accepting another word. |
|
3.2 sd_rrslow |
3.2 sd_rrmux |
|
This block implements a "slow" round-robin arbiter/mux. It has multiple modes |
This block implements a round-robin arbiter/mux. It has multiple modes |
with options on whether a grant implies that input will "hold" the grant, or |
whether it moves on. |
|
103,6 → 103,8
kept together. Once srdy is asserted, the block will not switch inputs until the |
end pattern is seen, even if srdy is deasserted. |
|
Also has a slow (1 cycle per input) and fast (immediate) arb mode. |
|
Validation note: modes 1 and 2 have not been verified to date. |
|
4.0 Utility |
/srdydrdy_lib/trunk/examples/bridge/rtl/ring_arb.v
8,23 → 8,42
); |
integer i; |
reg [`NUM_PORTS-1:0] nxt_rarb_ack; |
reg [$clog2(`NUM_PORTS)-1:0] nxt_ack; |
|
//reg [$clog2(`NUM_PORTS)-1:0] nxt_ack; |
|
function [`NUM_PORTS-1:0] nxt_grant; |
input [`NUM_PORTS-1:0] cur_grant; |
input [`NUM_PORTS-1:0] cur_req; |
reg [`NUM_PORTS-1:0] msk_req; |
reg [`NUM_PORTS-1:0] tmp_grant; |
begin |
msk_req = cur_req & ~((cur_grant - 1) | cur_grant); |
tmp_grant = msk_req & (~msk_req + 1); |
|
if (msk_req != 0) |
nxt_grant = tmp_grant; |
else |
nxt_grant = cur_req & (~cur_req + 1); |
end |
endfunction // if |
|
//assign nxt_rarb_ack = nxt_grant (rarb_ack, rarb_req); |
|
always @* |
begin |
nxt_rarb_ack = rarb_ack; |
nxt_ack = 0; |
|
if (rarb_req == 0) |
nxt_rarb_ack = 0; |
else if ((rarb_ack == 0) | |
((rarb_req & rarb_ack) == 0)) |
else if ((rarb_req & rarb_ack) == 0) |
begin |
nxt_rarb_ack = nxt_grant (rarb_ack, rarb_req); |
/* -----\/----- EXCLUDED -----\/----- |
nxt_ack = 0; |
for (i=`NUM_PORTS; i>0; i=i-1) |
if (rarb_req[i-1]) |
nxt_ack = i-1; |
nxt_rarb_ack = 1 << nxt_ack; |
-----/\----- EXCLUDED -----/\----- */ |
end |
end // always @ * |
|
32,7 → 51,7
begin |
if (reset) |
rarb_ack <= #1 0; |
else |
else if ((rarb_req & rarb_ack) == 0) |
rarb_ack <= #1 nxt_rarb_ack; |
end |
|
/srdydrdy_lib/trunk/examples/bridge/rtl/bridge_ex1.v
50,11 → 50,11
wire [`PAR_DATA_SZ-1:0] p2f_data_1; // From p1 of port_macro.v |
wire [`PAR_DATA_SZ-1:0] p2f_data_2; // From p2 of port_macro.v |
wire [`PAR_DATA_SZ-1:0] p2f_data_3; // From p3 of port_macro.v |
wire [`NUM_PORTS-1:0] p2f_drdy; // From fib_arb of sd_rrslow.v |
wire [`NUM_PORTS-1:0] p2f_drdy; // From fib_arb of sd_rrmux.v |
wire [3:0] p2f_srdy; // From p0 of port_macro.v, ... |
wire [`PAR_DATA_SZ-1:0] ppi_data; // From fib_arb of sd_rrslow.v |
wire [`PAR_DATA_SZ-1:0] ppi_data; // From fib_arb of sd_rrmux.v |
wire ppi_drdy; // From fib_lookup of fib_lookup.v |
wire ppi_srdy; // From fib_arb of sd_rrslow.v |
wire ppi_srdy; // From fib_arb of sd_rrmux.v |
wire [`NUM_PORTS-1:0] rarb_ack; // From ring_arb of ring_arb.v |
wire [3:0] rarb_req; // From p0 of port_macro.v, ... |
wire ri_drdy_0; // From p0 of port_macro.v |
186,8 → 186,9
.ri_srdy (ri_srdy_3), // Templated |
.ro_drdy (ri_drdy_0)); // Templated |
|
/* sd_rrslow AUTO_TEMPLATE |
/* sd_rrmux AUTO_TEMPLATE |
( |
.p_grant (), |
.p_data (ppi_data[`PAR_DATA_SZ-1:0]), |
.c_data ({p2f_data_3,p2f_data_2,p2f_data_1,p2f_data_0}), |
.c_srdy (p2f_srdy[`NUM_PORTS-1:0]), |
196,11 → 197,17
.p_\(.*\) (ppi_\1[]), |
); |
*/ |
sd_rrslow #(`PAR_DATA_SZ,`NUM_PORTS,0) fib_arb |
sd_rrmux #( |
// Parameters |
.width (`PAR_DATA_SZ), |
.inputs (`NUM_PORTS), |
.mode (0), |
.fast_arb (1)) fib_arb |
(/*AUTOINST*/ |
// Outputs |
.c_drdy (p2f_drdy[`NUM_PORTS-1:0]), // Templated |
.p_data (ppi_data[`PAR_DATA_SZ-1:0]), // Templated |
.p_grant (), // Templated |
.p_srdy (ppi_srdy), // Templated |
// Inputs |
.clk (clk), |
/srdydrdy_lib/trunk/examples/bridge/env/tests/sample_test.v
21,7 → 21,7
#2000; |
|
get_packet_count (pcount); |
check_expected (9, pcount); |
check_expected (6, pcount); |
$display ("TEST: Received %d packets", pcount); |
$finish; |
end |
/srdydrdy_lib/trunk/examples/bridge/env/tests/overflow1.v
35,7 → 35,9
#10000; |
|
get_packet_count (pcount); |
check_expected (9, pcount); |
//check_expected (9, pcount); |
if (pcount <= 1900) |
$display ("ERROR -- Should receive at least 1900 packets"); |
$display ("TEST: Received %d packets", pcount); |
$finish; |
end |