//
//									dcp3.v - RF Modem for DCP-3
//
//							(C) Copyright 2007-2010 John B. Stephensen
//
// This Verilog source file and all explicitly and implicitly referenced files and all of their
// derivatives are licensed only for personal non-profit educational use in the Amateur Radio
// Service with the DCP-3 PCB and the license is not transferrable. The information is provided
// as-is for experimental purposes and the author does not warranty its freedom from defects or
// its suitability for any specific application.
//
//	This module implements digital signal processing (DSP) for a transceiver. The ADC output and
// DAC input use the sample clock, SCLK, and usually run at 80 MSPS. The DDS and filters use a
// double-rate clock, DCLK, to process 1.28 GTPS in the CIC filter and up to 320 MTPS in the two
// FIR filters. A 16-bit CPU, clocked by MCLK, executes 64 MIPS and controls the transceiver.
// Dedicated logic implements frequency conversion, filtering, modulation and demodulation so
// the CPU operates on 2-wire baseband data at 500 SPS to 2 MSPS. It is augmented by peripherals
// implementing additional filtering, convolutional encoding and Viterbi decoding. Ethernet, SPI,
// UART and I2S I/O ports are also provided. See subsidiary modules for more information.
//
// This code is intended to execute in a Xilinx XC3S500E FPGA on a DCP-3 PCB with a 12-bit ADC,
// 14-bit DAC, SPI flash memory and RMII ethernet PHY. It is capable of supporting analog
// communication using SSB, ISB, FM and AM plus digital communication using PSK, FSK and OFDM.
// The DCP-3 is designed for use in the 1-30 MHz IF system of an HF, VHF or UHF transceiver.
//
// 4325 slices (92% XC3S500E), 20 BRAM and 18 multipliers used with 18-bit FFT and CORDIC.
// 4322 slices (92% XC3S500E) after place and route
// 4261 slices (91% XC3S500E), 20 BRAM and 18 multipliers used with 16-bit FFT and CORDIC.
// 4159 slices (89% XC3S500E) after place and route
// 193 MHz DCLK (CRC, DDS, CIC & FIR), 92 MHz SCLK (ADC, DAC & CPU) and 148 MHz RCLK (RMII).
// 12.25 ns CLKIN period (81.7 MHz).
//
// TIG statements are required in dcp3.ucf for signals crossing the CPU to tuner boundary and between the
// I/O address bus and FIR filter shift register data input. The REF, IO[0] and IO[4] pins are not used.
//
// History:
//		2009-1-14	Modify CPU data in mux for 8 port I/O blocks
//		2009-2-2		Add I2S audio port
//		2009-3-6		Use 128-entry RAM LUT modulator (-76 dBc THD) to reduce block RAM use
//		2009-3-24	Added mask, add immediate and subtract immediate instructions to CPU
//		2009-3-26	Moved program memory to this module and allowed access from data address space
//		2009-4-6		New CORDIC engine supporting vector or rotate mode for modulation and demodulation.
//		2009-4-10	Added MAF for RSSI and phase error
//		2009-4-15	Sync. detect moved to modem
//		2009-12-22	New sync. detect module - more accurate minimum phase error and magnitude determination
//		2009-12-30	Added LS DAC port
//		2010-1-4		Added hardware FFT synchronization
//		2010-2-1		FM disciminator output for LS DAC
//		2010-3-11	add DCD
//		2010-4-27	20-bit tuner output
//
module dcp3(ADC, OVF, DAC, CLK, REF,
				MISO, MOSI, SS, SCK,
				RXD, RXER, RXV, TXD, TXV, REFCLK, MDC, MDIO, MINT, RSTN,
				URXD, UTXD, UTXE,
				LED, IO,
				SCK2, SDO2, SS2);
    input [11:0] ADC;	// 12-bit 80 Msps ADC
	 input OVF;				// ADC overflow
    output [13:0] DAC;	// 14-bit 80 Msps DAC
    input CLK;				// Master clock at ADC sample rate
	 input REF;				// frequency standard input
	 input MISO;			// SPI master in/slave out
	 output MOSI;			// SPI master out/slave in
	 output SS;				// SPI slave select (active low)
	 output SCK;			// SPI bit clock
	 input [1:0] RXD;		// Ethernet received data
	 input RXER;			// Ethernet receiver error
	 input RXV;				// Ethernet received signal valid
	 output [1:0] TXD;	// Ethernet transmit data
	 output TXV;			// Ethernet transmit output valid
	 output REFCLK;		// Ethernet clock
	 output MDC;			// Ethernet management interface clock
	 inout MDIO;			// Ethernet management interface bidirectional data
	 input MINT;			// Ethernet interrupt
	 output RSTN;			// Ethernet PHY reset (active low)
	 input URXD;			// UART received data
	 output UTXD;			// UART transmit data
	 output UTXE;			// UART transmit enable
	 output LED;			// active low LED
	 inout [4:0] IO;		// GPIO pins
	 output SCK2;			// LS DAC serial clock
	 output SDO2;			// LS DAC serial data
	 output SS2;			// LS DAC select (active low)
