]> Joshua Wise's Git repositories - vterm.git/blame - VTerm.v
Add the serial transmit module.
[vterm.git] / VTerm.v
CommitLineData
a55fc9f4
JW
1module 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";
31endmodule
32
33module VTerm(
34 input xtal,
35 output wire vs, hs,
36 output reg [2:0] red,
37 output reg [2:0] green,
0491ebad 38 output reg [1:0] blue,
01e9841e
JW
39 input serrx,
40 output sertx,
41 input ps2c, ps2d);
a55fc9f4
JW
42
43 wire clk25;
44
45 wire [11:0] x, y;
46 wire border;
47
48 MulDivDCM dcm25(xtal, clk25);
49 defparam dcm25.div = 4;
50 defparam dcm25.mul = 2;
51
52 SyncGen sync(clk25, vs, hs, x, y, border);
53
d3ae999b
JW
54 wire [7:0] cschar;
55 wire [2:0] csrow;
56 wire [7:0] csdata;
57
7b96452d 58 wire [10:0] vraddr;
d3ae999b
JW
59 wire [7:0] vrdata;
60
7b96452d 61 wire [10:0] vwaddr;
0491ebad 62 wire [7:0] vwdata;
7b96452d
JW
63 wire [7:0] serdata;
64 wire vwr, serwr;
65 wire [10:0] vscroll;
d3ae999b
JW
66
67 wire odata;
68
69 CharSet cs(cschar, csrow, csdata);
7b96452d 70 VideoRAM vram(clk25, vraddr + vscroll, vrdata, vwaddr, vwdata, vwr);
d3ae999b 71 VDisplay dpy(clk25, x, y, vraddr, vrdata, cschar, csrow, csdata, odata);
7b96452d 72 SerRX rx(clk25, serwr, serdata, serrx);
01e9841e 73 SerTX tx(clk25, 0, 0, sertx);
7b96452d 74 RXState rxsm(clk25, vwr, vwaddr, vwdata, vscroll, serwr, serdata);
d3ae999b 75
a55fc9f4 76 always @(posedge clk25) begin
d3ae999b
JW
77 red <= border ? 0 : {3{odata}};
78 green <= border ? 0 : {3{odata}};
79 blue <= border ? 0 : {2{odata}};
a55fc9f4
JW
80 end
81endmodule
82
83module SyncGen(
84 input pixclk,
85 output reg vs, hs,
86 output reg [11:0] x, y,
87 output reg border);
88
89 parameter XRES = 640;
90 parameter XFPORCH = 16;
91 parameter XSYNC = 96;
92 parameter XBPORCH = 48;
93
94 parameter YRES = 480;
95 parameter YFPORCH = 10;
96 parameter YSYNC = 2;
97 parameter YBPORCH = 29;
98
99 always @(posedge pixclk)
100 begin
101 if (x >= (XRES + XFPORCH + XSYNC + XBPORCH))
102 begin
103 if (y >= (YRES + YFPORCH + YSYNC + YBPORCH))
104 y = 0;
105 else
106 y = y + 1;
107 x = 0;
108 end else
109 x = x + 1;
110 hs <= (x >= (XRES + XFPORCH)) && (x < (XRES + XFPORCH + XSYNC));
111 vs <= (y >= (YRES + YFPORCH)) && (y < (YRES + YFPORCH + YSYNC));
112 border <= (x > XRES) || (y > YRES);
113 end
114endmodule
d3ae999b
JW
115
116module CharSet(
117 input [7:0] char,
118 input [2:0] row,
119 output wire [7:0] data);
120
121 reg [7:0] rom [(256 * 8 - 1):0];
122
123 initial
124 $readmemb("ibmpc1.mem", rom);
125
126 assign data = rom[{char, row}];
127endmodule
128
129module VideoRAM(
130 input pixclk,
7b96452d 131 input [10:0] raddr,
d3ae999b 132 output reg [7:0] rdata,
7b96452d 133 input [10:0] waddr,
d3ae999b
JW
134 input [7:0] wdata,
135 input wr);
136
7b96452d 137 reg [7:0] ram [2047 : 0];
d3ae999b
JW
138
139 always @(posedge pixclk)
140 rdata <= ram[raddr];
141
142 always @(posedge pixclk)
143 if (wr)
144 ram[waddr] <= wdata;
145endmodule
146
147module VDisplay(
148 input pixclk,
149 input [11:0] x,
150 input [11:0] y,
7b96452d 151 output wire [10:0] raddr,
d3ae999b
JW
152 input [7:0] rchar,
153 output wire [7:0] cschar,
154 output wire [2:0] csrow,
155 input [7:0] csdata,
01e9841e 156 output reg data);
d3ae999b
JW
157
158 wire [7:0] col = x[11:3];
159 wire [5:0] row = y[9:3];
160 reg [7:0] ch;
161 reg [11:0] xdly;
162
163 assign raddr = ({row,4'b0} + {row,6'b0} + {4'h0,col});
164 assign cschar = rchar;
165 assign csrow = y[2:0];
166
167 always @(posedge pixclk)
168 xdly <= x;
169
170 always @(posedge pixclk)
171 data = ((xdly < 80 * 8) && (y < 25 * 8)) ? csdata[7 - xdly[2:0]] : 0;
172endmodule
0491ebad
JW
173
174`define IN_CLK 25000000
175`define OUT_CLK 57600
176`define CLK_DIV (`IN_CLK / `OUT_CLK)
177
178module SerRX(
179 input pixclk,
180 output reg wr = 0,
0491ebad 181 output reg [7:0] wchar = 0,
01e9841e 182 input serialrx);
0491ebad
JW
183
184 reg [15:0] rx_clkdiv = 0;
185 reg [3:0] rx_state = 4'b0000;
186 reg [7:0] rx_data_tmp;
187
188
189 always @(posedge pixclk)
190 begin
191 if ((rx_state == 0) && (serialrx == 0) /*&& (rx_hasdata == 0)*/) /* Kick off. */
192 rx_state <= 4'b0001;
193 else if ((rx_state != 4'b0000) && (rx_clkdiv == 0)) begin
194 if (rx_state != 4'b1010)
195 rx_state <= rx_state + 1;
196 else
197 rx_state <= 0;
198 case (rx_state)
199 4'b0001: begin end /* Twiddle thumbs -- this is the end of the half bit. */
200 4'b0010: rx_data_tmp[0] <= serialrx;
201 4'b0011: rx_data_tmp[1] <= serialrx;
202 4'b0100: rx_data_tmp[2] <= serialrx;
203 4'b0101: rx_data_tmp[3] <= serialrx;
204 4'b0110: rx_data_tmp[4] <= serialrx;
205 4'b0111: rx_data_tmp[5] <= serialrx;
206 4'b1000: rx_data_tmp[6] <= serialrx;
207 4'b1001: rx_data_tmp[7] <= serialrx;
208 4'b1010: if (serialrx == 1) begin
209 wr <= 1;
210 wchar <= rx_data_tmp;
211 end
212 endcase
213 end
214
7b96452d 215 if (wr)
0491ebad 216 wr <= 0;
0491ebad
JW
217
218 if ((rx_state == 0) && (serialrx == 0) /*&& (rx_hasdata == 0)*/) /* Wait half a period before advancing. */
219 rx_clkdiv <= `CLK_DIV / 2 + `CLK_DIV / 4;
220 else if (rx_clkdiv == `CLK_DIV)
221 rx_clkdiv <= 0;
222 else
223 rx_clkdiv <= rx_clkdiv + 1;
224 end
01e9841e
JW
225endmodule
226
227module SerTX(
228 input pixclk,
229 input wr,
230 input [7:0] char,
231 output reg serial = 1);
232
233 reg [7:0] tx_data = 0;
234 reg [15:0] tx_clkdiv = 0;
235 reg [3:0] tx_state = 4'b0000;
236 reg tx_busy = 0;
237 wire tx_newdata = wr && !tx_busy;
0491ebad 238
01e9841e
JW
239 always @(posedge pixclk)
240 begin
241 if(tx_newdata) begin
242 tx_data <= char;
243 tx_state <= 4'b0000;
244 tx_busy <= 1;
245 end else if (tx_clkdiv == 0) begin
246 tx_state <= tx_state + 1;
247 if (tx_busy)
248 case (tx_state)
249 4'b0000: serial <= 0;
250 4'b0001: serial <= tx_data[0];
251 4'b0010: serial <= tx_data[1];
252 4'b0011: serial <= tx_data[2];
253 4'b0100: serial <= tx_data[3];
254 4'b0101: serial <= tx_data[4];
255 4'b0110: serial <= tx_data[5];
256 4'b0111: serial <= tx_data[6];
257 4'b1000: serial <= tx_data[7];
258 4'b1001: serial <= 1;
259 4'b1010: tx_busy <= 0;
260 default: $stop;
261 endcase
262 end
263
264 if(tx_newdata || (tx_clkdiv == `CLK_DIV))
265 tx_clkdiv <= 0;
266 else
267 tx_clkdiv <= tx_clkdiv + 1;
268 end
0491ebad 269endmodule
7b96452d
JW
270
271module RXState(
272 input clk25,
273 output reg vwr = 0,
274 output reg [10:0] vwaddr = 0,
275 output reg [7:0] vwdata = 0,
276 output reg [10:0] vscroll = 0,
277 input serwr,
278 input [7:0] serdata);
279
280 parameter STATE_IDLE = 4'b0000;
281 parameter STATE_NEWLINE = 4'b0001;
282 parameter STATE_CLEAR = 4'b0010;
283
284 reg [3:0] state = STATE_CLEAR;
285
286 reg [6:0] x = 0;
287 reg [4:0] y = 0;
288
289 reg [10:0] clearstart = 0;
290 reg [10:0] clearend = 11'b11111111111;
291
292 always @(posedge clk25)
293 case (state)
294 STATE_IDLE: if (serwr) begin
295 if (serdata == 8'h0A) begin
296 state <= STATE_NEWLINE;
297 vwr <= 0;
298 end else if (serdata == 8'h0D) begin
299 x <= 0;
300 vwr <= 0;
301 end else if (serdata == 8'h0C) begin
302 clearstart <= 0;
303 clearend <= 11'b11111111111;
304 x <= 0;
305 y <= 0;
306 vscroll <= 0;
307 state <= STATE_CLEAR;
308 end else begin
309 vwr <= 1;
310 vwaddr <= ({y,4'b0} + {y,6'b0} + {4'h0,x}) + vscroll;
311 vwdata <= serdata;
312 if (x == 79) begin
313 x <= 0;
314 state <= STATE_NEWLINE;
315 end else
316 x <= x + 1;
317 end
318 end
319 STATE_NEWLINE:
320 begin
321 vwr <= 0;
322 if (y == 24) begin
323 vscroll <= vscroll + 80;
324 clearstart <= (25 * 80) + vscroll;
325 clearend <= (26*80) + vscroll;
326 state <= STATE_CLEAR;
327 end else begin
328 y <= y + 1;
329 state <= STATE_IDLE;
330 end
331 end
332 STATE_CLEAR:
333 begin
334 vwr <= 1;
335 vwaddr <= clearstart;
336 vwdata <= 8'h20;
337 clearstart <= clearstart + 1;
338 if (clearstart == clearend)
339 state <= STATE_IDLE;
340 end
341 endcase
342endmodule
This page took 0.052102 seconds and 4 git commands to generate.