Skip to content

Commit 4cb08a4

Browse files
authored
Merge pull request #8 from edanuff/main
fix high frequency noise by adding IIR filter
2 parents b1f2a52 + 974b9c3 commit 4cb08a4

21 files changed

+13025
-12640
lines changed

boards/a2n20v1/a2n20v1.gprj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@
3434
<File path="../../hdl/memory/a2mem_if.sv" type="file.verilog" enable="1"/>
3535
<File path="../../hdl/memory/apple_memory.sv" type="file.verilog" enable="1"/>
3636
<File path="../../hdl/mockingboard/mockingboard.sv" type="file.verilog" enable="1"/>
37+
<File path="../../hdl/sound/apple_speaker.sv" type="file.verilog" enable="1"/>
38+
<File path="../../hdl/sound/audio_out.v" type="file.verilog" enable="1"/>
3739
<File path="../../hdl/ssc/ssc_rom.vhd" type="file.vhdl" enable="1"/>
3840
<File path="../../hdl/ssc/super_serial_card.sv" type="file.verilog" enable="1"/>
3941
<File path="../../hdl/supersprite/supersprite.sv" type="file.verilog" enable="1"/>
4042
<File path="../../hdl/support/cdc.sv" type="file.verilog" enable="1"/>
43+
<File path="../../hdl/support/iir_filter.v" type="file.verilog" enable="1"/>
4144
<File path="../../hdl/support/sdpram32.sv" type="file.verilog" enable="1"/>
4245
<File path="../../hdl/support/uart_6551.v" type="file.verilog" enable="1"/>
4346
<File path="../../hdl/support/uart_rx.v" type="file.verilog" enable="1"/>

boards/a2n20v1/hdl/top.sv

Lines changed: 47 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -452,68 +452,60 @@ module top #(
452452

453453
assign irq_n_w = (mb_irq_n && vdp_irq_n && ssc_irq_n) || !IRQ_OUT_ENABLE;
454454

455-
// HDMI
455+
// Audio
456+
457+
wire speaker_audio_w;
458+
459+
apple_speaker apple_speaker (
460+
.a2bus_if(a2bus_if),
461+
.enable(APPLE_SPEAKER_ENABLE | sw_apple_speaker_w),
462+
.speaker_o(speaker_audio_w)
463+
);
464+
465+
localparam [31:0] aflt_rate = 7_056_000;
466+
localparam [39:0] acx = 4258969;
467+
localparam [7:0] acx0 = 3;
468+
localparam [7:0] acx1 = 3;
469+
localparam [7:0] acx2 = 1;
470+
localparam [23:0] acy0 = -24'd6216759;
471+
localparam [23:0] acy1 = 24'd6143386;
472+
localparam [23:0] acy2 = -24'd2023767;
456473

