//  Completely reconfigurable Pseudo Random Bit Sequence Generator
//  tap_config = 0 means that there will be no feedback for that
//  particular tap.  Ensure that your last_tap is the last "1" in
//  the tap_config input.  ex: 000...00010100 would mean that
//  your feedback equation was 1 + x^3 + x^5, and if last_tap
//  is set to 000101, then you're fine because you're last tap is 
//  in position #5.
//  Author:  Andrew Iverson
//  Date:  11-9-99
//----------------------------------------------------------------

`include "dff.v"

module prbs(prbs_out, data_in, last_tap, clk, tap_config, n_reset);

  output prbs_out;
  input [4:0] last_tap;
  input data_in, clk, n_reset;
  input [31:0] tap_config;
  
  wire [31:0] interconnect;
  wire xnor_out;

  assign xnor_out  = ! (^ (interconnect[31:0] & tap_config[31:0]));
  
  dff prbs_dff0 (.q(interconnect[0]), .d(xnor_out), .n_reset(n_reset), .clk(clk));
  dff prbs_dff1 (.q(interconnect[1]), .d(interconnect[0]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff2 (.q(interconnect[2]), .d(interconnect[1]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff3 (.q(interconnect[3]), .d(interconnect[2]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff4 (.q(interconnect[4]), .d(interconnect[3]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff5 (.q(interconnect[5]), .d(interconnect[4]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff6 (.q(interconnect[6]), .d(interconnect[5]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff7 (.q(interconnect[7]), .d(interconnect[6]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff8 (.q(interconnect[8]), .d(interconnect[7]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff9 (.q(interconnect[9]), .d(interconnect[8]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff10 (.q(interconnect[10]), .d(interconnect[9]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff11 (.q(interconnect[11]), .d(interconnect[10]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff12 (.q(interconnect[12]), .d(interconnect[11]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff13 (.q(interconnect[13]), .d(interconnect[12]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff14 (.q(interconnect[14]), .d(interconnect[13]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff15 (.q(interconnect[15]), .d(interconnect[14]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff16 (.q(interconnect[16]), .d(interconnect[15]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff17 (.q(interconnect[17]), .d(interconnect[16]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff18 (.q(interconnect[18]), .d(interconnect[17]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff19 (.q(interconnect[19]), .d(interconnect[18]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff20 (.q(interconnect[20]), .d(interconnect[19]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff21 (.q(interconnect[21]), .d(interconnect[20]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff22 (.q(interconnect[22]), .d(interconnect[21]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff23 (.q(interconnect[23]), .d(interconnect[22]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff24 (.q(interconnect[24]), .d(interconnect[23]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff25 (.q(interconnect[25]), .d(interconnect[24]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff26 (.q(interconnect[26]), .d(interconnect[25]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff27 (.q(interconnect[27]), .d(interconnect[26]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff28 (.q(interconnect[28]), .d(interconnect[27]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff29 (.q(interconnect[29]), .d(interconnect[28]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff30 (.q(interconnect[30]), .d(interconnect[29]), .n_reset(n_reset), .clk(clk));
  dff prbs_dff31 (.q(interconnect[31]), .d(interconnect[30]), .n_reset(n_reset), .clk(clk));
  
  assign prbs_out = data_in ? interconnect[last_tap] : ~interconnect[last_tap];

endmodule
