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