Skip to content

Commit 62f78b5

Browse files
authored
Merge pull request #15 from edanuff/main
merge enhanced build cleanup
2 parents 4ceb216 + 974d0e6 commit 62f78b5

9 files changed

+6503
-7202
lines changed

boards/a2n20v2-Enhanced/a2n20v2_enhanced.gprj

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
<Device name="GW2AR-18C" pn="GW2AR-LV18QN88C8/I7">gw2ar18c-000</Device>
77
<FileList>
88
<File path="../../hdl/bus/a2bus_if.sv" type="file.verilog" enable="1"/>
9+
<File path="../../hdl/disk/apple_disk.sv" type="file.verilog" enable="1"/>
10+
<File path="../../hdl/disk/drive_ii.sv" type="file.verilog" enable="1"/>
11+
<File path="../../hdl/disk/drive_volume_if.sv" type="file.verilog" enable="1"/>
912
<File path="../../hdl/f18a/f18a_color.vhd" type="file.vhdl" enable="1"/>
1013
<File path="../../hdl/f18a/f18a_core.vhd" type="file.vhdl" enable="1"/>
1114
<File path="../../hdl/f18a/f18a_counters.vhd" type="file.vhdl" enable="1"/>
@@ -32,6 +35,20 @@
3235
<File path="../../hdl/hdmi/tmds_channel.sv" type="file.verilog" enable="1"/>
3336
<File path="../../hdl/memory/a2mem_if.sv" type="file.verilog" enable="1"/>
3437
<File path="../../hdl/mockingboard/mockingboard.sv" type="file.verilog" enable="1"/>
38+
<File path="../../hdl/picosoc/picorv32/picorv32.v" type="file.verilog" enable="1"/>
39+
<File path="../../hdl/picosoc/peripherals/a2fpga/picosoc_a2fpga.sv" type="file.verilog" enable="1"/>
40+
<File path="../../hdl/picosoc/peripherals/gpio/picosoc_gpio.sv" type="file.verilog" enable="1"/>
41+
<File path="../../hdl/picosoc/peripherals/sdcard/picosoc_sdcard.sv" type="file.verilog" enable="1"/>
42+
<File path="../../hdl/picosoc/peripherals/sdcard/spi_master.v" type="file.verilog" enable="1"/>
43+
<File path="../../hdl/picosoc/peripherals/sdram/fast_cache.sv" type="file.verilog" enable="1"/>
44+
<File path="../../hdl/picosoc/peripherals/sdram/picosoc_sdram.sv" type="file.verilog" enable="1"/>
45+
<File path="../../hdl/picosoc/peripherals/sram/picosoc_sram.sv" type="file.verilog" enable="1"/>
46+
<File path="../../hdl/picosoc/peripherals/uart/picosoc_uart.sv" type="file.verilog" enable="1"/>
47+
<File path="../../hdl/picosoc/peripherals/uart/simpleuart.v" type="file.verilog" enable="1"/>
48+
<File path="../../hdl/picosoc/firmware.hex" type="file.other" enable="1"/>
49+
<File path="../../hdl/picosoc/picosoc.sv" type="file.verilog" enable="1"/>
50+
<File path="../../hdl/sound/apple_speaker.sv" type="file.verilog" enable="1"/>
51+
<File path="../../hdl/sound/audio_out.v" type="file.verilog" enable="1"/>
3552
<File path="../../hdl/sdram/sdram_if_mux.sv" type="file.verilog" enable="1"/>
3653
<File path="../../hdl/sdram/sdram_port_if.sv" type="file.verilog" enable="1"/>
3754
<File path="../../hdl/sdram/sdram_ports.sv" type="file.verilog" enable="1"/>
@@ -44,9 +61,13 @@
4461
<File path="../../hdl/supersprite/supersprite.sv" type="file.verilog" enable="1"/>
4562
<File path="../../hdl/support/cdc.sv" type="file.verilog" enable="1"/>
4663
<File path="../../hdl/support/clock_enable_counter.sv" type="file.verilog" enable="1"/>
64+
<File path="../../hdl/support/countdown.sv" type="file.verilog" enable="1"/>
65+
<File path="../../hdl/support/iir_filter.v" type="file.verilog" enable="1"/>
4766
<File path="../../hdl/support/pulse_crossing.v" type="file.verilog" enable="1"/>
67+
<File path="../../hdl/support/rom.v" type="file.verilog" enable="1"/>
4868
<File path="../../hdl/support/sdpram32.sv" type="file.verilog" enable="1"/>
4969
<File path="../../hdl/support/srff.v" type="file.verilog" enable="1"/>
70+
<File path="../../hdl/support/timer.sv" type="file.verilog" enable="1"/>
5071
<File path="../../hdl/support/uart_6551.v" type="file.verilog" enable="1"/>
5172
<File path="../../hdl/support/uart_rx.v" type="file.verilog" enable="1"/>
5273
<File path="../../hdl/support/uart_tx.v" type="file.verilog" enable="1"/>

