]> Joshua Wise's Git repositories - firearm.git/blob - xst/Console.v
xst: Add synthesis files (part 1).
[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 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
148 endmodule
149
150 module 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
181 endmodule
182
183 module 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}];
194 endmodule
195
196 module 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;
213 endmodule
214
215 module 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;
248 endmodule
249
250 module 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
331 endmodule
332
333 module 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
436 endmodule
This page took 0.044531 seconds and 4 git commands to generate.