5 parameter LAST_ROW = (ROWS-1) * COLS,
6 parameter ONE_PAST_LAST_ROW = ROWS * COLS,
7 parameter ROW_BITS = 5,
8 parameter COL_BITS = 7,
9 parameter ADDR_BITS = 11)
16 output [ADDR_BITS-1:0] new_first_char,
17 output new_first_char_wen,
18 output [7:0] new_char,
19 output [ADDR_BITS-1:0] new_char_address,
21 output [COL_BITS-1:0] new_cursor_x,
22 output [ROW_BITS-1:0] new_cursor_y,
23 output new_cursor_wen,
29 reg [ADDR_BITS-1:0] new_char_address_q;
31 reg [COL_BITS-1:0] new_cursor_x_q;
32 reg [ROW_BITS-1:0] new_cursor_y_q;
34 reg [ADDR_BITS-1:0] new_first_char_q;
35 reg new_first_char_wen_q;
37 reg [ROW_BITS-1:0] new_row;
38 reg [COL_BITS-1:0] new_col;
42 reg [ADDR_BITS:0] new_addr;
43 reg [ADDR_BITS-1:0] last_char_to_erase;
45 reg [ADDR_BITS-1:0] current_row_addr;
46 reg [ADDR_BITS-1:0] current_char_addr;
53 localparam state_char = 8'b00000001;
54 localparam state_esc = 8'b00000010;
55 localparam state_row = 8'b00000100;
56 localparam state_col = 8'b00001000;
57 localparam state_addr = 8'b00010000;
58 localparam state_cursor = 8'b00100000;
59 localparam state_erase = 8'b01000000;
66 assign ready = (state & (state_erase | state_cursor | state_addr)) == 0;
67 assign new_char = new_char_q;
68 assign new_char_address = new_char_address_q;
69 assign new_char_wen = new_char_wen_q;
70 assign new_cursor_x = new_cursor_x_q;
71 assign new_cursor_y = new_cursor_y_q;
72 assign new_cursor_wen = new_cursor_wen_q;
73 assign new_first_char = new_first_char_q;
74 assign new_first_char_wen = new_first_char_wen_q;
75 assign graphic_mode = graphic_mode_set;
77 always @(posedge clk) begin
80 new_char_address_q <= 0;
85 new_cursor_wen_q <= 0;
87 current_row_addr <= 0;
88 current_char_addr <= 0;
90 new_first_char_q <= 0;
91 new_first_char_wen_q <= 0;
97 last_char_to_erase <= 0;
98 graphic_mode_set <= 0;
102 if (new_char_wen_q) new_char_wen_q <= 0;
103 if (new_cursor_wen_q) new_cursor_wen_q <= 0;
104 if (new_first_char_wen_q) new_first_char_wen_q <= 0;
106 if (ready && valid) begin
110 if (data >= 8'h20 && data != 8'h7f) begin
113 new_char_address_q <= current_char_addr;
116 if (new_cursor_x_q != (COLS-1)) begin
117 new_cursor_x_q <= new_cursor_x_q + 1;
118 current_char_addr <= current_char_addr + 1;
119 new_cursor_wen_q <= 1;
126 if (new_cursor_x_q != 0) begin
127 new_cursor_x_q <= new_cursor_x_q - 1;
128 current_char_addr <= current_char_addr - 1;
129 new_cursor_wen_q <= 1;
135 if (new_cursor_x_q < (COLS-9)) begin
136 new_cursor_x_q <= {(new_cursor_x_q[COL_BITS-1:3]+1), 3'b000};
137 current_char_addr <= {(current_char_addr[ADDR_BITS-1:3]+1), 3'b000};
138 new_cursor_wen_q <= 1;
140 else if (new_cursor_x_q != (COLS-1)) begin
141 new_cursor_x_q <= new_cursor_x_q + 1;
142 current_char_addr <= current_char_addr + 1;
143 new_cursor_wen_q <= 1;
148 if (new_cursor_y_q == (ROWS-1)) begin
149 new_first_char_q <= new_first_char_q == LAST_ROW?
150 0 : new_first_char_q + COLS;
152 if (current_row_addr == LAST_ROW) begin
153 current_row_addr <= 0;
154 current_char_addr <= new_cursor_x_q;
157 current_row_addr <= current_row_addr + COLS;
158 current_char_addr <= current_char_addr + COLS;
160 new_first_char_wen_q <= 1;
163 new_char_address_q <= new_first_char_q;
165 last_char_to_erase <= new_first_char_q + (COLS-1);
166 state <= state_erase;
169 new_cursor_y_q <= new_cursor_y_q + 1;
170 new_cursor_wen_q <= 1;
171 if (current_row_addr == LAST_ROW) begin
172 current_row_addr <= 0;
173 current_char_addr <= new_cursor_x_q;
176 current_row_addr <= current_row_addr + COLS;
177 current_char_addr <= current_char_addr + COLS;
183 if (new_cursor_x != 0) begin
185 new_cursor_wen_q <= 1;
186 current_char_addr <= current_row_addr;
201 if (new_cursor_y_q != (ROWS-1)) begin
202 new_cursor_y_q <= new_cursor_y_q + 1;
203 new_cursor_wen_q <= 1;
204 if (current_row_addr == LAST_ROW) begin
205 current_row_addr <= 0;
206 current_char_addr <= new_cursor_x_q;
209 current_row_addr <= current_row_addr + COLS;
210 current_char_addr <= current_char_addr + COLS;
216 if (new_cursor_y_q == 0) begin
217 if (new_first_char_q == 0) begin
218 new_first_char_q <= LAST_ROW;
219 current_row_addr <= LAST_ROW;
220 current_char_addr <= LAST_ROW + new_cursor_x_q;
222 new_char_address_q <= LAST_ROW;
223 last_char_to_erase <= LAST_ROW+(COLS-1);
226 new_first_char_q <= new_first_char_q - COLS;
227 current_row_addr <= current_row_addr - COLS;
228 current_char_addr <= current_char_addr - COLS;
230 new_char_address_q <= new_first_char_q - COLS;
231 last_char_to_erase <= new_first_char_q - 1;
233 new_first_char_wen_q <= 1;
237 state <= state_erase;
240 new_cursor_y_q <= new_cursor_y_q - 1;
241 new_cursor_wen_q <= 1;
242 if (current_row_addr == 0) begin
243 current_row_addr <= LAST_ROW;
244 current_char_addr <= LAST_ROW + new_cursor_x_q;
247 current_row_addr <= current_row_addr - COLS;
248 current_char_addr <= current_char_addr - COLS;
254 if (new_cursor_y_q != 0) begin
255 new_cursor_y_q <= new_cursor_y_q - 1;
256 new_cursor_wen_q <= 1;
257 if (current_row_addr == 0) begin
258 current_row_addr <= LAST_ROW;
259 current_char_addr <= LAST_ROW + new_cursor_x_q;
262 current_row_addr <= current_row_addr - COLS;
263 current_char_addr <= current_char_addr - COLS;
269 if (new_cursor_x_q != (COLS-1)) begin
270 new_cursor_x_q <= new_cursor_x_q + 1;
271 new_cursor_wen_q <= 1;
272 current_char_addr <= current_char_addr+1;
277 if (new_cursor_x_q != 0) begin
278 new_cursor_x_q <= new_cursor_x_q - 1;
279 new_cursor_wen_q <= 1;
280 current_char_addr <= current_char_addr-1;
289 new_cursor_wen_q <= 1;
290 current_row_addr <= new_first_char_q;
291 current_char_addr <= new_first_char_q;
302 new_char_address_q <= current_char_addr;
304 last_char_to_erase <= current_row_addr + (COLS-1);
305 state <= state_erase;
310 new_char_address_q <= current_char_addr;
312 last_char_to_erase <= new_first_char_q == 0?
313 LAST_ROW+(COLS-1): new_first_char_q-1;
314 state <= state_erase;
318 graphic_mode_set <= 1;
322 graphic_mode_set <= 0;
339 new_row <= (data >= 8'h20 && data < (8'h20 + ROWS))?
340 data - 8'h20 : new_cursor_y;
346 new_col <= (data >= 8'h20 && data < (8'h20 + COLS))?
347 data - 8'h20 : (COLS-1);
351 new_addr <= new_row * 80 + new_first_char_q;
361 if (new_char_address_q == last_char_to_erase) begin
367 new_char_address_q = new_char_address_q == LAST_ROW + (COLS+1)?
368 0 : new_char_address_q + 1;
375 new_addr <= new_addr > LAST_ROW? new_addr - ONE_PAST_LAST_ROW : new_addr;
376 state <= state_cursor;
380 new_cursor_x_q <= new_col;
381 new_cursor_y_q <= new_row;
382 new_cursor_wen_q <= 1;
384 current_row_addr <= new_addr[ADDR_BITS-1:0];
385 current_char_addr <= new_addr + new_col;
module command_handler(input clk, input reset, input[8] data, input valid, output ready, output[ADDR_BITS-1:0] new_first_char, output new_first_char_wen, output[8] new_char, output[ADDR_BITS-1:0] new_char_address, output new_char_wen, output[COL_BITS-1:0] new_cursor_x, output[ROW_BITS-1:0] new_cursor_y, output new_cursor_wen, output graphic_mode)