|
@@ -5,7 +5,7 @@
|
|
|
*
|
|
|
* Pulse Density Modulation core (1st order with dither)
|
|
|
*
|
|
|
- * Copyright (C) 2019 Sylvain Munaut <tnt@246tNt.com>
|
|
|
+ * Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
|
|
|
* All rights reserved.
|
|
|
*
|
|
|
* BSD 3-clause, see LICENSE.bsd
|
|
@@ -37,18 +37,23 @@
|
|
|
|
|
|
module pdm #(
|
|
|
parameter integer WIDTH = 8,
|
|
|
- parameter PHY = "GENERIC",
|
|
|
- parameter DITHER = "NO"
|
|
|
+ parameter DITHER = "NO",
|
|
|
+ parameter PHY = "GENERIC"
|
|
|
)(
|
|
|
- input wire [WIDTH-1:0] in,
|
|
|
+ // PWM out
|
|
|
output wire pdm,
|
|
|
- input wire oe,
|
|
|
+
|
|
|
+ // Config
|
|
|
+ input wire [WIDTH-1:0] cfg_val,
|
|
|
+ input wire cfg_oe,
|
|
|
+
|
|
|
+ // Clock / Reset
|
|
|
input wire clk,
|
|
|
input wire rst
|
|
|
);
|
|
|
|
|
|
// Signals
|
|
|
- wire [WIDTH:0] in_i;
|
|
|
+ wire [WIDTH:0] inc;
|
|
|
reg [WIDTH:0] acc;
|
|
|
|
|
|
reg dither;
|
|
@@ -56,14 +61,14 @@ module pdm #(
|
|
|
wire pdm_i;
|
|
|
|
|
|
// Delta Sigma
|
|
|
- assign in_i = { acc[WIDTH], in };
|
|
|
+ assign inc = { acc[WIDTH], cfg_val };
|
|
|
|
|
|
always @(posedge clk)
|
|
|
begin
|
|
|
if (rst)
|
|
|
acc <= 0;
|
|
|
else
|
|
|
- acc <= acc + in_i + dither;
|
|
|
+ acc <= acc + inc + dither;
|
|
|
end
|
|
|
|
|
|
assign pdm_i = acc[WIDTH];
|
|
@@ -71,6 +76,7 @@ module pdm #(
|
|
|
// Dither generator
|
|
|
generate
|
|
|
if (DITHER == "YES") begin
|
|
|
+ // Dither using a simple LFSR
|
|
|
wire [7:0] lfsr_out;
|
|
|
|
|
|
pdm_lfsr #(
|
|
@@ -86,19 +92,29 @@ module pdm #(
|
|
|
dither <= lfsr_out[0] ^ lfsr_out[3];
|
|
|
|
|
|
end else begin
|
|
|
- always @(posedge clk)
|
|
|
- dither <= 1'b0;
|
|
|
+ // No dither
|
|
|
+ always @(*)
|
|
|
+ dither = 1'b0;
|
|
|
end
|
|
|
endgenerate
|
|
|
|
|
|
// PHY (Basically just IO register)
|
|
|
generate
|
|
|
- if (PHY == "GENERIC") begin
|
|
|
- reg pdm_r;
|
|
|
+ if (PHY == "NONE") begin
|
|
|
+ // No PHY (and no OE support)
|
|
|
+ assign pdm = pdm_i;
|
|
|
+ end else if (PHY == "GENERIC") begin
|
|
|
+ // Generic IO register, let tool figure it out
|
|
|
+ reg pdm_d_r;
|
|
|
+ reg pdm_oe_r;
|
|
|
always @(posedge clk)
|
|
|
- pdm_r <= oe ? pdm_i : 1'bz;
|
|
|
- assign pdm = pdm_r;
|
|
|
+ begin
|
|
|
+ pdm_d_r <= pdm_i;
|
|
|
+ pdm_oe_r <= cfg_oe;
|
|
|
+ end
|
|
|
+ assign pdm = pdm_oe_r ? pdm_d_r : 1'bz;
|
|
|
end else if (PHY == "ICE40") begin
|
|
|
+ // iCE40 specific IOB
|
|
|
SB_IO #(
|
|
|
.PIN_TYPE(6'b110100),
|
|
|
.PULLUP(1'b0),
|
|
@@ -110,7 +126,7 @@ module pdm #(
|
|
|
.CLOCK_ENABLE(1'b1),
|
|
|
.INPUT_CLK(1'b0),
|
|
|
.OUTPUT_CLK(clk),
|
|
|
- .OUTPUT_ENABLE(oe),
|
|
|
+ .OUTPUT_ENABLE(cfg_oe),
|
|
|
.D_OUT_0(pdm_i),
|
|
|
.D_OUT_1(1'b0),
|
|
|
.D_IN_0(),
|