Experiment 17: Echo Synthesizer with fixed delay - ml7715/VERI-Laboratory GitHub Wiki

This experiment consists in realizing an echo synthesized with a fixed delay. In order to produce an echo effect two components were added to generate the output signal:

  • The original input signal, obtained through the ADC;
  • a delayed version of the original signal attenuated by a factor beta, which over-imposed on the original signal will produce the echo effect;

The design of Experiment 12 was used as a prototype to execute this experiment by changing the audio processing module.

The general design of the processor module is the following:

processor

The delayed signal was obtained using a first-in-first-out buffer from the IP Catalog. In this case we created a FIFO component of size 8192 x 10-bit, which will provide a delay of 0.8192 seconds (sampling period 0.1ms * 8192). A new input is stored by the FIFO unit when tick (obtained from a tick_5000 module) is asserted.

FIFO inputs and outputs in verilog:

module FIFO (
	clock,
	data,
	rdreq,
	wrreq,
	full,
	q);

The echo simulation starts when the full flag of the FIFO is asserted and the FIFO starts providing an output.

processing unit verilog:

module processor (sysclk, tick, data_in, data_out);

	input				sysclk, tick;		// system clock
	input [9:0]		data_in;		// 10-bit input data
	output [9:0] 	data_out;	// 10-bit output data

	wire				sysclk;
	wire [9:0]		data_in;
	reg [9:0] 		data_out;
	wire [9:0]		x,y;
	wire [9:0]		tmp_data, echoed_data;
	wire is_full, and_if, from_dff;

	parameter 		ADC_OFFSET = 10'h181;
	parameter 		DAC_OFFSET = 10'h200;

	assign x = data_in[9:0] - ADC_OFFSET;		// x is input in 2's complement
	
	FIFO fifo(sysclk, x, and_if, tick, is_full, tmp_data);
	
	d_ff d(tick, is_full, from_dff);
	
	assign and_if = tick & from_dff;
	
	div_by_2(tmp_data, echoed_data);
		
	assign y = x + echoed_data;
	
	//  Now clock y output with system clock
	always @(posedge sysclk)
		data_out <=  y + DAC_OFFSET;
		
endmodule

The attenuation factor beta was implemented using a right arithmetic shift by 1:

module div_by_2(in, out);

	input signed [9:0] in;
	output signed [9:0] out;
	
	assign out = in >>> 1;
	
endmodule

We have to use the signed keyword to make sure that the arithmetic shift right is not synthesised as a logical shift.

The top design of the circuit is the following:

module ex17 (CLOCK_50, SW, HEX0, HEX1, HEX2, 
					DAC_SDI, DAC_SCK, DAC_CS, DAC_LD,
					ADC_SDI, ADC_SCK, ADC_CS, ADC_SDO, PWM_OUT);

	input			CLOCK_50;		// DE0 50MHz system clock
	input [9:0]	SW;				// 10 slide switches to specify address to ROM
	output [6:0] HEX0, HEX1, HEX2;
	output 		DAC_SDI;			//Serial data out to SDI of the DAC
	output 		DAC_SCK;				//Serial clock signal to both DAC and ADC
	output		DAC_CS;			//Chip select to the DAC, low active
	output 		DAC_LD;			//Load new data to DAC, low active	
	output 		ADC_SDI;			//Serial data out to SDI of the ADC
	output 		ADC_SCK;		// ADC Clock signal
	output		ADC_CS;			//Chip select to the ADC, low active
	input 		ADC_SDO;			//Converted serial data from ADC	
	output		PWM_OUT;			// PWM output to R channel
		
	wire			tick_10k;		// internal clock at 10kHz
	wire [9:0] 	data_in;		// converted data from ADC
	wire [9:0] 	data_out;	// processed data to DAC
	wire			data_valid;
	wire			DAC_SCK, ADC_SCK;
	
	clktick_16  GEN_10K (CLOCK_50, 1'b1, 16'd4999, tick_10k);  	// generate 10KHz sampling clock ticks
	spi2dac SPI_DAC (CLOCK_50, data_out, tick_10k, 		// send processed sample to DAC
					DAC_SDI, DAC_CS, DAC_SCK, DAC_LD);		// order of signals matter
	pwm PWM_DC(CLOCK_50, data_out, tick_10k, PWM_OUT);		// output via PWM - R-channel
					
	spi2adc SPI_ADC (												// perform a A-to-D conversion
		.sysclk (CLOCK_50), 										// order of parameters do not matter
		.channel (1'b1), 											// use only CH1
		.start (tick_10k),
		.data_from_adc (data_in),
		.data_valid (data_valid),
		.sdata_to_adc (ADC_SDI),
		.adc_cs (ADC_CS),
		.adc_sck (ADC_SCK),
		.sdata_from_adc (ADC_SDO));		
					
	processor	ALLPASS (CLOCK_50, tick_10k, data_in, data_out);	// do some processing on the data
	
	hex_to_7seg		SEG0 (HEX0, data_in[3:0]);			
	hex_to_7seg		SEG1 (HEX1, data_in[7:4]);			
	hex_to_7seg		SEG2 (HEX2, {2'b0,data_in[9:8]});			
		
endmodule

The design was compiled and sent to the FPGA. The implementation of the echo synthesized worked as expected.