457474
localparam AUDIO_RATE = 44100;
458475
localparam AUDIO_BIT_WIDTH = 16;
459-
localparam AUDIO_CLK_COUNT = (CLOCK_SPEED_HZ / 2) / AUDIO_RATE;
460-
logic [$clog2(AUDIO_CLK_COUNT)-1:0] audio_counter_r;
461-
logic clk_audio_r;
462-
463-
always_ff @(posedge clk_pixel_w)
464-
begin
465-
audio_counter_r <= (audio_counter_r == AUDIO_CLK_COUNT) ? 1'd0 : audio_counter_r + 1'd1;
466-
clk_audio_r <= audio_counter_r == AUDIO_CLK_COUNT;
467-
end
468-
469-
reg speaker_bit;
470-
always @(posedge clk_logic_w or negedge system_reset_n_w) begin
471-
if (!system_reset_n_w) begin
472-
speaker_bit <= 1'b0;
473-
end else if (phi1_posedge && (a2bus_if.addr[15:0] == 16'hC030) && !a2bus_if.m2sel_n)
474-
speaker_bit <= !speaker_bit;
475-
end
476+
wire clk_audio_w;
477+
wire [15:0] audio_sample_word[1:0];
478+
audio_out #(
479+
.CLK_RATE(CLOCK_SPEED_HZ / 2),
480+
.AUDIO_RATE(AUDIO_RATE)
481+
) audio_out
482+
(
483+
.reset(~device_reset_n_w),
484+
.clk(clk_pixel_w),
485+
486+
.flt_rate(aflt_rate),
487+
.cx(acx),
488+
.cx0(acx0),
489+
.cx1(acx1),
490+
.cx2(acx2),
491+
.cy0(acy0),
492+
.cy1(acy1),
493+
.cy2(acy2),
494+
495+
.is_signed(1'b0),
496+
.core_l(ssp_audio_w + {mb_audio_l, 5'b00} + {speaker_audio_w, 13'b0}),
497+
.core_r(ssp_audio_w + {mb_audio_r, 5'b00} + {speaker_audio_w, 13'b0}),
498+
499+
.audio_clk(clk_audio_w),
500+
.audio_l(audio_sample_word[0]),
501+
.audio_r(audio_sample_word[1])
502+
);
476503

477-
// Apple intermal audio toggles a +5V signal to a speaker. We cannot simply leave a square wave
478-
// indefinitaley on the HDMI audio line, so we need to generate a pulse of a maximum length.
479-
// If we don't do this, the HDMI audio line will essentially have an amplitude offset, which
480-
// will cause the HDMI receiver to clip the audio or amplify anything such as the Mockingboard
481-
// audio that is added to it.
482-
483-
reg speaker_audio;
484-
reg [7:0] speaker_audio_counter;
485-
reg prev_speaker_bit;
486-
487-
always_ff @(posedge clk_pixel_w) begin
488-
if (clk_audio_r) begin
489-
if (speaker_bit != prev_speaker_bit) begin
490-
speaker_audio_counter <= 8'b11111111;
491-
end else if (speaker_audio_counter != 0) begin
492-
speaker_audio_counter <= speaker_audio_counter - 8'd1;
493-
end
494-
prev_speaker_bit <= speaker_bit;
495-
496-
if (prev_speaker_bit && (speaker_audio_counter != 0)) begin
497-
speaker_audio <= APPLE_SPEAKER_ENABLE | sw_apple_speaker_w;
498-
end else begin
499-
speaker_audio <= 1'b0;
500-
end
501-
end
502-
end
504+
// HDMI
503505

504-
////
505506
logic [2:0] tmds;
506507
wire tmdsClk;
507508

508-
//wire [15:0] sample = {ssp_psg_mix_audio_o, 2'b00};
509-
reg [15:0] audio_sample_word[1:0], audio_sample_word0[1:0];
510-
always @(posedge clk_pixel_w) begin // crossing clock domain
511-
audio_sample_word0[0] <= ssp_audio_w + {mb_audio_l, 4'b00} + {speaker_audio, 13'b0};
512-
audio_sample_word[0] <= audio_sample_word0[0];
513-
audio_sample_word0[1] <= ssp_audio_w + {mb_audio_r, 4'b00} + {speaker_audio, 13'b0};
514-
audio_sample_word[1] <= audio_sample_word0[1];
515-
end
516-
517509
wire scanline_en = scanlines_w && hdmi_y[0];
518510

519511
hdmi #(
@@ -531,7 +523,7 @@ module top #(
531523
) hdmi (
532524
.clk_pixel_x5(clk_hdmi_w),
533525
.clk_pixel(clk_pixel_w),
534-
.clk_audio(clk_audio_r),
526+
.clk_audio(clk_audio_w),
535527
.rgb({
536528
scanline_en ? {1'b0, rgb_r_w[7:1]} : rgb_r_w,
537529
scanline_en ? {1'b0, rgb_g_w[7:1]} : rgb_g_w,

boards/a2n20v1/impl/pnr/a2n20v1.fs

Lines changed: 1544 additions & 1544 deletions
Large diffs are not rendered by default.

boards/a2n20v1/impl/pnr/a2n20v1.pin.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ <h1><a name="Message">Pin Messages</a></h1>
5050
</tr>
5151
<tr>
5252
<td class="label">Design File</td>
53-
<td>D:\Gowin\Projects\a2fpga_core\boards\a2n20v1\impl\gwsynthesis\a2n20v1.vg</td>
53+
<td>C:\Users\ed\GitHub\a2fpga_core\boards\a2n20v1\impl\gwsynthesis\a2n20v1.vg</td>
5454
</tr>
5555
<tr>
5656
<td class="label">Physical Constraints File</td>
57-
<td>D:\Gowin\Projects\a2fpga_core\boards\a2n20v1\hdl\a2n20v1.cst</td>
57+
<td>C:\Users\ed\GitHub\a2fpga_core\boards\a2n20v1\hdl\a2n20v1.cst</td>
5858
</tr>
5959
<tr>
6060
<td class="label">Timing Constraints File</td>
61-
<td>D:\Gowin\Projects\a2fpga_core\boards\a2n20v1\hdl\a2n20v1.sdc</td>
61+
<td>C:\Users\ed\GitHub\a2fpga_core\boards\a2n20v1\hdl\a2n20v1.sdc</td>
6262
</tr>
6363
<tr>
6464
<td class="label">Version</td>
@@ -78,7 +78,7 @@ <h1><a name="Message">Pin Messages</a></h1>
7878
</tr>
7979
<tr>
8080
<td class="label">Created Time</td>
81-
<td>Mon Feb 19 17:41:03 2024
81+
<td>Thu Apr 25 19:11:25 2024
8282
</td>
8383
</tr>
8484
<tr>

0 commit comments

Comments
 (0)