]> Joshua Wise's Git repositories - firearm.git/blame - xst/Console.nexys2.v
Add chip enable correctness for CellularRAM.
[firearm.git] / xst / Console.nexys2.v
CommitLineData
1e7ff543
JW
1module MulDivDCM(input xtal, output clk);
2 parameter div = 5;
3 parameter mul = 2;
4
5 wire CLKFX_BUF;
6 wire GND_BIT = 0;
7 BUFG CLKFX_BUFG_INST (.I(CLKFX_BUF),
8 .O(clk));
9 DCM_SP DCM_SP_INST (.CLKFB(GND_BIT),
10 .CLKIN(xtal),
11 .DSSEN(GND_BIT),
12 .PSCLK(GND_BIT),
13 .PSEN(GND_BIT),
14 .PSINCDEC(GND_BIT),
15 .RST(GND_BIT),
16 .CLKFX(CLKFX_BUF));
17 defparam DCM_SP_INST.CLK_FEEDBACK = "NONE";
18 defparam DCM_SP_INST.CLKDV_DIVIDE = 2.0;
19 defparam DCM_SP_INST.CLKFX_DIVIDE = div;
20 defparam DCM_SP_INST.CLKFX_MULTIPLY = mul;
21 defparam DCM_SP_INST.CLKIN_DIVIDE_BY_2 = "FALSE";
22 defparam DCM_SP_INST.CLKIN_PERIOD = 20.000;
23 defparam DCM_SP_INST.CLKOUT_PHASE_SHIFT = "NONE";
24 defparam DCM_SP_INST.DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS";
25 defparam DCM_SP_INST.DFS_FREQUENCY_MODE = "LOW";
26 defparam DCM_SP_INST.DLL_FREQUENCY_MODE = "LOW";
27 defparam DCM_SP_INST.DUTY_CYCLE_CORRECTION = "TRUE";
28 defparam DCM_SP_INST.FACTORY_JF = 16'hC080;
29 defparam DCM_SP_INST.PHASE_SHIFT = 0;
30 defparam DCM_SP_INST.STARTUP_WAIT = "TRUE";
31endmodule
32
33module Console(
34 input xtal,
35 input rst,
36 output wire rstact,
37 output wire vs, hs,
38 output wire [2:0] r, g,
39 output wire [1:0] b,
40 input ps2c, ps2d,
41 output wire cr_nADV, cr_nCE, cr_nOE, cr_nWE, cr_CRE, cr_nLB, cr_nUB, cr_CLK,
42 inout wire [15:0] cr_DQ,
43 output wire [22:0] cr_A,
44 output wire st_nCE);
45
46 wire pixclk, coreclk;
47
48 wire [11:0] x, y;
49 wire border;
50
51 assign coreclk = pixclk;
52 MulDivDCM dcm31_25(xtal, pixclk);
53 defparam dcm31_25.div = 4;
54 defparam dcm31_25.mul = 2;
55
56 SyncGen sync(pixclk, vs, hs, x, y, border);
57
58 wire [7:0] cschar;
59 wire [2:0] csrow;
60 wire [7:0] csdata;
61
62 wire [10:0] vraddr;
63 wire [7:0] vrdata;
64
65 wire [10:0] vwaddr;
66 wire [7:0] vwdata;
67 wire [7:0] serdata;
68 wire vwr, serwr;
69 wire [10:0] vscroll;
70
71 wire odata;
72
73 wire [6:0] vcursx;
74 wire [4:0] vcursy;
75
76 reg [16:0] rsttimer = 17'h3FFFF;
77 always @(posedge coreclk)
78 if (rst)
79 rsttimer <= 17'h3FFFF;
80 else if (rsttimer)
81 rsttimer <= rsttimer - 1;
82 assign rstact = rsttimer != 17'h0;
83
84 wire tookdata;
85 reg ps2_hasd = 0;
86 reg [7:0] ps2_d = 0;
87 wire sertxwr;
88 wire [7:0] sertxdata;
89
90 CharSet cs(cschar, csrow, csdata);
91 VideoRAM vram(pixclk, vraddr + vscroll, vrdata, coreclk, vwaddr, vwdata, vwr);
92 VDisplay dpy(pixclk, x, y, vraddr, vrdata, cschar, csrow, csdata, vcursx, vcursy, odata);
93 RXState rxsm(coreclk, vwr, vwaddr, vwdata, vscroll, vcursx, vcursy, serwr, serdata);
94 PS2 ps2(coreclk, ps2c, ps2d, sertxwr, sertxdata);
95 System sys(.clk(coreclk), .rst(rstact), .sys_odata({serwr, serdata}), .sys_idata({ps2_hasd, ps2_d}), .sys_tookdata(tookdata),
96 .cr_nADV (cr_nADV),
97 .cr_nCE (cr_nCE),
98 .cr_nOE (cr_nOE),
99 .cr_nWE (cr_nWE),
100 .cr_CRE (cr_CRE),
101 .cr_nLB (cr_nLB),
102 .cr_nUB (cr_nUB),
103 .cr_CLK (cr_CLK),
104 .cr_A (cr_A),
105 .st_nCE (st_nCE),
106 .cr_DQ (cr_DQ));
107
108 always @(posedge coreclk)
109 if (sertxwr)
110 {ps2_hasd, ps2_d} <= {1'b1, sertxdata};
111 else if (tookdata)
112 {ps2_hasd, ps2_d} <= {1'b0, 8'hxxxxxxxx};
113
114 wire [7:0] red, green, blue;
115 assign r = (odata ? 3'b111 : 0) | (x[8:7] ^ y[7:6]);
116 assign g = (odata ? 3'b111 : 0) | (x[7:6] ^ y[8:7]);
117 assign b = (odata ? 2'b11 : 0) | (x[8 ] ^ y[8 ]);
118endmodule
119
120module SyncGen(
121 input pixclk,
122 output reg vs, hs,
123 output reg [11:0] x, y,
124 output reg border);
125
126 parameter XRES = 640;
127 parameter XFPORCH = 16;
128 parameter XSYNC = 96;
129 parameter XBPORCH = 48;
130
131 parameter YRES = 480;
132 parameter YFPORCH = 10;
133 parameter YSYNC = 2;
134 parameter YBPORCH = 29;
135
136 always @(posedge pixclk)
137 begin
138 if (x >= (XRES + XFPORCH + XSYNC + XBPORCH))
139 begin
140 if (y >= (YRES + YFPORCH + YSYNC + YBPORCH))
141 y = 0;
142 else
143 y = y + 1;
144 x = 0;
145 end else
146 x = x + 1;
147 hs <= (x >= (XRES + XFPORCH)) && (x < (XRES + XFPORCH + XSYNC));
148 vs <= (y >= (YRES + YFPORCH)) && (y < (YRES + YFPORCH + YSYNC));
149 border <= (x > XRES) || (y > YRES);
150 end
151endmodule
152
153module CharSet(
154 input [7:0] char,
155 input [2:0] row,
156 output wire [7:0] data);
157
158 reg [7:0] rom [(256 * 8 - 1):0];
159
160 initial
161 $readmemb("ibmpc1.mem", rom);
162
163 assign data = rom[{char, row}];
164endmodule
165
166module VideoRAM(
167 input pixclk,
168 input [10:0] raddr,
169 output reg [7:0] rdata,
170 input wclk,
171 input [10:0] waddr,
172 input [7:0] wdata,
173 input wr);
174
175 reg [7:0] ram [2047 : 0];
176
177 always @(posedge pixclk)
178 rdata <= ram[raddr];
179
180 always @(posedge wclk)
181 if (wr)
182 ram[waddr] <= wdata;
183endmodule
184
185module VDisplay(
186 input pixclk,
187 input [11:0] x,
188 input [11:0] y,
189 output wire [10:0] raddr,
190 input [7:0] rchar,
191 output wire [7:0] cschar,
192 output wire [2:0] csrow,
193 input [7:0] csdata,
194 input [6:0] cursx,
195 input [4:0] cursy,
196 output reg data);
197
198 wire [7:0] col = x[11:3];
199 wire [5:0] row = y[10:4];
200 reg [7:0] ch;
201 reg [11:0] xdly;
202
203 assign raddr = ({row,4'b0} + {row,6'b0} + {4'h0,col});
204 assign cschar = rchar;
205 assign csrow = y[3:1];
206
207 reg [23:0] blinktime = 0;
208
209 always @(posedge pixclk) blinktime <= blinktime + 1;
210
211 wire curssel = (cursx == col) && (cursy == row) && blinktime[23];
212
213 always @(posedge pixclk)
214 xdly <= x;
215
216 always @(posedge pixclk)
217 data = ((xdly < 80 * 8) && (y < 25 * 16)) ? (csdata[7 - xdly[2:0]] ^ curssel) : 0;
218endmodule
219
220module RXState(
221 input clk25,
222 output reg vwr = 0,
223 output reg [10:0] vwaddr = 0,
224 output reg [7:0] vwdata = 0,
225 output reg [10:0] vscroll = 0,
226 output wire [6:0] vcursx,
227 output wire [4:0] vcursy,
228 input serwr,
229 input [7:0] serdata);
230
231 parameter STATE_IDLE = 4'b0000;
232 parameter STATE_NEWLINE = 4'b0001;
233 parameter STATE_CLEAR = 4'b0010;
234
235 reg [3:0] state = STATE_CLEAR;
236
237 reg [6:0] x = 0;
238 reg [4:0] y = 0;
239
240 assign vcursx = x;
241 assign vcursy = y;
242
243 reg [10:0] clearstart = 0;
244 reg [10:0] clearend = 11'b11111111111;
245
246 always @(posedge clk25)
247 case (state)
248 STATE_IDLE: if (serwr) begin
249 if (serdata == 8'h0A) begin
250 state <= STATE_NEWLINE;
251 x <= 0;
252 vwr <= 0;
253 end else if (serdata == 8'h0D) begin
254 x <= 0;
255 vwr <= 0;
256 end else if (serdata == 8'h0C) begin
257 clearstart <= 0;
258 clearend <= 11'b11111111111;
259 x <= 0;
260 y <= 0;
261 vscroll <= 0;
262 state <= STATE_CLEAR;
263 end else if (serdata == 8'h08) begin
264 if (x != 0)
265 x <= x - 1;
266 vwr <= 0;
267 end else begin
268 vwr <= 1;
269 vwaddr <= ({y,4'b0} + {y,6'b0} + {4'h0,x}) + vscroll;
270 vwdata <= serdata;
271 if (x == 79) begin
272 x <= 0;
273 state <= STATE_NEWLINE;
274 end else
275 x <= x + 1;
276 end
277 end
278 STATE_NEWLINE:
279 begin
280 vwr <= 0;
281 if (y == 24) begin
282 vscroll <= vscroll + 80;
283 clearstart <= (25 * 80) + vscroll;
284 clearend <= (26*80) + vscroll;
285 state <= STATE_CLEAR;
286 end else begin
287 y <= y + 1;
288 state <= STATE_IDLE;
289 end
290 end
291 STATE_CLEAR:
292 begin
293 vwr <= 1;
294 vwaddr <= clearstart;
295 vwdata <= 8'h20;
296 clearstart <= clearstart + 1;
297 if (clearstart == clearend)
298 state <= STATE_IDLE;
299 end
300 endcase
301endmodule
302
303module PS2(
304 input pixclk,
305 input inclk,
306 input indata,
307 output reg wr,
308 output reg [7:0] data
309 );
310
311 reg [3:0] bitcount = 0;
312 reg [7:0] key = 0;
313 reg keyarrow = 0, keyup = 0, parity = 0;
314
315
316 /* Clock debouncing */
317 reg lastinclk = 0;
318 reg [6:0] debounce = 0;
319 reg fixedclk = 0;
320 reg [11:0] resetcountdown = 0;
321
322 reg [6:0] unshiftedrom [127:0]; initial $readmemh("scancodes.unshifted.hex", unshiftedrom);
323 reg [6:0] shiftedrom [127:0]; initial $readmemh("scancodes.shifted.hex", shiftedrom);
324
325 reg mod_lshift = 0;
326 reg mod_rshift = 0;
327 reg mod_capslock = 0;
328 wire mod_shifted = (mod_lshift | mod_rshift) ^ mod_capslock;
329
330 reg nd = 0;
331 reg lastnd = 0;
332
333 always @(posedge pixclk) begin
334 if (inclk != lastinclk) begin
335 lastinclk <= inclk;
336 debounce <= 1;
337 resetcountdown <= 12'b111111111111;
338 end else if (debounce == 0) begin
339 fixedclk <= inclk;
340 resetcountdown <= resetcountdown - 1;
341 end else
342 debounce <= debounce + 1;
343
344 if (nd ^ lastnd) begin
345 lastnd <= nd;
346 wr <= 1;
347 end else
348 wr <= 0;
349 end
350
351 always @(negedge fixedclk) begin
352 if (resetcountdown == 0)
353 bitcount <= 0;
354 else if (bitcount == 10) begin
355 bitcount <= 0;
356 if(parity != (^ key)) begin
357 if(keyarrow) begin
358 casex(key)
359 8'hF0: keyup <= 1;
360 8'hxx: keyarrow <= 0;
361 endcase
362 end
363 else begin
364 if(keyup) begin
365 keyup <= 0;
366 keyarrow <= 0;
367 casex (key)
368 8'h12: mod_lshift <= 0;
369 8'h59: mod_rshift <= 0;
370 endcase
371 // handle this? I don't fucking know
372 end
373 else begin
374 casex(key)
375 8'hE0: keyarrow <= 1; // handle these? I don't fucking know
376 8'hF0: keyup <= 1;
377 8'h12: mod_lshift <= 1;
378 8'h59: mod_rshift <= 1;
379 8'h14: mod_capslock <= ~mod_capslock;
380 8'b0xxxxxxx: begin nd <= ~nd; data <= mod_shifted ? shiftedrom[key] : unshiftedrom[key]; end
381 8'b1xxxxxxx: begin /* AAAAAAASSSSSSSS */ end
382 endcase
383 end
384 end
385 end
386 else begin
387 keyarrow <= 0;
388 keyup <= 0;
389 end
390 end else
391 bitcount <= bitcount + 1;
392
393 case(bitcount)
394 1: key[0] <= indata;
395 2: key[1] <= indata;
396 3: key[2] <= indata;
397 4: key[3] <= indata;
398 5: key[4] <= indata;
399 6: key[5] <= indata;
400 7: key[6] <= indata;
401 8: key[7] <= indata;
402 9: parity <= indata;
403 endcase
404 end
405
406endmodule
This page took 0.054787 seconds and 4 git commands to generate.