module spectrum(output wire[7:0] LED, output wire[33:0] GPIO_0, input wire CLOCK_50, // Input clock 50 MHz input wire[1:0] KEY, // 0 = RESET button; active low, 1 = NMI button input wire PS2_CLK, input wire PS2_DAT, inout wire I2C_SCLK, inout wire I2C_SDAT, output wire AUD_XCK, output wire AUD_ADCLRCK, output wire AUD_DACLRCK, output wire AUD_BCLK, output wire AUD_DACDAT, input wire AUD_ADCDAT, output wire [3:0] VGA_R, output wire [3:0] VGA_G, output wire [3:0] VGA_B, output reg VGA_HS, output reg VGA_VS, input wire[3:0] SW, // 0 = ROM selection, 1 = enable/disable interrupts, 2 = turbo speed output wire[33:0] GPIO_1 // Exports CPU chip pins ); `default_nettype none wire reset; wire locked; assign reset = locked & KEY[0:0]; // Export selected pins to the extension connector assign GPIO_1[15:0] = A[15:0]; assign GPIO_1[23:16] = D[7:0]; assign GPIO_1[31:24] = {nM1,nMREQ,nIORQ,nRD,nWR,nRFSH,nHALT,nBUSACK}; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Internal buses and address map selection logic //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ wire [15:0] A; // Global address bus wire [7:0] D; // CPU data bus wire [7:0] ram_data; // Internal 16K RAM data wire RamWE; assign RamWE = A[15:14]==2'b01 && nIORQ==1 && nRD==1 && nWR==0; wire ExtRamWE; // Extended (and external) 32K RAM assign ExtRamWE = A[15]==1 && nIORQ==1 && nRD==1 && nWR==0; wire [7:0] ula_data; // ULA wire io_we; assign io_we = nIORQ==0 && nRD==1 && nWR==0; // Memory map: // 0000 - 3FFF 16K ROM (mapped to rom0) // 4000 - 7FFF 16K dual-port ram0 // 8000 - FFFF 32K RAM (mapped to ram1) always @(*) // always_comb begin case ({nIORQ,nRD,nWR}) // -------------------------------- Memory read -------------------------------- 3'b101: begin casez (A[15:14]) 2'b00: D[7:0] = rom_data; 2'b01: D[7:0] = ram0_data; 2'b1?: D[7:0] = ram1_data; endcase end // ---------------------------------- IO read ---------------------------------- 3'b001: begin // Normally data supplied by the ULA D[7:0] = ula_data; // Kempston joystick at the IO address 0x1F; active bits are high: // FIRE UP DOWN LEFT RIGHT // if (A[7:0]==8'h1F) begin // D[7:0] = { 3'b0, !kempston[4],!kempston[0],!kempston[1],!kempston[2],!kempston[3] }; // end end default: D[7:0] = {8{1'bz}}; endcase end // ---------------------------------------------------- // Instantiate ROM, 16K // ---------------------------------------------------- wire[7:0] rom_data; rom0 rom( .clock(clk_cpu), .address(A), .q(rom_data) ); // ---------------------------------------------------- // Instantiate RAM0, 16K, dual port // ---------------------------------------------------- wire clk_vram; wire[7:0] ram0_data; // "A" port is the CPU side, "B" port is the VGA image generator in the ULA ram16 ram0( .clock(clk_vram), .address_a(A[13:0]), .data_a(D), .q_a(ram0_data), .wren_a(RamWE), .address_b({1'b0, vram_address}), .data_b(8'b0), .q_b(vram_data), .wren_b(0) ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Rest of RAM, 32K //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ wire[7:0] ram1_data; ram32 ram1( .clock(clk_cpu), .address(A[14:0]), .data(D), .q(ram1_data), .wren(0) ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Instantiate ULA //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ wire clk_cpu; // Global CPU clock of 3.5 MHz assign LED[2:2] = SW[2:2]; // Glow red when in turbo mode (7.0 MHz) wire [12:0] vram_address; // ULA video block requests a byte from the video RAM wire [7:0] vram_data; // ULA video block reads a byte from the video RAM wire vs_nintr; // Generates a vertical retrace interrupt wire pressed; // Show that a key is being pressed wire beeper; // Show the beeper state ula ula_( //-------- Clocks and reset ----------------- .CLOCK_50 (CLOCK_50), // Input clock 50 MHz .turbo (SW[2:2]), // Turbo speed (3.5 MHz x 2 = 7.0 MHz) .clk_vram (clk_vram), .nreset (reset), // KEY0 is reset; on DE1, keys are active low! .locked (locked), // PLL is locked signal //-------- CPU control ---------------------- .clk_cpu (clk_cpu), // Generates CPU clock of 3.5 MHz .vs_nintr (vs_nintr), // Generates a vertical retrace interrupt //-------- Address and data buses ----------- .A (A), // Input address bus .D (D), // Input data bus .ula_data (ula_data), // Output data .io_we (io_we), // Write enable to data register through IO .vram_address (vram_address),// ULA video block requests a byte from the video RAM .vram_data (vram_data), // ULA video block reads a byte from the video RAM //-------- PS/2 Keyboard -------------------- .PS2_CLK (PS2_CLK), .PS2_DAT (PS2_DAT), .pressed (pressed), //-------- Audio (Tape player) -------------- .I2C_SCLK (I2C_SCLK), .I2C_SDAT (I2C_SDAT), .AUD_XCK (AUD_XCK), .AUD_ADCLRCK (AUD_ADCLRCK), .AUD_DACLRCK (AUD_DACLRCK), .AUD_BCLK (AUD_BCLK), .AUD_DACDAT (AUD_DACDAT), .AUD_ADCDAT (AUD_ADCDAT), .beeper (beeper), //-------- VGA connector -------------------- .VGA_R (VGA_R), .VGA_G (VGA_G), .VGA_B (VGA_B), .VGA_HS (VGA_HS), .VGA_VS (VGA_VS) ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Instantiate A-Z80 CPU //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ wire nM1; wire nMREQ; wire nIORQ; wire nRD; wire nWR; wire nRFSH; wire nHALT; wire nBUSACK; wire nWAIT = 1; wire nINT = (SW[1:1]==0)? vs_nintr : 1'b1;// SW1 disables interrupts and, hence, keyboard assign LED[0] = SW[1:1]; // Glow red when interrupts are *disabled* wire nNMI = KEY[1:1]; // Pressing KEY1 issues a NMI wire nBUSRQ = 1; z80_top_direct_n z80_( .nM1 (nM1), .nMREQ (nMREQ), .nIORQ (nIORQ), .nRD (nRD), .nWR (nWR), .nRFSH (nRFSH), .nHALT (nHALT), .nBUSACK (nBUSACK), .nWAIT (nWAIT), .nINT (nINT), .nNMI (nNMI), .nRESET (reset), .nBUSRQ (nBUSRQ), .CLK (clk_cpu), .A (A), .D (D) ); // reg[21:0] counter; // always @(posedge CLOCK_50) // begin // counter <= counter + 1; // if (counter == 0) // begin // A <= A + 1; // end // end // // make the leds blink with rom and ram0 data // assign LED[3:0] = rom_data[3:0]; // assign LED[7:4] = ram0_data[7:4]; // // expose memories at A to GPIO_0 // assign GPIO_0[7:0] = rom_data; // assign GPIO_0[15:8] = ram0_data; // assign GPIO_0[23:16] = ram1_data; // assign GPIO_0[31:24] = vram_data; endmodule