diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2024-12-16 16:53:54 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2024-12-16 16:53:54 +0100 |
commit | 8daccb896619f054c49a65a76b73e92fcce330e9 (patch) | |
tree | 407c96c7fdd2571b1623e8c32ee99b05fe7d779c /mictoled/mictoled.v | |
parent | 959edc17ff8f4b71a258c3c66d25bd904fb98bf0 (diff) | |
download | iceFUN-8daccb896619f054c49a65a76b73e92fcce330e9.tar.gz iceFUN-8daccb896619f054c49a65a76b73e92fcce330e9.tar.bz2 iceFUN-8daccb896619f054c49a65a76b73e92fcce330e9.zip |
mictoled: improve sim test data
Diffstat (limited to 'mictoled/mictoled.v')
-rw-r--r-- | mictoled/mictoled.v | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/mictoled/mictoled.v b/mictoled/mictoled.v new file mode 100644 index 0000000..0f14d71 --- /dev/null +++ b/mictoled/mictoled.v @@ -0,0 +1,103 @@ +/* + * Copyright(C) 2024 Matthias P. Braendli <matthias.braendli@mpb.li> + * Copyright(C) 2018 Gerald Coe, Devantech Ltd <gerry@devantech.co.uk> + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with or + * without fee is hereby granted, provided that the above copyright notice and + * this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +// This is following the excellent explanation on +// https://tomverbeure.github.io/2020/09/30/Moving-Average-and-CIC-Filters.html + +module mictoled + #( + parameter integer INTEGRATOR_WIDTH=16, + parameter integer COMB_WIDTH=12) + ( + input clk, // 12MHz + input btn, + + output mic_clk, + input mic_dat, + + output led1, output led2, output led3, output led4, + output led5, output led6, output led7, output led8, + output lcol1, output lcol2, output lcol3, output lcol4 + ); + /* PDM mic clock gen */ + reg [31:0] clkdiv = 8'b0; + always @ (posedge clk) begin + clkdiv <= (clkdiv + 1) % 24; + end + + wire mic_strobe = clkdiv == 12; + assign mic_clk = clkdiv >= 12; + + /* CIC decimator by 64 => 2MHz -> 31.25 kHz */ + reg [INTEGRATOR_WIDTH-1:0] integrator = 0; + reg [5:0] decim_strobe_counter = 8'b0; + always @ (posedge clk) begin + if (mic_strobe) begin + if (mic_dat == 0) + integrator <= integrator + 1; + else + integrator <= integrator - 1; + + decim_strobe_counter <= (decim_strobe_counter + 1) % 64; + end + end + + /* Comb stage after decimation */ + wire decim_strobe = decim_strobe_counter == 0 && mic_strobe; + reg [INTEGRATOR_WIDTH-1:0] previous_integrator = 0; + reg [COMB_WIDTH-1:0] comb_out = 0; // can be reduced_width + always @ (posedge clk) begin + if (decim_strobe) begin + comb_out = integrator - previous_integrator; + previous_integrator <= integrator; + end + end + + /* Goertzel Algorithm to detect presence of frequencies */ + // coef = 2 * cos(2 * PI * freq / sample_rate); + // 440 Hz -> 1.992178649 + // 1200 Hz -> 1.942068556 + // Represent in fixed point in Q4.10, i.e. a scaling factor of 1024 + //integer coef_440 = 2040; // 439.75 Hz + real coef_440 = 1.992178649; + + real q1_440 = 0; + real q2_440 = 0; + reg [9:0] goertzel_strobe_counter = 0; + + real m_squared_440 = 0; + + always @ (posedge clk) begin + if (decim_strobe) begin + goertzel_strobe_counter <= goertzel_strobe_counter + 1; // overflow at 1024 + + if (goertzel_strobe_counter % 256 == 0) begin + m_squared_440 <= q1_440 * q1_440 + q2_440 * q2_440 - coef_440 * q1_440 * q2_440; + q1_440 <= 0; + q2_440 <= 0; + end + else begin + q1_440 <= coef_440 * q1_440 - q2_440 + comb_out; + q2_440 <= q1_440; + end + end + end + + /* LED drivers - counter is inverted for display because leds are active low */ + //assign {led8, led7, led6, led5, led4, led3, led2, led1} = m_squared_440[14:6] ^ 8'hff; + assign {lcol4, lcol3, lcol2, lcol1} = 4'b1110; + +endmodule |