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