Fix some simulator-only bugs involving debugging/illegal states. Make rd and wr...
[fpgaboy.git] / System.v
1
2 `timescale 1ns / 1ps
3 module ROM(
4         input [15:0] address,
5         inout [7:0] data,
6         input clk,
7         input wr, rd);
8
9         reg rdlatch = 0;
10         reg [7:0] odata;
11
12         // synthesis attribute ram_style of rom is block
13         reg [7:0] rom [1023:0];
14         initial $readmemh("rom.hex", rom);
15
16         wire decode = address[15:13] == 0;
17         always @(posedge clk) begin
18                 rdlatch <= rd && decode;
19                 odata <= rom[address[10:0]];
20         end
21         assign data = rdlatch ? odata : 8'bzzzzzzzz;
22 endmodule
23
24 module BootstrapROM(
25         input [15:0] address,
26         inout [7:0] data,
27         input clk,
28         input wr, rd);
29
30         reg rdlatch = 0;
31         reg [7:0] addrlatch = 0;
32         reg [7:0] brom [255:0];
33         initial $readmemh("bootstrap.hex", brom);
34
35         wire decode = address[15:8] == 0;
36         wire [7:0] odata = brom[addrlatch];
37         always @(posedge clk) begin
38                 rdlatch <= rd && decode;
39                 addrlatch <= address[7:0];
40         end
41         assign data = rdlatch ? odata : 8'bzzzzzzzz;
42 endmodule
43
44 module MiniRAM(
45         input [15:0] address,
46         inout [7:0] data,
47         input clk,
48         input wr, rd);
49         
50         reg [7:0] ram [127:0];
51         
52         wire decode = (address >= 16'hFF80) && (address <= 16'hFFFE);
53         reg rdlatch = 0;
54         reg [7:0] odata;
55         assign data = rdlatch ? odata : 8'bzzzzzzzz;
56         
57         always @(posedge clk)
58         begin
59                 rdlatch <= rd && decode;
60                 if (decode)             // This has to go this way. The only way XST knows how to do
61                 begin                   // block ram is chip select, write enable, and always
62                         if (wr)         // reading. "else if rd" does not cut it ...
63                                 ram[address[6:0]] <= data;
64                         odata <= ram[address[6:0]];
65                 end
66         end
67 endmodule
68
69 module CellularRAM(
70         input clk,
71         input [15:0] address,
72         inout [7:0] data,
73         input wr, rd,
74         output wire cr_nADV, cr_nCE, cr_nOE, cr_nWE, cr_CRE, cr_nLB, cr_nUB, cr_CLK,
75         output wire [22:0] cr_A,
76         inout [15:0] cr_DQ);
77         
78         parameter ADDR_PROGADDRH = 16'hFF60;
79         parameter ADDR_PROGADDRM = 16'hFF61;
80         parameter ADDR_PROGADDRL = 16'hFF62;
81         parameter ADDR_PROGDATA = 16'hFF63;
82         
83         reg rdlatch = 0, wrlatch = 0;
84         reg [15:0] addrlatch = 0;
85         reg [7:0] datalatch = 0;
86         
87         reg [7:0] progaddrh, progaddrm, progaddrl;
88         
89         assign cr_nADV = 0;     /* Addresses are always valid! :D */
90         assign cr_nCE = 0;      /* The chip is enabled */
91         assign cr_nLB = 0;      /* Lower byte is enabled */
92         assign cr_nUB = 0;      /* Upper byte is enabled */
93         assign cr_CRE = 0;      /* Data writes, not config */
94         assign cr_CLK = 0;      /* Clock? I think not! */
95         
96         wire decode = (addrlatch[15:14] == 2'b00) /* extrom */ || (addrlatch[15:13] == 3'b101) /* extram */ || (addrlatch == ADDR_PROGDATA);
97         
98         assign cr_nOE = decode ? ~rdlatch : 1;
99         assign cr_nWE = decode ? ~wrlatch : 1;
100         
101         assign cr_DQ = (~cr_nOE) ? 16'bzzzzzzzzzzzzzzzz : {8'b0, datalatch};
102         assign cr_A = (addrlatch[15:14] == 2'b00) ? /* extrom */ {9'b0,addrlatch[13:0]} :
103                         (addrlatch[15:13] == 3'b101) ? {1'b1, 9'b0, addrlatch[12:0]} :
104                         (addrlatch == ADDR_PROGDATA) ? {progaddrh[6:0], progaddrm[7:0], progaddrl[7:0]} :
105                         23'b0;
106         
107         reg [7:0] regbuf;
108         
109         always @(posedge clk) begin
110                 case (address)
111                 ADDR_PROGADDRH: if (wr) progaddrh <= data;
112                 ADDR_PROGADDRM: if (wr) progaddrm <= data;
113                 ADDR_PROGADDRL: if (wr) progaddrl <= data;
114                 endcase
115                 rdlatch <= rd;
116                 wrlatch <= wr;
117                 addrlatch <= address;
118                 datalatch <= data;
119         end
120         
121         assign data = (rdlatch && decode) ?
122                                 (addrlatch == ADDR_PROGADDRH) ? progaddrh :
123                                 (addrlatch == ADDR_PROGADDRM) ? progaddrm :
124                                 (addrlatch == ADDR_PROGADDRL) ? progaddrl :
125                                 cr_DQ
126                         : 8'bzzzzzzzz;
127 endmodule
128
129 module InternalRAM(
130         input [15:0] address,
131         inout [7:0] data,
132         input clk,
133         input wr, rd);
134         
135         // synthesis attribute ram_style of ram is block
136         reg [7:0] ram [8191:0];
137         
138         wire decode = (address >= 16'hC000) && (address <= 16'hFDFF);   /* This includes echo RAM. */
139         reg [7:0] odata;
140         reg rdlatch = 0;
141         assign data = rdlatch ? odata : 8'bzzzzzzzz;
142         
143         always @(posedge clk)
144         begin
145                 rdlatch <= rd && decode;
146                 if (decode)             // This has to go this way. The only way XST knows how to do
147                 begin                   // block ram is chip select, write enable, and always
148                         if (wr)         // reading. "else if rd" does not cut it ...
149                                 ram[address[12:0]] <= data;
150                         odata <= ram[address[12:0]];
151                 end
152         end
153 endmodule
154
155 module Switches(
156         input [15:0] address,
157         inout [7:0] data,
158         input clk,
159         input wr, rd,
160         input [7:0] switches,
161         output reg [7:0] ledout = 0);
162         
163         wire decode = address == 16'hFF51;
164         reg [7:0] odata;
165         reg rdlatch = 0;
166         assign data = rdlatch ? odata : 8'bzzzzzzzz;
167         
168         always @(posedge clk)
169         begin
170                 rdlatch <= rd && decode;
171                 if (decode && rd)
172                         odata <= switches;
173                 else if (decode && wr)
174                         ledout <= data;
175         end
176 endmodule
177
178 `ifdef isim
179 module Dumpable(input [2:0] r, g, input [1:0] b, input hs, vs, vgaclk);
180 endmodule
181 `endif
182
183 module CoreTop(
184 `ifdef isim
185         output reg vgaclk = 0,
186         output reg clk = 0,
187 `else
188         input xtal,
189         input [7:0] switches,
190         input [3:0] buttons,
191         output wire [7:0] leds,
192         output serio,
193         output wire [3:0] digits,
194         output wire [7:0] seven,
195         output wire cr_nADV, cr_nCE, cr_nOE, cr_nWE, cr_CRE, cr_nLB, cr_nUB, cr_CLK,
196         output wire [22:0] cr_A,
197         inout [15:0] cr_DQ,
198 `endif
199         output wire hs, vs,
200         output wire [2:0] r, g,
201         output wire [1:0] b,
202         output wire soundl, soundr);
203
204 `ifdef isim
205         always #62 clk <= ~clk;
206         always #100 vgaclk <= ~vgaclk;
207         
208         Dumpable dump(r,g,b,hs,vs,vgaclk);
209         
210         wire [7:0] leds;
211         wire serio;
212         wire [3:0] digits;
213         wire [7:0] seven;
214         wire [7:0] switches = 8'b0;
215         wire [3:0] buttons = 4'b0;
216 `else   
217         wire xtalb, clk, vgaclk;
218         IBUFG iclkbuf(.O(xtalb), .I(xtal));
219         CPUDCM dcm (.CLKIN_IN(xtalb), .CLKFX_OUT(clk));
220         pixDCM pixdcm (.CLKIN_IN(xtalb), .CLKFX_OUT(vgaclk));
221 `endif
222
223         wire [15:0] addr [1:0];
224         wire [7:0] data [1:0];
225         wire wr [1:0], rd [1:0];
226         
227         wire irq, tmrirq, lcdcirq, vblankirq;
228         wire [7:0] jaddr;
229         wire [1:0] state;
230         
231         GBZ80Core core(
232                 .clk(clk),
233                 .bus0address(addr[0]),
234                 .bus0data(data[0]),
235                 .bus0wr(wr[0]),
236                 .bus0rd(rd[0]),
237                 .bus1address(addr[1]),
238                 .bus1data(data[1]),
239                 .bus1wr(wr[1]),
240                 .bus1rd(rd[1]),
241                 .irq(irq),
242                 .jaddr(jaddr),
243                 .state(state));
244         
245         BootstrapROM brom(
246                 .address(addr[1]),
247                 .data(data[1]),
248                 .clk(clk),
249                 .wr(wr[1]),
250                 .rd(rd[1]));
251         
252 `ifdef isim
253         ROM rom(
254                 .address(addr[0]),
255                 .data(data[0]),
256                 .clk(clk),
257                 .wr(wr[0]),
258                 .rd(rd[0]));
259 `else
260         CellularRAM cellram(
261                 .address(addr[0]),
262                 .data(data[0]),
263                 .clk(clk),
264                 .wr(wr[0]),
265                 .rd(rd[0])
266                 .cr_nADV(cr_nADV),
267                 .cr_nCE(cr_nCE),
268                 .cr_nOE(cr_nOE),
269                 .cr_nWR(cr_nWE),
270                 .cr_CRE(cr_CRE),
271                 .cr_nLB(cr_nLB),
272                 .cr_nUB(cr_nUB),
273                 .cr_CLK(cr_CLK),
274                 .cr_A(cr_A),
275                 .cr_DQ(cr_DQ));
276 `endif
277         
278         wire lcdhs, lcdvs, lcdclk;
279         wire [2:0] lcdr, lcdg;
280         wire [1:0] lcdb;
281         
282         LCDC lcdc(
283                 .clk(clk),
284                 .addr(addr[0]),
285                 .data(data[0]),
286                 .wr(wr[0]),
287                 .rd(rd[0]),
288                 .lcdcirq(lcdcirq),
289                 .vblankirq(vblankirq),
290                 .lcdclk(lcdclk),
291                 .lcdhs(lcdhs),
292                 .lcdvs(lcdvs),
293                 .lcdr(lcdr),
294                 .lcdg(lcdg),
295                 .lcdb(lcdb));
296         
297         Framebuffer fb(
298                 .lcdclk(lcdclk),
299                 .lcdhs(lcdhs),
300                 .lcdvs(lcdvs),
301                 .lcdr(lcdr),
302                 .lcdg(lcdg),
303                 .lcdb(lcdb),
304                 .vgaclk(vgaclk),
305                 .vgahs(hs),
306                 .vgavs(vs),
307                 .vgar(r),
308                 .vgag(g),
309                 .vgab(b));
310         
311         AddrMon amon(
312                 .clk(clk), 
313                 .addr(addr[0]),
314                 .digit(digits), 
315                 .out(seven),
316                 .freeze(buttons[0]),
317                 .periods(
318                         (state == 2'b00) ? 4'b0010 :
319                         (state == 2'b01) ? 4'b0001 :
320                         (state == 2'b10) ? 4'b1000 :
321                                            4'b0100) );
322          
323         Switches sw(
324                 .clk(clk),
325                 .address(addr[0]),
326                 .data(data[0]),
327                 .wr(wr[0]),
328                 .rd(rd[0]),
329                 .ledout(leds),
330                 .switches(switches)
331                 );
332
333         UART nouart (   /* no u */
334                 .clk(clk),
335                 .addr(addr[0]),
336                 .data(data[0]),
337                 .wr(wr[0]),
338                 .rd(rd[0]),
339                 .serial(serio)
340                 );
341
342         InternalRAM ram(
343                 .clk(clk),
344                 .address(addr[0]),
345                 .data(data[0]),
346                 .wr(wr[0]),
347                 .rd(rd[0])
348                 );
349         
350         MiniRAM mram(
351                 .clk(clk),
352                 .address(addr[1]),
353                 .data(data[1]),
354                 .wr(wr[1]),
355                 .rd(rd[1])
356                 );
357
358         Timer tmr(
359                 .clk(clk),
360                 .addr(addr[0]),
361                 .data(data[0]),
362                 .wr(wr[0]),
363                 .rd(rd[0]),
364                 .irq(tmrirq)
365                 );
366         
367         Interrupt intr(
368                 .clk(clk),
369                 .addr(addr[0]),
370                 .data(data[0]),
371                 .wr(wr[0]),
372                 .rd(rd[0]),
373                 .vblank(vblankirq),
374                 .lcdc(lcdcirq),
375                 .tovf(tmrirq),
376                 .serial(1'b0),
377                 .buttons(1'b0),
378                 .master(irq),
379                 .jaddr(jaddr));
380         
381         Soundcore sound(
382                 .core_clk(clk),
383                 .addr(addr[0]),
384                 .data(data[0]),
385                 .rd(rd[0]),
386                 .wr(wr[0]),
387                 .snd_data_l(soundl),
388                 .snd_data_r(soundr));
389 endmodule
This page took 0.038998 seconds and 4 git commands to generate.