summaryrefslogtreecommitdiffstats
path: root/mictoled/mictoled.v
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2024-12-16 16:53:54 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2024-12-16 16:53:54 +0100
commit8daccb896619f054c49a65a76b73e92fcce330e9 (patch)
tree407c96c7fdd2571b1623e8c32ee99b05fe7d779c /mictoled/mictoled.v
parent959edc17ff8f4b71a258c3c66d25bd904fb98bf0 (diff)
downloadiceFUN-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.v103
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