aboutsummaryrefslogtreecommitdiffstats
path: root/sound.v
diff options
context:
space:
mode:
authorhpa <hpa@trantor.hos.anvin.org>2008-12-22 15:46:11 -0800
committerhpa <hpa@trantor.hos.anvin.org>2008-12-22 15:46:11 -0800
commit0d42337dfa2a3db9da5e1ae08654b4649bfcf770 (patch)
treed00d1bee0e6fd5554430fd23d757e56e62db2be3 /sound.v
parentdba2fb4c9ea7251ea22c36f36c5be035d94f1091 (diff)
downloadabc80-0d42337dfa2a3db9da5e1ae08654b4649bfcf770.tar.gz
abc80-0d42337dfa2a3db9da5e1ae08654b4649bfcf770.tar.xz
abc80-0d42337dfa2a3db9da5e1ae08654b4649bfcf770.zip
Make the sound generator work
Make the sound generator work. However, the clock frequency change (25 MHz to 16 MHz, needed for I2S output) seems to have gotten the pitches wrong.
Diffstat (limited to 'sound.v')
-rw-r--r--sound.v142
1 files changed, 77 insertions, 65 deletions
diff --git a/sound.v b/sound.v
index 5bd4d0f..a95d651 100644
--- a/sound.v
+++ b/sound.v
@@ -14,14 +14,15 @@
// Decay = 470 ms
+`define vco_min 14'd1024
+`define vco_max 14'd12499
+
// Model the 76477 SLF. This returns a "sawtooth" value
-// between (approximately) [1024,12288) which gives about
+// between (approximately) [1024,12499] which gives about
// the 10:1 range needed by the VCO.
-`define vco_min 14'd1024
-`define vco_max 14'd12288
module slf(
- input clk, // 25 MHz
+ input clk, // 16 MHz
input clk_en, // One pulse every 16 us (62.5 kHz)
output slf, // SLF squarewave
output [13:0] saw // Sawtooth magnitude
@@ -35,9 +36,9 @@ module slf(
always @(posedge clk)
if ( clk_en )
begin
- if ( ctr[13:10] == 4'b1100 )
+ if ( ctr[13:10] == `vco_max )
up <= 0;
- else if ( ctr[13:10] == 4'b0000 )
+ else if ( ctr[13:10] == `vco_min )
up <= 1;
if ( up )
@@ -51,12 +52,12 @@ endmodule // slf
// The VCO. The output frequency = clk/pitch/2.
//
module vco(
- input clk, // 25 MHz
+ input clk, // 16 MHz
input [13:0] pitch, // Pitch control
output vco, // VCO squarewave output
output vco2 // VCO output with every other pulse suppressed
);
- reg [14:0] ctr = 0;
+ reg [13:0] ctr = 0;
reg [1:0] cycle;
assign vco = cycle[0];
@@ -66,7 +67,7 @@ module vco(
begin
if ( ctr == 0 )
begin
- ctr <= { pitch, 1'b0 };
+ ctr <= pitch;
cycle <= cycle + 1;
end
else
@@ -79,7 +80,7 @@ endmodule // vco
// which should be inaudible.
//
module noise(
- input clk, // 25 MHz
+ input clk, // 16 MHz
input clk_en, // One pulse every 16 us (62.5 kHz)
output noise
);
@@ -139,7 +140,7 @@ endmodule // mixer
// Output is parallel digital.
//
module oneshot(
- input clk, // 25 MHz
+ input clk, // 16 MHz
input clk_en, // One pulse every 16 us (62.5 kHz)
input inhibit,
output reg oneshot
@@ -187,7 +188,7 @@ module envelope_select(
endmodule // envelope_select
module envelope_shape(
- input clk, // 25 MHz
+ input clk, // 16 MHz
input clk_en, // One pulse every 16 us (62.5 kHz)
input envelope,
output reg [13:0] env_mag
@@ -210,36 +211,11 @@ module envelope_shape(
endmodule // envelope_shape
//
-// Delta-sigma DAC for the final output
-//
-module dac(
- input [13:0] magnitude,
- input clk, // The higher the better
- output signal
- );
- reg [13:0] mag_latch = 0;
- reg [15:0] sigma_latch = 0;
-
- assign signal = sigma_latch[15];
-
- wire [15:0] delta_add = { sigma_latch[15], sigma_latch[15], mag_latch };
- wire [15:0] sigma_add = delta_add + sigma_latch;
-
-
- always @(posedge clk)
- begin
- mag_latch <= magnitude;
- sigma_latch <= sigma_add;
- end
-endmodule // dac
-
-//
// Putting it all together...
//
module sound_generator(
- input ctr_16us,
- input clk_fast,
- input clk_25MHz,
+ input clk,
+ input stb_16us,
input [2:0] mixer_ctl,
input vco_sel,
@@ -247,8 +223,7 @@ module sound_generator(
input [1:0] envsel,
input inhibit,
- output signal,
- output [7:0] debug
+ output [13:0] magnitude
);
wire w_slf;
wire [13:0] saw;
@@ -262,33 +237,22 @@ module sound_generator(
wire [13:0] env_mag;
wire signal_on;
- wire [13:0] magnitude;
-
- reg ctr_16us_1;
- reg clk_en;
- // ctr_16us should be synchronous with clk_25MHz.
- // We set clk_en to 1 for one cycle every positive edge of ctr_16us.
-
- always @(posedge clk_25MHz)
- begin
- ctr_16us_1 <= ctr_16us;
- clk_en <= ctr_16us & ~ctr_16us_1;
- end
-
- slf slf ( .clk (clk_25MHz),
+ assign clk_en = stb_16us;
+
+ slf slf ( .clk (clk),
.clk_en (clk_en),
.saw (saw),
.slf (w_slf) );
assign vco_level = vco_sel ? saw : vco_pitch ? `vco_max : `vco_min;
- vco vco ( .clk (clk_25MHz),
+ vco vco ( .clk (clk),
.pitch (vco_level),
.vco (w_vco),
.vco2 (w_vco2) );
- noise noise ( .clk (clk_25MHz),
+ noise noise ( .clk (clk),
.clk_en (clk_en),
.noise (w_noise) );
@@ -301,7 +265,7 @@ module sound_generator(
.mixer_out (w_mixer_out) );
- oneshot oneshot ( .clk (clk_25MHz),
+ oneshot oneshot ( .clk (clk),
.clk_en (clk_en),
.inhibit (inhibit),
.oneshot (w_oneshot) );
@@ -312,19 +276,67 @@ module sound_generator(
.vco2 (w_vco2),
.envelope (w_envelope) );
- envelope_shape envelope_shape ( .clk (clk_25MHz),
+ envelope_shape envelope_shape ( .clk (clk),
.clk_en (clk_en),
.envelope (w_envelope),
.env_mag (env_mag) );
assign signal_on = ~inhibit & w_mixer_out;
- assign magnitude = signal_on ? env_mag : 0;
+ assign magnitude = env_mag & {14{signal_on}};
- dac dac ( .magnitude (magnitude),
- .clk (clk_fast),
- .signal (signal) );
+endmodule // sound_generator
- assign debug = { w_noise, w_slf, w_vco, w_vco2, w_oneshot, w_envelope, w_mixer_out, signal_on };
+//
+// I2S output module - outputs 256 clocks/frame
+//
+module sound_i2s(
+ input i2s_clk, // 16 MHz
+
+ input [2:0] mixer_ctl,
+ input vco_sel,
+ input vco_pitch,
+ input [1:0] envsel,
+ input inhibit,
+
+ output i2s_dat,
+ output i2s_lrck
+ );
+
+ reg [7:0] ctr;
+ wire [13:0] magnitude;
+ reg [13:0] sample;
+ reg [13:0] serial_out;
-endmodule // sound_generator
+ wire stb_16us = &ctr;
+
+ assign i2s_dat = serial_out[13];
+ assign i2s_lrck = ctr[7];
+
+ always @(posedge i2s_clk)
+ ctr <= ctr + 1;
+
+ always @(posedge i2s_clk)
+ if (stb_16us)
+ sample <= magnitude;
+
+ always @(posedge i2s_clk)
+ if (ctr[6:0] == 7'h00)
+ serial_out <= sample;
+ else
+ serial_out <= { serial_out[12:0], 1'b0 };
+
+ sound_generator sound_generator (
+ .clk (i2s_clk),
+ .stb_16us (stb_16us),
+
+ .mixer_ctl (mixer_ctl),
+ .vco_sel (vco_sel),
+ .vco_pitch (vco_pitch),
+ .envsel (envsel),
+ .inhibit (inhibit),
+
+ .magnitude (magnitude)
+ );
+
+endmodule // sound_i2s