OpenCores
URL https://opencores.org/ocsvn/a-z80/a-z80/trunk

Subversion Repositories a-z80

[/] [a-z80/] [trunk/] [host/] [zxspectrum_de1/] [ula/] [ula.sv] - Blame information for rev 8

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 gdevic
//============================================================================
2
// The implementation of the Sinclair ZX Spectrum ULA
3
//
4
//  Copyright (C) 2014-2016  Goran Devic
5
//
6
//  This program is free software; you can redistribute it and/or modify it
7
//  under the terms of the GNU General Public License as published by the Free
8
//  Software Foundation; either version 2 of the License, or (at your option)
9
//  any later version.
10
//
11
//  This program is distributed in the hope that it will be useful, but WITHOUT
12
//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14
//  more details.
15
//
16
//  You should have received a copy of the GNU General Public License along
17
//  with this program; if not, write to the Free Software Foundation, Inc.,
18
//  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
//============================================================================
20
module ula
21
(
22
    //-------- Clocks and reset -----------------
23
    input wire CLOCK_27,            // Input clock 27 MHz
24
    input wire CLOCK_24,            // Input clock 24 MHz
25
    input wire turbo,               // Turbo speed (3.5 MHz x 2 = 7.0 MHz)
26
    output wire clk_vram,
27
    input wire reset,               // KEY0 is reset
28
    output wire locked,             // PLL is locked signal
29
 
30
    //-------- CPU control ----------------------
31
    output wire clk_cpu,            // Generates CPU clock of 3.5 MHz
32
    output wire vs_nintr,           // Generates a vertical retrace interrupt
33
 
34
    //-------- Address and data buses -----------
35
    input wire [15:0] A,            // Input address bus
36
    input wire [7:0] D,             // Input data bus
37
    output wire [7:0] ula_data,     // Output data
38
    input wire io_we,               // Write enable to data register through IO
39
 
40
    output wire [12:0] vram_address,// ULA video block requests a byte from the video RAM
41
    input wire [7:0] vram_data,     // ULA video block reads a byte from the video RAM
42
 
43
    //-------- PS/2 Keyboard --------------------
44
    input wire PS2_CLK,
45
    input wire PS2_DAT,
46
    output wire pressed,
47
 
48
    //-------- Audio (Tape player) --------------
49
    inout wire I2C_SCLK,
50
    inout wire I2C_SDAT,
51
    output wire AUD_XCK,
52
    output wire AUD_ADCLRCK,
53
    output wire AUD_DACLRCK,
54
    output wire AUD_BCLK,
55
    output wire AUD_DACDAT,
56
    input wire AUD_ADCDAT,
57
    output reg beeper,
58
 
59
    //-------- VGA connector --------------------
60
    output wire [3:0] VGA_R,
61
    output wire [3:0] VGA_G,
62
    output wire [3:0] VGA_B,
63
    output reg VGA_HS,
64
    output reg VGA_VS
65
);
66
`default_nettype none
67
 
68
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
69
// Instantiate PLL and clocks block
70
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71
wire clk_pix;                       // VGA pixel clock (25.175 MHz)
72
wire clk_ula;                       // ULA master clock (14 MHz)
73
assign clk_vram = clk_pix;
74
pll pll_( .locked(locked), .inclk0(CLOCK_27), .c0(clk_pix), .c1(clk_ula) );
75
 
76
clocks clocks_( .* );
77
 
78
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79
// The border color index
80
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81
reg [2:0] border;                   // Border color index value
82
 
83
always @(posedge clk_cpu)
84
begin
85
    if (A[0]==0 && io_we==1) begin
86
        border <= D[2:0];
87
        // EAR output (produces a louder sound)
88
        pcm_outl[14] <= D[4];       // Why [14] and not [15]? Less loud.
89
        pcm_outr[14] <= D[4];
90
        // MIC (echoes the input)
91
        pcm_outl[13] <= D[3];
92
        pcm_outr[13] <= D[3];
93
        // Let us hear the tape loading!
94
        pcm_outl[12] <= pcm_inl[14] | pcm_inr[14];
95
        pcm_outr[12] <= pcm_inl[14] | pcm_inr[14];
96
        // Let us see the tape loading!
97
        beep <= (pcm_inl[14] | pcm_inr[14]) ^ D[4] ^ D[3];
98
    end
99
end
100
 
101
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102
// Instantiate audio interface
103
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
104
wire audio_done;
105
wire audio_error;
106
 
107
i2c_loader i2c_loader_( .CLK(CLOCK_24), .nRESET(reset), .I2C_SCL(I2C_SCLK), .I2C_SDA(I2C_SDAT), .IS_DONE(audio_done), .IS_ERROR(audio_error) );
108
 
109
assign AUD_DACLRCK = AUD_ADCLRCK;
110
wire [15:0] pcm_inl;
111
wire [15:0] pcm_inr;
112
reg  [15:0] pcm_outl;
113
reg  [15:0] pcm_outr;
114
 
115
i2s_intf i2s_intf_( .CLK(CLOCK_24), .nRESET(reset),
116
    .PCM_INL(pcm_inl[15:0]), .PCM_INR(pcm_inr[15:0]), .PCM_OUTL(pcm_outl[15:0]), .PCM_OUTR(pcm_outr[15:0]),
117
    .I2S_MCLK(AUD_XCK), .I2S_LRCLK(AUD_ADCLRCK), .I2S_BCLK(AUD_BCLK), .I2S_DOUT(AUD_DACDAT), .I2S_DIN(AUD_ADCDAT) );
118
 
119
// Show the beeper visually by dividing the frequency with some factor to generate blinks
120
reg beep;                           // Beeper latch
121
reg [6:0] beepcnt;                  // Beeper counter
122
always @(posedge beep)
123
begin
124
    beepcnt <= beepcnt - '1;
125
    if (beepcnt==0) beeper <= ~beeper;
126
end
127
 
128
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
129
// Instantiate ULA's video subsystem
130
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
131
video video_( .* );
132
 
133
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
134
// Instantiate keyboard support
135
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136
wire [7:0] scan_code;
137
wire scan_code_ready;
138
wire scan_code_error;
139
 
140
ps2_keyboard ps2_keyboard_( .*, .clk(clk_cpu) );
141
 
142
wire [4:0] key_row;
143
zx_keyboard zx_keyboard_( .*, .clk(clk_cpu) );
144
 
145
always @(*) // always_comb
146
begin
147
    ula_data = 8'hFF;
148
    // Regular IO at every odd address: line-in and keyboard
149
    if (A[0]==0) begin
150
        ula_data = { 1'b0, pcm_inl[14] | pcm_inr[14], 1'b0, key_row[4:0] };
151
    end
152
end
153
 
154
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.