Parcourir la source

cores/misc: Import simple PDM core (pulse density modulation)

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Sylvain Munaut il y a 5 ans
Parent
commit
57373928b0
3 fichiers modifiés avec 230 ajouts et 0 suppressions
  1. 2 0
      cores/misc/core.mk
  2. 147 0
      cores/misc/rtl/pdm.v
  3. 81 0
      cores/misc/sim/pdm_tb.v

+ 2 - 0
cores/misc/core.mk

@@ -7,6 +7,7 @@ RTL_SRCS_misc = $(addprefix rtl/, \
 	glitch_filter.v \
 	ram_sdp.v \
 	prims.v \
+	pdm.v \
 	pwm.v \
 	uart_rx.v \
 	uart_tx.v \
@@ -17,6 +18,7 @@ RTL_SRCS_misc = $(addprefix rtl/, \
 
 TESTBENCHES_misc := \
 	fifo_tb \
+	pdm_tb \
 	uart_tb \
 
 include $(ROOT)/build/core-magic.mk

+ 147 - 0
cores/misc/rtl/pdm.v

@@ -0,0 +1,147 @@
+/*
+ * pdm.v
+ *
+ * vim: ts=4 sw=4
+ *
+ * Pulse Density Modulation core (1st order with dither)
+ *
+ * Copyright (C) 2019  Sylvain Munaut <tnt@246tNt.com>
+ * All rights reserved.
+ *
+ * BSD 3-clause, see LICENSE.bsd
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+`default_nettype none
+
+module pdm #(
+	parameter integer WIDTH = 8,
+	parameter PHY = "GENERIC",
+	parameter DITHER = "NO"
+)(
+	input  wire [WIDTH-1:0] in,
+	output wire pdm,
+	input  wire oe,
+	input  wire clk,
+	input  wire rst
+);
+
+	// Signals
+	wire [WIDTH:0] in_i;
+	reg  [WIDTH:0] acc;
+
+	reg  dither;
+
+	wire pdm_i;
+
+	// Delta Sigma
+	assign in_i = { acc[WIDTH], in };
+
+	always @(posedge clk)
+	begin
+		if (rst)
+			acc <= 0;
+		else
+			acc <= acc + in_i + dither;
+	end
+
+	assign pdm_i = acc[WIDTH];
+
+	// Dither generator
+	generate
+		if (DITHER == "YES") begin
+			wire [7:0] lfsr_out;
+
+			pdm_lfsr #(
+				.WIDTH(8),
+				.POLY(8'h71)
+			) lfsr_I (
+				.out(lfsr_out),
+				.clk(clk),
+				.rst(rst)
+			);
+
+			always @(posedge clk)
+				dither <= lfsr_out[0] ^ lfsr_out[3];
+
+		end else begin
+			always @(posedge clk)
+				dither <= 1'b0;
+		end
+	endgenerate
+
+	// PHY (Basically just IO register)
+	generate
+		if (PHY == "GENERIC") begin
+			reg pdm_r;
+			always @(posedge clk)
+				pdm_r <= oe ? pdm_i : 1'bz;
+			assign pdm = pdm_r;
+		end else if (PHY == "ICE40") begin
+			SB_IO #(
+				.PIN_TYPE(6'b110100),
+				.PULLUP(1'b0),
+				.NEG_TRIGGER(1'b0),
+				.IO_STANDARD("SB_LVCMOS")
+			) io_reg_I (
+				.PACKAGE_PIN(pdm),
+				.LATCH_INPUT_VALUE(1'b0),
+				.CLOCK_ENABLE(1'b1),
+				.INPUT_CLK(1'b0),
+				.OUTPUT_CLK(clk),
+				.OUTPUT_ENABLE(oe),
+				.D_OUT_0(pdm_i),
+				.D_OUT_1(1'b0),
+				.D_IN_0(),
+				.D_IN_1()
+			);
+		end
+	endgenerate
+
+endmodule // pdm
+
+
+module pdm_lfsr #(
+	parameter integer WIDTH = 8,
+	parameter POLY = 8'h71
+)(
+	output reg  [WIDTH-1:0] out,
+	input  wire clk,
+	input  wire rst
+ );
+
+	// Signals
+	wire fb;
+
+	// Linear Feedback
+	assign fb = ^(out & POLY);
+
+	// Register
+	always @(posedge clk)
+		if (rst)
+			out <= { {(WIDTH-1){1'b0}}, 1'b1 };
+		else
+			out <= { fb, out[WIDTH-1:1] };
+
+endmodule // pdm_lfsr

+ 81 - 0
cores/misc/sim/pdm_tb.v

@@ -0,0 +1,81 @@
+/*
+ * pdm_tb.v
+ *
+ * vim: ts=4 sw=4
+ *
+ * Copyright (C) 2019  Sylvain Munaut <tnt@246tNt.com>
+ * All rights reserved.
+ *
+ * BSD 3-clause, see LICENSE.bsd
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+`default_nettype none
+`timescale 1ns / 100ps
+
+module pdm_tb;
+
+	// Signals
+	reg rst = 1;
+	reg clk = 1;
+
+	reg [7:0] data;
+	wire pdm;
+
+	// Setup recording
+	initial begin
+		$dumpfile("pdm_tb.vcd");
+		$dumpvars(0,pdm_tb);
+	end
+
+	// Reset pulse
+	initial begin
+		# 31 rst = 0;
+		# 20000 $finish;
+	end
+
+	// Clocks
+	always #5 clk = !clk;
+
+	// DUT
+	pdm #(
+		.WIDTH(12),
+		.PHY("ICE40"),
+		.DITHER("ON")
+	) dut_I (
+		.in({data[7:4],data}),
+		.pdm(pdm),
+		.oe(1'b1),
+		.clk(clk),
+		.rst(rst)
+	);
+
+	initial begin
+		#0		data <= 8'hc1;
+		#5000	data <= 8'h10;
+		#5000	data <= 8'hf0;
+		#5000	data <= 8'h80;
+	end
+
+endmodule // pdm_tb