Here is a data source in Verilog RTL for LocalLink that generates a stream of packets containing arbitrary data with arbitrary gaps.
module LocalLinkSrc( input reset, input clk, output [7:0] src_data, output src_sof_n, output src_eof_n, output src_src_rdy_n, input src_dst_rdy_n); // The source generates 'random' data using a pseudo random sequence generator (prbs). // The source also makes gaps in its data using bit[9] of the generator. reg [14:0] prbs; reg started; assign src_data = (!src_src_rdy_n) ? prbs[7:0] : 0; assign src_src_rdy_n = !(prbs[9]); // The end of packet is arbitrarily generated when bits 14:12 have a particular value. assign src_eof_n = !(!src_src_rdy_n && prbs[14:12]==2); // A start of frame must be flagged during the first new word after the previous frame has ended. assign src_sof_n = !(!src_src_rdy_n && !started); always @(posedge clk) begin started <= (reset) ? 0: (!src_eof_n) ? 0 : (!src_sof_n) ? 1 : started; prbs <= (reset) ? 100: (src_dst_rdy_n) ? prbs: (prbs << 1) | (prbs[14] != prbs[13]); end endmodule
And here is a corresponding data sink:
module LocalLinkSink( input reset, input clk, input [7:0] sink_data, input sink_sof_n, input sink_eof_n, output sink_src_rdy_n, input sink_dst_rdy_n); // The sink also maintains a prbs to make it go busy or not on an arbitrary basis. reg [14:0] prbs; assign sink_dst_rdy_n = prbs[0]; always @(posedge clk) begin if (!sink_dst_rdy_n && !sink_src_rdy_n) $display( "%m LocalLinkSink sof_n=%d eof_n=%d data=0x%h", sink_sof_n, sink_eof_n, sink_data); // Put a blank line between packets on the console. if (!sink_dst_rdy_n && !sink_src_rdy_n && !sink_eof_n) $display("\n\n"); prbs <= (reset) ? 200: (prbs << 1) | (prbs[14] != prbs[13]); end endmodule // LocalLinkSrc
And here is a testbench that wires them together:
module SIMSYS(); reg reset; reg clk; wire [7:0] data; wire sof_n; wire eof_n; wire ack_n; wire req_n; // Instance of the src LocalLinkSrc src (.reset(reset), .clk(clk), .src_data(data), .src_sof_n(sof_n), .src_eof_n(eof_n), .src_src_rdy_n(req_n), .src_dst_rdy_n(ack_n)); // Instance of the sink LocalLinkSink sink (.reset(reset), .clk(clk), .sink_data(data), .sink_sof_n(sof_n), .sink_eof_n(eof_n), .sink_src_rdy_n(req_n), .sink_dst_rdy_n(ack_n) ); initial begin clk =0; forever #50 clk = !clk; end initial begin reset = 1; #130 reset=0; end endmodule // SIMSYS
5: (C) 2008-18, DJ Greaves, University of Cambridge, Computer Laboratory. |