boards/a2n20v2-Enhanced/hdl/memory/apple_memory.sv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// 2N20v2_enhanced - Tang Nano 20K SDRAM implementation of Apple II memory
1+
// A2N20v2_enhanced - Tang Nano 20K SDRAM implementation of Apple II memory
22
//
33
// (c) 2023,2024 Ed Anuff <ed@a2fpga.com>
44
//

boards/a2n20v2-Enhanced/hdl/top.sv

Lines changed: 120 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,30 @@
33
//
44
// This version uses the Tang Nano 20K SDRAM for extended functionality
55
//
6+
// (c) 2023,2024 Ed Anuff <ed@a2fpga.com>
7+
//
8+
// Permission to use, copy, modify, and/or distribute this software for any
9+
// purpose with or without fee is hereby granted, provided that the above
10+
// copyright notice and this permission notice appear in all copies.
11+
//
12+
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13+
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14+
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15+
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16+
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17+
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18+
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19+
//
620

721
// Using the Gowin IDE
822
`define GW_IDE
923

10-
// Ensoniq and PicoSoC are included via defines in the top module
24+
// Ensoniq, PicoSoC, and DiskII are included via defines in the top module
25+
// Disk II requires PicoSoC
1126

1227
`undef ENSONIQ
13-
`undef PICOSOC
28+
`define PICOSOC
29+
`undef DISKII
1430

1531
module top #(
1632
parameter int CLOCK_SPEED_HZ = 54_000_000,
@@ -29,6 +45,9 @@ module top #(
2945
parameter bit SUPERSERIAL_ENABLE = 0,
3046
parameter SUPERSERIAL_SLOT = 2,
3147

48+
parameter bit DISK_II_ENABLE = 1,
49+
parameter DISK_II_SLOT = 5,
50+
3251
parameter bit ENSONIQ_ENABLE = 1,
3352

3453
parameter bit CLEAR_APPLE_VIDEO_RAM = 1, // Clear video ram on startup
@@ -160,13 +179,31 @@ module top #(
160179
`ifdef ENSONIQ
161180
localparam GLU_MEM_PORT = 2;
162181
localparam DOC_MEM_PORT = 3;
163-
`endif
164-
165-
`ifdef ENSONIQ
182+
`ifdef PICOSOC
183+
localparam SOC_MEM_PORT = 4;
184+
`ifdef DISKII
185+
localparam RAMDISK_MEM_PORT = 5;
186+
localparam NUM_PORTS = 6;
187+
`else
188+
localparam NUM_PORTS = 5;
189+
`endif
190+
`else
166191
localparam NUM_PORTS = 4;
192+
`endif
167193
`else
194+
`ifdef PICOSOC
195+
localparam SOC_MEM_PORT = 2;
196+
`ifdef DISKII
197+
localparam RAMDISK_MEM_PORT = 3;
198+
localparam NUM_PORTS = 4;
199+
`else
200+
localparam NUM_PORTS = 3;
201+
`endif
202+
`else
168203
localparam NUM_PORTS = 2;
204+
`endif
169205
`endif
206+
170207
localparam PORT_ADDR_WIDTH = 21;
171208
localparam DATA_WIDTH = 32;
172209
localparam DQM_WIDTH = 4;
@@ -372,6 +409,8 @@ module top #(
372409
wire [7:0] diskii_d_w;
373410
wire diskii_rd;
374411

412+
`ifdef DISKII
413+
375414
DiskII #(
376415
.ENABLE(DISK_II_ENABLE),
377416
.SLOT(DISK_II_SLOT)
@@ -385,6 +424,25 @@ module top #(
385424

386425
.volumes(volumes)
387426
);
427+
`else
428+
assign diskii_d_w = 8'b0;
429+
assign diskii_rd = 1'b0;
430+
431+
assign volumes[0].active = 1'b0;
432+
assign volumes[0].lba = 32'd0;
433+
assign volumes[0].blk_cnt = 6'd0;
434+
assign volumes[0].rd = 1'b0;
435+
assign volumes[0].wr = 1'b0;
436+
437+
438+
assign volumes[1].active = 1'b0;
439+
assign volumes[1].lba = 32'd0;
440+
assign volumes[1].blk_cnt = 6'd0;
441+
assign volumes[1].rd = 1'b0;
442+
assign volumes[1].wr = 1'b0;
443+
444+
`endif
445+
388446

389447
`else
390448

