Commit 2a8ede57 authored by Pascal Fitzner's avatar Pascal Fitzner
Browse files


parent 094a7bc4
Pipeline #16645 failed with stages
# The problem
The general idea of this project is to make a beat machine, by using the continuous alternating waveform of the 100MHz 50PPM MEMS/CMOS oscillator of the boolean board to create a sinus wave, which is converted to a PWM signal an sent to the audio port[^1]. So, to be more precise it is practically a synthesizer which plays on set intervals. In addition, the connected multi region clock should interrupt the signal in conjunction with slide switches to generate a repeating audio rhythm. To provide additional feedback when a tone should be played, the LEDs next to the switches should turn on, based on the state of the neighbouring switch. Both features together should provide consistent audio-visual feedback. To generate a digital circuit for our needs we need to fulfil following goals
- First generate an audible signal at the speaker, by conveying the output from the oscillator to the audio output.
- Secondly generate a discrete analog sinus function base on the internal clock cycle.
- Convert the Sinus signal to the digital pwm signal.
- Then I divide a four-four clock time into 16 slide switches in order to interrupt the signal according to their states. This means I can play 16 individual beats in one clock cycle.
- This is followed by audio-visual feedback through glowing LEDs at the position of the current beat in our four-four-time interval above the slide switches.
\ No newline at end of file
# Relevant concepts
PWM stands for pulse width modulation, it uses digital signals to control power applications. By generating a continuous series of pulses, which length and frequency are adjustable, it allows for easy controll of the average voltage autput. In any given duty cycle, the ratio of the signal high time to the signal low time determines the information carried by the signal [^1].
\ No newline at end of file
# Approach
For my strategy of solving the large problems connected to this project, I kept the approach of divide and conquer in my mind. By first completing smaller tasks like clock diver and counter, it was easier to approach the more complicated algorithem to generate and process the sinus function, required in this "beat-machine".
## Clock Divider
To generate sound and visual feedback in a desired interval, a reliable clock as input signal is required. The resonating frequency provide by Boolean board is 100MHz *[^1]*, but for the desired design four quarter notes in one music tact was wished. For this reason, a terminal count is set to 25MHz splitting one second roughly up to four. When the free running counter reaches the terminal count it will be reset to zero and the cycle begins anew. Now a clock with the desired frequency is provided, that can be used in other different subsystems like the decimal counter for further use.
module clk_div(
input clk, rst,
output reg clk_div
localparam terminalcount = (100000000/4 - 1);
reg [25:0] count;
wire tc;
assign tc = (count == terminalcount);
always @ (posedge(clk), posedge(rst))
if (rst) count <= 0;
else if (tc) count <= 0;
else count <= count + 1;
always @ (posedge(clk), posedge(rst))
if (rst) clk_div <= 0;
else if (tc) clk_div = !clk_div;
There is also a second, so called wave clock, which is used to adjust the frequency of the sinus wave form to PWM conversion. This in turn determines the final sound produced by the fpga, by influencing the there produced duty cyles.
## Decimal Counter
The decimal counter does practically, what the name implies. It is counting decimals, in this case from zero to fifteen as four, four time four clocks need to be play. This number is not a randomly chosen, because the Boolean board offers 16 identical LEDs and 16 associated switches, which will be used in the same frequency as visual feedback. The resulting integer will be provided as an input for the swich comparer as well as the LED counter.
`timescale 1ns / 1ps
module bcd_cnt(
input clk_div, rst,
output reg [3:0] count
always @ (posedge(clk_div), posedge(rst))
if (rst) count <= 0;
else if (count == 15) count <= 0;
else count <= count + 1;
## Switch Comparer
The Switch comparer takes the decimal counter as an input and uses it as index for the 16 switches, checking if the corresponding switch is one or of. While this task is quite simple to prevent the redundancy of checking the switch state in the LED counter as well as the audio synthesizer it got its one module, which provides a state as output.
`timescale 1ns / 1ps
module sw_cmp(
input [15:0] sw,
input [3:0] count,
output reg sw_state
always @ (count) begin
sw_state <= sw[count];
## LED Counter
The LED counter provides visual feedback based on the current decimal count, so the user has second validation at which point a hear sound should be heard. The second input is the switch state, that tells the board the what LED is allowed to glow at the current state, as the audio signal gets interrupted the same time.
`timescale 1ns / 1ps
module led_cnt(
input [3:0] count,
input sw_state,
output reg [15:0] led
always @ (count) begin
led = 0;
led[count] = sw_state;
## Synthesizing audio
### Discrete Sine Function
The simplest way to generate a sine wave generator, is to read discrete sine values from a lookup-table. In the scale of the project this process is simplified by working with a fixed frequency, improvements, and addition to this will be mentioned in the conclusion. First, discrete sinus values will be generated and store in a LUT for later reading from memory, this can easily be achieved by using free sine look up table generator .
*Fig. 2: Sinus Look Up Table Generator* [^2]
Now the sinus values from our memory file will be read with an index based on the clock cycle and store in a 16-bit register.
`timescale 1ns / 1ps
module synt_sin_lut(
input clk,
output reg [15:0] sinus
parameter SIZE = 1024;
reg [15:0] rom_memory [SIZE-1:0];
integer i;
initial begin
$readmemh("sine.mem", rom_memory); //File with the signal
i = 0;
//At every positive edge of the clock, output a sine wave sample.
always@(posedge clk)
sinus = rom_memory[i];
i = i+ 1;
if(i == SIZE)
i = 0;
Following image shows the output in a Vivado behavioral simulation in waveform. It is important to set our waveform style to analog, so we can see the following sinus function:
*Fig. 2: Sinus Simulation Analog Waveform View*
By changing the waveform from digital to analog in the simulation window it becomes clear that a sinus wave has successful be generated. But produce an actual sound from it, it has to converted to an digital signal like PWM.
### Pulse Wave Modulation
PWM (Pulse wave modulation) is a type of digital modulation in which a variable continously alternates between two values[^3]. For this a rectangular pulse is modulated at a constant frequency and varying length. The ratio between pulse and pause is called duty cycle. To put it simple a Pulse Width Modulator generates a periodic sequence of pulses, whose duration is proportional to the value that is provided as an input[^4]. In the case of the Boolean Board, a constant 100MHz clock signal from the MEMS/CMOS oscillator is the base frequency and goal is it to adjust it to the correct duty cycle, approximating the sinus values. This means changing the duty cycles dependent on the ever-changing sinus wave input. One way to achieve this is by comparing a sinus wave with a sawtooth wave. Depending one which function provides a higher or lower values, the PWM signal gets set to a 1 or a 0. For values where the sine value is higher than the sawtooth, 1 is set as output, if the opposite is the case, a 0 is set.
`timescale 1ns / 1ps
module sin_to_pwm(
input clk_div_wave,rst,
input sw_state,
input [dwidth_g-1:0] sin_in,
output reg pwm_out
reg convert;
parameter integer dwidth_g = 16;
reg [dwidth_g-1:0] cnt;
parameter cnt_max_c = 65535; // 3*5*17*257
always@(posedge clk_div_wave)
if(rst == 1'b1)
cnt = 0;
convert = 0;
convert = (cnt == cnt_max_c) ? 1'b1 : 1'b0;
if(convert == 1'b1)
cnt = 0;
cnt = cnt +4369; // 17*257
if(cnt < sin_in)
pwm_out = 1'b1;
pwm_out = 1'b0;
pwm_out = 1'b0;
This means that the higher the sine value, the longer is the duty cycle.
![Sine Wave Generation Using PWM With Hercules™ N2HET and HTU](_static\Capture_sine_pwm.PNG)
*Fig. 4: Sinus Sawtooth Comparison* [^5]
If you provide a simulation with both wave functions in analog form, its clearly visible how the duty cycles adjust in the following image:
![Charles J. Sharp, CC BY-SA 4.0 <>, via Wikimedia Commons](_static\sin_pwm_Capture.PNG)
*Fig. 4: Sinus Sawtooth Duty Cycle Adjustment Simulation*
## Final Design
The complete digital circute looks as followed and contains two clock divider, a decimal counter, a switch comparer, a led counter, a sinus wave synthesizer, as well as sinus to pwm converter:
![Charles J. Sharp, CC BY-SA 4.0 <>, via Wikimedia Commons](_static\block_design.PNG)
*Fig. 4: Project Block Design*
<video controls width="700">
[^4]: Audio Tone Generator Using Verilog HDL Coding Implementation of Audio Tone Generator on FPGA Using Verilog HDL Coding
[^5]: Sine Wave Generation Using PWM With Hercules™ N2HET and HTU
# Results
All proposed goals could be achieved, the generate an audible signal via a discrete sinus wave, as well as visual feedback for the four-four clock time through LEDs and switches. The final result can seen and heard in the following demo:
/demo video
But does not mean that this design, couldn’t be improved in various areas, which will further be elaborated in the conclusion
## Conclusion
There are many ways to improve the general design of this project, be it in features, efficiency of implementation or usability.
One would be volume control. Not only is this common and quit welcome feature of every synthesizer, for not hearing audio at the highest volume, but it would also mitigate the problem of power drain, by different audio end devices. Which means that different end devices with different energy requirements, also influence the volume output making it dependent on the used speaker.
A general design improvement would be dynamic frequency adjustment. On one hand this would allow to play all nots from a musical scale und the other the speed of the oscillating audio output could be speed up or slowed down.
Since scales have already been mentioned and there is already a fixed four-four clock interval, saving rhythms in memory is something to be considered. This could provide uses similar to a loop station.
There are also many other features like adjusting scale levels, pitch, audio effects, for example delaying the wave output provided by digital and analogy synthesizer, but as implementation and design was strongly time restricted these ground concept seemed to be the most important to implement for an acquirable goal.
## Hardware
- 0.5W ROHS speaker
\ No newline at end of file
# Markdown examples
Emphasis using *Italics*, **bold**.
The paragraph continues
This is the second paragraph.
## Blockquotes
Kermit from the Muppet Movie:
> Life's like a movie. Write your own ending.
## Lists
- apple
- banana
- cherry
## Links
More info can be found on [Python docs – Exceptions](
## Images
![Charles J. Sharp, CC BY-SA 4.0 <>, via Wikimedia Commons](
## Code snippets
We can use `find -iname STRING` to search for a file in Unix.
The following code[^1] shuffles a list:
from random import shuffle
foo = [1, 2, 3, 4]
## The end
If you want to try these, follow this [Markdown tutorial]( It also includes a web-based code editor.
[^1]: Code from [](
......@@ -17,9 +17,9 @@
# -- Project information -----------------------------------------------------
project = 'Sphinx-book template'
project = 'Beat-machine'
copyright = 'Creative Commons Attribution 4.0 International License'
author = 'Gökçe Aydos'
author = 'Pascal Fitzner'
# -- General configuration ---------------------------------------------------
# Heading
# Title
This is a Sphinx-book template. Markdown examples can be found on the left
This is a Sphinx-book template that you can use for your report. Markdown examples are included.
:maxdepth: 2
:caption: 'Contents'
# Unified simulation database file for selected simulation model for IP
# File: ssm.db (Mon Jun 27 21:49:08 2022)
# This file is generated by the unified simulation automation and contains the
# selected simulation model information for the IP/BD instances.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment