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