//  Top level FPGA module:  Spread Spectrum Tranmsitter
//  with arbitrary spreading sequences and programmable FIR filter.
// 
//  Authors:  Steve Harwood
//            Andrew Iverson
//
//  Date:  12-10-99
//
//------------------------------------------------------------------

`include "control.v"
`include "fifo.v"
`include "spreader.v"
`include "p2s.v"
`include "clk_mod.v"
`include "fir12.v"
`include "filt.v"
`include "accum.v"
`include "ram_fir.v"
`include "add_dec.v"

module fpga(i_spread, q_spread, iq_clk, fifo_full, fifo_half_full,
	    fifo_empty, mp_data, mp_addr, cs, rd_strobe, wr_strobe,
	    n_reset, fast_clk);

  output [17:0] i_spread, q_spread;
  output iq_clk, fifo_full, fifo_half_full, fifo_empty;

  inout [7:0] mp_data;
  input [3:0] mp_addr;
  input cs, rd_strobe, wr_strobe, n_reset, fast_clk;
 

  wire [31:0] tap_config_i, tap_config_q;
  wire [4:0] last_tap_i, last_tap_q;
  wire [7:0] fifo_data;
  wire [11:0] fir_data;
  wire [7:0] fir_addr;
  wire push_en, push_clk;
  wire fir_en;

  wire [7:0] fifo_data_out;
 

  wire p2s_data_out;
  wire load, s_clk;

  wire clk1x;

  wire [11:0] spread_out_i, spread_out_q;

  wire dval, prog;
  wire [3:0] paddr;
  wire [11:0] we;

  ramaddr ss_ramaddr(.clk40x(fast_clk),
                     .n_reset(n_reset),
		     .wr_strobe(wr_strobe),
		     .addr(fir_addr),
		     .fir_en(fir_en),
                     .paddr(paddr),
		     .firwe(we),
		     .prog(prog));

  fir12 ss_fir12(.clk(fast_clk),
		 .we(we),
		 .idin(spread_out_i),
		 .qdin(spread_out_q),
		 .coeff(fir_data),
		 .rst(~n_reset),
		 .dval(fifo_empty),
		 .iout_reg(i_spread),
		 .qout_reg(q_spread),
		 .iqclko(iq_clk),
		 .prog(prog),
		 .paddr(paddr));

  control ss_control_unit(.addr(mp_addr), 
			  .data_inout(mp_data), 
			  .cs(cs), 
	                  .rd_strobe(rd_strobe), 
			  .wr_strobe(wr_strobe), 
			  .tap_config_i(tap_config_i), 
			  .tap_config_q(tap_config_q), 
			  .last_tap_i(last_tap_i), 
			  .last_tap_q(last_tap_q), 
			  .fifo_data(fifo_data), 
			  .push_en(push_en), 
			  .push_clk(push_clk), 
			  .fir_data(fir_data), 
			  .fir_addr(fir_addr), 
			  .fir_en(fir_en), 
			  .n_reset(n_reset));

  fifo ss_fifo(.data_out(fifo_data_out), 
	       .empty(fifo_empty), 
	       .full(fifo_full), 
	       .half_full(fifo_half_full), 
	       .pop_en(!fifo_empty && load), 
	       .push_en(push_en), 
	       .data_in(fifo_data), 
	       .push_clk(push_clk), 
	       .pop_clk(s_clk), 
	       .n_reset(n_reset));


  p2s ss_p2s(.s_data_out(p2s_data_out), 
	     .load(load), 
	     .p_data_in(fifo_data_out), 
	     .s_clk(s_clk),
	     .n_reset(n_reset));


  clk_mod ss_clk_mod(.load_clk(load), 
		     .clk1x(clk1x), 
		     .slow_clk(s_clk), 
		     .clk40x(fast_clk), 
		     .n_reset(n_reset));

 
  spreader ss_spreader(.spread_out_i(spread_out_i), 
		       .spread_out_q(spread_out_q), 
		       .data_in(p2s_data_out), 
		       .last_tap_i(last_tap_i), 
		       .last_tap_q(last_tap_q), 
		       .tap_config_i(tap_config_i), 
		       .tap_config_q(tap_config_q), 
		       .prbs_clk(clk1x), 
		       .n_reset(n_reset));


endmodule
