////////////////////////////////////////////////////////////////////////////////// // Author: lsilvest // // Create Date: 02/02/2008 // // Module Name: lcd_write_number // // Target Devices: Altera DE2 // // Tool versions: Quartus II 7.2 Web Edition // // Description: This module writes a 32-bit hexadecimal number to the LCD // display character by character using the lcd display module. // // To get initialization, commands and timing, use the datasheet // for the LCD part number CFAH1602B-TMS-JP supplied with the DE2 // CD-ROM in the datasheet folder. // //////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2008 Authors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. ///////////////////////////////////////////////////////////////////////////////// module lcd_write_number (input CLOCK_50, input [0:0] KEY, output LCD_EN, output LCD_RW, output LCD_RS, output [7:0] LCD_DATA, output LCD_ON, output LCD_BLON, input [31:0] if_data, input if_write, output if_ready ); // turn on LCD and backlight assign LCD_ON = 1'b1; assign LCD_BLON = 1'b0; reg [7:0] disp_data; reg disp_rs; reg [31:0] disp_delay; reg disp_write; wire disp_ready; reg [7:0] char; // up to 256 chars reg [1:0] state; reg [31:0] number; reg init_done; reg running; reg [4:0] shift_cntr; reg if_ready_r; assign if_ready = if_ready_r; parameter NB_CHARS = 8'd10; parameter START = 2'b00, WAIT_WRITE_0 = 2'b01, WRITE_1 = 2'b10, WAIT_WRITE_1 = 2'b11; lcd_display display (.clk(CLOCK_50), .rst(KEY[0]), .lcd_e(LCD_EN), .lcd_rw(LCD_RW), .lcd_rs(LCD_RS), .lcd_d(LCD_DATA), .if_data(disp_data), .if_rs(disp_rs), .if_delay(disp_delay), .if_write(disp_write), .if_ready(disp_ready) ); initial begin state <= 2'b00; char <= 8'b0; init_done <= 1'b0; if_ready_r <= 1'b0; shift_cntr <= 5'b0; end always@ (posedge CLOCK_50) begin if (init_done && char > 8'd14) begin if (disp_ready) if_ready_r <= 1'b1; if (if_write) begin char <= 4'd6; // reset the display end end else if (char <= 8'd14) begin if_ready_r <= 1'b0; case (state) START: if (disp_ready) begin disp_write <= 1'b1; state <= WAIT_WRITE_0; end WAIT_WRITE_0: state <= WRITE_1; WRITE_1: begin disp_write <= 1'b0; state <= 2'b11; end WAIT_WRITE_1: begin state <= START; char <= char + 8'b1; end endcase // case (state) end // else: !if(!running) end // always@ (posedge CLK_50MHZ) always@ (negedge CLOCK_50) begin case (char) 1: begin disp_data <= 8'h38; disp_delay <= 32'd2050000; disp_rs <= 1'b0; end 2: begin disp_data <= 8'h01; disp_delay <= 32'd1000000; end 3: begin disp_data <= 8'h0C; disp_delay <= 32'd2000; end 4: disp_data <= 8'h06; 5: begin disp_data <= 8'h80; init_done <= 1'b1; shift_cntr <= 5'd9; end 6: // this state provides an entry point to reset the display and then // go on to the default state that writes the number begin disp_rs <= 1'b0; disp_data <= 8'h01; disp_delay <= 32'd1000000; shift_cntr <= 5'b0; number <= if_data; end default: // state machine to print a 32-bit number out if (disp_ready && state == START) begin if (shift_cntr < 5'd8) begin disp_rs <= 1'b1; disp_delay <= 32'd20000; if (number[31:28] < 4'b1010) disp_data <= number[31:28] + 8'h30; else disp_data <= number[31:28] + 8'h37; number <= number << 4; shift_cntr <= shift_cntr + 5'b1; end end endcase // case (char) end endmodule