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 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/bench/verilog/tb_arbiter.v
0,0 → 1,166
/* |
* 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 |
/trunk/bench/verilog/tb_abrbiter2.v
0,0 → 1,254
/* |
* 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 |
/trunk/bench/verilog/tb_arbiter.txt
0,0 → 1,241
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 |
/trunk/bench/verilog/tb_arbiter2.txt
0,0 → 1,8
8176255410b7cb44a074ee702a9a86db |
8176255410b7cb44a074ee702a9a86db |
49539737fd0c739c556513c608c1228b |
10a60347121e743967d73eb4a2dc629b |
ee6064c875d6fdbda8a95e35102c551e |
0d1361fd41adf235fdafff491b1963e4 |
0d1361fd41adf235fdafff491b1963e4 |
e89c064542709e292edd0abf77b1e89c |
/trunk/rtl/verilog/demo_arbiter.v
0,0 → 1,122
/* |
* 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. |
*/ |
|
`define PORT_WIDTH 8 |
`define ARB_WIDTH 256 |
`define SELECT_WIDTH 8 |
|
/* |
|
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 XC3S1600E-4FG320: |
|
arbiter arbiter_x2 |
/----------------------------\ /----------------------------\ |
width MHz slices LUTs registers MHz slices LUTs registers |
8 214.961 22 34 35 287.439 34 42 53 |
16 191.571 47 75 68 284.252 69 87 103 |
32 148.943 99 163 133 211.730 122 169 188 |
64 124.285 200 346 262 202.840 245 349 370 |
128 102.807 434 717 519 165.044 490 739 699 |
256 100.796 923 1555 1032 163.666 986 1504 1389 |
512 87.176 1867 3120 2057 148.854 1973 2914 2686 |
1024 81.974 3628 5976 4106 140.213 3947 5883 5360 |
2048 69.214 7089 11444 8203 116.050 7966 12164 10513 |
4096 49.332* 14853 24501 16396 113.404* 15592 23858 21011 |
|
* at 4096, arbiter and arbiter_x2 exceed device capacity |
|
Preliminary results using EP3C25F324C8: |
|
arbiter arbiter_x2 |
/----------------------------\ /----------------------------\ |
width MHz slices LUTs registers MHz slices LUTs registers |
8 384.17 37 33 35 453.31 55 29 53 |
16 289.60 80 73 68 452.90 108 68 103 |
32 259.74 165 160 133 357.53 206 152 188 |
64 187.51 337 320 262 299.94 415 319 370 |
128 132.12 675 630 519 226.50 853 685 699 |
256 122.37 1362 1279 1032 217.96 1694 1353 1389 |
512 99.91 2738 2627 2057 132.29 3303 2642 2686 |
1024 85.54 5434 5121 4106 130.28 6622 5312 5360 |
2048 71.77 10861 10128 8203 123.47 13236 10582 10513 |
4096 61.10 21777 20313 16396 140.86 23208 21177 21011 |
|
*/ |
|
module demo_arbiter ( |
input enable_in, |
input enable_out, |
input load, |
input [`PORT_WIDTH-1:0] port_in, |
output [`PORT_WIDTH-1:0] port_out, |
output [`SELECT_WIDTH-1:0] select, |
output valid, |
|
input clock, |
input reset |
); |
|
wire [`ARB_WIDTH-1:0] req, grant; |
|
shifter #( |
.count(`ARB_WIDTH/`PORT_WIDTH), |
.width(`PORT_WIDTH) |
) in_shifter ( |
.enable(enable_in), |
.load(1'b0), |
|
.parallel_in({`ARB_WIDTH{1'bx}}), |
.serial_in(port_in), |
.parallel_out(req), |
.serial_out(), |
|
.clock(clock) |
); |
|
arbiter #( |
.width(`ARB_WIDTH), |
.select_width(`SELECT_WIDTH) |
) arbiter ( |
.enable(1'b1), |
.req(req), |
.grant(grant), |
.select(select), |
.valid(valid), |
|
.clock(clock), |
.reset(reset) |
); |
|
shifter #( |
.count(`ARB_WIDTH/`PORT_WIDTH), |
.width(`PORT_WIDTH) |
) out_shifter ( |
.enable(enable_out), |
.load(load), |
|
.parallel_in(grant), |
.serial_in({`PORT_WIDTH{1'bx}}), |
.parallel_out(), |
.serial_out(port_out), |
|
.clock(clock) |
); |
|
endmodule |
/trunk/rtl/verilog/demo_filters.v
0,0 → 1,83
/* |
* 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 |
|
`define CLOCK_MHZ 40 |
`define DEBOUNCE_HIGH_COUNT 3 |
`define DEBOUNCE_LOW_COUNT 2 |
`define STRETCH_HIGH_COUNT 10 |
`define STRETCH_LOW_COUNT 5 |
|
module demo_filters ( |
input in, |
output out, |
output valid_in, |
output valid_out, |
|
input clock, |
input reset |
); |
|
wire usec_tick, msec_tick, interconnect; |
|
pulser #( |
.count(`CLOCK_MHZ) |
) usec_pulser ( |
.enable(1'b1), |
.out(usec_tick), |
|
.clock(clock), |
.reset(reset) |
); |
|
pulser #( |
.count(1000) |
) msec_pulser ( |
.enable(usec_tick), |
.out(msec_tick), |
|
.clock(clock), |
.reset(reset) |
); |
|
debouncer #( |
.high_count(`DEBOUNCE_HIGH_COUNT), |
.low_count(`DEBOUNCE_LOW_COUNT) |
) debouncer ( |
.enable(msec_tick), |
.in(in), |
.out(interconnect), |
.valid(valid_in), |
|
.clock(clock), |
.reset(reset) |
); |
|
stretcher #( |
.high_count(`STRETCH_HIGH_COUNT), |
.low_count(`STRETCH_LOW_COUNT) |
) stretcher ( |
.enable(msec_tick), |
.in(interconnect), |
.out(out), |
.valid(valid_out), |
|
.clock(clock), |
.reset(reset) |
); |
|
endmodule |
/trunk/rtl/verilog/stretcher.v
0,0 → 1,97
/* |
* 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 stretcher #( |
parameter count = 0, |
parameter high_count = count, |
parameter low_count = count |
)( |
input enable, |
input in, |
output reg 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 |
parameter counter_width = max(clog2(high_count), clog2(low_count)); |
|
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}) |
'b10: |
counter_load = ~(high_count - 1); |
'b01: |
counter_load = ~(low_count - 1); |
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 <= 1'b0; |
else if(counter_overflow) |
out <= in; |
end |
|
always @(posedge clock, posedge reset) |
begin |
if(reset) |
valid <= 0; |
else |
valid <= counter_overflow; |
end |
|
endmodule |
/trunk/rtl/verilog/shifter.v
0,0 → 1,56
/* |
* 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 shifter #( |
parameter count = 0, |
parameter width = 0 |
)( |
input enable, |
input load, |
|
input [(count*width)-1:0] parallel_in, |
input [width-1:0] serial_in, |
output [(count*width)-1:0] parallel_out, |
output [width-1:0] serial_out, |
|
input clock |
); |
|
reg [(count*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[(count*width)-1-:width] <= load |
? parallel_in[(count*width)-1-:width] |
: serial_in; |
|
for(i = count - 1; i > 0; i = i - 1) |
internal[(i*width)-1-:width] <= load |
? parallel_in[(i*width)-1-:width] |
: internal[((i+1)*width)-1-:width]; |
end |
end |
|
endmodule |
/trunk/rtl/verilog/debouncer.v
0,0 → 1,109
/* |
* 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 debouncer #( |
parameter count = 0, |
parameter high_count = count, |
parameter low_count = count |
)( |
input enable, |
input in, |
output reg out, |
output reg valid, |
|
input clock, |
input reset |
); |
|
`include "functions.v" |
|
// register and edge detect the input |
reg [1:0] in_reg; |
|
always @(posedge clock) |
begin |
in_reg <= {in_reg[0], in}; |
end |
|
// edge detector |
wire rising; |
wire falling; |
|
assign rising = in_reg[1] & ~in_reg[0]; |
assign falling = ~in_reg[1] & in_reg[0]; |
|
// counter |
parameter counter_width = max(clog2(high_count), clog2(low_count)); |
|
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}) |
'b10: |
counter_load = ~(high_count - 1); |
'b01: |
counter_load = ~(low_count - 1); |
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 |
always @(posedge clock, posedge reset) |
begin |
if(reset) |
out <= 1'b0; |
else |
begin |
if(counter_overflow) |
out <= in_reg[1]; |
end |
end |
|
always @(posedge clock, posedge reset) |
begin |
if(reset) |
valid <= 1'b0; |
else |
valid <= counter_overflow; |
end |
|
endmodule |
/trunk/rtl/verilog/arbiter.v
0,0 → 1,388
/* |
* 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 |
|
// 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_narb ( |
.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 |
/trunk/rtl/verilog/functions.v
0,0 → 1,75
/* |
* 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 up to the |
// nearest whole number |
function integer clog2 ( |
input integer number |
); |
integer i; |
integer count; |
begin |
clog2 = 0; |
count = 0; |
for(i = 0; i < 32; i = i + 1) |
begin |
if(number&(1<<i)) |
begin |
clog2 = i; |
count = count + 1; |
end |
end |
// clog2 holds the largest set bit position and count |
// holds the number of bits set. More than one bit set |
// indicates that the input was not an even power of 2, |
// so round the result up. |
if(count > 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 |
/trunk/rtl/verilog/pulser.v
0,0 → 1,66
/* |
* 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 = 0, |
parameter toggle = 0 |
) ( |
input enable, |
output reg out, |
|
input clock, |
input reset |
); |
|
`include "functions.v" |
|
parameter counter_width = clog2(count); |
parameter [counter_width-1:0] counter_load = ~(count - 1); |
|
reg [counter_width:0] counter; |
wire counter_overflow; |
|
assign counter_overflow = counter[counter_width]; |
|
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 |
/trunk/doc/arbiter_diagram.odg
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
trunk/doc/arbiter_diagram.odg
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/arbiter_diagram.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/arbiter_diagram.pdf
===================================================================
--- trunk/doc/arbiter_diagram.pdf (nonexistent)
+++ trunk/doc/arbiter_diagram.pdf (revision 2)
trunk/doc/arbiter_diagram.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property