URL
https://opencores.org/ocsvn/srdydrdy_lib/srdydrdy_lib/trunk
Subversion Repositories srdydrdy_lib
Compare Revisions
- This comparison shows the changes necessary to convert path
/srdydrdy_lib
- from Rev 21 to Rev 22
- ↔ Reverse comparison
Rev 21 → Rev 22
/trunk/rtl/verilog/buffers/sd_fifo_tail_b.v
105,7 → 105,7
nxt_cur_rdptr = com_rdptr; |
mem_re = 0; |
end |
else if (enable & !empty & ip_drdy) |
else if (enable & !empty & (ip_drdy | (rbuf1_drdy & !prev_re))) |
begin |
nxt_cur_rdptr = cur_rdptr_p1; |
mem_re = 1; |
/trunk/env/verilog/sd_seq_gen.v
File deleted
/trunk/env/verilog/bench_fifo_b.vf
File deleted
/trunk/env/verilog/sd_seq_check.v
File deleted
/trunk/env/verilog/bench_fifo_b.v
File deleted
/trunk/env/verilog/fifo_b/bench_fifo_b.v
0,0 → 1,299
`timescale 1ns/1ns |
|
module bench_fifo_b; |
|
reg clk, reset; |
|
localparam width = 16, depth=32, asz=$clog2(depth), usz=$clog2(depth+1); |
|
initial clk = 0; |
always #10 clk = ~clk; |
|
reg gen_commit, gen_abort; |
reg chk_commit, chk_abort; |
reg fail; |
/*AUTOWIRE*/ |
// Beginning of automatic wires (for undeclared instantiated-module outputs) |
wire [width-1:0] chk_data; // From fifo_s of sd_fifo_b.v |
wire chk_drdy; // From chk of sd_seq_check.v |
wire chk_srdy; // From fifo_s of sd_fifo_b.v |
wire [usz-1:0] chk_usage; // From fifo_s of sd_fifo_b.v |
wire [width-1:0] gen_data; // From gen of sd_seq_gen.v |
wire gen_drdy; // From fifo_s of sd_fifo_b.v |
wire gen_srdy; // From gen of sd_seq_gen.v |
wire [usz-1:0] gen_usage; // From fifo_s of sd_fifo_b.v |
// End of automatics |
|
/* sd_seq_gen AUTO_TEMPLATE |
( |
.p_\(.*\) (gen_\1[]), |
); |
*/ |
sd_seq_gen #(width) gen |
(/*AUTOINST*/ |
// Outputs |
.p_srdy (gen_srdy), // Templated |
.p_data (gen_data[width-1:0]), // Templated |
// Inputs |
.clk (clk), |
.reset (reset), |
.p_drdy (gen_drdy)); // Templated |
|
/* sd_seq_check AUTO_TEMPLATE |
( |
.c_\(.*\) (chk_\1[]), |
); |
*/ |
sd_seq_check #(width) chk |
(/*AUTOINST*/ |
// Outputs |
.c_drdy (chk_drdy), // Templated |
// Inputs |
.clk (clk), |
.reset (reset), |
.c_srdy (chk_srdy), // Templated |
.c_data (chk_data[width-1:0])); // Templated |
|
/* sd_fifo_b AUTO_TEMPLATE |
( |
.p_\(.*\) (chk_\1[]), |
.c_\(.*\) (gen_\1[]), |
); |
*/ |
sd_fifo_b #(width, depth, 1, 1) fifo_b |
(/*AUTOINST*/ |
// Outputs |
.c_drdy (gen_drdy), // Templated |
.p_srdy (chk_srdy), // Templated |
.p_data (chk_data[width-1:0]), // Templated |
.p_usage (chk_usage[usz-1:0]), // Templated |
.c_usage (gen_usage[usz-1:0]), // Templated |
// Inputs |
.clk (clk), |
.reset (reset), |
.c_srdy (gen_srdy), // Templated |
.c_commit (gen_commit), // Templated |
.c_abort (gen_abort), // Templated |
.c_data (gen_data[width-1:0]), // Templated |
.p_drdy (chk_drdy), // Templated |
.p_commit (chk_commit), // Templated |
.p_abort (chk_abort)); // Templated |
|
initial |
begin |
`ifdef VCS |
$vcdpluson; |
`else |
$dumpfile("fifo_b.lxt"); |
$dumpvars; |
`endif |
reset = 1; |
gen.rep_count = 0; |
gen_commit = 0; |
gen_abort = 0; |
chk_commit = 1; |
chk_abort = 0; |
fail = 0; |
#100; |
reset = 0; |
repeat (5) @(posedge clk); |
|
do_reset(); |
test1(); |
|
do_reset(); |
test2(); |
|
do_reset(); |
test3(); |
|
if (fail) |
$display ("!!!!! TEST FAILED !!!!!"); |
else |
$display ("----- TEST PASSED -----"); |
$finish; |
end // initial begin |
|
task do_reset; |
begin |
gen.rep_count = 0; |
gen_commit = 0; |
gen_abort = 0; |
chk_commit = 1; |
chk_abort = 0; |
reset = 1; |
repeat (5) @(posedge clk); |
reset = 0; |
|
repeat (10) @(posedge clk); |
end |
endtask // do_reset |
|
task end_check; |
begin |
if (chk.err_cnt > 0) |
fail = 1; |
end |
endtask |
|
|
// test basic overflow/underflow |
task test1; |
begin |
$display ("Running test 1"); |
gen_commit = 1; |
//gen.rep_count = 2000; |
|
fork |
begin : traffic_gen |
gen.send (depth * 2); |
|
repeat (5) @(posedge clk); |
gen.srdy_pat = 8'h5A; |
gen.send (depth * 2); |
|
repeat (5) @(posedge clk); |
chk.drdy_pat = 8'hA5; |
gen.send (depth * 2); |
|
// check FIFO overflow |
repeat (5) @(posedge clk); |
gen.srdy_pat = 8'hFD; |
gen.send (depth * 4); |
|
// check FIFO underflow |
repeat (5) @(posedge clk); |
gen.srdy_pat = 8'h11; |
gen.send (depth * 4); |
|
repeat (20) @(posedge clk); |
disable t1_timeout; |
end // block: traffic_gen |
|
begin : t1_timeout |
repeat (50 * depth) |
@(posedge clk); |
|
fail = 1; |
disable traffic_gen; |
$display ("%t: ERROR: test1 timeout", $time); |
end |
join |
|
#500; |
end_check(); |
end |
endtask // test1 |
|
// test of write commit/abort behavior |
task test2; |
begin |
$display ("Running test 2"); |
// first fill up entire FIFO |
//chk.drdy_pat = 0; |
gen_commit = 0; |
gen.send (depth-1); |
#50; |
|
wait (gen_drdy == 0); |
@(posedge clk); |
gen_abort <= #1 1; |
|
@(posedge clk); |
gen_abort <= #1 0; |
#5; |
if (gen_drdy !== 1) |
begin |
$display ("%t: ERROR -- drdy should be asserted on empty FIFO", $time); |
fail = 1; |
#100 $finish; |
end |
|
|
gen.send (depth-2); |
@(posedge clk); |
gen_commit <= 1; |
gen.send (1); |
gen_commit <= 0; |
|
repeat (depth+10) |
@(posedge clk); |
|
if (chk.last_seq != (depth*2-2)) |
begin |
$display ("%t: ERROR -- last sequence number incorrect (%x)", $time, chk.last_seq); |
fail = 1; |
$finish; |
end |
|
|
#5000; |
end_check(); |
end |
endtask // test2 |
|
// test read/commit behavior |
task test3; |
begin |
$display ("Running test 3"); |
// fill up FIFO |
gen_commit <= 1; |
chk_commit <= 0; |
chk_abort <= 0; |
|
@(negedge clk); |
chk.drdy_pat = 0; |
chk.c_drdy = 0; |
chk.nxt_c_drdy = 0; |
|
repeat (10) @(posedge clk); |
gen.send (depth-1); |
|
// read out contents of FIFO |
chk.drdy_pat = 8'h5A; |
|
repeat (depth*2+2) |
@(posedge clk); |
chk.drdy_pat = 0; |
|
// FIFO should be full at this point to write side, and empty to |
// read side |
if (gen_drdy || chk_srdy) |
begin |
$display ("ERROR -- c_drdy or p_srdy asserted"); |
fail = 1; |
#100 $finish; |
end |
|
// reset the read pointer and the expected value |
chk.last_seq = 0; |
chk_abort <= #1 1; |
@(posedge clk); |
chk_abort <= #1 0; |
|
// read out contents of FIFO again |
chk.drdy_pat = 8'hFF; |
|
@(posedge clk); |
repeat (depth-3) @(posedge clk); |
chk_commit <= #1 1; |
repeat (4) @(posedge clk); |
chk_commit <= #1 0; |
|
// All data has been committed, so drdy should be asserted |
if (gen_drdy !== 1) |
begin |
$display ("%t: ERROR -- c_drdy not asserted", $time); |
fail = 1; |
#100 $finish; |
end |
#500; |
end_check(); |
|
end |
endtask |
|
endmodule // bench_fifo_s |
// Local Variables: |
// verilog-library-directories:("." "../common" "../../../rtl/verilog/buffers") |
// End: |
/trunk/env/verilog/fifo_b/bench_fifo_b.vf
0,0 → 1,9
bench_fifo_b.v |
../common/sd_seq_check.v |
../common/sd_seq_gen.v |
../../../rtl/verilog/closure/sd_input.v |
../../../rtl/verilog/closure/sd_output.v |
../../../rtl/verilog/buffers/sd_fifo_b.v |
../../../rtl/verilog/buffers/sd_fifo_head_b.v |
../../../rtl/verilog/buffers/sd_fifo_tail_b.v |
../../../rtl/verilog/memory/behave2p_mem.v |
/trunk/env/verilog/common/sd_seq_check.v
0,0 → 1,109
//---------------------------------------------------------------------- |
// Srdy/Drdy sequence checker |
// |
// Simplistic traffic checker for srdy/drdy blocks. Checks for an |
// incrementing data sequence. |
// |
// Naming convention: c = consumer, p = producer, i = internal interface |
//---------------------------------------------------------------------- |
// Author: Guy Hutchison |
// |
// This block is uncopyrighted and released into the public domain. |
//---------------------------------------------------------------------- |
|
// delay unit for nonblocking assigns, default is to #1 |
`ifndef SDLIB_DELAY |
`define SDLIB_DELAY #1 |
`endif |
|
module sd_seq_check |
#(parameter width=8) |
(input clk, |
input reset, |
input c_srdy, |
output reg c_drdy, |
input [width-1:0] c_data); |
|
parameter pat_dep = 8; |
|
reg [width-1:0] last_seq; |
reg first; |
reg [pat_dep-1:0] drdy_pat; |
integer dpp; |
reg nxt_c_drdy; |
integer err_cnt; |
|
initial |
begin |
drdy_pat = {pat_dep{1'b1}}; |
dpp = 0; |
end |
|
initial |
begin |
first = 1; |
c_drdy = 0; |
err_cnt = 0; |
end |
|
always @* |
begin |
nxt_c_drdy = c_drdy; |
|
if (c_srdy & c_drdy) |
begin |
if (drdy_pat[dpp]) |
begin |
nxt_c_drdy = 1; |
end |
else |
nxt_c_drdy = 0; |
end |
else if (!c_drdy) |
begin |
if (drdy_pat[dpp]) |
begin |
nxt_c_drdy = 1; |
end |
else |
nxt_c_drdy = 0; |
end |
end |
always @(posedge clk) |
begin |
if ((c_srdy & c_drdy) | !c_drdy) |
dpp = (dpp + 1) % pat_dep; |
end |
|
always @(posedge clk) |
begin |
if (reset) |
begin |
c_drdy <= `SDLIB_DELAY 0; |
err_cnt = 0; |
drdy_pat = {pat_dep{1'b1}}; |
dpp = 0; |
first = 1; |
last_seq = 0; |
end |
else |
begin |
c_drdy <= `SDLIB_DELAY nxt_c_drdy; |
if (c_srdy & c_drdy) |
begin |
if (!first && (c_data !== (last_seq + 1))) |
begin |
$display ("%t: ERROR : %m: Sequence miscompare rcv=%x exp=%x", |
$time, c_data, last_seq+1); |
err_cnt = err_cnt + 1; |
end |
else |
begin |
last_seq = c_data; |
first = 0; |
end |
end // if (c_srdy & c_drdy) |
end // else: !if(reset) |
end |
|
endmodule // sd_seq_check |
/trunk/env/verilog/common/sd_seq_gen.v
0,0 → 1,119
//---------------------------------------------------------------------- |
// Srdy/Drdy sequence generator |
// |
// Simplistic traffic generator for srdy/drdy blocks. Generates an |
// incrementing data sequence. |
// |
// Naming convention: c = consumer, p = producer, i = internal interface |
//---------------------------------------------------------------------- |
// Author: Guy Hutchison |
// |
// This block is uncopyrighted and released into the public domain. |
//---------------------------------------------------------------------- |
|
// delay unit for nonblocking assigns, default is to #1 |
`ifndef SDLIB_DELAY |
`define SDLIB_DELAY #1 |
`endif |
|
module sd_seq_gen |
#(parameter width=8) |
(input clk, |
input reset, |
output reg p_srdy, |
input p_drdy, |
output reg [width-1:0] p_data); |
|
reg nxt_p_srdy; |
reg [width-1:0] nxt_p_data; |
|
parameter pat_dep = 8; |
|
reg [pat_dep-1:0] srdy_pat; |
integer spp, startup; |
integer rep_count; |
|
initial |
begin |
srdy_pat = {pat_dep{1'b1}}; |
spp = 0; |
startup = 0; |
rep_count = 0; |
end |
|
always @* |
begin |
nxt_p_data = p_data; |
nxt_p_srdy = p_srdy; |
|
if (p_srdy & p_drdy) |
begin |
|
if (srdy_pat[spp] && (rep_count > 1)) |
begin |
nxt_p_data = p_data + 1; |
nxt_p_srdy = 1; |
end |
else |
nxt_p_srdy = 0; |
end // if (p_srdy & p_drdy) |
else if (!p_srdy && (rep_count != 0)) |
begin |
if (srdy_pat[spp]) |
begin |
nxt_p_data = p_data + 1; |
nxt_p_srdy = 1; |
end |
else |
nxt_p_srdy = 0; |
end |
end // always @ * |
|
always @(posedge clk) |
begin |
if (reset) |
begin |
srdy_pat = {pat_dep{1'b1}}; |
spp = 0; |
startup = 0; |
rep_count = 0; |
end |
else |
begin |
if ((p_srdy & p_drdy) | !p_srdy) |
spp = (spp + 1) % pat_dep; |
|
if (p_srdy & p_drdy) |
begin |
if (rep_count != -1) |
rep_count = rep_count - 1; |
end |
end |
end |
|
always @(posedge clk) |
begin |
if (reset) |
begin |
p_srdy <= `SDLIB_DELAY 0; |
p_data <= `SDLIB_DELAY 0; |
end |
else |
begin |
p_srdy <= `SDLIB_DELAY nxt_p_srdy; |
p_data <= `SDLIB_DELAY nxt_p_data; |
end |
end // always @ (posedge clk) |
|
// simple blocking task to send N words and then wait until complete |
task send; |
input [31:0] amount; |
begin |
rep_count = amount; |
@(posedge clk); |
while (rep_count != 0) |
@(posedge clk); |
end |
endtask |
|
endmodule // sd_seq_gen |
/trunk/examples/bridge/doc/intro_ethernet.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
trunk/examples/bridge/doc/intro_ethernet.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/examples/bridge/doc/bridge_example.txt
===================================================================
--- trunk/examples/bridge/doc/bridge_example.txt (nonexistent)
+++ trunk/examples/bridge/doc/bridge_example.txt (revision 22)
@@ -0,0 +1,43 @@
+----------------------------------
+ Example Bridge / Switching Hub
+----------------------------------
+
+The bridge directory contains an example bridge built using
+srdy-drdy components. It could more accurately be called
+a switching hub, since it does not implement spanning tree
+or QoS.
+
+The bridge is designed for simplicity rather than efficiency,
+as the purpose is not to make a functioning product but to
+demonstrate use of the library.
+
+The bridge design pushes the bulk of the logic into each
+individual port, called a port_macro. The only global logic
+is the FIB (Forwarding Information Block) that contains the
+address lookup and learning logic, and a centralized ring
+arbiter.
+
+The port_macros are connected to each other via a ring interface.
+Only one packet can be transmitted on the ring at a time.
+The system is designed so that it has more ring bandwidth than
+the maximum amount of incoming traffic, so that the ring should
+not be the bottleneck for system performance.
+
+The bridge is designed to be output-queued, so that all packets
+are forwarded to their output port and the output port will
+drop packets if there is insufficient transmit bandwidth.
+
+The bridge handles all transmission errors on the input port,
+using the rx_fifo to drop packets which arrive with bad CRC.
+The parser waits until the end of packet is received to determine
+if the packet is good, and only sends the packet to the FIB
+if CRC is OK. Otherwise the parser errors the packet so it
+will be dropped in RX FIFO.
+
+Packets are transmitted and received using an 8-bit GMII interface.
+In order to create a higher-bandwidth internal interface, data
+is aggregated into 64-bit words to get 8x bandwidth. This gives
+the internal ring roughly 2x the bandwidth of all receiving ports
+combined.
+
+
Index: trunk/examples/bridge/env/run
===================================================================
--- trunk/examples/bridge/env/run (revision 21)
+++ trunk/examples/bridge/env/run (revision 22)
@@ -6,7 +6,7 @@
which iverilog &> /dev/null
if [ "$?" == "0" ]; then
rm -f a.out
- iverilog -f bridge.vf tests/$TESTNAME.v $* |& tee compile.log
+ iverilog -f bridge.vf tests/$TESTNAME.v $* | tee compile.log
./a.out -lxt | tee run.log
else
vcs -full64 +v2k -R -I -f bridge.vf tests/$TESTNAME.v $*