OpenCores
URL https://opencores.org/ocsvn/scalable_arbiter/scalable_arbiter/trunk

Subversion Repositories scalable_arbiter

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 10 to Rev 11
    Reverse comparison

Rev 10 → Rev 11

scalable_arbiter/branches Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: scalable_arbiter/tags =================================================================== --- scalable_arbiter/tags (revision 10) +++ scalable_arbiter/tags (nonexistent)
scalable_arbiter/tags Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: scalable_arbiter/trunk/bench/verilog/tb_abrbiter2.v =================================================================== --- scalable_arbiter/trunk/bench/verilog/tb_abrbiter2.v (revision 10) +++ scalable_arbiter/trunk/bench/verilog/tb_abrbiter2.v (nonexistent) @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2008, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`timescale 1ns / 1ps - -// This bench applies req vectors, deasserts req lines as -// they are granted, and tests that each req is granted -// only once for each vector. It seems to be a pretty good -// test because it is similar to the arbiter's intended -// application, and it focuses on fairness, the most -// important aspect of the arbiter's behavior. This test -// also makes it easy to use large arbiter configurations, -// which tend to find more problems. - -`define WIDTH 128 -`define SELECT_WIDTH 7 -`define TURNAROUND 3 -//`define TURNAROUND 6 for arbiter x2 -`define TICK 10 -`define HALF_TICK 5 -`define TEST_VEC_COUNT 8 -`define PATTERN_FILE "tb_arbiter2.txt" -`define ROUND_COUNT 3 - -module tb_arbiter2; - -reg reset; -reg clock; - -reg [`WIDTH-1:0] req; -wire [`WIDTH-1:0] grant; -wire [`SELECT_WIDTH-1:0] select; -wire valid; - -reg [`WIDTH-1:0] pattern[`TEST_VEC_COUNT-1:0]; - -integer test_i; -integer grant_i; -integer grant_count; -integer req_i; -integer req_count[`TEST_VEC_COUNT-1:0]; -integer failures; -integer monitor_exceptions; -integer fill_i; -integer round; -integer reqs[`WIDTH-1:0]; -integer grants[`ROUND_COUNT-1:0][`WIDTH-1:0]; - -// -// UUT -// - -arbiter #( - .width(`WIDTH), - .select_width(`SELECT_WIDTH) -) arbiter ( - .enable(1'b1), - .req(req), - .grant(grant), - .select(select), - .valid(valid), - - .clock(clock), - .reset(reset) -); - -// -// clock -// - -always @(clock) - #`HALF_TICK clock <= !clock; - -// -// test monitors -// - -always @(grant) -begin - grant_count = 0; - for(grant_i = 0; grant_i < `WIDTH; grant_i = grant_i + 1) - begin - if(grant[grant_i]) - begin - grant_count = grant_count + 1; - grants[round][grant_i] = grants[round][grant_i] + 1; - - if(!req[grant_i]) - begin - monitor_exceptions = monitor_exceptions + 1; - - $display("EXCEPTION @%e: grant line %d with no req", - $realtime, grant_i); - end - - if(select != grant_i) - begin - monitor_exceptions = monitor_exceptions + 1; - - $display("EXCEPTION @%e: select of %d does not match grant of line %d", - $realtime, select, grant_i); - end - end - end - - if(grant_count > 1) - begin - monitor_exceptions = monitor_exceptions + 1; - - $display("EXCEPTION @%e: grant %h asserts multiple lines", - $realtime, grant); - end -end - -// -// test sequence -// - -initial -begin - $readmemh(`PATTERN_FILE, pattern); - failures = 0; - monitor_exceptions = 0; - fill_i = 0; - round = 0; - for(req_i = 0; req_i < `WIDTH; req_i = req_i + 1) - begin - reqs[req_i] = 0; - - grants[0][req_i] = 0; - grants[1][req_i] = 0; - grants[2][req_i] = 0; - end - // pre-calculate some values used in the test - for(test_i = 0; test_i < `TEST_VEC_COUNT; test_i = test_i + 1) - begin - req_count[test_i] = 0; - for(req_i = 0; req_i < `WIDTH; req_i = req_i + 1) - begin - if(pattern[test_i][req_i]) - begin - req_count[test_i] = req_count[test_i] + 1; - reqs[req_i] = reqs[req_i] + 1; - end - end - end - - clock = 1; - req = 0; - reset = 1; - #`TICK @(negedge clock) reset = 0; - - // apply reqs, and turn off granted reqs permanently - for(test_i = 0; test_i < `TEST_VEC_COUNT; test_i = test_i + 1) - begin - req = pattern[test_i]; - - for(req_i = 0; req_i < req_count[test_i]; req_i = req_i + 1) - begin - #(`TURNAROUND*`TICK); - - req = req & ~grant; - end - - // one clock to deassert the last req before we apply - // the next req vector - #`TICK; - end - - // apply reqs, but only turn off granted reqs temporarily - round = round + 1; - for(test_i = 0; test_i < `TEST_VEC_COUNT; test_i = test_i + 1) - begin - req = pattern[test_i]; - - for(req_i = 0; req_i < req_count[test_i]; req_i = req_i + 1) - begin - #(`TURNAROUND*`TICK); - - req = pattern[test_i] & ~grant; - end - - // one clock to deassert the reqs before we apply the - // next req vector - req = 0; - #`TICK; - end - - // apply reqs, and fill behind with the next vector as reqs - // are granted - round = round + 1; - req = pattern[0]; - fill_i = `WIDTH; - for(test_i = 0; test_i < `TEST_VEC_COUNT; test_i = test_i + 1) - begin - for(req_i = 0; req_i < req_count[test_i]; req_i = req_i + 1) - begin - #(`TURNAROUND*`TICK); - - req = req & ~grant; - - for(fill_i = fill_i; ~grant[fill_i%`WIDTH]; fill_i = fill_i + 1) - begin - req[fill_i%`WIDTH] = (fill_i/`WIDTH < `TEST_VEC_COUNT) - ? pattern[fill_i/`WIDTH][fill_i%`WIDTH] - : 1'b0; - end - end - end - - // check the results - for(req_i = 0; req_i < `WIDTH; req_i = req_i + 1) - begin - if(reqs[req_i] != grants[0][req_i] - || reqs[req_i] != grants[1][req_i] - || reqs[req_i] != grants[2][req_i]) - begin - failures = failures + 1; - - $display("FAILED %d: %d reqs, %d %d %d grants", - req_i, reqs[req_i], grants[0][req_i], - grants[1][req_i], grants[2][req_i]); - end - else - begin - $display("ok %d: %d reqs, %d %d %d grants", - req_i, reqs[req_i], grants[0][req_i], - grants[1][req_i], grants[2][req_i]); - end - end - - $display("%d failures", failures); - $display("%d monitor exceptions", monitor_exceptions); - - if(failures == 0 && monitor_exceptions == 0) - $display("PASS"); - else - $display("FAIL"); -end - -endmodule Index: scalable_arbiter/trunk/bench/verilog/tb_arbiter.txt =================================================================== --- scalable_arbiter/trunk/bench/verilog/tb_arbiter.txt (revision 10) +++ scalable_arbiter/trunk/bench/verilog/tb_arbiter.txt (nonexistent) @@ -1,241 +0,0 @@ -0 0 -11111111 00000001 -11111110 00000010 -11111100 00000100 -11111000 00001000 -11110000 00010000 -11100000 00100000 -11000000 01000000 -10000000 10000000 -0 0 -11111111 00000001 -11111110 00000010 -11111100 00000100 -11111000 00001000 -11110000 00010000 -11100000 00100000 -11000000 01000000 -10000000 10000000 -0 0 -11111111 00000001 -01111111 00000001 -00111111 00000001 -00011111 00000001 -00001111 00000001 -00000111 00000001 -00000011 00000001 -00000001 00000001 -0 0 -00000001 00000001 -00000010 00000010 -00000100 00000100 -00001000 00001000 -00010000 00010000 -00100000 00100000 -01000000 01000000 -10000000 10000000 -0 0 -10000000 10000000 -01000000 01000000 -00100000 00100000 -00010000 00010000 -00001000 00001000 -00000100 00000100 -00000010 00000010 -00000001 00000001 -0 0 -11111110 00000010 -11111101 00000100 -11111011 00001000 -11110111 00010000 -11101111 00100000 -11011111 01000000 -10111111 10000000 -01111111 00000001 -0 0 -01111111 00000001 -10111111 00000001 -11011111 00000001 -11101111 00000001 -11110111 00000001 -11111011 00000001 -11111101 00000001 -11111110 00000010 -0 0 -00000001 00000001 -00000000 00000000 -00000010 00000010 -00000000 00000000 -00000100 00000100 -00000000 00000000 -00001000 00001000 -00000000 00000000 -00010000 00010000 -00000000 00000000 -00100000 00100000 -00000000 00000000 -01000000 01000000 -00000000 00000000 -10000000 10000000 -0 0 -10000000 10000000 -00000000 00000000 -01000000 01000000 -00000000 00000000 -00100000 00100000 -00000000 00000000 -00010000 00010000 -00000000 00000000 -00001000 00001000 -00000000 00000000 -00000100 00000100 -00000000 00000000 -00000010 00000010 -00000000 00000000 -00000001 00000001 -0 0 -11111111 00000001 -11111110 00000010 -11111111 00000010 -11111101 00000100 -11111111 00000100 -11111011 00001000 -11111111 00001000 -11110111 00010000 -11111111 00010000 -11101111 00100000 -11111111 00100000 -11011111 01000000 -11111111 01000000 -10111111 10000000 -11111111 10000000 -01111111 00000001 -11111111 00000001 -0 0 -11111111 00000001 -01111111 00000001 -11111111 00000001 -10111111 00000001 -11111111 00000001 -11011111 00000001 -11111111 00000001 -11101111 00000001 -11111111 00000001 -11110111 00000001 -11111111 00000001 -11111011 00000001 -11111111 00000001 -11111101 00000001 -11111111 00000001 -11111110 00000010 -11111111 00000010 -0 0 -01010101 00000001 -10000000 10000000 -01010101 00000001 -00100000 00100000 -01010101 01000000 -00001000 00001000 -01010101 00010000 -00000010 00000010 -01010101 00000100 -0 0 -10101010 00000010 -01000000 01000000 -10101010 10000000 -00010000 00010000 -10101010 00100000 -00000100 00000100 -10101010 00001000 -00000001 00000001 -10101010 00000010 -0 0 -00010000 00010000 -00100001 00100000 -01000001 01000000 -10000001 10000000 -00010001 00000001 -00010010 00000010 -00010100 00000100 -00011000 00001000 -00010001 00010000 -00100001 00100000 -01000001 01000000 -10000001 10000000 -00010001 00000001 -00010010 00000010 -00010100 00000100 -00011000 00001000 -0 0 -01010101 00000001 -01010110 00000010 -01010101 00000100 -01011001 00001000 -01010101 00010000 -01100101 00100000 -01010101 01000000 -10010101 10000000 -01010101 00000001 -0 0 -10101010 00000010 -10101101 00001000 -11110111 00100000 -11011111 10000000 -01111111 00000001 -11111110 00000010 -11111100 00000100 -11111010 00001000 -11110010 00010000 -11101010 00100000 -11001010 01000000 -10101010 10000000 -0 0 -11001110 00000010 -01010101 00000100 -00100001 00000001 -00101100 00000100 -01000000 01000000 -10110110 10000000 -11100111 10000000 -01011101 00000100 -10010110 00000100 -01010010 00010000 -00000111 00000010 -01110110 00000010 -00010100 00000100 -10110110 00000100 -00011110 00000100 -00110111 00000100 -10101001 00001000 -11000100 10000000 -01001011 00001000 -11110001 01000000 -01101110 01000000 -10011110 10000000 -01001100 00000100 -11110111 00000100 -11010011 01000000 -01111110 01000000 -00000011 00000010 -01001110 00000010 -10011101 00000100 -00110000 00010000 -00110110 00010000 -01000110 01000000 -10001101 10000000 -01110000 00010000 -00001011 00000001 -01111100 00001000 -11010100 00010000 -01001111 01000000 -00010001 00000001 -11101010 00000010 -01000111 00000010 -01100001 01000000 -11111011 01000000 -00011001 00000001 -10011111 00000001 -10010000 00010000 -00001100 00000100 -11110011 00010000 -0 0 \ No newline at end of file Index: scalable_arbiter/trunk/bench/verilog/tb_arbiter2.txt =================================================================== --- scalable_arbiter/trunk/bench/verilog/tb_arbiter2.txt (revision 10) +++ scalable_arbiter/trunk/bench/verilog/tb_arbiter2.txt (nonexistent) @@ -1,8 +0,0 @@ -8176255410b7cb44a074ee702a9a86db -8176255410b7cb44a074ee702a9a86db -49539737fd0c739c556513c608c1228b -10a60347121e743967d73eb4a2dc629b -ee6064c875d6fdbda8a95e35102c551e -0d1361fd41adf235fdafff491b1963e4 -0d1361fd41adf235fdafff491b1963e4 -e89c064542709e292edd0abf77b1e89c \ No newline at end of file Index: scalable_arbiter/trunk/bench/verilog/tb_arbiter.v =================================================================== --- scalable_arbiter/trunk/bench/verilog/tb_arbiter.v (revision 10) +++ scalable_arbiter/trunk/bench/verilog/tb_arbiter.v (nonexistent) @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2008, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`timescale 1ns / 1ps - -// This bench simply applies the vectors in the pattern file, -// and tests that the output matches the expected values. This -// test is usful to verify basic behavior, but it is difficult -// to generate vectors for large configurations. - -`define WIDTH 8 -`define SELECT_WIDTH 8 -`define TURNAROUND 3 -//`define TURNAROUND 6 for arbiter x2 -`define TICK 10 -`define HALF_TICK 5 -`define TEST_VEC_COUNT 241 -`define TEST_VEC_MULT 2 -`define PATTERN_FILE "tb_arbiter.txt" - -module tb_arbiter; - -reg reset; -reg clock; - -reg [`WIDTH-1:0] req; -wire [`WIDTH-1:0] grant; -wire [`SELECT_WIDTH-1:0] select; -wire valid; - -reg [`WIDTH-1:0] pattern[(`TEST_VEC_MULT*`TEST_VEC_COUNT)-1:0]; -reg [`WIDTH-1:0] grant_expected; - -integer test_i; -integer grant_i; -integer grant_count; -integer failures; -integer monitor_exceptions; - -// -// UUT -// - -arbiter #( - .width(`WIDTH), - .select_width(`SELECT_WIDTH) -) arbiter ( - .enable(1'b1), - .req(req), - .grant(grant), - .select(select), - .valid(valid), - - .clock(clock), - .reset(reset) -); - -// -// clock -// - -always @(clock) - #`HALF_TICK clock <= !clock; - -// -// test monitors -// - -always @(grant) -begin - grant_count = 0; - for(grant_i = 0; grant_i < `WIDTH; grant_i = grant_i + 1) - begin - if(grant[grant_i]) - begin - grant_count = grant_count + 1; - - if(!req[grant_i]) - begin - monitor_exceptions = monitor_exceptions + 1; - - $display("EXCEPTION @%e: grant line %d with no req", - $realtime, grant_i); - end - - if(select != grant_i) - begin - monitor_exceptions = monitor_exceptions + 1; - - $display("EXCEPTION @%e: select of %d does not match grant of line %d", - $realtime, select, grant_i); - end - end - end - - if(grant_count > 1) - begin - monitor_exceptions = monitor_exceptions + 1; - - $display("EXCEPTION @%e: grant %h asserts multiple lines", - $realtime, grant); - end -end - -// -// test sequence -// - -initial -begin - $readmemb(`PATTERN_FILE, pattern); - failures = 0; - monitor_exceptions = 0; - - clock = 1; - req = 0; - reset = 1; - #`TICK @(negedge clock) reset = 0; - - // apply reqs, and test grants against exepcted values - for(test_i = 0; test_i < `TEST_VEC_COUNT; test_i = test_i + 1) - begin - #`TICK; - - req = pattern[test_i*`TEST_VEC_MULT]; - grant_expected = pattern[test_i*`TEST_VEC_MULT + 1]; - - #(`TURNAROUND*`TICK); - - if(grant != grant_expected) - begin - failures = failures + 1; - - $display("FAILED %d: req %h, grant %h (expected %h)", - test_i, req, grant, grant_expected); - end - else - begin - $display("ok %d: req %h, grant %h (expected %h)", - test_i, req, grant, grant_expected); - end - end - - $display("%d failures", failures); - $display("%d monitor exceptions", monitor_exceptions); - - if(failures == 0 && monitor_exceptions == 0) - $display("PASS"); - else - $display("FAIL"); -end - -endmodule Index: scalable_arbiter/trunk/bench/verilog/tb_arbiter3.v =================================================================== --- scalable_arbiter/trunk/bench/verilog/tb_arbiter3.v (revision 10) +++ scalable_arbiter/trunk/bench/verilog/tb_arbiter3.v (nonexistent) @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2009, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`timescale 1ns / 1ps - -// This bench walks the demo through its sequence, but it does not verify outputs. - -`define WIDTH 16 -`define SELECT_WIDTH 4 -`define TURNAROUND 3 -`define TICK 10 -`define HALF_TICK 5 - -module tb_arbiter3; - -reg clock; -reg reset; - -reg next_test; -reg next_step; - -wire [`SELECT_WIDTH-1:0] select; -wire valid; - -integer test_i; - -`include "functions.v" - -// -// UUT -// - -demo #( - .width(`WIDTH), - .select_width(`SELECT_WIDTH) -) demo ( - .next_test(next_test), - .next_step(next_step), - .select(select), - .valid(valid), - .clock(clock), - .reset(reset) -); - -// -// clock -// - -always @(clock) -begin - #`HALF_TICK clock <= !clock; -end - -// -// test sequence -// - -initial begin - clock = 1; - next_test = 0; - next_step = 0; - reset = 1; - #`TICK @(negedge clock) reset = 0; - - // step through the stimulus sequence, 'req_enable' is always high, so - // reqs will be deasserted as soon as they are granted - while(1'b1) - begin - #`TICK next_test = 1; - #`TICK next_test = 0; - - for(test_i = 0; test_i < `WIDTH; test_i = test_i + 1) - begin - #(`TURNAROUND*`TICK) next_step = 1; - #`TICK next_step = 0; - end - end -end - -endmodule Index: scalable_arbiter/trunk/rtl/verilog/stretcher.v =================================================================== --- scalable_arbiter/trunk/rtl/verilog/stretcher.v (revision 10) +++ scalable_arbiter/trunk/rtl/verilog/stretcher.v (nonexistent) @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2008-2009, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`timescale 1ns / 1ps - -module stretcher #( - parameter count = 1, - parameter high_count = count, - parameter low_count = count, - parameter width = 1, - parameter reset_value = {width{1'b0}} -)( - input enable, - input [width-1:0] in, - output reg [width-1:0] out, - output reg valid, - - input clock, - input reset -); - -`include "functions.v" - -// edge detector -wire rising; -wire falling; - -assign rising = |(~out & in); -assign falling = |(out & ~in); - -/// counter width is the maximum size of the loaded value -parameter counter_width = max(flog2(count - 1) + 1, - max(flog2(high_count - 1) + 1, flog2(low_count - 1) + 1)); - -reg [counter_width:0] counter; -reg [counter_width-1:0] counter_load; -wire counter_overflow; - -assign counter_overflow = counter[counter_width]; - -// select counter value for rising or falling edge -always @(rising, falling) -begin - case({rising, falling}) - 'b11: - counter_load = -count; - 'b10: - counter_load = -high_count; - 'b01: - counter_load = -low_count; - default: - counter_load = {counter_width{1'bx}}; - endcase -end - -// the counter is reset on a rising or falling edge -// overflow has priority over reset, so input changes -// will be ignored until the full count is reached -always @(posedge clock, posedge reset) -begin - if(reset) - counter <= {counter_width{1'b0}}; - else - begin - if(enable & ~counter_overflow) - counter <= counter + 1; - else if((rising | falling) & counter_overflow) - counter <= { 1'b0, counter_load }; - end -end - -// output is gated by the counter overflow -always @(posedge clock, posedge reset) -begin - if(reset) - out <= reset_value; - else - begin - if(counter_overflow) - out <= in; - end -end - -always @(posedge clock, posedge reset) -begin - if(reset) - valid <= 0; - else - valid <= counter_overflow; -end - -endmodule Index: scalable_arbiter/trunk/rtl/verilog/shifter.v =================================================================== --- scalable_arbiter/trunk/rtl/verilog/shifter.v (revision 10) +++ scalable_arbiter/trunk/rtl/verilog/shifter.v (nonexistent) @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2008-2009, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`timescale 1ns / 1ps - -module shifter #( - parameter depth = 0, - parameter width = 0 -)( - input enable, - input load, - - input [(depth*width)-1:0] parallel_in, - input [width-1:0] serial_in, - output [(depth*width)-1:0] parallel_out, - output [width-1:0] serial_out, - - input clock -); - -reg [(depth*width)-1:0] internal; - -assign parallel_out = internal; -assign serial_out = internal[width-1:0]; - -integer i; - -always @(posedge clock) -begin - if(enable) - begin - internal[(depth*width)-1-:width] <= load - ? parallel_in[(depth*width)-1-:width] - : serial_in; - - for(i = depth - 1; i > 0; i = i - 1) - begin - internal[(i*width)-1-:width] <= load - ? parallel_in[(i*width)-1-:width] - : internal[((i+1)*width)-1-:width]; - end - end -end - -endmodule Index: scalable_arbiter/trunk/rtl/verilog/demo.v =================================================================== --- scalable_arbiter/trunk/rtl/verilog/demo.v (revision 10) +++ scalable_arbiter/trunk/rtl/verilog/demo.v (nonexistent) @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2008-2009, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* -These results give a rough idea of how the timing and size scale -with the arbiter width. It is useful to look at the trends, but -the individual values should be taken with a grain of salt. - -Preliminary results using XC6SLX45-2FGG484: - - arbiter arbiter_x2 - /----------------------------\ /----------------------------\ - width MHz LEs LUTs FFs MHz LEs LUTs FFs - 8 289.855 42 34 35 399.672 56 36 53 - 16 273.000 83 67 68 397.377 109 70 103 - 32 230.240 188 156 133 289.855 214 143 188 - 64 189.593 391 320 262 289.855 428 288 370 - 128 166.073 796 650 519 261.852 886 618 699 - 256 161.496 1582 1267 1032 261.852 1779 1245 1389 - 512 136.753 3164 2493 2057 196.883 3489 2443 2686 - 1024 122.155 6755 5348 4106 197.280 7015 4928 5360 - 2048 102.198 12538 9485 8203 193.289 13956 9767 10513 - 4096 103.433 27182 20683 16396 190.964 27813 19450 21011 - -note: width 4096 arbiter_x2 exceeds device capacity - -Preliminary results using EP3C40F484C8: - - arbiter arbiter_x2 - /---------------------------\ /---------------------------\ - width MHz LEs LUTs FFs MHz LEs LUTs FFs - 8 444.25 50 42 35 457.67 65 46 53 - 16 313.77 92 91 68 396.67 114 92 103 - 32 239.52 195 194 133 338.18 232 194 188 - 64 185.08 388 387 262 311.04 465 393 370 - 128 161.47 769 768 519 283.37 959 822 699 - 256 138.26 1551 1550 1032 249.25 1889 1619 1389 - 512 103.90 3132 3131 2057 155.88 3657 3132 2686 - 1024 88.39 6150 6149 4106 132.93 7328 6282 5360 - 2048 76.24 12283 12282 8203 138.12 14549 12479 10513 - 4096 57.02 24533 24532 16396 128.07 29099 24964 21011 -*/ - -`timescale 1ns / 1ps - -module demo #( - parameter width = 128, - parameter select_width = 7 -)( - input next_test, - input next_step, - output [select_width-1:0] select, - output valid, - - input clock, - input reset -); - -reg [width-1:0] req; -wire [width-1:0] seq; -wire [width-1:0] grant; - -lfsr #( - .width(width) -) lfsr ( - .enable(next_test), - .load(1'b0), - .in(1'bx), - .out(seq), - - .clock(clock), - .reset(reset) -); - -arbiter #( - .width(width), - .select_width(select_width) -) arbiter ( - .enable(1'b1), - .req(req), - .grant(grant), - .select(select), - .valid(valid), - - .clock(clock), - .reset(reset) -); - -always @(posedge clock) -begin - if(reset) - req <= 0; - else - begin - if(next_test) - req <= seq; - else if(next_step) - req <= req & ~grant; - end -end - -endmodule Index: scalable_arbiter/trunk/rtl/verilog/debouncer.v =================================================================== --- scalable_arbiter/trunk/rtl/verilog/debouncer.v (revision 10) +++ scalable_arbiter/trunk/rtl/verilog/debouncer.v (nonexistent) @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2008-2009, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`timescale 1ns / 1ps - -module debouncer #( - parameter count = 1, - parameter high_count = count, - parameter low_count = count, - parameter width = 1, - parameter reset_value = {width{1'b0}} -)( - input enable, - input [width-1:0] in, - output [width-1:0] out, - output reg rising_pulse, - output reg falling_pulse, - output reg valid, - - input clock, - input reset -); - -`include "functions.v" - -reg [width-1:0] in_reg; -reg [width-1:0] out_reg; - -always @(posedge clock) -begin - in_reg <= in; -end - -// edge detector -wire rising; -wire falling; - -assign rising = |(~in_reg & in); -assign falling = |(in_reg & ~in); - -// counter width is the maximum size of the loaded value -parameter counter_width = max(flog2(count - 1) + 1, - max(flog2(high_count - 1) + 1, flog2(low_count - 1) + 1)); - -reg [counter_width:0] counter; -reg [counter_width-1:0] counter_load; -wire counter_overflow; - -assign counter_overflow = counter[counter_width]; - -// select counter value for rising or falling edge -always @(rising, falling) -begin - case({rising, falling}) - 'b11: - counter_load = -count; - 'b10: - counter_load = -high_count; - 'b01: - counter_load = -low_count; - default: - counter_load = {counter_width{1'bx}}; - endcase -end - -// the counter is reset on a rising or falling edge -// reset has priority over overflow, so the counter -// will not overflow until the input has been stable -// for a full count -always @(posedge clock, posedge reset) -begin - if(reset) - counter <= {counter_width{1'b0}}; - else - begin - if(rising | falling) - counter <= { 1'b0, counter_load }; - else if(enable & ~counter_overflow) - counter <= counter + 1; - end -end - -// output is gated by the counter overflow -assign out = out_reg; - -always @(posedge clock, posedge reset) -begin - if(reset) - out_reg <= reset_value; - else - begin - if(counter_overflow) - out_reg <= in_reg; - end -end - -always @(posedge clock, posedge reset) -begin - if(reset) - begin - rising_pulse <= 1'b0; - falling_pulse <= 1'b0; - end - else - begin - rising_pulse <= counter_overflow & ~out_reg & in_reg; - falling_pulse <= counter_overflow & out_reg & ~in_reg; - end -end - -always @(posedge clock, posedge reset) -begin - if(reset) - valid <= 1'b0; - else - valid <= counter_overflow; -end - -endmodule Index: scalable_arbiter/trunk/rtl/verilog/demo_top.v =================================================================== --- scalable_arbiter/trunk/rtl/verilog/demo_top.v (revision 10) +++ scalable_arbiter/trunk/rtl/verilog/demo_top.v (nonexistent) @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2009, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`timescale 1ns / 1ps - -`define MHZ 100 -`define WIDTH 8 -`define SELECT_WIDTH 3 -`define DEBOUNCE_MSEC 250 -`define STRETCH_MSEC 250 - -module demo_top ( - input [1:0] buttons, - output [`SELECT_WIDTH:0] indicators, - - input refclock -); - -wire reset; -wire clock; -wire locked; -wire usec_tick; -wire msec_tick; -wire next_test; -wire next_step; -wire [`SELECT_WIDTH-1:0] select; -wire valid; - -reg [1:0] buttons_reg; - -// replace the clock generator with the appropriate module for your part -assign reset = ~locked; - -/*clockgen clockgen ( - .inclk0(refclock), - .c0(clock), - .locked(locked) -);*/ -clockgen clockgen ( - .CLKIN_IN(refclock), - .CLKFX_OUT(clock), - .CLKIN_IBUFG_OUT(), - .LOCKED_OUT(locked) -); - -// register inputs -always @(posedge clock) -begin - buttons_reg <= buttons; -end - -// this counter is always enabled, so subtract 1 from the count to account for -// the extra clock that it takes to reload the counter -pulser #( - .count(`MHZ-1) -) usec_pulser ( - .enable(1'b1), - .out(usec_tick), - - .clock(clock), - .reset(1'b0) -); - -// this counter is only enabled every few clocks, so use the full count because -// the clock that it takes to reload the counter will happen between enables -pulser #( - .count(1000) -) msec_pulser ( - .enable(usec_tick), - .out(msec_tick), - - .clock(clock), - .reset(1'b0) -); - -// this assumes that the buttons are normally low, it fires a pulse on the -// rising edge of a button event, and only accepts one event per DEBOUNCE_MSEC -debouncer #( - .low_count(`DEBOUNCE_MSEC) -) next_test_debouncer ( - .enable(msec_tick), - .in(buttons_reg[1]), - .out(), - .rising_pulse(next_test), - .falling_pulse(), - .valid(), - - .clock(clock), - .reset(1'b0) -); - -debouncer #( - .low_count(`DEBOUNCE_MSEC) -) next_step_debouncer ( - .enable(msec_tick), - .in(buttons_reg[0]), - .out(), - .rising_pulse(next_step), - .falling_pulse(), - .valid(), - - .clock(clock), - .reset(1'b0) -); - -// the arbiter demo module -demo #( - .width(`WIDTH), - .select_width(`SELECT_WIDTH) -) demo ( - .next_test(next_test), - .next_step(next_step), - .select(select), - .valid(valid), - - .clock(clock), - .reset(reset) -); - -// this stretches brief changes long enough to be visible, specifically, to see -// select blip when the arbiter wraps around (a wrap around is the transition -// from granting a higher number req to a lower number, and while select blips, -// all grants are deasserted) -stretcher #( - .count(`STRETCH_MSEC), - .width(`SELECT_WIDTH) -) select_stretcher ( - .enable(msec_tick), - .in(select), - .out(indicators[`SELECT_WIDTH:1]), - .valid(), - - .clock(clock), - .reset(1'b0) -); - -stretcher #( - .count(`STRETCH_MSEC) -) valid_stretcher ( - .enable(msec_tick), - .in(valid), - .out(indicators[0]), - .valid(), - - .clock(clock), - .reset(1'b0) -); - -endmodule \ No newline at end of file Index: scalable_arbiter/trunk/rtl/verilog/lfsr.v =================================================================== --- scalable_arbiter/trunk/rtl/verilog/lfsr.v (revision 10) +++ scalable_arbiter/trunk/rtl/verilog/lfsr.v (nonexistent) @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2009, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`timescale 1ns / 1ps - -module lfsr #( - parameter width = 0, - parameter reset_value = {width{1'b1}} -)( - input enable, - input load, - input in, - output reg [width-1:0] out, - - input clock, - input reset -); - -// it's assumed that the msb is a tap so it need not be in this table, -// indexes are 0-based, you can add cases for any other widths -function is_tap ( - input integer width, index -); -begin - case(width) - 3: is_tap = index == 1; - 4: is_tap = index == 2; - 5: is_tap = index == 2; - 6: is_tap = index == 4; - 7: is_tap = index == 5; - 8: is_tap = index == 5 || index == 4 || index == 3; - 15: is_tap = index == 13; - 16: is_tap = index == 14 || index == 12 || index == 3; - 31: is_tap = index == 27; - 32: is_tap = index == 21 || index == 1 || index == 0; - 63: is_tap = index == 61; - 64: is_tap = index == 62 || index == 60 || index == 59; - 127: is_tap = index == 125; - 128: is_tap = index == 125 || index == 100 || index == 98; - default: is_tap = 0; - endcase -end -endfunction - -// combine the taps to compute the next lsb -function [0:0] feedback ( - input [width-1:0] value -); -integer i; -begin - // always include the msb - feedback = value[width-1]; - - // include the other taps specified by the table - for(i = 0; i < width - 1; i = i + 1) - begin - if(is_tap(width, i)) - feedback = feedback ^ value[i]; - end -end -endfunction - -// the shift register -always @(posedge clock, posedge reset) -begin - if(reset) - out <= reset_value; - else - begin - if(enable) - out <= {out[width-2:0], load ? in : feedback(out)}; - end -end - -endmodule Index: scalable_arbiter/trunk/rtl/verilog/arbiter.v =================================================================== --- scalable_arbiter/trunk/rtl/verilog/arbiter.v (revision 10) +++ scalable_arbiter/trunk/rtl/verilog/arbiter.v (nonexistent) @@ -1,388 +0,0 @@ -/* - * Copyright (c) 2008-2009, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`timescale 1ns / 1ps - -// Two synchronous arbiter implementations are provided: -// 'arbiter' and 'arbiter_x2'. Both are round-robin arbiters -// with a configurable number of inputs. The algorithm used is -// recursive in that you can build a larger arbiter from a -// tree of smaller arbiters. 'arbiter_x2' is a tree of -// 'arbiter' modules, 'arbiter' is a tree of 'arbiter_node' -// modules, and 'arbiter_node' is the primitive of the -// algorithm, a two input round-robin arbiter. -// -// Both 'arbiter' and 'arbiter_x2' can take multiple clocks -// to grant a request. (Of course, neither arbiter should -// assert an invalid grant while changing state.) 'arbiter' -// can take up to three clocks to grant a req, and 'arbiter_x2' -// can take up to five clocks. 'arbiter_x2' is probably only -// necessary for configurations over a thousand inputs. -// Presently, the width of both 'arbiter' and 'arbiter_x2' -// must be power of two due to the way they instantiate a tree -// of sub-arbiters. Extra inputs can be assigned to zero, and -// extra outputs can be left disconnected. -// -// Parameters for 'arbiter' and 'arbiter_x2': -// 'width' is width of the 'req' and 'grant' ports, which -// must be a power of two. -// 'select_width' is the width of the 'select' port, which -// should be the log base two of 'width'. -// -// Ports for 'arbiter' and 'arbiter_x2': -// 'enable' masks the 'grant' outputs. It is used to chain -// arbiters together, but it might be useful otherwise. -// It can be left disconnected if not needed. -// 'req' are the input lines asserted to request access to -// the arbitrated resource. -// 'grant' are the output lines asserted to grant each -// requestor access to the arbitrated resource. -// 'select' is a binary encoding of the bitwise 'grant' -// output. It is useful to control a mux that connects -// requestor outputs to the arbitrated resource. It can -// be left disconnected if not needed. -// 'valid' is asserted when any 'req' is asserted. It is -// used to chain arbiters together, but it might be -// otherwise useful. It can be left disconnected if not -// needed. - -// 'arbiter_x2' is a two-level tree of arbiters made from -// registered 'arbiter' modules. It allows a faster clock in -// large configurations by breaking the arbiter into two -// registered stages. For most uses, the standard 'arbiter' -// module is plenty fast. See the 'demo_arbiter' module for -// some implemntation results. - -module arbiter_x2 #( - parameter width = 0, - parameter select_width = 1 -)( - input enable, - input [width-1:0] req, - output reg [width-1:0] grant, - output reg [select_width-1:0] select, - output reg valid, - - input clock, - input reset -); - -`include "functions.v" - -// 'width1' is the width of the first stage arbiters, which -// is the square root of 'width' rounded up to the nearest -// power of 2, calculated as: exp2(ceiling(log2(width)/2)) -parameter width1 = 1 << ((clog2(width)/2) + (clog2(width)%2)); -parameter select_width1 = clog2(width1); - -// 'width0' is the the width of the second stage arbiter, -// which is the number of arbiters in the first stage. -parameter width0 = width/width1; -parameter select_width0 = clog2(width0); - -genvar g; - -wire [width-1:0] grant1; -wire [(width0*select_width1)-1:0] select1; -wire [width0-1:0] enable1; -wire [width0-1:0] req0; -wire [width0-1:0] grant0; -wire [select_width0-1:0] select0; -wire valid0; -wire [select_width1-1:0] select_mux[width0-1:0]; - -assign enable1 = grant0 & req0; - -// Register the outputs. -always @(posedge clock, posedge reset) -begin - if(reset) - begin - valid <= 0; - grant <= 0; - select <= 0; - end - else - begin - valid <= valid0; - grant <= grant1; - select <= { select0, select_mux[select0] }; - end -end - -// Instantiate the first stage of the arbiter tree. -arbiter #( - .width(width1), - .select_width(select_width1) -) stage1_arbs[width0-1:0] ( - .enable(enable1), - .req(req), - .grant(grant1), - .select(select1), - .valid(req0), - - .clock(clock), - .reset(reset) -); - -// Instantiate the second stage of the arbiter tree. -arbiter #( - .width(width0), - .select_width(select_width0) -) stage0_arb ( - .enable(enable), - .req(req0), - .grant(grant0), - .select(select0), - .valid(valid0), - - .clock(clock), - .reset(reset) -); - -// Generate muxes for the select outputs. -generate -for(g = 0; g < width0; g = g + 1) -begin: gen_mux - assign select_mux[g] = select1[((g+1)*select_width1)-1-:select_width1]; -end -endgenerate - -endmodule - -// 'arbiter' is a tree made from unregistered 'arbiter_node' -// modules. Unregistered carries between nodes allows -// the tree to change state on the same clock. The tree -// contains (width - 1) nodes, so resource usage of the -// arbiter grows linearly. The number of levels and thus the -// propogation delay down the tree grows with log2(width). -// The logarithmic delay scaling makes this arbiter suitable -// for large configuations. This module can take up to three -// clocks to grant the next requestor after its inputs change -// (two clocks for the 'arbiter_node' modules and one clock -// for the output registers). - -module arbiter #( - parameter width = 0, - parameter select_width = 1 -)( - input enable, - input [width-1:0] req, - output reg [width-1:0] grant, - output reg [select_width-1:0] select, - output reg valid, - - input clock, - input reset -); - -`include "functions.v" - -genvar g; - -// These wires interconnect arbiter nodes. -wire [2*width-2:0] interconnect_req; -wire [2*width-2:0] interconnect_grant; -wire [width-2:0] interconnect_select; -wire [mux_sum(width,clog2(width))-1:0] interconnect_mux; - -// Assign inputs to some interconnects. -assign interconnect_req[2*width-2-:width] = req; -assign interconnect_grant[0] = enable; - -// Assign the select outputs of the first arbiter stage to -// the first mux stage. -assign interconnect_mux[mux_sum(width,clog2(width))-1-:width/2] = interconnect_select[width-2-:width/2]; - -// Register some interconnects as outputs. -always @(posedge clock, posedge reset) -begin - if(reset) - begin - valid <= 0; - grant <= 0; - select <= 0; - end - else - begin - valid <= interconnect_req[0]; - grant <= interconnect_grant[2*width-2-:width]; - select <= interconnect_mux[clog2(width)-1:0]; - end -end - -// Generate the stages of the arbiter tree. Each stage is -// instantiated as an array of 'abiter_node' modules and -// is half the width of the previous stage. Some simple -// arithmetic part-selects the interconnects for each stage. -// See the "Request/Grant Interconnections" diagram of an -// arbiter in the documentation. -generate -for(g = width; g >= 2; g = g / 2) -begin: gen_arb - arbiter_node nodes[(g/2)-1:0] ( - .enable(interconnect_grant[g-2-:g/2]), - .req(interconnect_req[2*g-2-:g]), - .grant(interconnect_grant[2*g-2-:g]), - .select(interconnect_select[g-2-:g/2]), - .valid(interconnect_req[g-2-:g/2]), - - .clock(clock), - .reset(reset) - ); -end -endgenerate - -// Generate the select muxes for each stage of the arbiter -// tree. The generate begins on the second stage because -// there are no muxes in the first stage. Each stage is -// a two dimensional array of muxes, where the dimensions -// are number of arbiter nodes in the stage times the -// number of preceeding stages. It takes some tricky -// arithmetic to part-select the interconnects for each -// stage. See the "Select Interconnections" diagram of an -// arbiter in the documentation. -generate -for(g = width/2; g >= 2; g = g / 2) -begin: gen_mux - mux_array #( - .width(g/2) - ) mux_array[clog2(width/g)-1:0] ( - .in(interconnect_mux[mux_sum(g,clog2(width))-1-:clog2(width/g)*g]), - .select(interconnect_select[g-2-:g/2]), - .out(interconnect_mux[mux_sum(g/2,clog2(width))-(g/2)-1-:clog2(width/g)*g/2]) - ); - assign interconnect_mux[mux_sum(g/2,clog2(width))-1-:g/2] = interconnect_select[g-2-:g/2]; -end -endgenerate - -endmodule - -module mux_array #( - parameter width = 0 -)( - input [(2*width)-1:0] in, - input [width-1:0] select, - output [width-1:0] out -); - -mux_node nodes[width-1:0] ( - .in(in), - .select(select), - .out(out) - ); - -endmodule - -module mux_node ( - input [1:0] in, - input select, - output out -); - -assign out = select ? in[1] : in[0]; - -endmodule - -// This is a two input round-robin arbiter with the -// addition of the 'valid' and 'enable' signals -// that allow multiple nodes to be connected to form a -// larger arbiter. Outputs are not registered to allow -// interconnected nodes to change state on the same clock. - -module arbiter_node ( - input enable, - input [1:0] req, - output [1:0] grant, - output select, - output valid, - - input clock, - input reset -); - -// The state determines which 'req' is granted. State '0' -// grants 'req[0]', state '1' grants 'req[1]'. -reg grant_state; -wire next_state; - -// The 'grant' of this stage is masked by 'enable', which -// carries the grants of the subsequent stages back to this -// stage. The 'grant' is also masked by 'req' to ensure that -// 'grant' is dropped as soon 'req' goes away. -assign grant[0] = req[0] & ~grant_state & enable; -assign grant[1] = req[1] & grant_state & enable; - -// Select is a binary value that tracks grant. It could -// be used to control a mux on the arbitrated resource. -assign select = grant_state; - -// The 'valid' carries reqs to subsequent stages. It is -// high when the 'req's are high, except during 1-to-0 state -// transistions when it's dropped for a cycle to allow -// subsequent arbiter stages to make progress. This causes a -// two cycle turnaround for 1-to-0 state transistions. -/* -always @(grant_state, next_state, req) -begin - if(grant_state & ~next_state) - valid <= 0; - else if(req[0] | req[1]) - valid <= 1; - else - valid <= 0; -end -*/ -// reduced 'valid' logic -assign valid = (req[0] & ~grant_state) | req[1]; - -// The 'next_state' logic implements round-robin fairness -// for two inputs. When both reqs are asserted, 'req[0]' is -// granted first. This state machine along with some output -// logic can be cascaded to implement round-robin fairness -// for many inputs. -/* -always @(grant_state, req) -begin - case(grant_state) - 0: - if(req[0]) - next_state <= 0; - else if(req[1]) - next_state <= 1; - else - next_state <= 0; - 1: - if(req[1]) - next_state <= 1; - else - next_state <= 0; - endcase -end -*/ -// reduced next state logic -assign next_state = (req[1] & ~req[0]) | (req[1] & grant_state); - -// state register -always @(posedge clock, posedge reset) -begin - if(reset) - grant_state <= 0; - else - grant_state <= next_state; -end - -endmodule Index: scalable_arbiter/trunk/rtl/verilog/functions.v =================================================================== --- scalable_arbiter/trunk/rtl/verilog/functions.v (revision 10) +++ scalable_arbiter/trunk/rtl/verilog/functions.v (nonexistent) @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2008, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -function integer min ( - input integer a, b -); -begin - min = a < b ? a : b; -end -endfunction - -function integer max ( - input integer a, b -); -begin - max = a > b ? a : b; -end -endfunction - -// compute the log base 2 of a number, rounded down to the -// nearest whole number -function integer flog2 ( - input integer number -); -integer i; -integer count; -begin - flog2 = 0; - for(i = 0; i < 32; i = i + 1) - begin - if(number&(1< 1) - clog2 = clog2 + 1; -end -endfunction - -// compute the size of the interconnect for the arbiter's -// 'select' muxes -function integer mux_sum ( - input integer width, select_width -); -integer i, number; -begin - mux_sum = 0; - number = 1; - for(i = select_width; i > 0 && number <= width; i = i - 1) - begin - mux_sum = mux_sum + i*(number); - number = number * 2; - end -end -endfunction \ No newline at end of file Index: scalable_arbiter/trunk/rtl/verilog/pulser.v =================================================================== --- scalable_arbiter/trunk/rtl/verilog/pulser.v (revision 10) +++ scalable_arbiter/trunk/rtl/verilog/pulser.v (nonexistent) @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2008, Kendall Correll - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`timescale 1ns / 1ps - -module pulser #( - parameter count = 1, - parameter toggle = 0 -)( - input enable, - output reg out, - - input clock, - input reset -); - -`include "functions.v" - -// counter width is the size of the loaded value -parameter counter_width = flog2(count - 1) + 1; - -reg [counter_width:0] counter; -wire [counter_width-1:0] counter_load; -wire counter_overflow; - -assign counter_overflow = counter[counter_width]; -assign counter_load = -count; - -always @(posedge clock, posedge reset) -begin - if(reset) - out <= 1'b0; - else - begin - if(toggle) - out <= out ^ counter_overflow; - else - out <= counter_overflow; - end -end - -always @(posedge clock, posedge reset) -begin - if(reset) - counter <= {counter_width{1'b1}}; - else - begin - if(counter_overflow) - counter <= { 1'b0, counter_load }; - else if(enable) - counter <= counter + 1; - end -end - -endmodule Index: scalable_arbiter/trunk/doc/arbiter_diagram.odg =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: scalable_arbiter/trunk/doc/arbiter_diagram.odg =================================================================== --- scalable_arbiter/trunk/doc/arbiter_diagram.odg (revision 10) +++ scalable_arbiter/trunk/doc/arbiter_diagram.odg (nonexistent)
scalable_arbiter/trunk/doc/arbiter_diagram.odg Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: scalable_arbiter/trunk/doc/arbiter_diagram.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: scalable_arbiter/trunk/doc/arbiter_diagram.pdf =================================================================== --- scalable_arbiter/trunk/doc/arbiter_diagram.pdf (revision 10) +++ scalable_arbiter/trunk/doc/arbiter_diagram.pdf (nonexistent)
scalable_arbiter/trunk/doc/arbiter_diagram.pdf Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: scalable_arbiter/trunk =================================================================== --- scalable_arbiter/trunk (revision 10) +++ scalable_arbiter/trunk (nonexistent)
scalable_arbiter/trunk Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ## Index: scalable_arbiter/web_uploads =================================================================== --- scalable_arbiter/web_uploads (revision 10) +++ scalable_arbiter/web_uploads (nonexistent)
scalable_arbiter/web_uploads Property changes : Deleted: svn:mergeinfo ## -0,0 +0,0 ##

powered by: WebSVN 2.1.0

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