Verilog LCD Implementation - Page 1
Forum section: electronics / general

author: Sparky49
author_rank: Regular Contributor
timestamp: April 17, 2018, 11:04:42 am
content: I'm wanting to include a text LCD display in a project I've implemented on a FPGA in verilog, but it seems this is causing me more confusion than the project itself. I think this down in part to state machines and becoming focused on ensuring I have a solid initialization by instruction of the LCD with proper comms timings. Perhaps I am getting way ahead of myself here...I am using a 1602 display, with a HD44780 controller (datasheethttps://www.sparkfun.com/datasheets/LCD/HD44780.pdf). I'm trying to implement the startup on page 45, as well as ensure I have proper timings (page 52). At the moment I think my biggest trouble is implementing timings greater than what is required using my 48MHz clock. Would a sensible approach be to set up a state machine for pg 45, with a bunch of if's in each state controlling delay counters for the delays on page 45, as well as a bunch of ifs controlling the delays required on page 52 for each line? I've tried doing this but it just seems to be getting messier and messier.Or would it be better to reduce the clk speed for the state machine such that the timings on pg 52 are irrelevant?I've tried looking for implementations elsewhere online, but I cannot seem to get any of them to work, regardless of how simple they appear. I'd really like to get something working myself though too... I'm 99% certain I've connected the LCD correctly too.Apologies for the rambling post.EDIT: I do have some code I've started writing if you'd like to see the mess I'm getting into...

author: joshtyler
author_rank: Contributor
timestamp: April 17, 2018, 07:10:54 pm
content: It might help to post the code which you have already, so we can see what you are doingIf it was me, I'd stick with the 48MHz clock, because this is (presumably) what your external logic uses, and just use a counter to generate a write strobe.I'd maybe tackle it with something like this, as a very pesudo-codey implementation (I haven't looked closely at all at exactly what needs to be done to init the display):Code:reg [5:0] strobe_ctr; //Count up to 32 to get a 1.5MHz clock from 48MHz (meets p.52 timing)reg [12:0] delay_ctr; // Count up to 2^13, to get >4.1ms delay from 1.5Mhz strobe (meets max initialisation delay)reg delay_en; //Activate from within state machinealways @(posedge clk)begin//Handle strobe counterstrobe_ctr <= strobe_ctr + 1;if(strobe_ctr == 0)begin// State machinecase(state)SM_DO_INIT_1://Do your first bit of init herestate <= SM_WAIT_1;SM_WAIT_1:if (delay_ctr == '1)state <= SM_DO_INIT_2;end ifSM_DO_INIT_2://Do your second bit of init herestate <= SM_WAIT_2;SM_WAIT_2:if (delay_ctr == '1)state <= SM_DO_INIT_3;end if// Etc....endcase// Handle delay counterif (delay_en)delay_ctr <= delay_ctr + 1;elsedelay_ctr <= 0;end ifendendassign delay_en = (state == SM_WAIT_1) or (state == SM_WAIT_2);(Excuse any syntax errors, It's been a few months since I've written any verilog!)

author: Sparky49
author_rank: Regular Contributor
timestamp: April 17, 2018, 09:33:57 pm
content: Thanks very much for the reply Josh. I'll continue writing out my interpretation and compare it against your pseudo-code.I'll be away for a few days but will 100% report back.