The Blair Witch story of my first FPGA devboard made from a printer front panel - Page 1
Forum section: electronics / general

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 08:31:44 am
content: This is true story, happened long ago, on another forum.The tail, the reverse engineer, the schematic, FPGA 101.Would be too long to post all at once. Trying a new format, with reserved slots.Please feel free to post a subscribe reply if you want to read the next episodes.It was my very first FPGA, and the following content is Google translated from Ro to En, so any observations, corrections or comments are welcome.

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 08:33:37 am
content: Part 1 - Looking through the guts of the beast, I saw an FPGA, a Xilinx Spartan IIE with 50000 gates.About 5 years ago [in fact, cca. 2007 colorized], a very large company I worked for bought several dozen HP Color Laserjet 4730 MFP multifunction printers.All well and good, except that after a few months, the printers started dropping like flies, due to a design mistake. Their control panel stopped working.These panels were a real "Made in Japan" gem. They had them like this:- 6 LEDs (3 green + 1 red + a red/green combination)- numeric keypad with 20 physical buttons- a black and white LCD, 20 cm wide, with touch screen and backlight- piezo speaker (buzzer)The printers being under warranty, when a panel broke, HP sent a new one, and the defective one was thrown in the trash.When I found out, I asked a former colleague and friend, whom I want to thank, and him and his boss, to give me a defective panel, not to throw it away, because I was going to recover the LCD and the touch screen. He gave me two panels that were going to the trash. Now, I'm sorry I didn't get them all.Looking through the guts of the beast, I saw an FPGA, a Xilinx Spartan IIE, with 50,000 gates. I really wanted to see what his skin could do, but at the time I thought the plate was defective. Otherwise, the LCD seemed hard to use, the touch screen as well, I didn't even know if they were good or burnt, so I put everything back together and almost forgot about them.Later, it was found out that the fault was the mechanical assembly, the electronics of the panel worked perfectly, but that's another story.A few weeks ago [so, cca. 2012 colorized, we are now in 2024], ratza said that the company he works for is hiring. One of the jobs required FPGA knowledge.This reminded me of something I've been wanting to do for a long time, which is playing around with FPGAs. I started looking for development boards, but they were a bit expensive, between 50 euros for a chior chip on a test board, up to 500-1000 euros for a development board with LCD and touch screen. That's how much the cheap boards cost, for amateurs, the professional ones cost about as much as a car...These prices instantly refreshed my memory, and made me remember the FPGA seen on the printer panel board, only good development board panel.I've always liked to do reverse engineering (that is, to take things apart to see how they were made), and for this money, it's definitely worth a try. Let's see what comes out.

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 08:34:43 am
content: Part 2 - front panel board peripherals, DIY a power supply and a Xilinx JTAG programmerBack to the printer board, I first looked up the datasheet for each integrated on the board. That's how I got an idea about the block diagram. Upon further inventory, the board was found to have the following:- FPGA Xilinx Spartan IIE, XC2S50E-6, 50,000 gates, i.e. 768 slices- 50 MHz oscillator- numeric keypad + several other buttons (20 push buttons in total)- Black/white LCD 256*64 (not sure about the resolution)- white backlight for LCD- LCD controller with EPSON S1D13503- 64K x 16 SRAM linked to the LCD controller- resistive touch screen- controller (ADC) for touch screen, made with ADS7846N- sensor for temperature and for supply voltage (included in ADS7846N)- an ADC channel with SAR at 125 KHz, left free from ADS7846N- piezo buzzer with volume control (2 bits, PWM + ON/OFF)- 4 LEDs + 1 bicolor LED (red + green)- several connections with buffers linked to a connector, 3 in + 1 out, suitable for serial, synchronous or asynchronous communication- Configuration PROM- standard JTAG connector, with 9 pins at 0.1 inch (it was not mounted, but it was very good that there were holes for it)In terms of equipment, it is only good as a didactic board with FPGA, it has more than enough on it to develop applications in VHDL, Verilog or other HDL.I already knew the power supplies, because I had put the oscilloscope on the connector of the board, to a functional printer. Otherwise I wouldn't have known how much to feed the board (yes, a few days after I got the boards, I took the oscilloscope from home, put it in a travel bag, and did the measurements at work, on a printer which was just having another defective panel replaced).I got what is written in blue on the sheet in the picture. What is written in black, was added these days [in 2012].The board needs 24V, later I would find out that they are for the LCD backlight and buzzer, and 3.3V for the logic part. I hastily whipped up a power supply, from a 24V switching power supply (salvaged from another broken printer), followed by a 12V LM7812 and an LF33 LDO which produces 3.3V. 12V was not needed, but the LF33 did not support more than 16V on the input, I could not connect it directly to 24V. So I put an LM7812 first, which supports a maximum of 36V, followed by an LF33. I don't put the diagram of the power supply anymore, I didn't even draw it. It's the one in the catalog, with a few tens of microfarads in parallel with 100 nF, both on inputs and outputs, at each stabilizer. The assembly is done in the air, it doesn't look very nice, but I was eager to start the toy.Starting from the FPGA datasheet, I saw that the JTAG pins are dedicated, they cannot be mapped elsewhere. Following the wiring traces, I discovered that the JTAG pins go to the holes corresponding to the CN4 connector. Luckily for me, although the entire board was SMD technology and contained all sorts of hard-to-find connectors, standard 1x9 0.1 inch pin holes had been provided for CN4. Now I also had a way to talk to the FPGA, to reprogram it.Once the JTAG connector was figured out, I needed a JTAG programmer for Xilinx Spartan IIE FPGAs, plus the rigor software.Searching about JTAG, I found a link that explains very clearly what it is, how it came about and what can be done with JTAG.http://www.fpga4fun.com/JTAG.htmlI recommend the entire fpga4fun website, it is very clear and concise.After understanding better than ever what JTAG is, I looked for a programmer. Too bad and these. They are usually included with the development board you buy. There are also separate programmers, but at prices of 50-100 euros. Too much. I decided to make my own. Again, fortunately, the chip manufacturer itself, Xilinx, provided a very simple programmer schematic for the parallel port:My computer has a parallel port, and I already had the rest of the parts around the house. Compared to the original scheme, I added an LED connected to a free gate, to see when the programmer is working. Later I would find that I did very well, the LED is particularly useful.After some tinkering I got this:Buuun, we have a board powered and connected to the computer.We just need to talk to her.Xilinx offers a free software variant for configuring and programming their FPGAs, called ISE WebPack. It's a very large package, you need a few free GBs for download and a few more for installation. Cleaned by computer, downloaded the newest version, installed and...surprise! Spartan IIE, the FPGA on my board, was not supported.Searched the net for the problem, the last variant that supported Spartan IIE was ISE 10.1. Made more space on the hard drive, downloaded another GB, installed another GB. All this lasted one day.Finally, I was able to talk to the FPGA and read its ID.Total victory!

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 08:35:48 am
content: Part 3 - raising the schematic of the HP Color Laserjet 4730 MFP front panel board, prepare a Xilinx UCF file corresponding to that schematicThe next step was to remove the schematic, piece by piece and not very detailed, just enough to find out how, and to which pins, each peripheral is connected. It took quite a while, I'm not done yet. So that others don't waste time, the schemes:Schematic 1- HP Color LaserJet 4730 MFP - keyboard, piezo speaker, connectorsSchematic 2- HP Color LaserJet 4730 MFP - LCD controllerSchematic 3- HP Color LaserJet 4730 MFP - touch screen controllerSchematic 4- HP Color LaserJet 4730 MFP - connectors for power, LCD and high voltage backlightFrom the schemes above, I wrote the UCF file (User Constraint File). The UCF is a file that specifies, among other things, the connections between the FPGA pins and our scheme. For example, in the UCF it is written how we want to name each pin of the FPGA and where it is connected, if the pins have pull-up or pull-down resistors, etc. This file is used by the programs that configure the FPGA (ISE).Below, theUCF filefor PWB51652J-V0 (that's the name of the board in the pictures).Code:#========================================================#Pin assignement for XILINX Spartan 2E - XC2S50E#Printer display board PWB51652J-V0 (Mihai)##Author: RoGeorge#Version: 2012.07.13 V0.4#========================================================#========================================================#Touch Screen Controller - ADS7846#========================================================NET"TSC_DCLK"LOC = "P77";NET"NTSC_CS"LOC = "P78";NET"TSC_DIN"LOC = "P79";NET"TSC_BUSY"LOC = "P82";NET"TSC_DOUT"LOC = "P44";NET"NTSC_PENIRQ"LOC = "P80";#========================================================#CN1 Connector - 10 pins connector to outside world#========================================================NET "CN1_DI"LOC = "P85";# CN1 pin 4NET "CN1_CK"LOC = "P83";# CN1 pin 6NET "NCN1_CS"LOC = "P86";# CN1 pin 8NET "CN1_DO"LOC = "P84";# CN1 pin 2#========================================================#Not shure - Buzzer BZ1#========================================================NET "BZ_VOL_PWM" LOC = "P48";# PWM '0' -> (BZ+ = 24V)#'1' -> (BZ+ = 0V)NET "BZ_PULSE"LOC = "P47";# '0' -> (BZ- = BZ+)# '1' -> (BZ- = 0V)#========================================================#Keyboard buttons, 8 input columns x 3 output rows#========================================================#12345678- A0_#9*0#Cypbl- A1_#NCNCNCNCgrglgubr- A2_#||||||||# D0_D1_D2_D3_D4_D5_D6_D7_##y = Yellow button#p = Pink button#bl = Blue Left button#gr = Grey Right button#gl = Grey Left button#gu = Grey Up button#br = Blue Right button#========================================================#8 input columns with pullup resistorsNET "NKBD_D<7>"LOC = "P27";# Data input D7 keyboardNET "NKBD_D<6>"LOC = "P28";# Data input D6 keyboardNET "NKBD_D<5>"LOC = "P29";# Data input D5 keyboardNET "NKBD_D<4>"LOC = "P30";# Data input D4 keyboardNET "NKBD_D<3>"LOC = "P31";# Data input D3 keyboardNET "NKBD_D<2>"LOC = "P32";# Data input D2 keyboardNET "NKBD_D<1>"LOC = "P38";# Data input D1 keyboardNET "NKBD_D<0>"LOC = "P39";# Data input D0 keyboardNET "NKBD_D<?>" PULLUP;# Pullup resistors#3 output rows with pullup resistorsNET "NKBD_A<2>"LOC = "P23";# Address A2 keyboardNET "NKBD_A<1>"LOC = "P26";# Address A1 keyboardNET "NKBD_A<0>"LOC = "P24";# Address A0 keyboardNET "NKBD_A<?>" PULLUP;# Pullup resistors#========================================================#LEDs - 6 discrete LEDs, common anod#========================================================NET "NLED<6>"LOC = "P18";NET "NLED<5>"LOC = "P21";NET "NLED<4>"LOC = "P22";NET "NLED<3>"LOC = "P15";NET "NLED<2>"LOC = "P20";NET "NLED<1>"LOC = "P14";#========================================================#LCD controller - EPSON S1D13503F01#========================================================#controll busNET "LCD_BKL"LOC = "P13";#LCD backlightNET "LCD_READY"LOC = "P12";NET "LCD_OSC1"LOC = "P67";NET "LCD_RESET"LOC = "P11";NET "NLCD_MEMR"LOC = "P10";NET "NLCD_MEMW"LOC = "P8";NET "NLCD_MEMCS"LOC = "P7";NET "NLCD_IOR"LOC = "P6";NET "NLCD_IOW"LOC = "P5";NET "NLCD_IOCS"LOC = "P4";NET "NLCD_BHE"LOC = "P3";#data bus - 16 bitsNET "LCD_DB7"LOC = "P132";NET "LCD_DB6"LOC = "P131";NET "LCD_DB5"LOC = "P125";NET "LCD_DB4"LOC = "P124";NET "LCD_DB3"LOC = "P123";NET "LCD_DB2"LOC = "P122";NET "LCD_DB1"LOC = "P121";NET "LCD_DB0"LOC = "P118";NET "LCD_DB8"LOC = "P133";NET "LCD_DB9"LOC = "P134";NET "LCD_DB10"LOC = "P137";NET "LCD_DB11"LOC = "P138";NET "LCD_DB12"LOC = "P139";NET "LCD_DB13"LOC = "P140";NET "LCD_DB14"LOC = "P141";NET "LCD_DB15"LOC = "P142";#address bus - 20 bitsNET "LCD_AB0"LOC = "P87";NET "LCD_AB1"LOC = "P89";NET "LCD_AB2"LOC = "P92";NET "LCD_AB3"LOC = "P93";NET "LCD_AB4"LOC = "P94";NET "LCD_AB5"LOC = "P95";NET "LCD_AB6"LOC = "P96";NET "LCD_AB7"LOC = "P97";NET "LCD_AB8"LOC = "P98";NET "LCD_AB9"LOC = "P100";NET "LCD_AB10"LOC = "P101";NET "LCD_AB11"LOC = "P102";NET "LCD_AB12"LOC = "P103";NET "LCD_AB13"LOC = "P104";NET "LCD_AB14"LOC = "P69";NET "LCD_AB15"LOC = "P106";NET "LCD_AB16"LOC = "P114";NET "LCD_AB17"LOC = "P115";NET "LCD_AB18"LOC = "P116";NET "LCD_AB19"LOC = "P117";#========================================================#Clock and Reset#========================================================NET "CLK"LOC = "P129";# NET "RESET"LOC = "Pyy";#========================================================#Timing constraint of 50 MHz onboard oscillator#name of the clock signal is CLK#========================================================NET "CLK"TNM_NET = "CLK";TIMESPEC "TS_CLK" = PERIOD "CLK" 20 ns HIGH 50 %;Now, we have everything we need to start programming. In the following examples, I will use the VHDL language.For those who don't know, if we look from the plane, an FPGA is an integrated circuit in which you can put whatever scheme you want. The diagram can be drawn or written in a programming language to describe the diagram. An example of such a language is VHDL. We are talking here about circuits with digital (numerical) circuits, that is, circuits with logic gates, counters and the like, not analog circuits, such as those with operational amplifiers. On the board in the pictures, the FPGA is that big, fat, 144-foot integrated that says Xilinx Spartan. Xilinx is the company that produces it. Spartan is the trade name that Xilinx has given to a range of FPGAs produced by them.Acronyms:FPGA - Field Programmable Gate ArrayUCF - User Constraint FileISE - Integrated Synthesis EnvironmentHDL - Hardware Description LanguageVHSIC - Very High Speed ​​Integrated CircuitVHDL - VHSIC HDL

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 08:36:45 am
content: Part 4 - All set. Now, a crash course. What's the "Hello World" for FPGAs? A blinking LED? No, that would be too complicated.We have a power supply, we have a programmer, we have the software installed, we know the equipment (peripherals) of the board and to which pins of the FPGA they are connected. It's time to start putting different schematics into the FPGA to control the peripherals.What schematic should we do? Flash an LED? No, it's too complicated. Something else simpler. We read the keyboard of the board, and for each button pressed (from 1 to 6), we light one of the 5 LEDs. In other words, we connect one LED to each button, as in the diagram in Fig. 1:Fig. 1If we look at the picture with Scheme 1 (the one published in previous messages, don't confuse it with Fig. 1 from now), we notice that the LEDs and buttons are already connected to the FPGA, as in Fig. 2.Fig. 2But we want to make a montage like in Fig. 1, what do we do?Very simple, we cut the PCB traces, then solder some wires from the buttons, directly to the LEDs.No, we won't do that, just kidding. We will make the connections between the LEDs and the buttons inside the FPGA, programming it to "transform" as in the diagram in Fig. 3.Fig. 3To obtain the diagram in Fig. 3, the program written in the VHDL language, looks like this:Prog. 1Code:library IEEE;use IEEE.STD_LOGIC_1164.ALL;entity KBD_to_LED isport(NKBD_A: out std_logic_vector(2 downto 0);NKBD_D: in std_logic_vector(7 downto 0);NLED:out std_logic_vector(1 to 6));end KBD_to_LED;architecture Behavioral of KBD_to_LED isbeginNKBD_A(0) <= '0';NKBD_A(2 downto 1) <= "11";NLED(1) <= NKBD_D(0);NLED(2) <= NKBD_D(1);NLED(3) <= NKBD_D(2);NLED(4) <= NKBD_D(3);NLED(5) <= NKBD_D(4);NLED(6) <= NKBD_D(5);end Behavioral;Let's explain the above program a little.First about the notations that appear. KBD comes from KeyBoarD (keyboard) and NKBD is the negated signal. This is how we named the wires connected to the buttons earlier, in the USL file. D comes from Data, where the button matrix is ​​read, and A comes from Address, where different rows of the button matrix are addressed. For example, pin P24 of the FPGA, was named (in the USL file) with the name NKBD_A(0), Not KeyBoarD Address line 0, and pin P31, corresponding to button "4" in the schematics, was named in USL with NKBD_D(3), Not KeyBoarD Data line 3.Now, back to the code. We notice that first the type of signals is declared, in the "port" instruction. In our case, signals (that is, the FPGA pins) can be of input or output type, and they are vectors, that is, there are several grouped signals. "NKBD_D: in std_logic_vector(7 downto 0);" means that we have grouped 8 input signals, from NKBD_D(7) to NKBD_D(0), each of the 8 corresponds to a pin of the FPGA. To which pin each signal corresponds, write in the USL file.Almost any pin of the FPGA can be input or output, as we want. We just need to configure it. After we have declared what kind of pins they are (that is, we have configured them as inputs or outputs), we start using them, in the "architecture" section.Let's take the first instruction, "NKBD_A(0) <= '0';". This means that we assign NKBD_A(0) value logical "0". Logical "0" means GND, i.e. grounded. Logical "1" means Vcc, in our case +3.3V. In other words, "NKBD_A(0) <= '0';" means we tie the P24 pin of the FPGA to ground.Now I will tell you the secrets of VHDL.- All instructions are executed simultaneously (in parallel, at once) not like in other programming languages, such as Basic or C, where the instructions are executed one at a time, sequentially. In other words, in the program above we can change the order of the instructions as we want, because they are all executed at once anyway. There are also instructions that are executed sequentially, we will meet them along the way, but not in the program above.- The sign "<=" does not mean "less than or equal to", as in other languages. It means attribution. To better understand the assignment sign in VHDL and the fact that everything executes simultaneously, rather than reading it as "equals", it's better to read it and think of it as "is bound to". So, "NLED(1) <= NKBD_D(0);" means that LED 1 is linked to keyboard data 0.- If we still encounter the assignment sign "<=" in a block of sequential instructions, "<=" is still not executed sequentially. All assignments of type "<=" are executed only at the exit of the sequential block, simultaneously and in the order of appearance. For example, if in a sequential block we have "NLED(1) <= '0';" and then "NLED(1) <= '1';", the signal will never take the value '0', it will only take the value '1'.Done, now you know VHDL.After we program the FPGA with the code in Prog. 1, we will obtain the following result:Movie 1- watch what happens to the board's LEDs when we press the buttons.We just made our first program in VHDL. We can officially say that we know how to program an FPGA!Now that we have VHDL, let's make a slightly more complicated scheme, where LED 1 lights up only when we press buttons "1" and "2" simultaneously, as in Fig. 4.Fig. 4The VHDL code corresponding to the assembly in Fig. 4 is:Prog. 2Code:library IEEE;use IEEE.STD_LOGIC_1164.ALL;entity KBD_to_LED isport(NKBD_A: out std_logic_vector(2 downto 0);NKBD_D: in std_logic_vector(7 downto 0);NLED:out std_logic_vector(1 to 6));end KBD_to_LED;architecture Behavioral of KBD_to_LED isbeginNKBD_A(0) <= '0';NKBD_A(2 downto 1) <= "11";NLED(1) <= NKBD_D(0) or NKBD_D(1);NLED(2) <= '0';NLED(3) <= NKBD_D(2);NLED(4) <= NKBD_D(3);NLED(5) <= NKBD_D(4);NLED(6) <= NKBD_D(5);end Behavioral;The result can be seen in Movie 2.Movie 2- watch what happens to the first LED on the left of the board, it lights up only if we press buttons "1" and "2" simultaneously, otherwise it remains off.One more try and done. Until now, in order for the LED to stay lit, we had to hold down the button. Now, we want to make something that remembers which of the buttons "1" or "2" we pressed last, that is, a circuit that remembers the last button pressed (we are only talking about buttons "1" and "2", the rest remain as before). For this, we will make a montage with a bistable, as in Fig. 5.Fig. 5The program for the scheme in Fig. 5, is:Code:library IEEE;use IEEE.STD_LOGIC_1164.ALL;entity KBD_to_LED isport(NKBD_A: out std_logic_vector(2 downto 0);NKBD_D: in std_logic_vector(7 downto 0);NLED:out std_logic_vector(1 to 6));end KBD_to_LED;architecture Behavioral of KBD_to_LED issignal q: std_logic;signal nq: std_logic;beginNKBD_A(0) <= '0';NKBD_A(2 downto 1) <= "11";q <= NKBD_D(0) nand nq;nq <= NKBD_D(1) nand q;NLED(1) <= q;NLED(2) <= nq;NLED(3) <= NKBD_D(2);NLED(4) <= NKBD_D(3);NLED(5) <= NKBD_D(4);NLED(6) <= NKBD_D(5);end Behavioral;We notice that two internal FPGA signals appear here, called "q" and "nq", and declared at the beginning, in the architecture of the KBD_to_LED block.The behavior of the scheme in Fig. 5, i.e. the result of the program Prog. 3, we see him in the last movie:Movie 3- watch what happens to the first two LEDs on the left of the board.Acronyms:LED - Light Emitting Diode

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 08:37:48 am
content: Part 5 - Blink!How can we blink an LED with an FPGA? Will the LED blink if we write one after anotherCode:LED <= '0';LED <= '1';LED <= '0';LED <= '1';...? No.It won't blink because in VHDL all the instructions are executed simultaneously, not one after the other. So how can we blink the LED?One way to blink an LED would be to take the clock signal from the 50MHz oscillator, and first, divide it by 50,000,000 to get a 1Hz signal. Then, we tie an LED to the 1 Hz signal, so the LED will blink once per second.Remember, in VHDL we do schematics, not programs. Let's detail the schematic a little. We do the divider by 50 million with the help of a counter. At each clock signal (CLK) coming from the oscillator, the counter is incremented. When we reach 50 million, we reset the counter. Thus, we obtain a divisor with 50 million. Because at the input of the divider we put a frequency of 50MHz (that's what the oscillator of the board outputs), at the output of the divider we will have 1Hz.Since we want the 1Hz signal to have a 50% duty factor, we'll do a little trick. First we put a divider with 25 million (I called it a prescaler) from which we will get 2Hz. The 2Hz pulses will be very narrow, so to get a 50% duty factor, we add one more flip-flop to divide by 2, so in the end we get a 1Hz signal with a 50% duty factor.Apart from the LED that beats the second, a few more features were added as a demo:- count and display on LEDs 1 and 2, in binary, the seconds (we only do this on 2 bits, i.e. we only count 4 seconds, then it starts again). For this, we will make a counter linked to the 2 Hz signal, a counter called cnt_led- from button 1 we pause, and from button 2 we continue. For this, we make a FF as in the example inFig. 5, and we use its output as a signal to validate (enable) the counting. If en = 0, it pauses, the prescaler stops counting, if en = 1, it continues counting.- from button 3 we bring to zero (reset - rst) both the prescaler (cnt_div) and the seconds counter (cnt_led).- the signals corresponding to reset, 1Hz, enable/disable and number of the second, are also tied to LEDs indicatorsThe entire schematic will look like inFig. 6. Along with the FPGA, I also drew the board's panel to show where each LED is.Fig. 6The schematic inFig. 6is described in VHDL as inProg. 6Prog. 6Code:------------------------------------------------------------------------------------ Company:-- Engineer:---- Create Date: 10:10:59 07/26/2012-- Design Name:-- Module Name: blinking_LED - Behavioral-- Project Name:-- Target Devices:-- Tool versions:---- Description:--button 1 enable counting--button 2 disable counting--button 3 reset----LED 1 & 2 - binary count upto 4 seconds--LED 3 - reset indicator--LED 4 - blinking with 1 Hz--LED 5 & 6 - indicate enable(green)/disable(red) counting---- Dependencies:---- Revision:-- Revision 0.01 - File Created-- Additional Comments:------------------------------------------------------------------------------------library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity blinking_LED isport(NKBD_A: out std_logic_vector(2 downto 0);NKBD_D: in std_logic_vector(7 downto 0);NLED: out std_logic_vector(6 downto 1);CLK: in std_logic);end blinking_LED;architecture Behavioral of blinking_LED is-- prescaler divider constant = 24 999 999constant divider: std_logic_vector(24 downto 0) := "1011111010111100000111111";-- other signalssignal q, nq, en, rst: std_logic;signal cnt_div: std_logic_vector(24 downto 0);-- prescaler 25 000 000signal cnt_led: std_logic_vector(2 downto 0);-- for 50% PWM of 1 Hzbeginq <= NKBD_D(0) nand nq;-- FF gate 1nq <= NKBD_D(1) nand q;-- FF gate 2en <= nq; -- for program clarityrst <= not NKBD_D(2); -- for program clarity, gate 4NKBD_A <= "110";NLED(4) <= not cnt_led(0);-- display 1 Hz beat, gate 3NLED(1) <= not cnt_led(1);-- display seconds binary counter bit 1, gate 6NLED(2) <= not cnt_led(2);-- display seconds binary counter bit 2, gate 5NLED(3) <= NKBD_D(2);-- display reset button statusNLED(5) <= nq;-- display red when counting is disabledNLED(6) <= q;-- display green when counting is enabled-- prescaler counter with asynchronous reset and synchronous enableprescaler: process(CLK, rst, en)beginif rst = '1' thencnt_div <= (others => '0');elsif CLK'event and CLK = '1' and en = '1' thenif cnt_div = divider thencnt_div <= (others => '0');elsecnt_div <= cnt_div + '1';end if;end if;end process;-- seconds counter with asynchronous resetcounter: process(cnt_div(24), rst)beginif rst = '1' thencnt_led <= (others => '0');elsif cnt_div(24)'event and cnt_div(24) = '1' thencnt_led <= cnt_led + '1';end if;end process;end Behavioral;We notice that two blocks calledprocesshave appeared. The instructions inside a process are executed sequentially, not in parallel. Immediately after the word process, a list of signals appears in parentheses. That list is called the sensitivity list.A process is executed only when an event occurs for the signals in the sensitivity list. An event means a change of state. For example, a rising edge of a signal is an event.Instructions of the type "if ... end if;" are executed sequentially. They cannot be used outside theprocessblock.The expression "if CLK'event and CLK = '1'" means: "if a change occurs in the CLK signal and the current value is logic 1" then... In other words, the expression detects the rising edge of the CLK signal. It can be read "on the rising edge of CLK" execute...Anything after "--" is a comment, it does not matter when the program is executed.The expression "(others => '0')" fills the rest of the bits with zero (we don't need to specify how many zero bits to put). For example,Code:cnt_div <= (others => '0');is equivalent toCode:cnt_div <= "0000000000000000000000000";The result of the program can be seen inMovie 6. First, the green LED of the programmer under the board lights up. After the FPGA finishes programming (2-3 seconds), LEDs 5-6 (bottom right) turn green, LED 4 (top right) starts to count seconds, and LEDs 1 and 2 ( left of the LCD), count up to 4, in binary. If button 1 is pressed, there is a pause, and LEDs 5-6 light up red. If button 2 is pressed, LEDs 5-6 turn green again and counting continues. Whenever button 3 is pressed, all counts are reset to 0.Movie 6Acronyms:IT - Information TechnologyCLK - ClockFF - Flip FlopPWM - Pulse Width ModulationLCD - Liquid Crystal Display

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 08:38:53 am
content: Reserved 6

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 08:39:55 am
content: Reserved 7

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 09:33:37 am
content: OK, found the pics, too, part 1 ready:Part 1 - Looking through the guts of the beast, I saw an FPGA, a Xilinx Spartan IIE with 50000 gates.

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 03, 2024, 09:47:50 am
content: Interesting journey.At that time what was the status of the Xilinx software? Still only paid for licensing or already free for the simpler devices?This because you mentioned the high prices of development boards, and what I know from how expensive the software was in the beginning. (Around 1990)

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 10:30:40 am
content: Back then, the current tool chain was Xilinx ISE 12.x or so, with both a paid and a free (reduced) version.However, the chip found in that printer front panel was a Spartan 2. The Xilinx Spartan 2 family was no longer supported in any IDE greater than Xilinx ISE 10.x (? not very sure about the minor version number back then). Xilinx Vivado was not yet invented. There was an unreleased project (i think the internal Xilinx name was of a sculptor name, IIRC "Rodin"), later to become Vivado - no idea how the sculptor name was changed into Vivado.AFAIK, starting from at least Xilinx ISE 10.x to today Xilinx tools, there always was a free version of their IDE. At first the name for the free Xilinx ISE wasISE WebPack(the name might seem like a cloud product, but Xilinx cloud compiling was not yet a thing until Vivado, around cca 2015 or so).The ISE WebPack was a standalone/offline toolchain perfectly usable for learning/small projects, just that it was stripped away from the most IP blocks and from other productivity tools that one might want/need for a more elaborated/professional design.

author: iMo
author_rank: Super Contributor
timestamp: September 03, 2024, 10:49:55 am
content: Quote from: RoGeorge on September 03, 2024, 08:33:37 amI bought (my own money) my first Xilinx FPGA in around year 2000 - XC5202 (3000 gates) - for aprox 50E (in 2000 value), still have the board with 9k6 YAM TNC Packet Radio modem.. None Xilinx programming environment available at that time to me, I just flashed the binary into it via the parallel port and some simple bitbanging sw somebody wrote..

author: pcprogrammer
author_rank: Super Contributor
timestamp: September 03, 2024, 11:25:10 am
content: My first FPGA experience was with a Xilinx XC3042 (144 CLB's 480 FF) and I was amazed with what I could cram into it.The software was made available to the foundation I worked for at a reduced rate, but still expensive. A full version would cost about 4500 euro or so (10000 Dutch guilders) and definitely not affordable for a hobbyist. I still have the floppies, documentation and a bunch of these old FPGA's, because when I left there, no one was interested in it all.

author: daisizhou
author_rank: Super Contributor
timestamp: September 03, 2024, 12:01:00 pm
content: Looking forward to your masterpiece

author: RoGeorge
author_rank: Super Contributor
timestamp: September 03, 2024, 05:38:00 pm
content: Thank you, part 2:Part 2 - front panel board peripherals, DIY a power supply and a Xilinx JTAG programmer

author: RoGeorge
author_rank: Super Contributor
timestamp: September 04, 2024, 07:29:21 am
content: Ready part 3, the must have prerequisites needed to use that printer front panel board as an FPGA devboard for Xilinx ISE:Part 3 - raising the schematic of the HP Color Laserjet 4730 MFP front panel board, prepare a Xilinx UCF file corresponding to that schematic

author: RoGeorge
author_rank: Super Contributor
timestamp: September 10, 2024, 08:13:46 am
content: FPGA programming crash course ready:Part 4 - All set. Now, a crash course. What's the "Hello World" for FPGAs? A blinking LED? No, that would be too complicated.

author: PA0PBZ
author_rank: Super Contributor
timestamp: September 10, 2024, 08:28:17 am
content: Fig. 4 in the Part 4 text is actually Fig. 5, you may want to correct that.

author: RoGeorge
author_rank: Super Contributor
timestamp: September 10, 2024, 08:31:09 am
content: Fixed, thank you.

author: TomS_
author_rank: Frequent Contributor
timestamp: September 13, 2024, 09:27:53 pm
content: I love these kinds of reverse engineering projects - taking something old and giving it new life! 👍

author: RoGeorge
author_rank: Super Contributor
timestamp: September 13, 2024, 09:46:36 pm
content: Glad you like it, thanks.Just added another episode:Part 5 - Blink!

author: tom66
author_rank: Super Contributor
timestamp: September 16, 2024, 01:18:08 pm
content: This is really cool!