OpenCores
URL https://opencores.org/ocsvn/zx_ula/zx_ula/trunk

Subversion Repositories zx_ula

[/] [zx_ula/] [trunk/] [cpld_version/] [rtl/] [ula.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 mcleod_ide
`timescale 1ns / 1ps
2
//////////////////////////////////////////////////////////////////////////////////
3
// Company:        Dept. Architecture and Computing Technology. University of Seville
4
// Engineer:       Miguel Angel Rodriguez Jodar
5
// 
6
// Create Date:    19:13:39 4-Apr-2012 
7
// Design Name:    ULA
8
// Module Name:    ula_reference_design 
9
// Project Name: 
10
// Target Devices: 
11
// Tool versions: 
12
// Description: 
13
//
14
// Dependencies: 
15
//
16
// Revision: 
17
// Revision 0.01 - File Created
18
// Additional Comments: 
19
//
20
//////////////////////////////////////////////////////////////////////////////////
21
 
22
`define cyclestart(a,b) ((a)==(b))
23
`define cycleend(a,b) ((a)==(b+1))
24
 
25
module ula(
26
    input clk14,                        // 14MHz master clock
27
         // CPU interfacing
28
    input [15:0] a,              // Address bus from CPU (not all lines are used)
29
    input [7:0] d,               // Data bus from VRAM
30
    input mreq_n,                       // MREQ from CPU
31
    input ioreq_n,              // IORQ+A0 from CPU
32
         output clkcpu,         // CLK to CPU
33
         output msk_int_n,      // Vertical retrace interrupt, to CPU
34
         // VRAM interfacing
35
    output [13:0] va,     // Address bus to VRAM (16K)
36
    output vramoe_n,             // 
37
    output vramcs_n,             // Control signals for VRAM
38
    output vramwe_n,             //
39
         // Control signals
40
         output vram_in_use,  // ==1 to indicate that VRAM is in use by ULA
41
         input [2:0] BorderColor,  // current border colour
42
         // Video output
43
    output r,                           //
44
    output g,                           // RGB TTL signal
45
    output b,                           // with separate bright
46
    output i,                           // and composite sync
47
    output csync                        //               
48
    );
49
 
50
        // Pixel clock
51
        reg clk7 = 0;
52
        always @(posedge clk14)
53
                clk7 <= !clk7;
54
 
55
        // Horizontal counter
56
        reg [8:0] hc = 0;
57
        always @(posedge clk7) begin
58
                if (hc==447)
59
                        hc <= 0;
60
                else
61
                        hc <= hc + 1;
62
        end
63
 
64
        // Vertical counter
65
        reg [8:0] vc = 0;
66
        always @(posedge clk7) begin
67
                if (hc==447) begin
68
                        if (vc == 311)
69
                                vc <= 0;
70
                        else
71
                                vc <= vc + 1;
72
                end
73
        end
74
 
75
        // HBlank generation
76
        reg HBlank_n = 1;
77
        always @(negedge clk7) begin
78
                if (`cyclestart(hc,320))
79
                        HBlank_n <= 0;
80
                else if (`cycleend(hc,415))
81
                        HBlank_n <= 1;
82
        end
83
 
84
        // HSync generation (6C ULA version)
85
        reg HSync_n = 1;
86
        always @(negedge clk7) begin
87
                if (`cyclestart(hc,344))
88
                        HSync_n <= 0;
89
                else if (`cycleend(hc,375))
90
                        HSync_n <= 1;
91
        end
92
 
93
        // VBlank generation
94
        reg VBlank_n = 1;
95
        always @(negedge clk7) begin
96
                if (`cyclestart(vc,248))
97
                        VBlank_n <= 0;
98
                else if (`cycleend(vc,255))
99
                        VBlank_n <= 1;
100
        end
101
 
102
        // VSync generation (PAL)
103
        reg VSync_n = 1;
104
        always @(negedge clk7) begin
105
                if (`cyclestart(vc,248))
106
                        VSync_n <= 0;
