CPLD and Verilog Learning Experiment with 8 5x7 Displays

Topics relating to PALs, CPLDs, FPGAs, and other PLDs used for the support or creation of 65-family processors, both hardware and HDL.
Post Reply
Berzerkula
Posts: 8
Joined: 06 Jun 2022

CPLD and Verilog Learning Experiment with 8 5x7 Displays

Post by Berzerkula »

Greetings,

I first got started with CPLD's with the CPLD trainer from plasmo. I only dabbled a bit from examples in books and others. This time I took on another challenge. I have a bunch of TIL305/LTP305/LRT1704 5x7 dot matrix displays. Also, some newer ones from Pimoroni. My goal? Output the hex value at a specific 32 bit address for some machine. In this case, an M68K type machine.

This project was started in August, and just now, got to the point where I can drive 8 of these displays. There are probably many ways to bite this beast, but I've used Maxim 6952/3's and some other devices that do all the hard work when multiplexing or charlieplexing. I decided to figure how to drive these bad boys with 2 CPLD's and supporting drive hardware.

All of this has been prototyped using Altera evaluation boards, ATF15xx boards, bread boards, darlington arrays (UDN2982A for the columns, ULN2803APG for the rows) AT28C16 (character ROM), etc. I've been simulating 32 bit data input from an external source.

It took quite a bit of work getting to this point, but starting with figuring out how to multiplex a 5x7 display, column scanning (programming a custom ring counter) and sending row data and keep it synced took quite a bit of effort. However, it is possible using 2 EPM7128/ATF1508AS CPLD's with supporting driving hardware.

I present the 8 digit 5x7 custom driver! Still a huge work in progress! (Only recently fabricated a PCB for the 5x7 displays with anode column/decimal point with cathode row limiting resistors.

Why do this? Because hardware was hanging around staring me in the face to do something with it.

I'm not the best with verilog and still quite the young guy with it. However I'll share what I have so, far.

The column scanning isn't demanding, but the row data driver is demanding and I have been able to get Quartus 13.0.1 Build 232 06/12/2013 SJ eb Edition with SP1 to build and get 107/128 (84%) macrocells after some tweaking.

For the column scanning (Using the ATF1508AS for this, use POF2JED and program with an ATF15xx programmer)

Code: Select all

module ringcounter (CLK,CLK_DIV,SYNC,ANODE);
    input CLK;								// Clock input
	 output CLK_DIV;						// Passthrough CLK for external device
	 output wire SYNC;					// Sync for external row data driver
    output reg [39:0] ANODE;        // Internal Anode Scanning for 40 Columns

    reg [5:0] cols;
	 
	 assign CLK_DIV = CLK;
	 assign SYNC = ANODE[39];			// Sync on first anode column (For Row data driver)

	 always @ (posedge CLK) begin
		  
        ANODE[39:0] <= 1 << cols;
		  cols = cols + 1;
		  if (cols > 39) cols = 0;

    end
endmodule
For the row data driver (Using the EPM7128SLC84-7 with the Altera UP1 Evaluation Board)

Code: Select all

module TIL305_02 (CLK,CLK_DIV,SYNC,ROMADDR,NIBBLE1,NIBBLE2,NIBBLE3,NIBBLE4,NIBBLE5,NIBBLE6,NIBBLE7,NIBBLE8);
    input CLK;								// Clock input
	 output wire CLK_DIV;				// CLK passthrough for another device when needed (40 bit shift register)
	 input SYNC;							// Sync with external column scan.
    input [3:0] NIBBLE1;            // First Digit
    input [3:0] NIBBLE2;            // Second Digit
    input [3:0] NIBBLE3;            // Third Digit
    input [3:0] NIBBLE4;            // Fourth Digit
	 input [3:0] NIBBLE5;				// Fifth Digit
	 input [3:0] NIBBLE6;				// Sixth Digit
	 input [3:0] NIBBLE7;				// Seventh Digit
	 input [3:0] NIBBLE8;				// Eighth Digit
	 output reg [6:0] ROMADDR;			// 7 bit ROM Address
	 
    reg [5:0] cols = 1;
	 
	 assign CLK_DIV = CLK;
	 
	 always @ (posedge CLK) begin
		  
		  if (SYNC == 1) cols = 0;
		  if (cols > 39) cols = 0;
		  
        case (cols)

				 0,  1,  2,  3,  4 : ROMADDR <= ( NIBBLE1 * 5 + (cols % 5));
             5,  6,  7,  8,  9 : ROMADDR <= ( NIBBLE2 * 5 + (cols % 5));
            10, 11, 12, 13, 14 : ROMADDR <= ( NIBBLE3 * 5 + (cols % 5));
				15, 16, 17, 18, 19 : ROMADDR <= ( NIBBLE4 * 5 + (cols % 5));
				20, 21, 22, 23, 24 : ROMADDR <= ( NIBBLE5 * 5 + (cols % 5));
				25, 26, 27, 28, 29 : ROMADDR <= ( NIBBLE6 * 5 + (cols % 5));
				30, 31, 32, 33, 34 : ROMADDR <= ( NIBBLE7 * 5 + (cols % 5));
            default            : ROMADDR <= ( NIBBLE8 * 5 + (cols % 5));
				
        endcase
		  
		  cols = cols + 1;

    end
endmodule
Attachments
8_5x7_PCB.jpeg
5x7_DISP_CNTRLR.jpeg
Last edited by Berzerkula on Thu Nov 27, 2025 5:34 pm, edited 1 time in total.
plasmo
Posts: 1273
Joined: 21 Dec 2018
Location: Albuquerque NM USA

Re: CPLD and Verilog Learning Experiment with 8 5x7 Displays

Post by plasmo »

Your multiplexed dot-matrix display reminds me of similar display I built up from individual 0603 LEDs and the associated CPLD to drive it. There are 6 digits in this homemade display, meant to display addresses and data on RC2014 bus. Each digit has 20 LEDs, so there are 20 row drivers. Since only one LED is driven at any given moment, row drivers need no buffer, other than current limiting resistors. Each digit does need a FET driver to sink 20 LED's current.
It had been 15+ years since I used Verilog, so I don't remember it anymore, so I designed the CPLD in Quartus schematic. Quartus schematic consisted of latches for each digit, 6-to-1 mux to drive the ROM that translates 4-bit hex input to 20 LED rows, and a ring counter to successively turn on each digit. The design used 65% macrocells of EPM7128S CPLD.
Bill
CPLDTIL_on_Zuno.jpg
Attachments
CPLDTIL_CPLD_scm.pdf
(23.92 KiB) Downloaded 36 times
CPLDTIL_r2_scm.pdf
(38.83 KiB) Downloaded 39 times
CPLDTIL_component_side.jpg
Post Reply