// internal signals
wire locked; 				// DCM locked
wire rst;					// reset logic
wire sclk;					// clock for ADC and DAC derived from external input
wire dclk;					// clock for DDS, CIC filter and FIR filters
wire rclk;					// RMII clock (50 MHz)
wire [13:0] paddr;		// program address (of next instruction)
wire [15:0] pdata;		// program data (current instruction)
wire pcs;					// program RAM enable
wire [13:0] maddr;		// data address (of word)
wire [15:0] min,mout;	// data bus (direction referenced to MCU)
wire mwr;					// write to memory in MCU
wire mcs0,mcs1,mcs2;		// memory bank selects
reg [1:0] msel;			// memory output multiplxer port select input
wire [15:0] min0,min1,min2,min3;	// memory input ports
wire [6:0] ioaddr;		// I/O address bus
wire [15:0] din,dout;	// I/O data bus (direction referenced to MCU)
wire iord,iowr;			// read and write enables
wire iocs0,iocs1,iocs2,iocs3,iocs4,iocs5,iocs6,iocs7,iocs8,iocs9,iocs10,iocs11,
		iocs12,iocs13,iocs14,iocs15a,iocs15b,iocs15c,iocs15d;	// CPU I/O port selects
reg [3:0] isel;			// input multiplexer port select input
wire [15:0] din0,din1,din2,din3,din4,din5,din6,din7,din8,din9,din10,din11,din12,din13;	// input ports
reg [11:0] adcin;			// ADC input latch
wire [15:0] dacout;		// tuner output
reg [13:0] dacdly;		// ADC output latch
wire [19:0] rx20,ry20;	// tuner baseband I/Q data output
wire rv20;					// data valid
wire [15:0] rx16,ry16;	// AGC baseband I/Q data output
wire rv16,rf16;			// data valid, final data
wire [15:0] mtx,mty;		// modem baseband I/Q data output
wire mtv;					// data valid
wire [15:0] cx,cy;		// tuner baseband I/Q data input
wire cv;						// data valid
wire [15:0] ftx,fty;		// FFT output (to tuner)
wire fte,ftv;				// data enable, data valid
wire trdy;					// tuner ready for more transmit data
wire tce;					// get one sample to transmit
wire unused;
wire [1:0] unused2x,unused2y;
//wire full,rdy1,rdy2;		// monitor last FIFO and filters
reg [4:0] test;			// test output register
wire start,sync,dcd;		// synchronization signals for FFT
//wire fftint;				// FFT interrupt for test
//wire [15:0] x,y,m;		// test signals for output on LS DAC
//wire [11:0] p;
//wire xyv,mpv;
//wire [15:0] agc;
//wire [15:0] minm,maxm;	// min/max regs in syndet
//wire [11:0] minp;
//reg [2:0] bbs;
//wire esof,erxce,eeof,erxswap;	// ethernet test
//reg [11:0] bbd;						// LSDAC hardwired data
//reg bbv;
// I/O registers
reg ledreg;			// LED driver
// terminate unused signals
assign unused = REF;
// use 5-bit I/O connector for debug
OBUF a0buf (.I(test[0]), .O(IO[0]));	// pin 2
//OBUF a0buf (.I(RXV), .O(IO[0]));	// pin 2
//OBUF a1buf (.I(esof), .O(IO[1]));	// pin 4
//OBUF a2buf (.I(erxce), .O(IO[2]));	// pin 6
//OBUF a3buf (.I(eeof), .O(IO[3]));	// pin 8
//OBUF a4buf (.I(erxswap), .O(IO[4]));		// pin 10
OBUF a4buf (.I(test[4]), .O(IO[4]));		// pin 10
// generate internal clocks from 80 MHz input
wire clkin,sclk1,dclk1,rclk0;	// DCM clocks
IBUFG bufclkin (.I(CLK), .O(clkin));
DCM_SP #(
	.CLKIN_DIVIDE_BY_2("FALSE"),
	.CLK_FEEDBACK("1X"),
	.CLKFX_DIVIDE(8),
	.CLKFX_MULTIPLY(5)
	) gencpuclk (
	.CLKIN(clkin),	// external clock input
	.CLKFB(sclk),	// DLL feedback
	.CLK0(sclk1),	// 80 MHz ADC/DAC/CPU clock
	.CLK2X(dclk1),	// 160 MHz DDS/CIC/FIR clock
	.CLKFX(rclk0),	// 50 MHz RMII clock
	.RST(1'b0),
	.LOCKED(locked)
	);
BUFG bufsclk (.I(sclk1), .O(sclk));
BUFG bufdclk (.I(dclk1), .O(dclk));
BUFG bufrclk (.I(rclk0), .O(rclk));
assign rst = ~locked;	// reset everything until DCM outputs stable
// CPU uses MCLK and DMA uses SCLK
CPU16 cpu (
	.ioaddr(ioaddr),	// I/O bus 
	.din(din),
	.iord(iord), 
	.dout(dout), 
	.iowr(iowr),
	.maddr(maddr), 	// memory bus
	.min(min), 
	.mout(mout),
	.mwr(mwr),
	.paddr(paddr),
	.pdata(pdata),
	.pcs(pcs),
	.clk(sclk), 
	.rst(rst) 
	);
// Memory input multiplexer supports 3 banks of memory
// read instruction is 2 cycles so select input is latched
always @ (posedge sclk) msel = maddr[13:12];
MUX4X16 rammux (
	.D0(min0),
	.D1(min1),
	.D2(min2),
	.D3(min3),
	.S(msel),
	.Y(min)
	);
assign min3 = 16'hFFFF;
// Memory bank selects - 3 blocks of 4 kW
assign mcs0 = (maddr[13:12] == 0);
assign mcs1 = (maddr[13:12] == 1);
assign mcs2 = (maddr[13:12] == 2);
// shared program and data memory with 4 bits in each RAM
RAMB16_S4_S4 #(
	) pgmram0 (
   .ADDRA(paddr[11:0]),
   .DIA(4'hF),
   .DOA(pdata[3:0]),
   .CLKA(sclk),
   .WEA(1'b0),
   .ENA(pcs),
   .SSRA(rst),
   .ADDRB(maddr[11:0]),
   .DIB(mout[3:0]),
   .DOB(min0[3:0]),
   .CLKB(sclk),
   .WEB(mwr),
   .ENB(mcs0),
   .SSRB(1'b0)
   );
RAMB16_S4_S4 #(
	) pgmram1 (
   .ADDRA(paddr[11:0]),
   .DIA(4'hF),
   .DOA(pdata[7:4]),
   .CLKA(sclk),
   .WEA(1'b0),
   .ENA(pcs),
   .SSRA(rst),
   .ADDRB(maddr[11:0]),
   .DIB(mout[7:4]),
   .DOB(min0[7:4]),
   .CLKB(sclk),
   .WEB(mwr),
   .ENB(mcs0),
   .SSRB(1'b0)
   );
RAMB16_S4_S4 #(
	) pgmram2 (
   .ADDRA(paddr[11:0]),
   .DIA(4'hF),
   .DOA(pdata[11:8]),
   .CLKA(sclk),
   .WEA(1'b0),
   .ENA(pcs),
   .SSRA(rst),
   .ADDRB(maddr[11:0]),
   .DIB(mout[11:8]),
   .DOB(min0[11:8]),
   .CLKB(sclk),
   .WEB(mwr),
   .ENB(mcs0),
   .SSRB(1'b0)
   );
RAMB16_S4_S4 #(
	) pgmram3 (
   .ADDRA(paddr[11:0]),
   .DIA(4'hF),
   .DOA(pdata[15:12]),
   .CLKA(sclk),
   .WEA(1'b0),
   .ENA(pcs),
   .SSRA(rst),
   .ADDRB(maddr[11:0]),
   .DIB(mout[15:12]),
   .DOB(min0[15:12]),
   .CLKB(sclk),
   .WEB(mwr),
   .ENB(mcs0),
   .SSRB(1'b0)
   );
// I/O port input multiplexer supports 8 blocks of 8 input ports
always @ (posedge sclk) isel = ioaddr[6:3];
MUX16X16 imux (
	.D0(din0),		// Ethernet
	.D1(din1),		// SPI
	.D2(din2),		// convolutional encoder
	.D3(din3),		// viterbi decoder
	.D4(din4),		// UART
	.D5(din5),		// FIR Filter
	.D6(din6),		// I2S audio
	.D7(din7),		// CRC
	.D8(din8),		// modem
	.D9(din9),		// FFT
	.D10(din10),	// BCH CODEC
	.D11(din11),	// tuner
	.D12(din12),	// AGC
	.D13(din13),	// LS DAC (unused)
	.D14(16'hFFFF),// unused
	.D15(16'hFFFF),
	.S(isel),		// upper bits of I/O address
	.Y(din)			// data to multiplexer in ALU
	);
// I/O port selects - 12 blocks of 8
assign iocs0 = (ioaddr[6:3] == 0);		// Ethernet
assign iocs1 = (ioaddr[6:3] == 1);		// SPI
assign iocs2 = (ioaddr[6:3] == 2);		// encoder
assign iocs3 = (ioaddr[6:3] == 3);		// decoder
assign iocs4 = (ioaddr[6:3] == 4);		// UART
assign iocs5 = (ioaddr[6:3] == 5);		// FIR filter
assign iocs6 = (ioaddr[6:3] == 6);		// I2S
assign iocs7 = (ioaddr[6:3] == 7);		// CRC
assign iocs8 = (ioaddr[6:3] == 8);		// Modem
assign iocs9 = (ioaddr[6:3] == 9);		// FFT
assign iocs10 = (ioaddr[6:3] == 10);	// BCH CODEC
assign iocs11 = (ioaddr[6:3] == 11);	// tuner
assign iocs12 = (ioaddr[6:3] == 12);	// AGC/resampler/clipper
assign iocs13 = (ioaddr[6:3] == 13);	// LS DAC
//assign iocs14 = (ioaddr[6:3] == 14);	// unused
//assign iocs15a = (ioaddr[6:1] == 60);	// doppler simulator
//assign iocs15b = (ioaddr[6:1] == 61);	// path simulator
assign iocs15c = (ioaddr[6:1] == 62);	// test
assign iocs15d = (ioaddr[6:1] == 63);	// LED
// Ethernet Interface (100 Mbps FDX)
assign REFCLK = rclk;	// connect clock to PHY
ethernet enet (
	.mcs(mcs1),
	.maddr(maddr[9:0]),	// 1 kW RAM
	.mout(min1),
	.min(mout),
	.mwr(mwr),
	.mclk(sclk),
	.iocs(iocs0),
	.ioaddr(ioaddr[2:0]),// I/O interface
	.din(dout),
	.dout(din0),
	.iowr(iowr),
	.iord(iord),
	.clk(sclk),				// CPU clock
	.rst(rst),
	.rxd(RXD),				// Ethernet PHY
	.rxer(RXER),
	.rxv(RXV),
	.txd(TXD),
	.txv(TXV),
	.refclk(rclk),
	.rstn(RSTN),
	.mdc(MDC),				// Ethernet PHY management
	.mdio(MDIO),
	.mint(MINT)//,
//	.esof(esof),			// test signals
//	.erxce(erxce),
//	.eeof(eeof),
//	.erxswap(erxswap)
	);
//assign TXD = 0;
//assign TXV = 0;
//assign MDC = 0;
//assign MDIO = 0;
//assign min1 = 0;
//assign din0 = 0;
// SPI (for serial flash)
spi spi0 (
	.iocs(iocs1),
	.ioaddr(ioaddr[2:0]),	// I/O interface
	.din(dout),
	.dout(din1),
	.iowr(iowr),
	.clk(sclk),			// CPU clock
	.rst(rst),
	.sdi(MISO),			// SPI
	.sdo(MOSI),
	.scs(SS),
	.sck(SCK)
	);
//assign MOSI = 0;
//assign SS = 0;
//assign SCK = 0;
//assign din1 = 0;
// Convolutional Encoder
encoder enc (
	.iocs(iocs2),
	.ioaddr(ioaddr[2:0]),
	.din(dout),
	.dout(din2),
	.iord(iord),
	.iowr(iowr),
	.clk(sclk),
	.rst(rst)
	);
//assign din2 = 0;
// Viterbi Decoder
viterbi dec (
	.iocs(iocs3),
	.ioaddr(ioaddr[2:0]),
	.din(dout),
	.dout(din3),
	.iord(iord),
	.iowr(iowr),
	.clk(sclk),
	.rst(rst)
	);
//assign din3 = 0;
// UART
uart uart0 (
	.iocs(iocs4),
	.ioaddr(ioaddr[2:0]),
	.din(dout),
	.dout(din4),
	.iord(iord),
	.iowr(iowr),
	.clk(sclk),
	.rst(rst),
	.txd(UTXD),
	.txen(UTXE),
	.rxd(URXD)
	);
//assign UTXD = 0;
//assign UTXE = 0;
//assign din4 = 0;
// FIR Filter Engine
fir128x16x18x4 fir (
	.ioaddr(ioaddr[2:0]),
	.iocs(iocs5),
	.din(dout),
	.iowr(iowr),
	.dout(din5),
	.clk(sclk),
	.rst(rst)
	);
//assign din5 = 0;
// I2S Audio Port
audio2 afio (
	.ioaddr(ioaddr[2:0]),
	.iocs(iocs6),
	.din(dout),
	.iowr(iowr),
	.dout(din6),
	.iord(iord),
	.clk(sclk),
	.rst(rst),
	.sdi(IO[1]),	// DCP3 pin 4 - AC2 pin 7
	.sdo(IO[3]),	// DCP3 pin 8 - AC2 pin 3
	.sfs(IO[2])		// DCP3 pin 6 - AC2 pin 5
	);
//assign din6 = 0;
// CRC hardware assist
crc1632 crc (
	.ioaddr(ioaddr[2:0]),
	.iocs(iocs7),
	.din(dout),
	.iowr(iowr),
	.dout(din7),
	.iord(iord),
	.mclk(sclk),
	.dclk(dclk),	// CRCs calculated with 2x clock
	.rst(rst)
	 );
//assign din7 = 0;
// Low Speed DAC Multiplexer
//always @ (posedge sclk)
//begin
//	if (rst) bbs <= 2;	// source select register
//	else if (iocs13 & iowr) bbs <= dout[2:0];
//	case (bbs[1:0])		// data multiplexer
//	0: bbd <= x[13:2];	// magnitude
//	1: bbd <= {~y[15],y[14:4]};	// phase or frequency
//	2: bbd <= m[13:2];	// RSSI
//	3: bbd <= agc[15:4];	// AGC
//	4: bbd <= minm[15:4];
//	5: bbd <= maxm[15:4];
//	6: bbd <= minp[11:0];
//	7: bbd <= 0;
//	default: bbd <= 12'hxxx;
//	endcase
//	case (bbs)				// data valid multiplexer
//	0: bbv <= xyv;
//	1: bbv <= xyv;
//	2: bbv <= mpv;
//	3: bbv <= rv;
//	4: bbv <= mpv;
//	5: bbv <= mpv;
//	6: bbv <= mpv;
//	7: bbv <= mpv;
//	default: bbv <= 1'bx;
//	endcase
//end
// LS DAC output port
spi16o lsdac (
	.iocs(iocs13),	// output-only parallel port
	.iowr(iowr),
	.din(dout),
//	.iocs(bbv),
//	.iowr(bbv),
//	.din({4'h0,bbd}),
	.clk(sclk),
	.rst(rst),
	.sck(SCK2),		// SPI output port
	.sdo(SDO2),
	.sync(SS2)		// active low
	);
assign din13 = 16'hFFFF;
// test register drives 10-pin header
always @ (posedge sclk)
begin
	if (rst) test <= 0;
	else if (iocs15c & iowr) test <= dout[4:0];
end
// write port 126 to turn on LED
// write port 127 to turn off LED
always @ (posedge sclk)
begin
	if (rst) ledreg <= 1'b1;	// turn off when powered up
	else if (iocs15d & iowr) ledreg <= ioaddr[0];
end
OBUF ledbuf (.I(ledreg), .O(LED));
// modem contains resampling filter, modulator and demodulator
// baseband I/O is 16x16-bits to/from CPU
modem16 modem (
//	.x(x),				// test signals
//	.y(y),
//	.xyv(xyv),
//	.m(m),
//	.p(p),
//	.mpv(mpv),
//	.minm(minm),
//	.maxm(maxm),
//	.minp(minp),
	.iocs(iocs8),		// CPU interface
	.ioaddr(ioaddr[2:0]),
	.din(dout),
	.dout(din8),
	.iowr(iowr),
	.iord(iord),
	.rdix(rx16),		// receiver input from AGC
	.rdiy(ry16),
	.riv(rv16),
	.rif(rf16),
	.toe(tce),
	.tdox(mtx),			// transmitter output to clipper
	.tdoy(mty),
	.tov(mtv),
	.start(start),		// synchronization signals to FFT
	.sync(sync),
	.dcd(dcd),
	.clk(sclk),			// common clock and reset
	.rst(rst),
	.xmt(xmt)			// T/R switch output
	);
// 8-256 point FFT and IFFT
dft256x16 fft ( 
	.iocs(iocs9),			// CPU interface
	.ioaddr(ioaddr[2:0]),
	.din(dout),
	.iowr(iowr),
	.dout(din9),
	.iord(iord),
	.mcs(mcs2),
	.maddr(maddr[9:0]),	// DMA interface
	.min(mout),
	.mout(min2),
	.mwr(mwr),
	.mclk(sclk),
	.toe(tce),				// 2x16-bit output to clipper 
	.tdox(ftx), 
	.tdoy(fty),
//	.tdox({ftx,unused2x}), 
//	.tdoy({fty,unused2y}),
	.tov(ftv),
	.ten(fte),
	.rdix(rx16),	// 2x16-bit input from AGC
	.rdiy(ry16), 
//	.rdix({rx16,2'b00}),	// 2x16-bit input from AGC
//	.rdiy({ry16,2'b00}), 
	.riv(rv16),
	.clk(sclk), 
	.rst(rst), 
	.xmt(xmt),				// transmit
	.sof(start),			// sync. inputs
	.sync(sync),
	.dcd(dcd),
	.intr()					// sync. output
	);
//assign fx = 0;
//assign fy = 0;
//assign min2 = 0;
//assign din9 = 0;
//assign ofdm = 0;
// BCH CODEC
bch16x8s bch (
	.iocs(iocs10),			// CPU interface
	.ioaddr(ioaddr[2:0]),
	.din(dout),
	.iowr(iowr),
	.dout(din10),
	.iord(iord),
	.clk(sclk), 
	.rst(rst),
	.xmt(xmt)
	);
//assign din10 = 0;
// The tuner converts a signal at specified a frequency to a baseband output near DC. The
// AD9236 ADC output changes 2-6 ns after positive edge of SCLK and tuner samples on both
// edges so the value must be latched. In transmit mode, the baseband signal is converted
// to the specified output frequency. The signal to the THS5671 or DAC904 DAC must have
// 1.5 ns seteup time and 1.0 ns hold time relative to the postiive-going edge of SCLK so
// the output must be delayed by 1/2 SCLK period. The DAC uses offset binary so the tuner
// output must be converted from a 2's complement signed number by inverting the MSB.
always @ (posedge sclk) adcin <= ADC;
always @ (negedge sclk) dacdly <= {~dacout[15],dacout[14:2]};
assign DAC = dacdly;
tuner2x fe (
//	.iocs1(iocs15b),		// Doppler simulator
	.iocs(iocs11), 		// select this module
	.ioaddr(ioaddr[2:0]),// 8 registers
	.din(dout), 			// configuration data
	.iowr(iowr), 			// write configuration
	.dout(din11),			// status
	.iord(iord),			// read staus
	.adc({adcin,4'h0}),	// 16-bit ADC input at SCLK rate
	.ovf(OVF),				// ADC overflow
	.dac(dacout),			// 16-bit DAC output at SCLK rate
	.rfd(trdy),
	.dix(cx),				// 2x16-bit baseband input from clipper
	.diy(cy), 
	.iv(cv),
//	.dix(tsx),				// 2x18-bit baseband input from path simulator
//	.diy(tsy), 
//	.iv(tsv),
	.dox(rx20),				// 2x20-bit baseband output to AGC
	.doy(ry20), 
	.ov(rv20),
	.sclk(sclk), 			// ADC/DAC and I/O clock
	.dclk(dclk), 			// filter clock 
	.mclk(sclk), 			// I/O clock 
	.mrst(rst), 
	.xmt(xmt)//,
//	.rdy1(rdy1),			// test signals
//	.rdy2(rdy2),
//	.full(full)
	);
// AGC Module converts 20 to 16 bits on receive
agcrsmplclip arc (
	.iocs(iocs12),		// configuration interface
	.ioaddr(ioaddr[2:0]),
	.iowr(iowr),
	.din(dout),
	.iord(iord),
	.dout(din12),
	.rdix(rx20),		// 2x20-bit baseband input from tuner
	.rdiy(ry20),
	.riv(rv20),
	.rdox(rx16),		// 2x16-bit baseband output to modem and FFT
	.rdoy(ry16),
	.rov(rv16),
	.final(rf16),
	.tie(tce),			// 2x16-bit baseband input from modem or FFT
	.tdix(fte ? ftx : mtx),
	.tdiy(fte ? fty : mty),
	.tiv(fte ? ftv : mtv),
	.toe(trdy),			// 2x16-bit baseband output to tuner
	.tdox(cx),
	.tdoy(cy),
	.tov(cv),
	.clk(sclk),			// master clock and reser
	.rst(rst),
	.xmt(xmt)
	);
// Path simulation module
//pathsim psim (
//	.dix(tx),
//	.diy(ty),
//	.iv(tv),
//	.dox(tsx),
//	.doy(tsy),
//	.ov(tsv),
//	.clk(sclk),
//	.rst(rst),
//	.iocs(iocs15a),
//	.din(dout),
//	.iowr(iowr)
//	);
endmodule