107
                else if (`cycleend(vc,251))
108
                        VSync_n <= 1;
109
        end
110
 
111
        // INT generation
112
        reg INT_n = 1;
113
        assign msk_int_n = INT_n;
114
        always @(negedge clk7) begin
115
                if (`cyclestart(vc,248) && `cyclestart(hc,0))
116
                        INT_n <= 0;
117
                else if (`cyclestart(vc,248) && `cycleend(hc,31))
118
                        INT_n <= 1;
119
        end
120
 
121
        // Border control signal (=0 when we're not displaying paper/ink pixels)
122
        reg Border_n = 1;
123
        always @(negedge clk7) begin
124
                if ( (vc[7] & vc[6]) | vc[8] | hc[8])
125
                        Border_n <= 0;
126
                else
127
                        Border_n <= 1;
128
        end
129
 
130
        // VidEN generation (delaying Border 8 clocks)
131
        reg VidEN_n = 1;
132
        always @(negedge clk7) begin
133
                if (hc[3])
134
                        VidEN_n <= !Border_n;
135
        end
136
 
137
        // DataLatch generation (posedge to capture data from memory)
138
        reg DataLatch_n = 1;
139
        always @(negedge clk7) begin
140
                if (hc[0] & !hc[1] & Border_n & hc[3])
141
                        DataLatch_n <= 0;
142
                else
143
                        DataLatch_n <= 1;
144
        end
145
 
146
        // AttrLatch generation (posedge to capture data from memory)
147
        reg AttrLatch_n = 1;
148
        always @(negedge clk7) begin
149
                if (hc[0] & hc[1] & Border_n & hc[3])
150
                        AttrLatch_n <= 0;
151
                else
152
                        AttrLatch_n <= 1;
153
        end
154
 
155
        // SLoad generation (negedge to load shift register)
156
        reg SLoad = 0;
157
        always @(negedge clk7) begin
158
                if (!hc[0] & !hc[1] & hc[2] & !VidEN_n)
159
                        SLoad <= 1;
160
                else
161
                        SLoad <= 0;
162
        end
163
 
164
        // AOLatch generation (negedge to update attr output latch)
165
        reg AOLatch_n = 1;
166
        always @(negedge clk7) begin
167
                if (hc[0] & !hc[1] & hc[2])
168
                        AOLatch_n <= 0;
169
                else
170
                        AOLatch_n <= 1;
171
        end
172
 
173
        // First buffer for bitmap
174
        reg [7:0] BitmapReg = 0;
175
        always @(negedge DataLatch_n) begin
176
                BitmapReg <= d;
177
        end
178
 
179
        // Shift register (second bitmap register)
180
        reg [7:0] SRegister = 0;
181
        always @(negedge clk7) begin
182
                if (SLoad)
183
                        SRegister <= BitmapReg;
184
                else
185
                        SRegister <= {SRegister[6:0],1'b0};
186
        end
187
 
188
        // First buffer for attribute
189
        reg [7:0] AttrReg = 0;
190
        always @(negedge AttrLatch_n) begin
191
                AttrReg <= d;
192
        end
193
 
194
        // Second buffer for attribute
195
        reg [7:0] AttrOut = 0;
196
        always @(negedge AOLatch_n) begin
197
                if (!VidEN_n)
198
                        AttrOut <= AttrReg;
199
                else
200
                        AttrOut <= {2'b00,BorderColor,BorderColor};
201
        end
202
 
203
        // Flash counter and pixel generation
204
        reg [4:0] FlashCnt = 0;
205
        always @(negedge VSync_n) begin
206
                FlashCnt <= FlashCnt + 1;
207
        end
208
        wire Pixel = SRegister[7] ^ (AttrOut[7] & FlashCnt[4]);
209
 
210
        // RGB generation
211
        reg rI,rG,rR,rB;
212
        assign r = rR;
213
        assign g = rG;
214
        assign b = rB;
215
        assign i = rI;
216
        always @(*) begin
217
                if (HBlank_n && VBlank_n)
218
                        {rI,rG,rR,rB} = (Pixel)? {AttrOut[6],AttrOut[2:0]} : {AttrOut[6],AttrOut[5:3]};
219
                else
220
                        {rI,rG,rR,rB} = 4'b0000;
221
        end
222
 
223
        //CSync generation
224
        assign csync = HSync_n & VSync_n;
225
 
226
        // VRAM address and control line generation
227
        reg [13:0] rVA = 0;
228
        reg rVCS_n = 1;
229
        reg rVOE_n = 1;
230
        reg rVWE_n = 1;
231
        reg rVRAMInUse = 0;
232
        assign va = rVA;
233
        assign vramcs_n = rVCS_n;
234
        assign vramoe_n = rVOE_n;
235
        assign vramwe_n = rVWE_n;
236
        assign vram_in_use = rVRAMInUse;
237
        // Latches to hold delayed versions of V and H counters
238
        reg [8:0] v = 0;
239
        reg [8:0] c = 0;
240
        // Address and control line multiplexor ULA/CPU
241
        always @(negedge clk7) begin
242
                if (Border_n && (hc[3:0]==4'b0111 || hc[3:0]==4'b1011)) begin     // cycles 7 and 11: load V and C from VC and HC
243
                        c <= hc;
244
                        v <= vc;
245
                end
246
        end
247
        // Address and control line multiplexor ULA/CPU
248
        always @(*) begin
249
                if (Border_n && (hc[3:0]==4'b1000 || hc[3:0]==4'b1001 || hc[3:0]==4'b1100 || hc[3:0]==4'b1101)) begin       // cycles 8 and 12: present display address to VRAM 
250
                        rVA = {1'b0,v[7:6],v[2:0],v[5:3],c[7:3]};                                                // (cycles 9 and 13 load display byte)
251
                        rVCS_n = 0;
252
                        rVOE_n = 0;
253
                        rVWE_n = 1;
254
                        rVRAMInUse = 1;
255
                end
256
                else if (Border_n && (hc[3:0]==4'b1010 || hc[3:0]==4'b1011 || hc[3:0]==4'b1110 || hc[3:0]==4'b1111)) begin  // cycles 10 and 14: present attribute address to VRAM
257
                        rVA = {4'b0110,v[7:3],c[7:3]};                                                                          // (cycles 11 and 15 load attr byte)
258
                        rVCS_n = 0;
259
                        rVOE_n = 0;
260
                        rVWE_n = 1;
261
                        rVRAMInUse = 1;
262
                end
263
                else begin      // when VRAM is not in use by ULA, give it to CPU by putting ULA lines in high impedance mode.
264
                        rVA = 14'bzzzzzzzzzzzzzz;
265
                        rVCS_n = 1'bz;
266
                        rVOE_n = 1'bz;
267
                        rVWE_n = 1'bz;
268
                        rVRAMInUse = 0;
269
                end
270
        end
271
 
272
        // CPU contention
273
        reg CPUClk = 0;
274
        assign clkcpu = CPUClk;
275
        reg ioreqtw3 = 0;
276
        reg mreqt23 = 0;
277
        wire Nor1 = (~(a[14] | ~ioreq_n)) |
278
                    (~(~a[15] | ~ioreq_n)) |
279
                                        (~(hc[2] | hc[3])) |
280
                                        (~Border_n | ~ioreqtw3 | ~CPUClk | ~mreqt23);
281
        wire Nor2 = (~(hc[2] | hc[3])) |
282
                    ~Border_n |
283
                                        ~CPUClk |
284
                                        ioreq_n |
285
                                        ~ioreqtw3;
286
        wire CLKContention = ~Nor1 | ~Nor2;
287
        always @(posedge clk7) begin    // change clk7 by clk14 for 7MHz CPU clock operation
288
                if (CPUClk && !CLKContention)   // if there's no contention, the clock can go low
289
                        CPUClk <= 0;
290
                else
291
                        CPUClk <= 1;
292
        end
293
        always @(posedge CPUClk) begin
294
                ioreqtw3 <= ioreq_n;
295
                mreqt23 <= mreq_n;
296
        end
297
endmodule

powered by: WebSVN 2.1.0

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