Electronics > FPGA

Programming (non-JTAG) MAX7000 devices

<< < (35/35)

Updated version, working both ways


--- Quote from: abyrvalg on September 15, 2022, 11:51:20 pm ---A script simulating raw to POF conversion as done by AMAX70.exe during read (all those bit tables are ripped from exe).
The output is not a full POF, just the data block as seen by exe. The programming function appears to be doing a reverse mapping using same tables.
A "row" in script's terminology is a full content of a single address (all SDINx-SDOUTx chains together, 2x80 bits), while a "plane" is an array connected to a single SDIN-SDOUT.

--- End quote ---

Yep, great work  :-+ I recognise the various tables, but had never got to the point of trying to convert them back as C structs (which Ghidra can do).

From a pervious posting (of mine)

--- Code: ---EPM7032LC44 - data length 1846 (compiled using Max+Plus 9.3)

--- End code ---
From your extracted tables

--- Code: ---EPM7032 = Device("EPM7032", "ALTERA92", [b]14672[/b], 2, 8, BlockTable7032)

--- End code ---

14672 / 8 => 1834   

1834 + 12 => 1846 , where 12 are the header bytes of the POF data section. These differ very slightly for different devices. Ties in nicely.

My best guess (based on disasembly)

--- Code: ---Block(88, 1, 7040, 0, 80, BitTable0),

--- End code ---

Each table entry controls the POF to SDINA/B mapping for a block of EEPROM addresses. There are 8 sections (as I call them) or table entries if you prefer. If you examine the blank check waveforms closely you can see "changes". The first 88 blocks are 80 bits on both SDINA and SDINB, but the later sections only program 16 or 8 bits, so appear shortened in the waveform trace.

first column = number of EEPROM blocks (different addresses)  in this section
second column = not sure, but I see you call it plane
third colum =some kind of bit offset into the POF, I see you call it plane_start_bit
fourth column = address of first EEPROM block in this section
fifth column = number of serial bits on SDINA (and B) for each block (80, 16 or 8 )
sixth column = pointer to bit translation/mapping table.

BlockTablePlaneA =bit translation/mapping for data to be shifted in on SDINA
BlockTablePlaneB = ditto ... SDINB

--- Code: ---Block(88, 0, 0, 0, 80, BitTable0),

--- End code ---
The first section (as I called it) starts with address 0x00 and goes to address 87 (0x57). There are 80 bits shifted in on SDINA. Mapping table is BitTable0.
Since the 7032 has 32 macrocells, we might guess that two EEPROM blocks (160 bits) are allocated per macrocell (but this is just a guess).
From the 1993 databook "MAX7000 EPLDs contain from 32 to 256 macrocells that are combined into groups called Logic Array Blocks (LABs).".

--- Code: ---Block(12, 0, 0, 0x62, 16, BitTable62),

--- End code ---
The second block is special in that the start address is 0x62, but the sequence of addresses is not sequential but a secondary table is used (Block62AddrTable). There are 12 blocks in this section and only 16 bits are shifted in on SDINA.

Thank you, there are some very interesting insights from your Python code which I hadn't yet figured out from the disassembly.

Check the __init__ method definition of class Block (and other classes), I gave names to all those numbers already :)


--- Quote from: abyrvalg on September 16, 2022, 10:32:24 pm ---Check the __init__ method definition of class Block (and other classes), I gave names to all those numbers already :)

--- End quote ---

Yes, thank you, I did note your variable names.

I am now converting the Python to C, to allow me to print some debugging information, which I can then compare with the instruction trace.

BTW, the programming function in exe builds a used bits mask together with pof to raw bit transfer - another buffer of the same full row size is filled with 0s initially, then bits are set to 1 in same positions where pof bits are being transferred into row write buffer. They use it during verification after each row write: read back a row without converting it back to pof and compare with write buffer, using a mask. So it looks like unused bits could have some unpredictable values (i.e. those remaining 64 bits in rows declared with only 16 used bits).

Just a thought: depending on your relationship with Python, perhaps you don’t need to convert that code to C at all. It is extremely easy to talk to serial ports from Python (search for “pyserial” examples, or I could provide some), you could just transfer the “cooked” row data to/from your Arduino right from read_row/write_row Python functions, staying in a comfort of desktop environment.


[0] Message Index

[*] Previous page

There was an error while thanking
Go to full version