]> Joshua Wise's Git repositories - firearm.git/blobdiff - xst/Console.v
xst: Add synthesis files (part 1).
[firearm.git] / xst / Console.v
diff --git a/xst/Console.v b/xst/Console.v
new file mode 100644 (file)
index 0000000..5f5e2da
--- /dev/null
@@ -0,0 +1,436 @@
+module MulDivDCM(input xtal, output clk, output clk90);
+       parameter div = 8;
+       parameter mul = 2;
+       
+       wire CLKFX_BUF;
+       wire CLK0_BUF;
+       wire CLK90_BUF;
+       wire clkfx;
+       wire GND_BIT = 0;
+       BUFG CLK0_BUFG_INST (.I(CLK0_BUF),
+                               .O(clk));
+       BUFG CLK90_BUFG_INST (.I(CLK90_BUF),
+                               .O(clk90));
+       BUFG CLKFX_BUFG_INST (.I(CLKFX_BUF),
+                               .O(clkfx));
+       
+       DCM_BASE DCM_INST2(.CLKFB(clk), 
+                       .CLKIN(clkfx),
+                       .RST(GND_BIT),
+                       .CLK0(CLK0_BUF),
+                       .CLK90(CLK90_BUF));
+       
+       DCM_BASE DCM_INST (.CLKFB(GND_BIT), 
+                       .CLKIN(xtal), 
+                       .RST(GND_BIT),
+                       .CLKFX(CLKFX_BUF));
+       defparam DCM_INST.CLK_FEEDBACK = "NONE";
+       defparam DCM_INST.CLKDV_DIVIDE = 2.0;
+       defparam DCM_INST.CLKFX_DIVIDE = div;
+       defparam DCM_INST.CLKFX_MULTIPLY = mul;
+       defparam DCM_INST.CLKIN_DIVIDE_BY_2 = "FALSE";
+       defparam DCM_INST.CLKIN_PERIOD = 10.000;
+       defparam DCM_INST.CLKOUT_PHASE_SHIFT = "NONE";
+       defparam DCM_INST.DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS";
+       defparam DCM_INST.DFS_FREQUENCY_MODE = "LOW";
+       defparam DCM_INST.DLL_FREQUENCY_MODE = "LOW";
+       defparam DCM_INST.DUTY_CYCLE_CORRECTION = "TRUE";
+       defparam DCM_INST.FACTORY_JF = 16'hC080;
+       defparam DCM_INST.PHASE_SHIFT = 0;
+       defparam DCM_INST.STARTUP_WAIT = "TRUE";
+endmodule
+
+`include "iic_init.v"
+
+module Console(
+       input xtal,
+       input rst,
+       output wire rstact,
+       output wire dvi_vs, dvi_hs,
+       output wire [11:0] dvi_d,
+       output wire dvi_xclk_p, dvi_xclk_n,
+       output wire dvi_de,
+       output wire dvi_reset_b,
+       inout wire dvi_sda,
+       inout wire dvi_scl,
+       input ps2c, ps2d);
+       
+       assign dvi_reset_b = 1'b1;
+       
+       wire clk25, clk25_90;
+
+       wire [11:0] x, y;
+       wire border;
+
+       MulDivDCM dcm25(xtal, clk25, clk25_90);
+       defparam dcm25.div = 16;
+       defparam dcm25.mul = 5;
+       
+       wire vs, hs;
+       SyncGen sync(clk25, vs, hs, x, y, border);
+       
+       wire [7:0] cschar;
+       wire [2:0] csrow;
+       wire [7:0] csdata;
+       
+       wire [10:0] vraddr;
+       wire [7:0] vrdata;
+       
+       wire [10:0] vwaddr;
+       wire [7:0] vwdata;
+       wire [7:0] serdata;
+       wire vwr, serwr;
+       wire [10:0] vscroll;
+       
+       wire odata;
+       
+       wire [6:0] vcursx;
+       wire [4:0] vcursy;
+       
+       reg [16:0] rsttimer = 17'h3FFFF;
+       always @(posedge clk25)
+               if (~rst)
+                       rsttimer <= 17'h3FFFF;
+               else if (rsttimer)
+                       rsttimer <= rsttimer - 1;
+       assign rstact = rsttimer != 17'h0;
+       
+       wire tookdata;
+       reg ps2_hasd = 0;
+       reg [7:0] ps2_d = 0;
+       wire sertxwr;
+       wire [7:0] sertxdata;
+       
+       CharSet cs(cschar, csrow, csdata);
+       VideoRAM vram(clk25, vraddr + vscroll, vrdata, clk25, vwaddr, vwdata, vwr);
+       VDisplay dpy(clk25, x, y, vraddr, vrdata, cschar, csrow, csdata, vcursx, vcursy, odata);
+       RXState rxsm(clk25, vwr, vwaddr, vwdata, vscroll, vcursx, vcursy, serwr, serdata);
+       PS2 ps2(clk25, ps2c, ps2d, sertxwr, sertxdata);
+       System sys(.clk(clk25), .rst(rstact), .sys_odata({serwr, serdata}), .sys_idata({ps2_hasd, ps2_d}), .sys_tookdata(tookdata));
+       
+       always @(posedge clk25)
+               if (sertxwr)
+                       {ps2_hasd, ps2_d} <= {1'b1, sertxdata};
+               else if (tookdata)
+                       {ps2_hasd, ps2_d} <= {1'b0, 8'hxxxxxxxx};
+       
+       /* FUCK! ASS! BALLS! EAT MY SHORT DICK! FUCKING XST */
+       /* EMSD stands for Eat My Short Dick.  Because XST should. */
+`define MAKE_DDR(n,q,d1,d2) ODDR n (.C(clk25), .Q(q), .D1(d1), .D2(d2), .R(0), .S(0), .CE(1))
+`define MAKE_DDR90(n,q,d1,d2) ODDR n (.C(clk25_90), .Q(q), .D1(d1), .D2(d2), .R(0), .S(0), .CE(1))
+       
+       wire [7:0] red, green, blue;
+       assign red   = (odata ? 8'hFF : 0) | (x[8:2] ^ y[7:1]);
+       assign green = (odata ? 8'hFF : 0) | (x[7:1] ^ y[8:2]);
+       assign blue  = (odata ? 8'hFF : 0) | (x[8:2] ^ y[8:2]);
+       
+       `MAKE_DDR90(EMSD_dvi_xclk_p, dvi_xclk_p, 1'b1, 1'b0);
+       `MAKE_DDR90(EMSD_dvi_xclk_n, dvi_xclk_n, 1'b0, 1'b1);
+       `MAKE_DDR(EMSD_dvi_de, dvi_de, ~border, ~border);
+       `MAKE_DDR(EMSD_dvi_vs, dvi_vs, vs, vs);
+       `MAKE_DDR(EMSD_dvi_hs, dvi_hs, hs, hs);
+       `MAKE_DDR(EMSD_dvi_d_0, dvi_d[0], blue[0], green[4]);
+       `MAKE_DDR(EMSD_dvi_d_1, dvi_d[1], blue[1], green[5]);
+       `MAKE_DDR(EMSD_dvi_d_2, dvi_d[2], blue[2], green[6]);
+       `MAKE_DDR(EMSD_dvi_d_3, dvi_d[3], blue[3], green[7]);
+       `MAKE_DDR(EMSD_dvi_d_4, dvi_d[4], blue[4], red[0]);
+       `MAKE_DDR(EMSD_dvi_d_5, dvi_d[5], blue[5], red[1]);
+       `MAKE_DDR(EMSD_dvi_d_6, dvi_d[6], blue[6], red[2]);
+       `MAKE_DDR(EMSD_dvi_d_7, dvi_d[7], blue[7], red[3]);
+       `MAKE_DDR(EMSD_dvi_d_8, dvi_d[8], green[0], red[4]);
+       `MAKE_DDR(EMSD_dvi_d_9, dvi_d[9], green[1], red[5]);
+       `MAKE_DDR(EMSD_dvi_d_10, dvi_d[10], green[2], red[6]);
+       `MAKE_DDR(EMSD_dvi_d_11, dvi_d[11], green[3], red[7]);
+       
+       wire wee;
+       iic_init #(.CLK_RATE_MHZ(31)) init (clk25, 1'b1, 1'b0, dvi_sda, dvi_scl, wee);
+
+endmodule
+
+module SyncGen(
+       input pixclk,
+       output reg vs, hs,
+       output reg [11:0] x, y,
+       output reg border);
+       
+       parameter XRES = 640;
+       parameter XFPORCH = 24;
+       parameter XSYNC = 40;
+       parameter XBPORCH = 128;
+       
+       parameter YRES = 480;
+       parameter YFPORCH = 9;
+       parameter YSYNC = 3;
+       parameter YBPORCH = 28;
+       
+       always @(posedge pixclk)
+       begin
+               if (x >= (XRES + XFPORCH + XSYNC + XBPORCH))
+               begin
+                       if (y >= (YRES + YFPORCH + YSYNC + YBPORCH))
+                               y = 0;
+                       else
+                               y = y + 1;
+                       x = 0;
+               end else
+                       x = x + 1;
+               hs <= (x >= (XRES + XFPORCH)) && (x < (XRES + XFPORCH + XSYNC));
+               vs <= (y >= (YRES + YFPORCH)) && (y < (YRES + YFPORCH + YSYNC));
+               border <= (x > XRES) || (y > YRES);
+       end
+endmodule
+
+module CharSet(
+       input [7:0] char,
+       input [2:0] row,
+       output wire [7:0] data);
+
+       reg [7:0] rom [(256 * 8 - 1):0];
+       
+       initial
+               $readmemb("ibmpc1.mem", rom);
+
+       assign data = rom[{char, row}];
+endmodule
+
+module VideoRAM(
+       input pixclk,
+       input [10:0] raddr,
+       output reg [7:0] rdata,
+       input wclk,
+       input [10:0] waddr,
+       input [7:0] wdata,
+       input wr);
+       
+       reg [7:0] ram [2047 : 0];
+       
+       always @(posedge pixclk)
+               rdata <= ram[raddr];
+       
+       always @(posedge wclk)
+               if (wr)
+                       ram[waddr] <= wdata;
+endmodule
+
+module VDisplay(
+       input pixclk,
+       input [11:0] x,
+       input [11:0] y,
+       output wire [10:0] raddr,
+       input [7:0] rchar,
+       output wire [7:0] cschar,
+       output wire [2:0] csrow,
+       input [7:0] csdata,
+       input [6:0] cursx,
+       input [4:0] cursy,
+       output reg data);
+
+       wire [7:0] col = x[11:3];
+       wire [5:0] row = y[10:4];
+       reg [7:0] ch;
+       reg [11:0] xdly;
+
+       assign raddr = ({row,4'b0} + {row,6'b0} + {4'h0,col});
+       assign cschar = rchar;
+       assign csrow = y[3:1];
+       
+       reg [23:0] blinktime = 0;
+       
+       always @(posedge pixclk) blinktime <= blinktime + 1;
+       
+       wire curssel = (cursx == col) && (cursy == row) && blinktime[23];
+       
+       always @(posedge pixclk)
+               xdly <= x;
+       
+       always @(posedge pixclk)
+               data = ((xdly < 80 * 8) && (y < 25 * 16)) ? (csdata[7 - xdly[2:0]] ^ curssel) : 0;
+endmodule
+
+module RXState(
+       input clk25,
+       output reg vwr = 0,
+       output reg [10:0] vwaddr = 0,
+       output reg [7:0] vwdata = 0,
+       output reg [10:0] vscroll = 0,
+       output wire [6:0] vcursx,
+       output wire [4:0] vcursy,
+       input serwr,
+       input [7:0] serdata);
+
+       parameter STATE_IDLE = 4'b0000;
+       parameter STATE_NEWLINE = 4'b0001;
+       parameter STATE_CLEAR = 4'b0010;
+
+       reg [3:0] state = STATE_CLEAR;
+       
+       reg [6:0] x = 0;
+       reg [4:0] y = 0;
+       
+       assign vcursx = x;
+       assign vcursy = y;
+       
+       reg [10:0] clearstart = 0;
+       reg [10:0] clearend = 11'b11111111111;
+       
+       always @(posedge clk25)
+               case (state)
+               STATE_IDLE:     if (serwr) begin
+                                       if (serdata == 8'h0A) begin
+                                               state <= STATE_NEWLINE;
+                                               x <= 0;
+                                               vwr <= 0;
+                                       end else if (serdata == 8'h0D) begin
+                                               x <= 0;
+                                               vwr <= 0;
+                                       end else if (serdata == 8'h0C) begin
+                                               clearstart <= 0;
+                                               clearend <= 11'b11111111111;
+                                               x <= 0;
+                                               y <= 0;
+                                               vscroll <= 0;
+                                               state <= STATE_CLEAR;
+                                       end else if (serdata == 8'h08) begin
+                                               if (x != 0)
+                                                       x <= x - 1;
+                                               vwr <= 0;
+                                       end else begin
+                                               vwr <= 1;
+                                               vwaddr <= ({y,4'b0} + {y,6'b0} + {4'h0,x}) + vscroll;
+                                               vwdata <= serdata;
+                                               if (x == 79) begin
+                                                       x <= 0;
+                                                       state <= STATE_NEWLINE;
+                                               end else 
+                                                       x <= x + 1;
+                                       end
+                               end
+               STATE_NEWLINE:
+                       begin
+                               vwr <= 0;
+                               if (y == 24) begin
+                                       vscroll <= vscroll + 80;
+                                       clearstart <= (25 * 80) + vscroll;
+                                       clearend <= (26*80) + vscroll;
+                                       state <= STATE_CLEAR;
+                               end else begin
+                                       y <= y + 1;
+                                       state <= STATE_IDLE;
+                               end
+                       end
+               STATE_CLEAR:
+                       begin
+                               vwr <= 1;
+                               vwaddr <= clearstart;
+                               vwdata <= 8'h20;
+                               clearstart <= clearstart + 1;
+                               if (clearstart == clearend)
+                                       state <= STATE_IDLE;
+                       end
+               endcase
+endmodule
+
+module PS2(
+       input pixclk,
+       input inclk,
+       input indata,
+       output reg wr,
+       output reg [7:0] data
+       );
+
+       reg [3:0] bitcount = 0;
+       reg [7:0] key = 0;
+       reg keyarrow = 0, keyup = 0, parity = 0;
+
+       
+       /* Clock debouncing */
+       reg lastinclk = 0;
+       reg [6:0] debounce = 0;
+       reg fixedclk = 0;
+       reg [11:0] resetcountdown = 0;
+       
+       reg [6:0] unshiftedrom [127:0]; initial $readmemh("scancodes.unshifted.hex", unshiftedrom);
+       reg [6:0] shiftedrom [127:0];   initial $readmemh("scancodes.shifted.hex", shiftedrom);
+       
+       reg mod_lshift = 0;
+       reg mod_rshift = 0;
+       reg mod_capslock = 0;
+       wire mod_shifted = (mod_lshift | mod_rshift) ^ mod_capslock;
+       
+       reg nd = 0;
+       reg lastnd = 0;
+       
+       always @(posedge pixclk) begin
+               if (inclk != lastinclk) begin
+                       lastinclk <= inclk;
+                       debounce <= 1;
+                       resetcountdown <= 12'b111111111111;
+               end else if (debounce == 0) begin
+                       fixedclk <= inclk;
+                       resetcountdown <= resetcountdown - 1;
+               end else
+                       debounce <= debounce + 1;
+               
+               if (nd ^ lastnd) begin
+                       lastnd <= nd;
+                       wr <= 1;
+               end else
+                       wr <= 0;
+       end
+
+       always @(negedge fixedclk) begin
+               if (resetcountdown == 0)
+                       bitcount <= 0;
+               else if (bitcount == 10) begin
+                       bitcount <= 0;
+                       if(parity != (^ key)) begin
+                               if(keyarrow) begin
+                                       casex(key)
+                                               8'hF0: keyup <= 1;
+                                               8'hxx: keyarrow <= 0;
+                                       endcase
+                               end
+                               else begin
+                                       if(keyup) begin
+                                               keyup <= 0;
+                                               keyarrow <= 0;
+                                               casex (key)
+                                               8'h12: mod_lshift <= 0;
+                                               8'h59: mod_rshift <= 0;
+                                               endcase
+                                               // handle this? I don't fucking know
+                                       end
+                                       else begin
+                                               casex(key)
+                                                       8'hE0: keyarrow <= 1;   // handle these? I don't fucking know
+                                                       8'hF0: keyup <= 1;
+                                                       8'h12: mod_lshift <= 1;
+                                                       8'h59: mod_rshift <= 1;
+                                                       8'h14: mod_capslock <= ~mod_capslock;
+                                                       8'b0xxxxxxx: begin nd <= ~nd; data <= mod_shifted ? shiftedrom[key] : unshiftedrom[key]; end
+                                                       8'b1xxxxxxx: begin /* AAAAAAASSSSSSSS */ end
+                                               endcase
+                                       end
+                               end
+                       end
+                       else begin
+                               keyarrow <= 0;
+                               keyup <= 0;
+                       end
+               end else
+                       bitcount <= bitcount + 1;
+
+               case(bitcount)
+                       1: key[0] <= indata;
+                       2: key[1] <= indata;
+                       3: key[2] <= indata;
+                       4: key[3] <= indata;
+                       5: key[4] <= indata;
+                       6: key[5] <= indata;
+                       7: key[6] <= indata;
+                       8: key[7] <= indata;
+                       9: parity <= indata;
+               endcase
+       end
+
+endmodule
This page took 0.03423 seconds and 4 git commands to generate.