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
    /
    from Rev 20 to Rev 21
    Reverse comparison

Rev 20 → Rev 21

/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

powered by: WebSVN 2.1.0

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