// demo_codec_delayline.v -- Codec delay-line demo (left channel only)
// Ed Doering
// 07/25/2000
//
// Updated to use Windows sliders application

//-------------------------------------------------------------------------------

// Uncomment the `define line below *only* if targeting the XStend version 1.3 board
// (the XStend board includes Schmitt trigger inverters between the FPGA
// and each of the four codec control inputs)
`define XSTEND 1

`define	UseSliderA 	1
`define SliderBitsA	15
`define	SliderAddressA	0
`include "sliders.v"

module Demo_Codec_DelayLine ( 
	// Loop the codec output back to its input, and do sign inversion along the way

	// Inputs: 
	I$Clock	// 12MHz clock
,
	I$_Reset	// Active low asynchronous reset
,
	I$SerialDataFromCodec	// Serial data from codec (connect to 'SDOUT' signal)
,
	I$ParallelPort	// Lower six bits of parallel port
,

	// Outputs: 
	O$MasterClock	// connect to 'MCLK' of codec
,
	O$LeftRightClock	// connect to 'LRCK' of codec
,
	O$SerialClock	// connect to 'SCLK' of codec
,
	O$SerialDataToCodec	// connect to 'SDIN' of codec
	
`ifdef XSTEND
,
	O$MicroReset	// connect to 8051 microcontroller reset pin
,
	O$_RAMCSXS40	// connect to XS40 RAM chip select
,
	O$_RAMCSXStendL	// connect to XStend left RAM chip select
,
	O$_RAMCSXStendR	// connect to XStend right RAM chip select
,
	O$_RAMOE	// connect XS40 RAM output enable
,
	O$_RAMWE	// connect to XS40 RAM write enable
,
	O$RAMAddress	// connect to XS40 RAM address bus
,
	IO$RAMData	// connect XS40 data bus
`endif

); 

// Port mode declarations:
input	I$Clock;
input	I$_Reset;
input	I$SerialDataFromCodec;
input	[5:0]	I$ParallelPort;
output	O$MasterClock;
output	O$LeftRightClock;
output	O$SerialClock;
output	O$SerialDataToCodec;
`ifdef XSTEND
output	O$MicroReset;
output	O$_RAMCSXS40;
output	O$_RAMCSXStendL;
output	O$_RAMCSXStendR;
output	O$_RAMOE;
output	O$_RAMWE;
output	[14:0]	O$RAMAddress;
inout	[7:0]	IO$RAMData;
`endif


// Wire declarations:
wire	[19:0]	w$CodecOutput;
wire	w$CodecOutputValid;
wire	[7:0]	w$DelayLineOutput;
wire	w$DelayLineOutputValid;
wire	w$MasterClock;
wire	w$LeftRightClock;
wire	w$SerialClock;
wire	w$SerialDataToCodec;
wire	w$RAMDataBusIsOutput;
wire	[7:0]	w$RAMDataToRAM;
wire	w$Reset;
wire	[14:0]	w$DelayLineLength;


`ifdef XSTEND
// Hold the XS40 micro in reset mode
assign O$MicroReset = 1;

// Invert the four codec signals to cancel out the inverters
assign	O$MasterClock = ~w$MasterClock;
assign	O$LeftRightClock = ~w$LeftRightClock;
assign	O$SerialClock = ~w$SerialClock;
assign	O$SerialDataToCodec = ~w$SerialDataToCodec;
`else
assign	O$MasterClock = w$MasterClock;
assign	O$LeftRightClock = w$LeftRightClock;
assign	O$SerialClock = w$SerialClock;
assign	O$SerialDataToCodec = w$SerialDataToCodec;
`endif


// Instantiate the codec interface
Codec U1 (
	// Inputs: 
	.I$Clock		( I$Clock ),
	.I$Reset		( w$Reset ),
	.I$LeftChannel		( {w$DelayLineOutput,12'h0} ),	
	.I$RightChannel		( {w$CodecOutput[19:12],12'h0} ),
	.I$SerialDataFromCodec	( I$SerialDataFromCodec ),

	// Outputs: 
	.O$LeftChannel		( w$CodecOutput ),
	.O$RightChannel		(  ),
	.O$LeftChannelDataValid	( w$CodecOutputValid ),
	.O$RightChannelDataValid(  ),
	.O$MasterClock		( w$MasterClock ),
	.O$LeftRightClock 	( w$LeftRightClock ),
	.O$SerialClock		( w$SerialClock ),
	.O$SerialDataToCodec 	( w$SerialDataToCodec )
);

// Instantiate the delay line interface, and connect it between the codec
// output and input (left channel input only, 8 bits; pass delayed version
// to left channel out, and undelayed version to right channel out)
DelayLine U2 (
	// Inputs: 
	.I$Clock	( I$Clock ),
	.I$Reset	( w$Reset ),
	.I$Data		( w$CodecOutput[19:12] ),
	.I$DataValid	( w$CodecOutputValid ),
	.I$Length	( {2'b0,w$DelayLineLength} ),
	.I$RAMData	( IO$RAMData ),

	// Outputs: 
	.O$Data	( w$DelayLineOutput ),
	.O$DataValid	(  ),
	.O$_RAMCSXS40	( O$_RAMCSXS40 ),
	.O$_RAMCSXStendL( O$_RAMCSXStendL ),
	.O$_RAMCSXStendR( O$_RAMCSXStendR ),
	.O$_RAMOE	( O$_RAMOE ),
	.O$_RAMWE	( O$_RAMWE ),
	.O$RAMAddress	( O$RAMAddress ),
	.O$RAMData	( w$RAMDataToRAM ),
	.O$RAMDataBusIsOutput ( w$RAMDataBusIsOutput )
); 

// Connect delay line RAM interface as bidirectional port
assign IO$RAMData = (w$RAMDataBusIsOutput) ? w$RAMDataToRAM : 8'hz;

// Invert the reset signal to make active high (use the active low
// 'RESET' pushbutton on XStend board)
assign w$Reset = ~I$_Reset;


Sliders U3 (
	// Inputs:
	.I$Clock	( I$Clock ),
	.I$Reset	( w$Reset ),
	.I$ParallelPort	( I$ParallelPort ),
	
	// Outputs
	.O$SliderA	( w$DelayLineLength )
);
	
endmodule