HOME       UP       PREV       NEXT (Structural Hazards.)  

Local Link Example Code

Here is a data source for LocalLink that makes a stream of packets containing arbitrary data with arbitrary gaps.

module LocalLinkSrc(  reset,   
                       clk,   
                       src_data,   
                       src_sof_n,   
                       src_eof_n,   
                       src_src_rdy_n,   
                       src_dst_rdy_n);
  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(reset,   
                    clk,   
                    sink_data,   
                    sink_sof_n,   
                    sink_eof_n,   
                    sink_src_rdy_n,   
                    sink_dst_rdy_n);
  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


28: (C) 2008-11, DJ Greaves, University of Cambridge, Computer Laboratory.