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