diff options
author | lonkaars <loek@pipeframe.xyz> | 2023-03-18 16:55:36 +0100 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2023-03-18 16:55:36 +0100 |
commit | 647f63e6b519e7ba9e5d6c189bd1c1d7786135c0 (patch) | |
tree | 03b5a0bafec8354d415d5d70fe3946630aad0051 /src | |
parent | 0a3fa36366c8314c4dbc02ecdbb6d80b7104af2c (diff) |
note-synth done and tested
Diffstat (limited to 'src')
-rw-r--r-- | src/note-synth.vhd | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/src/note-synth.vhd b/src/note-synth.vhd index 5ae9052..3d37022 100644 --- a/src/note-synth.vhd +++ b/src/note-synth.vhd @@ -2,6 +2,7 @@ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; +use ieee.math_real.all; entity note_synth is port( CLK: in std_logic; -- system clock @@ -13,6 +14,49 @@ entity note_synth is port( end note_synth; architecture Behavioral of note_synth is + function clk_for_freq(n : real) return natural is + constant SYSFREQ : real := 100000000.0; + begin + return natural(integer(round(SYSFREQ / n))); + end function; + + constant CLK_FOR_ERROR : natural := clk_for_freq(150.0); + constant CLK_FOR_E4 : natural := clk_for_freq(329.6); + constant CLK_FOR_F4 : natural := clk_for_freq(349.2); + constant CLK_FOR_G4 : natural := clk_for_freq(391.9); + constant CLK_FOR_A4 : natural := clk_for_freq(440.0); + constant CLK_FOR_B4 : natural := clk_for_freq(493.8); + constant CLK_FOR_C5 : natural := clk_for_freq(523.2); + constant CLK_FOR_D5 : natural := clk_for_freq(587.3); + constant CLK_FOR_E5 : natural := clk_for_freq(659.2); + constant CLK_FOR_F5 : natural := clk_for_freq(698.4); + signal MAX_CLK : natural := 1; + signal PWM_OUT_TEMP : std_logic := '0'; begin - PWM_OUT <= '0'; + MAX_CLK <= CLK_FOR_ERROR when NOTE_WRONG = '1' else + CLK_FOR_E4 when NOTE_IDX = x"0" else + CLK_FOR_F4 when NOTE_IDX = x"1" else + CLK_FOR_G4 when NOTE_IDX = x"2" else + CLK_FOR_A4 when NOTE_IDX = x"3" else + CLK_FOR_B4 when NOTE_IDX = x"4" else + CLK_FOR_C5 when NOTE_IDX = x"5" else + CLK_FOR_D5 when NOTE_IDX = x"6" else + CLK_FOR_E5 when NOTE_IDX = x"7" else + CLK_FOR_F5; + + PWM_OUT <= PWM_OUT_TEMP and NOTE_PLAY; + process(CLK) + variable CLK_COUNTER : integer := 0; + begin + if RESET = '1' then + CLK_COUNTER := 0; + elsif rising_edge(CLK) then + CLK_COUNTER := CLK_COUNTER + 1; + if CLK_COUNTER >= MAX_CLK then + CLK_COUNTER := 0; + + if PWM_OUT_TEMP = '0' then PWM_OUT_TEMP <= '1'; else PWM_OUT_TEMP <= '0'; end if; -- toggle output + end if; + end if; + end process; end Behavioral; |