Skip to content

Commit

Permalink
gateware: rewrite clocking architecture, improve ak4619 driver (#33)
Browse files Browse the repository at this point in the history
* Change default sample rate from ~96khz to ~48kHz and BICK from 12MHz -> 6MHz which improves stability a bit with long cables from FPGA/PMOD. There is no audible difference and the noise performance is a bit better.
* Clean up clocking architecture so we can select any sample rate from 8kHz to 48kHz, removing fixed 12MHz assumptions everywhere.
* Rewrite AK4619 driver to collapse most of the logic into one posedge block on clk_256fs.
* Some other minor fixes so that this repository plays better with LiteX (splitting out the wavetable osc as its own module, bubbling up .hex config paths).
* Compress ECP5 bitstreams so they upload faster

TESTED on all supported platforms
  • Loading branch information
schnommus committed Aug 23, 2023
1 parent 07b31a7 commit 052d6b0
Show file tree
Hide file tree
Showing 23 changed files with 999 additions and 913 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: build & test

on: [push, pull_request]
on: [push]

jobs:
ubuntu-build-icebreaker:
Expand Down
2 changes: 2 additions & 0 deletions gateware/boards/colorlight_i5/pinmap.lpf
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
SYSCONFIG COMPRESS_CONFIG=ON;

LOCATE COMP "CLK" SITE "P3";
IOBUF PORT "CLK" IO_TYPE=LVCMOS33;
FREQUENCY PORT "CLK" 25 MHZ;
Expand Down
26 changes: 15 additions & 11 deletions gateware/boards/colorlight_i5/sysmgr.v
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@ module sysmgr (
// Assumed 25Mhz for Colorlight i5.
input wire clk_in,
input wire rst_in,
output wire clk_12m,
output wire clk_256fs,
output wire clk_fs,
output wire rst_out
);

// Signals
wire clk_fb;

wire pll_lock;
wire pll_reset;

wire rst_i;

reg [7:0] rst_cnt;
reg [7:0] clkdiv;

assign pll_reset = rst_in;
assign rst_i = ~rst_cnt[7];
assign rst_out = rst_i;
assign clk_fs = clkdiv[7];

`ifndef VERILATOR_LINT_ONLY

Expand Down Expand Up @@ -49,7 +54,7 @@ EHXPLLL #(
.RST(pll_reset),
.STDBY(1'b0),
.CLKI(clk_in),
.CLKOS(clk_12m),
.CLKOS(clk_256fs),
.CLKFB(clk_fb),
.CLKINTFB(clk_fb),
.PHASESEL0(1'b0),
Expand All @@ -64,17 +69,16 @@ EHXPLLL #(

`endif

// PLL reset generation
assign pll_reset = rst_in;
// Logic reset generation
always @(posedge clk_in)
if (!pll_lock)
rst_cnt <= 8'h0;
else if (~rst_cnt[7])
rst_cnt <= rst_cnt + 1;

assign rst_i = ~rst_cnt[7];

assign rst_out = rst_i;
always @(posedge clk_256fs)
if (rst_i)
clkdiv <= 8'h00;
else
clkdiv <= clkdiv + 1;

endmodule // sysmgr
2 changes: 2 additions & 0 deletions gateware/boards/colorlight_i9/pinmap.lpf
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
SYSCONFIG COMPRESS_CONFIG=ON;

LOCATE COMP "CLK" SITE "P3";
IOBUF PORT "CLK" IO_TYPE=LVCMOS33;
FREQUENCY PORT "CLK" 25 MHZ;
Expand Down
6 changes: 4 additions & 2 deletions gateware/boards/ecpix5/pinmap.lpf
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
SYSCONFIG COMPRESS_CONFIG=ON;

LOCATE COMP "CLK" SITE "K23";
IOBUF PORT "CLK" IO_TYPE=LVCMOS33;
FREQUENCY PORT "CLK" 100 MHZ;

# This pinout assumes a ribbon cable IS used and the PMOD is
# connected through an IDC ribbon to the dev board.

# These pads are PMOD_P2A
# These pads are PMOD_P0
LOCATE COMP "PMOD_MCLK" SITE "W26";
LOCATE COMP "PMOD_PDN" SITE "V26";
LOCATE COMP "PMOD_I2C_SDA" SITE "U26";
Expand All @@ -24,7 +26,7 @@ IOBUF PORT "PMOD_SDOUT1" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
IOBUF PORT "PMOD_LRCK" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
IOBUF PORT "PMOD_BICK" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;

# This pad is the reset pin of the ECP5 (SW1_RESET)
# This pad is the reset pin of the ECP5
LOCATE COMP "RESET_BUTTON" SITE "N5";
IOBUF PORT "RESET_BUTTON" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;

Expand Down
26 changes: 15 additions & 11 deletions gateware/boards/ecpix5/sysmgr.v
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@ module sysmgr (
// Assumed 100Mhz for ECPIX-5.
input wire clk_in,
input wire rst_in,
output wire clk_12m,
output wire clk_256fs,
output wire clk_fs,
output wire rst_out
);

// Signals
wire clk_fb;

wire pll_lock;
wire pll_reset;

wire rst_i;

reg [7:0] rst_cnt;
reg [7:0] clkdiv;

assign rst_i = ~rst_cnt[7];
assign rst_out = rst_i;
assign pll_reset = rst_in;
assign clk_fs = clkdiv[7];

`ifndef VERILATOR_LINT_ONLY

Expand Down Expand Up @@ -45,7 +50,7 @@ EHXPLLL #(
.RST(pll_reset),
.STDBY(1'b0),
.CLKI(clk_in),
.CLKOP(clk_12m),
.CLKOP(clk_256fs),
.CLKFB(clk_fb),
.CLKINTFB(clk_fb),
.PHASESEL0(1'b0),
Expand All @@ -60,17 +65,16 @@ EHXPLLL #(

`endif

// PLL reset generation
assign pll_reset = rst_in;
// Logic reset generation
always @(posedge clk_in)
if (!pll_lock)
rst_cnt <= 8'h0;
else if (~rst_cnt[7])
rst_cnt <= rst_cnt + 1;

assign rst_i = ~rst_cnt[7];

assign rst_out = rst_i;
always @(posedge clk_256fs)
if (rst_i)
clkdiv <= 8'h00;
else
clkdiv <= clkdiv + 1;

endmodule // sysmgr
22 changes: 15 additions & 7 deletions gateware/boards/icebreaker/sysmgr.v
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ module sysmgr (
// Actually the output here is the same frequency as the input
// but we leave all this PLL logic here as you might need to scale
// the clock down to 12m on different boards.
output wire clk_12m,
output wire clk_256fs,
output wire clk_fs,
output wire rst_out
);

Expand All @@ -19,7 +20,14 @@ module sysmgr (
wire clk_2x_i;
wire clk_1x_i;
wire rst_i;

reg [7:0] rst_cnt;
reg [7:0] clkdiv;

assign clk_256fs = clk_1x_i;
assign pll_reset_n = ~rst_in;
assign rst_i = rst_cnt[7];
assign clk_fs = clkdiv[7];

// PLL instance
`ifndef VERILATOR_LINT_ONLY
Expand Down Expand Up @@ -50,19 +58,19 @@ module sysmgr (
);
`endif

assign clk_12m = clk_1x_i;

// PLL reset generation
assign pll_reset_n = ~rst_in;

// Logic reset generation
always @(posedge clk_1x_i or negedge pll_lock)
if (!pll_lock)
rst_cnt <= 8'h80;
else if (rst_cnt[7])
rst_cnt <= rst_cnt + 1;

assign rst_i = rst_cnt[7];
always @(posedge clk_256fs)
if (rst_i)
clkdiv <= 8'h00;
else
clkdiv <= clkdiv + 1;


`ifndef VERILATOR_LINT_ONLY
SB_GB rst_gbuf_I (
Expand Down
17 changes: 14 additions & 3 deletions gateware/boards/pico_ice/sysmgr.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@

module sysmgr (
input wire rst_in,
output wire clk_12m,
output wire clk_256fs,
output wire clk_fs,
output wire rst_out
);

wire clk_12m;
wire rst_i;

reg [7:0] rst_cnt = 8'h80;
reg [7:0] clkdiv;

assign clk_256fs = clk_12m;
assign clk_fs = clkdiv[7];
assign rst_i = rst_cnt[7];

`ifndef VERILATOR_LINT_ONLY
// The Pico-Ice V3 examples seem to use the internal ICE40 HFOSC
Expand All @@ -21,14 +28,18 @@ module sysmgr (
);
`endif

// Logic reset generation

always @(posedge clk_12m or posedge rst_in)
if (rst_in)
rst_cnt <= 8'h80;
else if (rst_cnt[7])
rst_cnt <= rst_cnt + 1;

assign rst_i = rst_cnt[7];
always @(posedge clk_256fs)
if (rst_i)
clkdiv <= 8'h00;
else
clkdiv <= clkdiv + 1;

`ifndef VERILATOR_LINT_ONLY
SB_GB rst_gbuf_I (
Expand Down
14 changes: 7 additions & 7 deletions gateware/cal/cal.sv
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ module cal #(
parameter W = 16, // sample width
parameter CAL_MEM_FILE = "cal/cal_mem.hex"
)(
input clk, // 12Mhz
input sample_clk,
input clk_256fs,
input clk_fs,
input [7:0] jack,
input signed [W-1:0] in0,
input signed [W-1:0] in1,
Expand Down Expand Up @@ -59,16 +59,16 @@ logic signed [W-1:0] cal_mem [0:(2*N_CHANNELS)-1];
logic signed [(2*W)-1:0] out [N_CHANNELS];
logic [2:0] ch = 0;
logic [2:0] state = CAL_ST_ZERO;
logic l_sample_clk = 1'd0;
logic l_clk_fs = 1'd0;

// Calibration memory for 8 channels stored as
// 2 bytes shift, 2 bytes multiply * 8 channels.
initial $readmemh(CAL_MEM_FILE, cal_mem);

always_ff @(posedge clk) begin
always_ff @(posedge clk_256fs) begin

// On rising sample_clk.
if (sample_clk && (l_sample_clk != sample_clk)) begin
// On rising clk_fs.
if (clk_fs && (l_clk_fs != clk_fs)) begin
state <= CAL_ST_LATCH;
ch <= 0;
end else begin
Expand Down Expand Up @@ -122,7 +122,7 @@ always_ff @(posedge clk) begin
end
endcase

l_sample_clk <= sample_clk;
l_clk_fs <= clk_fs;
end

`ifdef COCOTB_SIM
Expand Down
2 changes: 1 addition & 1 deletion gateware/cal/debug_uart.sv
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module debug_uart #(
parameter W = 16, // sample width
parameter DIV = 12 // baud rate == CLK / DIV
)(
input clk, // 12Mhz
input clk,
input rst,
output tx_o,
input [7:0] eeprom_mfg,
Expand Down
2 changes: 1 addition & 1 deletion gateware/cores/util/vco/gen_v_oct_lut.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def volts_to_freq(volts, a3_freq_hz=440.0):
"""Convert volts/oct (C3 == +3.0V) to frequency (Hz)."""
return (a3_freq_hz / 8.0) * 2 ** (volts - 3.0/4.0)

def volts_to_delta(volts, wavetable_n_samples=256, sample_rate_hz=93750):
def volts_to_delta(volts, wavetable_n_samples=256, sample_rate_hz=46875):
"""Index delta (fractional) for wavetable per sample clock)."""
return (wavetable_n_samples / sample_rate_hz) * volts_to_freq(volts)

Expand Down
13 changes: 9 additions & 4 deletions gateware/cores/util/vco/gen_wavetable.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@

import math

import matplotlib.pyplot as plt

N = 256

values = []

with open("wavetable.hex", "w") as f:
for i in range(N):
# 3 sine waves and a sawtooth on top of each other.
value = (1.0*math.sin(2*math.pi*i/N) +
0.5*math.sin(4*math.pi*i/N) +
0.3*math.sin(6*math.pi*i/N) +
(0.2*i/N - 0.5))/2)
value = i/N - 0.5
# Scale up to fit inside 16 bit integer and use 2s comp for negative.
value = int((1<<14) * value)
values.append(value)
if value < 0:
value = 0xffff + value
line = "{:04x}\n".format(value)
f.write(line)

plt.plot(values)
plt.show()
Loading

0 comments on commit 052d6b0

Please sign in to comment.