lcdlab2.v
module lcdlab2( input CLOCK_50, // 50 MHz clock input [3:0] KEY, // Pushbutton[3:0] input [17:0] SW, // Toggle Switch[17:0] output [6:0] HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,HEX6,HEX7, // Seven Segment Digits output [8:0] LEDG, // LED Green output [17:0] LEDR, // LED Red inout [35:0] GPIO_0,GPIO_1, // GPIO Connections // LCD Module 16X2 output LCD_ON, // LCD Power ON/OFF output LCD_BLON, // LCD Back Light ON/OFF output LCD_RW, // LCD Read/Write Select, 0 = Write, 1 = Read output LCD_EN, // LCD Enable output LCD_RS, // LCD Command/Data Select, 0 = Command, 1 = Data inout [7:0] LCD_DATA // LCD Data bus 8 bits ); // All inout port turn to tri-state assign GPIO_0 = 36'hzzzzzzzzz; assign GPIO_1 = 36'hzzzzzzzzz; // reset delay gives some time for peripherals to initialize wire DLY_RST; Reset_Delay r0( .iCLK(CLOCK_50),.oRESET(DLY_RST) ); // Send switches to red leds assign LEDR = SW; assign LEDG[8:0] = 9'h000; // blank unused 7-segment digits assign HEX0 = 7'b111_1111; assign HEX1 = 7'b111_1111; assign HEX2 = 7'b111_1111; assign HEX3 = 7'b111_1111; assign HEX4 = 7'b111_1111; assign HEX5 = 7'b111_1111; assign HEX6 = 7'b111_1111; assign HEX7 = 7'b111_1111; // Setup clock divider wire [6:0] myclock; wire RST; assign RST = KEY[0]; clock_divider cdiv(CLOCK_50,RST,myclock); // state variable reg timer_state; // set up counters wire [3:0] digit3, digit2, digit1, digit0; wire [3:0] ovr; wire clock, reset, pulse; assign clock = (timer_state? myclock[0]: 1'b0); assign reset = (~pulse & RST); decimal_counter count0(digit0,ovr[0],clock,reset); decimal_counter count1(digit1,ovr[1],ovr[0],reset); decimal_counter count2(digit2,ovr[2],ovr[1],reset); decimal_counter count3(digit3,ovr[3],ovr[2],reset); // use one-pulse to trigger reset oneshot pulser1( .pulse_out(pulse), .trigger_in(timer_state), .clk(CLOCK_50) ); wire lcd_start; oneshot pulser2( .pulse_out(lcd_start), .trigger_in(myclock[0]), .clk(CLOCK_50) ); always @ (negedge KEY[3] or negedge RST) begin if (!RST) timer_state <= 1'b0; else timer_state <= ~timer_state; end // Internal Wires/Registers reg [5:0] LUT_INDEX; reg [8:0] LUT_DATA; reg [5:0] mLCD_ST; reg [17:0] mDLY; reg mLCD_Start; reg [7:0] mLCD_DATA; reg mLCD_RS; wire mLCD_Done; parameter LINE1 = 5; parameter LUT_SIZE = LINE1+5; always begin case(LUT_INDEX) 0: LUT_DATA <= 9'h038; 1: LUT_DATA <= 9'h00C; 2: LUT_DATA <= 9'h001; 3: LUT_DATA <= 9'h006; 4: LUT_DATA <= 9'h080; // Line 1 LINE1+0: LUT_DATA <= 9'h120; // blanks LINE1+1: LUT_DATA <= 9'h120; LINE1+2: LUT_DATA <= {5'h13,digit3}; LINE1+3: LUT_DATA <= {5'h13,digit2}; LINE1+4: LUT_DATA <= {5'h13,digit1}; LINE1+5: LUT_DATA <= {5'h13,digit0}; default: LUT_DATA <= 9'dx ; endcase end // turn LCD ON assign LCD_ON = 1'b1; assign LCD_BLON = 1'b1; always@(posedge CLOCK_50 or negedge DLY_RST or posedge lcd_start) begin if(!DLY_RST || lcd_start) begin LUT_INDEX <= 0; mLCD_ST <= 0; mDLY <= 0; mLCD_Start <= 0; mLCD_DATA <= 0; mLCD_RS <= 0; end else begin case(mLCD_ST) 0: begin mLCD_DATA <= LUT_DATA[7:0]; mLCD_RS <= LUT_DATA[8]; mLCD_Start <= 1; mLCD_ST <= 1; end 1: begin if(mLCD_Done) begin mLCD_Start <= 0; mLCD_ST <= 2; end end 2: begin if(mDLY<18'h3FFFE) mDLY <= mDLY + 1'b1; else begin mDLY <= 0; mLCD_ST <= 3; end end 3: begin if (LUT_INDEX<LUT_SIZE) begin mLCD_ST <= 0; LUT_INDEX <= LUT_INDEX + 1'b1; end end endcase end end LCD_Controller u0( // Host Side .iDATA(mLCD_DATA), .iRS(mLCD_RS), .iStart(mLCD_Start), .oDone(mLCD_Done), .iCLK(CLOCK_50), .iRST_N(DLY_RST), // LCD Interface .LCD_DATA(LCD_DATA), .LCD_RW(LCD_RW), .LCD_EN(LCD_EN), .LCD_RS(LCD_RS) ); endmodule
clock_divider.v
module clock_divider(CLK,RST,clock); input CLK,RST; output [6:0] clock; wire clk_1Mhz,clk_100Khz,clk_10Khz,clk_1Khz,clk_100hz,clk_10hz,clk_1hz; assign clock = {clk_1Mhz,clk_100Khz,clk_10Khz,clk_1Khz,clk_100hz,clk_10hz,clk_1hz}; divide_by_50 d6(clk_1Mhz,CLK,RST); divide_by_10 d5(clk_100Khz,clk_1Mhz,RST); divide_by_10 d4(clk_10Khz,clk_100Khz,RST); divide_by_10 d3(clk_1Khz,clk_10Khz,RST); divide_by_10 d2(clk_100hz,clk_1Khz,RST); divide_by_10 d1(clk_10hz,clk_100hz,RST); divide_by_10 d0(clk_1hz,clk_10hz,RST); endmodule
decimal_counter.v
module decimal_counter(A,OVERFLOW,CLK,RST); input CLK, RST; output OVERFLOW; output [3:0] A; reg OVERFLOW; reg [3:0] A; always @ (posedge CLK or negedge RST) if (~RST) begin OVERFLOW <= 1'b0; A <= 4'b0000; end else if (A<9) begin A <= A + 1'b1; OVERFLOW <= 1'b0; end else begin A <= 4'b0000; OVERFLOW <= 1'b1; end endmodule
divide_by_10.v
module divide_by_10(Q,CLK,RST); input CLK, RST; output Q; reg Q; reg [2:0] count; always @ (posedge CLK or negedge RST) begin if (~RST) begin Q <= 1'b0; count <= 3'b000; end else if (count < 4) begin count <= count+1'b1; end else begin count <= 3'b000; Q <= ~Q; end end endmodule
divide_by_50.v
module divide_by_50(Q,CLK,RST); input CLK, RST; output Q; reg Q; reg [4:0] count; always @ (posedge CLK or negedge RST) begin if (~RST) begin Q <= 1'b0; count <= 5'b00000; end else if (count < 24) begin count <= count+1'b1; end else begin count <= 5'b00000; Q <= ~Q; end end endmodule
lcd_controller.v
module LCD_Controller ( // Host Side input [7:0] iDATA, input iRS, input iStart, output reg oDone, input iCLK,iRST_N, // LCD Interface output [7:0] LCD_DATA, output LCD_RW, output reg LCD_EN, output LCD_RS ); parameter CLK_Divide = 16; // Internal Register reg [4:0] Cont; reg [1:0] ST; reg preStart,mStart; ///////////////////////////////////////////// // Only write to LCD, bypass iRS to LCD_RS assign LCD_DATA = iDATA; assign LCD_RW = 1'b0; assign LCD_RS = iRS; ///////////////////////////////////////////// always@(posedge iCLK or negedge iRST_N) begin if(!iRST_N) begin oDone <= 1'b0; LCD_EN <= 1'b0; preStart<= 1'b0; mStart <= 1'b0; Cont <= 0; ST <= 0; end else begin ////// Input Start Detect /////// preStart<= iStart; if({preStart,iStart}==2'b01) begin mStart <= 1'b1; oDone <= 1'b0; end ////////////////////////////////// if(mStart) begin case(ST) 0: ST <= 1; // Wait Setup 1: begin LCD_EN <= 1'b1; ST <= 2; end 2: begin if(Cont<CLK_Divide) Cont <= Cont + 1'b1; else ST <= 3; end 3: begin LCD_EN <= 1'b0; mStart <= 1'b0; oDone <= 1'b1; Cont <= 0; ST <= 0; end endcase end end end endmodule
oneshot.v
module oneshot(output reg pulse_out, input trigger_in, input clk); reg delay; always @ (posedge clk) begin if (trigger_in && !delay) pulse_out <= 1'b1; else pulse_out <= 1'b0; delay <= trigger_in; end endmodule
reset_delay.v
module Reset_Delay( input iCLK, output reg oRESET); reg [19:0] Cont; always@(posedge iCLK) begin if(Cont!=20'hFFFFF) begin Cont <= Cont + 1'b1; oRESET <= 1'b0; end else oRESET <= 1'b1; end endmodule
fit.summary
Fitter Status : Successful - Tue Jan 22 22:26:33 2008 Quartus II Version : 7.2 Build 175 11/20/2007 SP 1 SJ Web Edition Revision Name : lcdlab2 Top-level Entity Name : lcdlab2 Family : Cyclone II Device : EP2C35F672C6 Timing Models : Final Total logic elements : 181 / 33,216 ( < 1 % ) Total combinational functions : 179 / 33,216 ( < 1 % ) Dedicated logic registers : 125 / 33,216 ( < 1 % ) Total registers : 125 Total pins : 191 / 475 ( 40 % ) Total virtual pins : 0 Total memory bits : 0 / 483,840 ( 0 % ) Embedded Multiplier 9-bit elements : 0 / 70 ( 0 % ) Total PLLs : 0 / 4 ( 0 % )
tan.summary
-------------------------------------------------------------------------------------- Timing Analyzer Summary -------------------------------------------------------------------------------------- Type : Worst-case tco Slack : N/A Required Time : None Actual Time : 8.225 ns From : mLCD_DATA[2] To : LCD_DATA[2] From Clock : CLOCK_50 To Clock : -- Failed Paths : 0 Type : Worst-case tpd Slack : N/A Required Time : None Actual Time : 9.857 ns From : SW[16] To : LEDR[16] From Clock : -- To Clock : -- Failed Paths : 0 Type : Clock Setup: 'CLOCK_50' Slack : N/A Required Time : None Actual Time : 52.23 MHz ( period = 19.145 ns ) From : decimal_counter:count3|A[1] To : mLCD_DATA[1] From Clock : CLOCK_50 To Clock : CLOCK_50 Failed Paths : 0 Type : Clock Setup: 'KEY[3]' Slack : N/A Required Time : None Actual Time : 256.54 MHz ( period = 3.898 ns ) From : decimal_counter:count0|A[3] To : decimal_counter:count0|OVERFLOW From Clock : KEY[3] To Clock : KEY[3] Failed Paths : 0 Type : Total number of failed paths Slack : Required Time : Actual Time : From : To : From Clock : To Clock : Failed Paths : 0 --------------------------------------------------------------------------------------
Maintained by John Loomis, last updated Wed Jan 23 14:58:32 2008