Experiment 19: Echo Synthesizer - ml7715/VERI-Laboratory GitHub Wiki

This experiment consists in creating an echo synthesizer with variable delay. In order to implement this circuit the following schematics were provided:

schematics

As we can see from the figure the design is fairly similar to the ones of the previous experiments with some noticeable differences:

  • Instead of using a ROM to contain to contain the sampled data the design uses a RAM. This is because we are continuously writing data, and therefore we need a faster storage device;
  • When reading and writing to RAM we skip the number of addresses indicated by the slide switches, this will allow us to generate a variable echo delay;

We will now design each of the blocks in the design and connect them together:

  • The Ram block was generated using the IP catalog tool; the RAM used has two ports one write and one read port, the size of the RAM is 8192 x 9-bit;

In cyclone three the embedded memory is limited to 9-bit data values so we used this limit in our design to maintain compatibility, although this limit does not apply to the DE1 board.

  • the 13-bit counter (same number of bits of a RAM address) was obtained using the IP catalog tool (LPM_COUNTER); whenever new data is obtained from the ADC the counter is increased (negative edge of data_available signal);

In particular from the block schematics we can see that the write address is generated from the read address adding the value of {SW[8:0], 4'b0}, therefore the delay generated is equal to SW[8:0] x 16 x 0.1 ms.

  • The rest of the feedback loop is identical to the one from the previous experiment;

The delayed signal is attenuated by a factor a 2 before being summed to the input signal. In order to do that the 9-bit output obtained from the RAM was sign extended by one bit.

  • in order to display the delay value in milliseconds on the 7-seg displays the value of SW[8:0] is multiplied by 1638 (SW[8:0] x 16 x 0.1 ms (delay between the read and write samples) x 1024). The most significant 10-bits (division by 1024) of the 20-bit product are then converted to BCD and displayed on the 7-seg displays.

multiplier by 1638 in verilog:

module mult(in, out);

	input signed [8:0] in;
	parameter mult_num = 11'd1638;
	
	output signed [19:0] out;
	
	wire [8:0] in;
	wire [19:0] out;
	
	assign out = mult_num * in;

endmodule 

Here is the verilog implementation of the processor module:

module processor (sysclk, tick, SW, data_in, data_out, data_valid, hex0, hex1, hex2, hex3, hex4);

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

	output [6:0]  	hex0, hex1, hex2, hex3, hex4;
	
	input [9:0]		SW;
	
	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 [12:0]		raw_address;
	
	wire [19:0]		delay;
	
	wire [3:0]		bcd0, bcd1, bcd2, bcd3, bcd4;

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

	assign x = data_in - ADC_OFFSET;		// x is input in 2's complement
	
	ctr_13_bit ctr(~data_valid, raw_address);
	
	delay_block del(sysclk, data_in, raw_address, tick, raw_address + {SW[8:0], 4'b0}, tick, tmp_data);
	
	div_by_2({tmp_data[8],tmp_data}, echoed_data);
		
	mult_by_h666 mul_by_h666(SW, delay);
		
	bin2bcd_16 bcd(delay[19:10], bcd0, bcd1, bcd2, bcd3, bcd4);
		
	hex_to_7seg h0(hex0, bcd0);
	hex_to_7seg h1(hex1, bcd1);
	hex_to_7seg h2(hex2, bcd2);
	hex_to_7seg h3(hex3, bcd3);
	hex_to_7seg h4(hex4, bcd4);
		
	assign y = x + echoed_data;
	
	//  Now clock y output with system clock
	always @(posedge sysclk)
		data_out <=  y + DAC_OFFSET;
		
endmodule

The design was then compiled and sent to the FPGA. The digital design worked as expected.