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:
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.