1 module MulDivDCM(input xtal, output clk, output clk90);
10 BUFG CLK0_BUFG_INST (.I(CLK0_BUF),
12 BUFG CLK90_BUFG_INST (.I(CLK90_BUF),
14 BUFG CLKFX_BUFG_INST (.I(CLKFX_BUF),
17 DCM_BASE DCM_INST2(.CLKFB(clk),
23 DCM_BASE DCM_INST (.CLKFB(GND_BIT),
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";
49 output wire dvi_vs, dvi_hs,
50 output wire [11:0] dvi_d,
51 output wire dvi_xclk_p, dvi_xclk_n,
53 output wire dvi_reset_b,
58 assign dvi_reset_b = 1'b1;
60 wire pixclk, pixclk_90, coreclk, coreclk_90;
65 MulDivDCM dcm31_25(xtal, pixclk, pixclk_90);
66 defparam dcm31_25.div = 16;
67 defparam dcm31_25.mul = 5;
69 MulDivDCM dcmcore(xtal, coreclk, coreclk_90); /* 50MHz */
70 defparam dcmcore.div = 4;
71 defparam dcmcore.mul = 2;
74 SyncGen sync(pixclk, vs, hs, x, y, border);
94 reg [16:0] rsttimer = 17'h3FFFF;
95 always @(posedge coreclk)
97 rsttimer <= 17'h3FFFF;
99 rsttimer <= rsttimer - 1;
100 assign rstact = rsttimer != 17'h0;
106 wire [7:0] sertxdata;
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));
115 always @(posedge coreclk)
117 {ps2_hasd, ps2_d} <= {1'b1, sertxdata};
119 {ps2_hasd, ps2_d} <= {1'b0, 8'hxxxxxxxx};
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))
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]);
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]);
150 iic_init #(.CLK_RATE_MHZ(31)) init (pixclk, 1'b1, 1'b0, dvi_sda, dvi_scl, wee);
157 output reg [11:0] x, y,
160 parameter XRES = 640;
161 parameter XFPORCH = 24;
162 parameter XSYNC = 40;
163 parameter XBPORCH = 128;
165 parameter YRES = 480;
166 parameter YFPORCH = 9;
168 parameter YBPORCH = 28;
170 always @(posedge pixclk)
172 if (x >= (XRES + XFPORCH + XSYNC + XBPORCH))
174 if (y >= (YRES + YFPORCH + YSYNC + YBPORCH))
181 hs <= (x >= (XRES + XFPORCH)) && (x < (XRES + XFPORCH + XSYNC));
182 vs <= (y >= (YRES + YFPORCH)) && (y < (YRES + YFPORCH + YSYNC));
183 border <= (x > XRES) || (y > YRES);
190 output wire [7:0] data);
192 reg [7:0] rom [(256 * 8 - 1):0];
195 $readmemb("ibmpc1.mem", rom);
197 assign data = rom[{char, row}];
203 output reg [7:0] rdata,
209 reg [7:0] ram [2047 : 0];
211 always @(posedge pixclk)
214 always @(posedge wclk)
223 output wire [10:0] raddr,
225 output wire [7:0] cschar,
226 output wire [2:0] csrow,
232 wire [7:0] col = x[11:3];
233 wire [5:0] row = y[10:4];
237 assign raddr = ({row,4'b0} + {row,6'b0} + {4'h0,col});
238 assign cschar = rchar;
239 assign csrow = y[3:1];
241 reg [23:0] blinktime = 0;
243 always @(posedge pixclk) blinktime <= blinktime + 1;
245 wire curssel = (cursx == col) && (cursy == row) && blinktime[23];
247 always @(posedge pixclk)
250 always @(posedge pixclk)
251 data = ((xdly < 80 * 8) && (y < 25 * 16)) ? (csdata[7 - xdly[2:0]] ^ curssel) : 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,
263 input [7:0] serdata);
265 parameter STATE_IDLE = 4'b0000;
266 parameter STATE_NEWLINE = 4'b0001;
267 parameter STATE_CLEAR = 4'b0010;
269 reg [3:0] state = STATE_CLEAR;
277 reg [10:0] clearstart = 0;
278 reg [10:0] clearend = 11'b11111111111;
280 always @(posedge clk25)
282 STATE_IDLE: if (serwr) begin
283 if (serdata == 8'h0A) begin
284 state <= STATE_NEWLINE;
287 end else if (serdata == 8'h0D) begin
290 end else if (serdata == 8'h0C) begin
292 clearend <= 11'b11111111111;
296 state <= STATE_CLEAR;
297 end else if (serdata == 8'h08) begin
303 vwaddr <= ({y,4'b0} + {y,6'b0} + {4'h0,x}) + vscroll;
307 state <= STATE_NEWLINE;
316 vscroll <= vscroll + 80;
317 clearstart <= (25 * 80) + vscroll;
318 clearend <= (26*80) + vscroll;
319 state <= STATE_CLEAR;
328 vwaddr <= clearstart;
330 clearstart <= clearstart + 1;
331 if (clearstart == clearend)
342 output reg [7:0] data
345 reg [3:0] bitcount = 0;
347 reg keyarrow = 0, keyup = 0, parity = 0;
350 /* Clock debouncing */
352 reg [6:0] debounce = 0;
354 reg [11:0] resetcountdown = 0;
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);
361 reg mod_capslock = 0;
362 wire mod_shifted = (mod_lshift | mod_rshift) ^ mod_capslock;
367 always @(posedge pixclk) begin
368 if (inclk != lastinclk) begin
371 resetcountdown <= 12'b111111111111;
372 end else if (debounce == 0) begin
374 resetcountdown <= resetcountdown - 1;
376 debounce <= debounce + 1;
378 if (nd ^ lastnd) begin
385 always @(negedge fixedclk) begin
386 if (resetcountdown == 0)
388 else if (bitcount == 10) begin
390 if(parity != (^ key)) begin
394 8'hxx: keyarrow <= 0;
402 8'h12: mod_lshift <= 0;
403 8'h59: mod_rshift <= 0;
405 // handle this? I don't fucking know
409 8'hE0: keyarrow <= 1; // handle these? I don't fucking know
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
425 bitcount <= bitcount + 1;