@@ -420,6 +478,10 @@ module top #(
420478
assign f18a_gpu_if.raddr = 13'b0;
421479
assign f18a_gpu_if.gstatus = 7'b0;
422480

481+
482+
wire [7:0] diskii_d_w = 8'b0;
483+
wire diskii_rd = 1'b0;
484+
423485
`endif
424486

425487
// Video
@@ -593,8 +655,10 @@ module top #(
593655

594656
wire ssc_uart_rx;
595657
wire ssc_uart_tx;
658+
`ifndef PICOSOC
596659
assign ssc_uart_rx = uart_rx;
597660
assign uart_tx = ssc_uart_tx;
661+
`endif
598662

599663
SuperSerial #(
600664
.ENABLE(SUPERSERIAL_ENABLE),
@@ -614,83 +678,72 @@ module top #(
614678

615679
// Data output
616680

617-
assign data_out_en_w = ssp_rd || mb_rd || ssc_rd;
681+
assign data_out_en_w = ssp_rd || mb_rd || ssc_rd || diskii_rd;
618682

619683
assign data_out_w = ssc_rd ? ssc_d_w :
620684
ssp_rd ? ssp_d_w :
621685
mb_rd ? mb_d_w :
686+
diskii_rd ? diskii_d_w :
622687
a2bus_if.data;
623688

624689
// Interrupts
625690

626691
assign irq_n_w = mb_irq_n && vdp_irq_n && ssc_irq_n;
627692

628-
// HDMI
693+
// Audio
694+
695+
wire speaker_audio_w;
696+
697+
apple_speaker apple_speaker (
698+
.a2bus_if(a2bus_if),
699+
.enable(APPLE_SPEAKER_ENABLE | sw_apple_speaker_w),
700+
.speaker_o(speaker_audio_w)
701+
);
629702

630-
// TODO - Needs to incorporate the audio filter code from a2n20v2
631-
// IMPORTANT - the Ensoniq module outputs signed 16-bit audio, so we need to
632-
// properly mix it with the apple audio and the mockingboard audio
703+
localparam [31:0] aflt_rate = 7_056_000;
704+
localparam [39:0] acx = 4258969;
705+
localparam [7:0] acx0 = 3;
706+
localparam [7:0] acx1 = 3;
707+
localparam [7:0] acx2 = 1;
708+
localparam [23:0] acy0 = -24'd6216759;
709+
localparam [23:0] acy1 = 24'd6143386;
710+
localparam [23:0] acy2 = -24'd2023767;
633711

634712
localparam AUDIO_RATE = 44100;
635713
localparam AUDIO_BIT_WIDTH = 16;
636-
localparam AUDIO_CLK_COUNT = (CLOCK_SPEED_HZ / 2) / AUDIO_RATE;
637-
logic [$clog2(AUDIO_CLK_COUNT)-1:0] audio_counter_r;
638-
logic clk_audio_r;
639-
640-
always_ff @(posedge clk_pixel_w)
641-
begin
642-
audio_counter_r <= (audio_counter_r == AUDIO_CLK_COUNT) ? 1'd0 : audio_counter_r + 1'd1;
643-
clk_audio_r <= audio_counter_r == AUDIO_CLK_COUNT;
644-
end
645-
646-
reg speaker_bit;
647-
always @(posedge clk_logic_w or negedge system_reset_n_w) begin
648-
if (!system_reset_n_w) begin
649-
speaker_bit <= 1'b0;
650-
end else if (phi1_posedge && (a2bus_if.addr[15:0] == 16'hC030) && !a2bus_if.m2sel_n)
651-
speaker_bit <= !speaker_bit;
652-
end
714+
wire clk_audio_w;
715+
wire [15:0] audio_sample_word[1:0];
716+
audio_out #(
717+
.CLK_RATE(CLOCK_SPEED_HZ / 2),
718+
.AUDIO_RATE(AUDIO_RATE)
719+
) audio_out
720+
(
721+
.reset(~device_reset_n_w),
722+
.clk(clk_pixel_w),
723+
724+
.flt_rate(aflt_rate),
725+
.cx(acx),
726+
.cx0(acx0),
727+
.cx1(acx1),
728+
.cx2(acx2),
729+
.cy0(acy0),
730+
.cy1(acy1),
731+
.cy2(acy2),
732+
733+
.is_signed(1'b0),
734+
.core_l(ssp_audio_w + {mb_audio_l, 5'b00} + {speaker_audio_w, 13'b0}),
735+
.core_r(ssp_audio_w + {mb_audio_r, 5'b00} + {speaker_audio_w, 13'b0}),
736+
737+
.audio_clk(clk_audio_w),
738+
.audio_l(audio_sample_word[0]),
739+
.audio_r(audio_sample_word[1])
740+
);
653741

654-
// Apple intermal audio toggles a +5V signal to a speaker. We cannot simply leave a square wave
655-
// indefinitaley on the HDMI audio line, so we need to generate a pulse of a maximum length.
656-
// If we don't do this, the HDMI audio line will essentially have an amplitude offset, which
657-
// will cause the HDMI receiver to clip the audio or amplify anything such as the Mockingboard
658-
// audio that is added to it.
659-
660-
reg speaker_audio;
661-
reg [7:0] speaker_audio_counter;
662-
reg prev_speaker_bit;
663-
664-
always_ff @(posedge clk_pixel_w) begin
665-
if (clk_audio_r) begin
666-
if (speaker_bit != prev_speaker_bit) begin
667-
speaker_audio_counter <= 8'b11111111;
668-
end else if (speaker_audio_counter != 0) begin
669-
speaker_audio_counter <= speaker_audio_counter - 8'd1;
670-
end
671-
prev_speaker_bit <= speaker_bit;
672-
673-
if (prev_speaker_bit && (speaker_audio_counter != 0)) begin
674-
speaker_audio <= APPLE_SPEAKER_ENABLE | sw_apple_speaker_w;
675-
end else begin
676-
speaker_audio <= 1'b0;
677-
end
678-
end
679-
end
742+
// HDMI
680743

681-
////
682744
logic [2:0] tmds;
683745
wire tmdsClk;
684746

685-
//wire [15:0] sample = {ssp_psg_mix_audio_o, 2'b00};
686-
reg [15:0] audio_sample_word[1:0], audio_sample_word0[1:0];
687-
always @(posedge clk_pixel_w) begin // crossing clock domain
688-
audio_sample_word0[0] <= ssp_audio_w + {mb_audio_l, 4'b00} + {speaker_audio, 13'b0} + sg_audio_l;
689-
audio_sample_word[0] <= audio_sample_word0[0];
690-
audio_sample_word0[1] <= ssp_audio_w + {mb_audio_r, 4'b00} + {speaker_audio, 13'b0} + sg_audio_r;
691-
audio_sample_word[1] <= audio_sample_word0[1];
692-
end
693-
694747
wire scanline_en = scanlines_w && hdmi_y[0];
695748

696749
hdmi #(
@@ -708,7 +761,7 @@ module top #(
708761
) hdmi (
709762
.clk_pixel_x5(clk_hdmi_w),
710763
.clk_pixel(clk_pixel_w),
711-
.clk_audio(clk_audio_r),
764+
.clk_audio(clk_audio_w),
712765
.rgb({
713766
scanline_en ? {1'b0, rgb_r_w[7:1]} : rgb_r_w,
714767
scanline_en ? {1'b0, rgb_g_w[7:1]} : rgb_g_w,
@@ -735,7 +788,9 @@ module top #(
735788
);
736789

737790
always @(posedge clk_logic_w) begin
738-
if (!s2) led <= {!a2mem_if.TEXT_MODE, !a2mem_if.MIXED_MODE, !a2mem_if.HIRES_MODE, !a2mem_if.AN3, !a2mem_if.STORE80};
791+
if (!s2) led <= {!a2mem_if.TEXT_MODE, !a2mem_if.SHRG_MODE, !a2mem_if.HIRES_MODE, !a2mem_if.RAMWRT, !a2mem_if.STORE80};
792+
//if (!s2) led <= {!a2mem_if.TEXT_MODE, !a2mem_if.MIXED_MODE, !a2mem_if.HIRES_MODE, !a2mem_if.RAMWRT, !a2mem_if.STORE80};
793+
//if (!s2) led <= {!a2mem_if.TEXT_MODE, !a2mem_if.MIXED_MODE, !a2mem_if.HIRES_MODE, !a2mem_if.AN3, !a2mem_if.STORE80};
739794
else led <= {!vdp_unlocked_w, ~vdp_gmode_w};
740795
//else led <= {!vdp_unlocked_w, dip_switches_n_w};
741796
end

0 commit comments

Comments
 (0)