Author Topic: Reverse engineering Anlogic AL3_10 FPGA  (Read 14326 times)

0 Members and 1 Guest are viewing this topic.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Reverse engineering Anlogic AL3_10 FPGA
« on: February 07, 2022, 06:11:03 pm »
I'm trying to reverse engineer the bitstream of an Anlogic AL3_10 FPGA, but have trouble matching the configuration bits onto logical names.

With the information from prjtang (https://github.com/mmicko/prjtang) I'm able to make a map of the used tiles, but mapping the actual bits fails. To check things, I made a simple design in the Tang Dynasty IDE and the bitstream generator tells me how many configuration bits are set one. This matches with output of my rudimentary tool mapping these bits to the tiles.

The json database files for the bits show a x,y coordinate system, for which I tried several matching options, but the resulting bit names make no sense. For most of the tiles it is just two bits for making connections over the interconnect, and one would expect logical names with something like "mux" in them to pop up.

To get a better understanding I'm also trying to decode the work files of the IDE, which is slowly coming together, but I'm not sure if that will provide the answer. The prjtang data is a big help in this quest but it lacks information about how the mapping of the bits is done.

So if anyone has some in-depth knowledge of this, I would appreciate if it is shared here.

When there is an interest in the code I'm making (written in either C or python) let me know. I have no problem with sharing it.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #1 on: February 13, 2022, 01:02:44 pm »
I'm new to modern FPGA's and certainly new to the internals of them. My quest to reverse engineer one is a learning one, so questions come up.

Here is one I hope someone has an answer for. When in an IO tile that holds 4 pads, a single pad is enabled for either input or output, do the other pads need to be configured then too?

I made a simple verilog project with just two wires connected to each other. P23 as input connected to P112 as output. When I list the configuration bits, it looks like the Tang IDE sets unused bits and bits for the other pads.

Attached is the list file I made and a zip of a bitmap I made showing the tiles and the configuration bits.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #2 on: February 17, 2022, 12:49:40 pm »
It took a lot of thinking and looking through the data to figure out what was wrong. At first I gave up on the whole quest due to not getting the wanted results, but the brain kept on wondering.

What I did wrong was to assume that the 4 pad bits each frame of the configuration data has were at the end.

At some point in the process I thought, hang on, when I change the "pulltype" property on a pin certain bits have to change, and looking in the bits file for the io tile in question and the pin used, showed these to be the bits in column 3 (x) and rows 14 and 16 (y), but in my generated image the bits were on column 3 and rows 18 and 20. So an offset of 4, and then the quarter dropped :o

I knew about the bit stream having 257 bytes per frame which is 2056 bits and the database only using 2052 of them. My programmers instinct naturally assumed the not used bits to be at the end. It turns out they are at the beginning.

After testing with more io pins at all sides of the chip this was confirmed and I now have clear data on the configuration bits.

It turns out that the Tang Dynasty software always sets the source and sink property bits for all the pads in a tile even when the pad is not used or connected to the actual pins. The other bits are only controlled when a pad is used.

Still a lot to figure out to get from the bit listing to a net list and from that back to hdl.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #3 on: July 26, 2022, 09:02:21 am »
I'm revisiting this topic after new information came up.

For the Gowin FPGA's more has been done on the front of the open source tools, and I was looking into that in regards to the Gowin FPGA used in the Hantek DSO2000 series. I learned from it about the naming convention in the routing. So to gain more experience on FPGA reverse engineering I decided to try the probably simpler design of the in the FNIRSI-1013D used Anlogic FPGA.

Still a lot of discovery to be done, but think it is possible to trace the connections through the FPGA.

The configuration bits are set based on a logic equation on input parameters. For the routing these are like "ARCVAL(S6BEG0,E1END0)" where this means a connection between a south going wire spanning 6 blocks and an east going wire spanning a single block. The first character is the direction letter, the second character is the span, being either 1,2 or 6. Then followed by a tap point being "BEG", "MID" or "END" and a last character being the wire index.

For the single block span it looks like there are only 4 wires per route. For the multi block spans there seem to be 8 wires per route.

I made a listing of all the separate ARCVAL entities to gain more insight.

The screen shot shows a routing in the Tang IDE chip viewer.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #4 on: August 06, 2022, 07:46:34 am »
I have a question about interconnect wires in a FPGA.

Are they unidirectional?

In the Anlogic AL3_10 FPGA I'm trying to reverse engineer a design from, I'm progressing slowly and gain more insight in the interconnect and wonder if I'm right in thinking that the interconnect wires are indeed unidirectional.

The Tang Dynasty IDE has a chip viewer and I found some new features that allow highlighting of the RSB/PIB SWI lines. It has three types, namely 1 hop, 2 hop and 6 hop lines. When viewing these for a single block it shows only 4 lines per type originating from the block. See the attached pictures.

This leads to the below and the total number of connections match up.

Code: [Select]
outgoing      incoming
 4x  1 hop     4x  1 hop
 4x  2 hop     8x  2 hop (4 mid and 4 end)
 4x  6 hop     8x  6 hop (4 mid and 4 end)

total connections
12      +     20 = 32 (4 x 8)

I made a listing of the arcval pairs found in the database and this seems to confirm my idea. The pairs have the following meaning (endpoint, startpoint). For instance (W6BEG5,Q0) signals a connection between a logic block output Q0 and a wire start W6BEG5. In the list it only shows connections to the BEG wires and not the MID or END wires. There are of course also connections to logic block inputs like A0, B0, etc.

Another question is if this setup is proprietary to the Anlogic FPGA's or a rather common thing?

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #5 on: August 08, 2022, 05:38:41 pm »
Making some progress.

A simple test design yielded no problems and showed the nets correctly, but the bitstream of the FNIRSI 1013D FPGA fails :palm:

Needs more tinkering, but I'm getting output which I can trace through to see what the problem is. It at least shows that I'm on the right track.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #6 on: August 09, 2022, 07:35:37 pm »
After a bit of tweaking and modding the code, it successfully created a full net list for the FNIRSI FPGA.

It is a small step in the big process of reversing the bit stream to HDL, but I feel it is good progress.

Next up is turning the list into an actual net list with just a start and an endpoint, because all the in between connection points are not of interest.

Code: [Select]
9 1 ARCVAL(W6BEG1,Q1) x0y35 pib 0 35 TOP.XI2.MC00 NONE 2 45 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W6BEG1,F1) ARCVAL(W6BEG1,F5) ARCVAL(W6BEG1,Q1) ARCVAL(W6BEG1,W1END2)
9 1 ARCVAL(W6BEG1,Q1) x0y35 pib 0 35 TOP.XI2.MC06 NONE 0 45 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W6BEG1,FX5) ARCVAL(W6BEG1,N6MID1) ARCVAL(W6BEG1,Q1) ARCVAL(W6BEG1,S6END1)
9 4 ARCVAL(S6BEG1,E6MID1) x2y35 plb 2 35 TOP.XI1.MC02 NONE 1 43 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG1,E1END2) ARCVAL(S6BEG1,E6MID1) ARCVAL(S6BEG1,S2END1) ARCVAL(S6BEG1,W1END2)
9 4 ARCVAL(S6BEG1,E6MID1) x2y35 plb 2 35 TOP.XI1.MC06 NONE 0 44 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG1,E6MID1) ARCVAL(S6BEG1,FX5) ARCVAL(S6BEG1,Q1) ARCVAL(S6BEG1,W6END1)
9 4 ARCVAL(S6BEG3,S6END1) x2y29 plb 2 29 TOP.XI33.MC03 NONE 2 30 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG3,E6END3) ARCVAL(S6BEG3,S6END1) ARCVAL(S6BEG3,W6END3) ARCVAL(S6BEG3,W6MID3)
9 4 ARCVAL(S6BEG3,S6END1) x2y29 plb 2 29 TOP.XI33.MC07 NONE 0 31 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG3,S1END2) ARCVAL(S6BEG3,S2END3) ARCVAL(S6BEG3,S6END1) ARCVAL(S6BEG3,S6END3)
9 4 ARCVAL(S6BEG1,S6END3) x2y23 plb 2 23 TOP.XI1.MC03 NONE 2 42 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG1,E6END1) ARCVAL(S6BEG1,S6END3) ARCVAL(S6BEG1,W6END1) ARCVAL(S6BEG1,W6MID1)
9 4 ARCVAL(S6BEG1,S6END3) x2y23 plb 2 23 TOP.XI1.MC07 NONE 0 43 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG1,S1END2) ARCVAL(S6BEG1,S2END1) ARCVAL(S6BEG1,S6END1) ARCVAL(S6BEG1,S6END3)
9 4 ARCVAL(E6BEG1,S6END1) x2y17 plb 2 17 TOP.XI2.MC13 NONE 3 47 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(E6BEG1,E6END3) ARCVAL(E6BEG1,N6END1) ARCVAL(E6BEG1,S6END1) ARCVAL(E6BEG1,S6MID1)
9 4 ARCVAL(E6BEG1,S6END1) x2y17 plb 2 17 TOP.XI2.MC16 NONE 0 47 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(E6BEG1,FX5) ARCVAL(E6BEG1,N6MID1) ARCVAL(E6BEG1,Q1) ARCVAL(E6BEG1,S6END1)
9 4 ARCVAL(E2BEG1,E6END1) x8y17 pib 8 17 TOP.XI21.MC12 NONE 17 46 0 0 A+B+C+D+E AB+C+D+E+ 5 ARCVAL(E2BEG1,E2END1) ARCVAL(E2BEG1,E6END1) ARCVAL(E2BEG1,N2MID1) ARCVAL(E2BEG1,N6MID1) ARCVAL(E2BEG1,S6MID1)
9 4 ARCVAL(E2BEG1,E6END1) x8y17 pib 8 17 TOP.XI21.MC14 NONE 12 47 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(E2BEG1,E6END1) ARCVAL(E2BEG1,F1) ARCVAL(E2BEG1,FX1) ARCVAL(E2BEG1,N2END1)
9 2 ARCVAL(B5,E2MID1) x9y17 plb 9 17 TOP.XI371.MC12 NONE 25 46 0 0 A+B+C+D+E+F+G+H AB+C+D+E+F+G+H+ 8 ARCVAL(B5,E2END1) ARCVAL(B5,E2MID1) ARCVAL(B5,N2END1) ARCVAL(B5,N2MID1) ARCVAL(B5,Q6) ARCVAL(B5,S2MID1) ARCVAL(B5,W2END1) ARCVAL(B5,W2MID1)
9 2 ARCVAL(B5,E2MID1) x9y17 plb 9 17 TOP.XI371.MC14 NONE 20 47 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(B5,E1END0) ARCVAL(B5,E2END0) ARCVAL(B5,E2MID1) ARCVAL(B5,S2END1)

Because the above list can be reduced to just a short entry where it shows that x0,y35 Q1 is connected to x9,y17 B5 where Q1 is an IO pin input signal onto the FPGA fabric and B5 is the input to a LUT on a logic block.

With such a list the step to HDL is much closer. But it also needs the information about what is in a LUT.

Still lots of work to be done.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #7 on: August 10, 2022, 08:12:58 am »
Found an oversight in my route tracing which I had thought about and knew investigation was needed.

My simple test was just an input pin connected to an output pin, but a FPGA can do so much more then that of course. But I was very happy that my fixes from last night ran through the original FNIRSI bitstream without obvious errors :)

So this morning I made a new test where two input pins are connected through logic with three output pins. (And, Or and Xor). And running that through my code did deliver a net list, but only 56 of the 92 routing bits were actually used. It turns out that interconnects can be linked to multiple targets, which I did expect but had no idea how it was done.

It is rather simple. An incoming connection on a RSB can be connected multiple times, which means that more bit pairs use the same start point. So I have to adapt the code to handle this too.

Offline fabiodl

  • Frequent Contributor
  • **
  • Posts: 282
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #8 on: August 10, 2022, 08:26:42 am »
I am sorry I have nothing meaningful to add, but please keep up with this work!!
 

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #9 on: August 10, 2022, 07:00:16 pm »
That I will.

Decided to move to a new c project to rewrite the net list generation. The bitstream analyzer is ok for creating the bitmap and a list of the bits, but for the net list a new approach is needed.

So I started the Anlogic_netlist_tracer project. It is a copy of the bitstream analyzer, but ripped out almost all the code and are writing new functions to get it done. First it reads in the bitstream and creates a tile array with all the route bits separated per tile. It then scans through all the tiles to find net start points and assign a net number to them. A single output from an IO or logic block can be connected to multiple interconnect routes and these are all assigned the same net number to create single nets for all the inputs connected to one output.

The next bit of code has to trace down all the connections, which is where I left of for today.

More to follow :)

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #10 on: August 11, 2022, 02:11:57 pm »
Finished the new tracing code and it matches all the routes of my test design, but when I run it on the FNIRSI bitstream it still goes somewhat wrong. It does match 30644 bits to 4049 nets, but it leaves 7820 bits that are not connected to any of the nets. So I'm missing something and have to investigate some more.

There is a possibility that it has to do with the clock nets. Most connections are made in pairs of bits, but I just spotted odd numbers of bits in some tiles, which means there can also be single bit connections. Experimenting is the only way to find out what is what and how it works, because documentation is non existent |O

But that is the challenge.

Edit: Found two problems. The first one was an oversight due to which multiple connections in a tile were not found properly. The fix for this reduced the not connected bits by some 3000 bits. The second one was a wrong assumption about the connections. The multi hop wires can have connections on both the middle as well as on the end point, where I assumed it to be to only one of them. This fix reduced the number of unconnected bits to 468, of which a large part are single bit connections for clock signals. The net count has reduced to 2295 because before a fix the multiple connections to a single block output were counted separately.

Conclusion is that I need to write some code to handle the clock routes in a different manner to solve these unconnected bits, but I also have to look into the remainder of the unconnected bit pairs.

But that is for tomorrow. :=\
« Last Edit: August 11, 2022, 07:05:13 pm by pcprogrammer »
 

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #11 on: August 12, 2022, 11:26:46 am »
Fixed most of the issues with the net list trace.

The result is a left over of 422 single bits to connect the clock signals to the logic, for which I have to add some extra functionality.

There is one more issue with the tracing and that has to do with CE and SR signals of the blocks. These are inputs to the logic, but can also connect to some other signals in a tile. I did not see this used in the FNIRSI FPGA bitstream so not an issue for now.

To get a proper net list I now have to change the code to first trace down all the inputs connected to GND, and then trace all the global clock nets to make them into bigger single nets per global clock line. After this it is making sure all the actual clock connections based on the single routing bits are traced into the nets too.

All in all a nice learning experience so far.

Still lots of work to be done before some HDL rolls out of it. 8)

Edit: Finished the changes to make the separate GND and GCLK nets. All the routing bits are now accounted for. It yields 1673 nets for the FNIRSI 1013D and 1699 nets for the FNIRSI 1014D.
Next up is to format the lists into a usable way. This means only one entry for a single output connected to one or more inputs, and identify the io pins and logic blocks the inputs and outputs belong to.

Code: [Select]
1699 1 ARCVAL(S1BEG2,Q1) x34y29 pib 34 29 TOP.XI315.MC01 NONE 8 37 0 0 A+B+C+D+E+F AB+C+D+E+F+ 6 ARCVAL(S1BEG2,F6) ARCVAL(S1BEG2,F7) ARCVAL(S1BEG2,Q0) ARCVAL(S1BEG2,Q1) ARCVAL(S1BEG2,Q2) ARCVAL(S1BEG2,Q3)
1699 1 ARCVAL(S1BEG2,Q1) x34y29 pib 34 29 TOP.XI315.MC07 NONE 6 37 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S1BEG2,F3) ARCVAL(S1BEG2,FX5) ARCVAL(S1BEG2,Q1) ARCVAL(S1BEG2,Q7)
1699 4 ARCVAL(S1BEG3,Q1) x34y29 pib 34 29 TOP.XI313.MC01 NONE 8 7 0 0 A+B+C+D+E+F AB+C+D+E+F+ 6 ARCVAL(S1BEG3,F6) ARCVAL(S1BEG3,F7) ARCVAL(S1BEG3,Q0) ARCVAL(S1BEG3,Q1) ARCVAL(S1BEG3,Q2) ARCVAL(S1BEG3,Q3)
1699 4 ARCVAL(S1BEG3,Q1) x34y29 pib 34 29 TOP.XI313.MC07 NONE 6 7 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S1BEG3,F3) ARCVAL(S1BEG3,FX5) ARCVAL(S1BEG3,Q1) ARCVAL(S1BEG3,Q7)
1699 4 ARCVAL(W6BEG3,S1END2) x34y28 pib 34 28 TOP.XI32.MC05 NONE 1 35 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W6BEG3,F7) ARCVAL(W6BEG3,FX3) ARCVAL(W6BEG3,S1END2) ARCVAL(W6BEG3,S6MID3)
1699 4 ARCVAL(W6BEG3,S1END2) x34y28 pib 34 28 TOP.XI32.MC02 NONE 1 34 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W6BEG3,N1END2) ARCVAL(W6BEG3,N6MID3) ARCVAL(W6BEG3,S1END2) ARCVAL(W6BEG3,W2END3)
1699 4 ARCVAL(W6BEG7,S1END3) x34y28 pib 34 28 TOP.XI58.MC05 NONE 1 5 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W6BEG7,F7) ARCVAL(W6BEG7,FX7) ARCVAL(W6BEG7,S1END3) ARCVAL(W6BEG7,S6MID7)
1699 4 ARCVAL(W6BEG7,S1END3) x34y28 pib 34 28 TOP.XI58.MC02 NONE 1 4 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W6BEG7,N1END3) ARCVAL(W6BEG7,N6MID7) ARCVAL(W6BEG7,S1END3) ARCVAL(W6BEG7,W2END7)
1699 4 ARCVAL(W6BEG3,W6END3) x28y28 plb 28 28 TOP.XI32.MC01 NONE 2 34 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W6BEG3,FX3) ARCVAL(W6BEG3,FX7) ARCVAL(W6BEG3,Q7) ARCVAL(W6BEG3,W6END3)
1699 4 ARCVAL(W6BEG3,W6END3) x28y28 plb 28 28 TOP.XI32.MC07 NONE 0 34 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W6BEG3,W1END2) ARCVAL(W6BEG3,W2END3) ARCVAL(W6BEG3,W6END1) ARCVAL(W6BEG3,W6END3)
1699 4 ARCVAL(W6BEG7,W6END7) x28y28 plb 28 28 TOP.XI58.MC01 NONE 2 4 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W6BEG7,FX3) ARCVAL(W6BEG7,FX7) ARCVAL(W6BEG7,Q7) ARCVAL(W6BEG7,W6END7)
1699 4 ARCVAL(W6BEG7,W6END7) x28y28 plb 28 28 TOP.XI58.MC07 NONE 0 4 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W6BEG7,W1END3) ARCVAL(W6BEG7,W2END7) ARCVAL(W6BEG7,W6END5) ARCVAL(W6BEG7,W6END7)
1699 4 ARCVAL(S6BEG3,W6END3) x22y28 plb 22 28 TOP.XI33.MC03 NONE 2 30 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG3,E6END3) ARCVAL(S6BEG3,S6END1) ARCVAL(S6BEG3,W6END3) ARCVAL(S6BEG3,W6MID3)
1699 4 ARCVAL(S6BEG3,W6END3) x22y28 plb 22 28 TOP.XI33.MC06 NONE 0 32 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG3,E6MID3) ARCVAL(S6BEG3,FX7) ARCVAL(S6BEG3,Q3) ARCVAL(S6BEG3,W6END3)
1699 4 ARCVAL(S6BEG7,W6END7) x22y28 plb 22 28 TOP.XI59.MC03 NONE 2 0 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG7,E6END7) ARCVAL(S6BEG7,S6END5) ARCVAL(S6BEG7,W6END7) ARCVAL(S6BEG7,W6MID7)
1699 4 ARCVAL(S6BEG7,W6END7) x22y28 plb 22 28 TOP.XI59.MC06 NONE 0 2 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG7,E6MID7) ARCVAL(S6BEG7,FX3) ARCVAL(S6BEG7,Q3) ARCVAL(S6BEG7,W6END7)
1699 4 ARCVAL(S6BEG1,S6END3) x22y22 plb 22 22 TOP.XI1.MC03 NONE 2 42 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG1,E6END1) ARCVAL(S6BEG1,S6END3) ARCVAL(S6BEG1,W6END1) ARCVAL(S6BEG1,W6MID1)
1699 4 ARCVAL(S6BEG1,S6END3) x22y22 plb 22 22 TOP.XI1.MC07 NONE 0 43 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG1,S1END2) ARCVAL(S6BEG1,S2END1) ARCVAL(S6BEG1,S6END1) ARCVAL(S6BEG1,S6END3)
1699 4 ARCVAL(S6BEG5,S6END7) x22y22 plb 22 22 TOP.XI47.MC03 NONE 2 12 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG5,E6END5) ARCVAL(S6BEG5,S6END7) ARCVAL(S6BEG5,W6END5) ARCVAL(S6BEG5,W6MID5)
1699 4 ARCVAL(S6BEG5,S6END7) x22y22 plb 22 22 TOP.XI47.MC07 NONE 0 13 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(S6BEG5,S1END3) ARCVAL(S6BEG5,S2END5) ARCVAL(S6BEG5,S6END5) ARCVAL(S6BEG5,S6END7)
1699 4 ARCVAL(W2BEG1,S6END1) x22y16 plb 22 16 TOP.XI21.MC01 NONE 14 46 0 0 A+B+C+D+E AB+C+D+E+ 5 ARCVAL(W2BEG1,FX1) ARCVAL(W2BEG1,N6END1) ARCVAL(W2BEG1,S6END1) ARCVAL(W2BEG1,W1END2) ARCVAL(W2BEG1,W6END1)
1699 4 ARCVAL(W2BEG1,S6END1) x22y16 plb 22 16 TOP.XI21.MC05 NONE 12 45 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W2BEG1,F5) ARCVAL(W2BEG1,N6MID1) ARCVAL(W2BEG1,S2MID1) ARCVAL(W2BEG1,S6END1)
1699 4 ARCVAL(W2BEG5,S6END5) x22y16 plb 22 16 TOP.XI25.MC01 NONE 14 16 0 0 A+B+C+D+E AB+C+D+E+ 5 ARCVAL(W2BEG5,FX5) ARCVAL(W2BEG5,N6END5) ARCVAL(W2BEG5,S6END5) ARCVAL(W2BEG5,W1END3) ARCVAL(W2BEG5,W6END5)
1699 4 ARCVAL(W2BEG5,S6END5) x22y16 plb 22 16 TOP.XI25.MC05 NONE 12 15 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(W2BEG5,F5) ARCVAL(W2BEG5,N6MID5) ARCVAL(W2BEG5,S2MID5) ARCVAL(W2BEG5,S6END5)
1699 2 ARCVAL(B4,W2END1) x20y16 plb 20 16 TOP.XI371.MC07 NONE 19 46 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(B4,F1) ARCVAL(B4,N2MID0) ARCVAL(B4,S1END0) ARCVAL(B4,W2END1)
1699 2 ARCVAL(B4,W2END1) x20y16 plb 20 16 TOP.XI371.MC02 NONE 18 46 0 0 A+B+C+D+E+F+G+H AB+C+D+E+F+G+H+ 8 ARCVAL(B4,E2END1) ARCVAL(B4,E2MID1) ARCVAL(B4,N2END1) ARCVAL(B4,N2MID1) ARCVAL(B4,Q6) ARCVAL(B4,S2MID1) ARCVAL(B4,W2END1) ARCVAL(B4,W2MID1)
1699 2 ARCVAL(MI4,W2END5) x20y16 plb 20 16 TOP.XI331.MC09 NONE 10 21 0 0 A+B+C+D AB+C+D+ 4 ARCVAL(MI4,GND) ARCVAL(MI4,LOCAL6) ARCVAL(MI4,N2END4) ARCVAL(MI4,W2END5)
1699 2 ARCVAL(MI4,W2END5) x20y16 plb 20 16 TOP.XI331.MC01 NONE 8 22 0 0 A+B+C+D+E+F AB+C+D+E+F+ 6 ARCVAL(MI4,E2END5) ARCVAL(MI4,E2MID5) ARCVAL(MI4,S2END4) ARCVAL(MI4,S2MID4) ARCVAL(MI4,W2END5) ARCVAL(MI4,W2MID5)


Needs to become something like
Code: [Select]
Q1   34,29 IO PIN xx
B4   20,16 SLICE2  LB4 B
MI4  20,16 SLICE2  LB4 MI
« Last Edit: August 12, 2022, 04:33:46 pm by pcprogrammer »
 
The following users thanked this post: paf

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #12 on: August 13, 2022, 04:42:50 pm »
I hit a snag again |O

Now that I have a net list with single outputs connected to multiple inputs, I wanted to couple the IO pins into the listing. I have mapped the IO pins with the control bits before but this is only for setting the type of the IO pin, like input or output and not for the connection with the fabric. There the mapping is not straight forward :o

In the PIB tiles the same naming is used as in the PLB tiles, where A, B, C, D, E, MI, CE, SR, CLK_S, CLKN_S are inputs and F, FX, Q are outputs. I did find that for an input pin the Q is used to bring it onto the fabric, but which one in which tile is which pin is the big question.

For the PLB it matches mostly with the picture I have of the slices, and I don't expect much problems there. Embedded memory and DSP slices are a different story again.

So it is back to the drawing board and try to find this information in the original Anlogic database or try to find it with test designs when using different pins. I understood that the latter is called "fuzzing" so maybe I have to look into that.

A well, I will see how it goes :)

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #13 on: August 14, 2022, 01:26:00 pm »
Seems I don't have to use fuzzing :)

I found a section in the database for the AL3-10 that gives information on which tile signal name matches onto which IO pad name.

Code: [Select]
6 4
0 10
ce 0 1
0 ce0 0 -1
clk 0 1
0 clk_s0 0 -1
di 0 1
0 q0 0 -1
eninr_dyn 0 1
0 d3 0 -1
icomp 0 1
0 f1 0 -1
itrue 0 1
0 f0 0 -1
ocomp 0 1
0 b3 0 -1
otrue 0 1
0 a3 0 -1
rst 0 1
0 sr0 0 -1
ts 0 1
0 c3 0 -1
1 10
ce 0 1
0 ce1 0 -1
clk 0 1
0 clk_s1 0 -1
di 0 1
0 q1 0 -1
eninr_dyn 0 1
0 d4 0 -1
icomp 0 1
0 f2 0 -1
itrue 0 1
0 f3 0 -1
ocomp 0 1
0 b4 0 -1
otrue 0 1
0 a4 0 -1
rst 0 1
0 sr1 0 -1
ts 0 1
0 c4 0 -1
2 10
ce 0 1
0 ce1 0 -2
clk 0 1
0 clk_s1 0 -2
di 0 1
0 q1 0 -2
eninr_dyn 0 1
0 d4 0 -2
icomp 0 1
0 f2 0 -2
itrue 0 1
0 f3 0 -2
ocomp 0 1
0 b4 0 -2
otrue 0 1
0 a4 0 -2
rst 0 1
0 sr1 0 -2
ts 0 1
0 c4 0 -2
3 10
ce 0 1
0 ce0 0 -2
clk 0 1
0 clk_s0 0 -2
di 0 1
0 q0 0 -2
eninr_dyn 0 1
0 d3 0 -2
icomp 0 1
0 f1 0 -2
itrue 0 1
0 f0 0 -2
ocomp 0 1
0 b3 0 -2
otrue 0 1
0 a3 0 -2
rst 0 1
0 sr0 0 -2
ts 0 1
0 c3 0 -2

All I have to do now is figure out how it translates from what I have to what I need. It requires a bit of tinkering because it differs for left/right to top/bottom pads and there are also io pair pads that also use a different mapping.

Have to code a bit of python first to convert the found data into something I can use in my C code and then modify my C code to make use of it.

The found tables also provide information about the embedded memory, dsp, pll, and what more there is in the FPGA. So again a step in the right direction.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #14 on: August 16, 2022, 08:09:17 am »
For me python sucks. I tried to write some code to convert the data I found into something I can use in my project, but failed on a stupid data copying bit I don't grasp and the IDE does not tell me what is wrong so I ended up just writing it in C. As ii was for just a single job one time conversion not the most elegant code but it did the trick.

The python code kept failing on the assignment "sectionnames = items[0]". I tried to just load it with a static but every time it just bailed out without any info. Was not in the mood to research it further. My python knowledge is very little and not high upon my list to learn more about it, but if it is obvious to someone why it fails, please enlighten me.

Code: [Select]
items = []
sectionnames = []
sectionids = []


def main():
    global items
    global sectionnames
    global sectionids

    inputfile = open("al3_10_connection_setup", "rt")
    outputfile = open("al3_10_signal_mapping.h", "wt")

    strinp = inputfile.readline()

    nofsections = int(strinp)

    for i in range(nofsections):
        strinp = inputfile.readline()

        items = strinp.split()

        sectionnames[i] = items[0]
        sectionids[i] = items[1]

    strinp = inputfile.readline()


if __name__ == "__main__":
    main()



In my C code I added a couple of if statements for breakpoints to detect if parts of the data did something unexpected and at some point it did. A counter was 2 instead of 1 so had to deal with that. Also the length of the names were bigger then expected.

Code: [Select]
#include <stdio.h>      // standard input / output functions
#include <stdlib.h>
#include <string.h>

void listdatasection(FILE *fin, FILE *fout, char *sectionname, int count)
{
  int datatid;
  int datacount;

  char hdl_name[32];
  char signal_name[32];
 
  int cnt0;
  int cnt1;
 
  int signalid;
 
  int xoff;
  int yoff;
 
  int len;
 
  char line[128];
 
  char *sptr;
  char *dptr;
 
  while(count--)
  {
    fgets(line, 128, fin);

    sptr = line;
   
    datatid = atoi(sptr);

    while(*sptr++ != ' ');

    datacount = atoi(sptr);

    fprintf(fout, "//----------------------------------------------------------------------------------------------------------------------------------\n\n");
   
    fprintf(fout, "SIGNAL_NAME_MAP %s_%d[] =\n{\n", sectionname, datatid);

    while(datacount--)
    {
      fgets(line, 128, fin);

      dptr = hdl_name;
      sptr = line;

      while(*sptr != ' ')
      {
        *dptr++ = *sptr++;
      }

      *dptr = 0;

      sptr++;

      cnt0 = atoi(sptr);

      while(*sptr++ != ' ');

      cnt1 = atoi(sptr);

      if((cnt0 != 0) || ((cnt1 != 1) && (cnt1 != 2)))
      {
        dptr = 0;
      }

      //This next bit needs to be done cnt1 times????
      //Not entirely. The multiple data is on the same line and is repeated as such indicating a signal can have entries in to tiles

      fgets(line, 128, fin);
     
      sptr = line;

      signalid = atoi(sptr);

      if(signalid != 0)
      {
        dptr = 0;
      }

      while(*sptr++ != ' ');

      dptr = signal_name;

      while(*sptr != ' ')
      {
        *dptr++ = *sptr++;
      }

      *dptr = 0;

      sptr++;

      xoff = atoi(sptr);

      while(*sptr++ != ' ');

      yoff = atoi(sptr);
     
      fprintf(fout, "  { \"%s\",", hdl_name);
     
      len = 21 - strlen(hdl_name);
     
      if(len < 0)
      {
        dptr = 0;
      }
     
      while(len--)
      {
        fwrite(" ", 1, 1, fout);
      }
     
      fprintf(fout, "\"%s\",", signal_name);

      len = 13 - strlen(signal_name);
     
      if(len < 0)
      {
        dptr = 0;
      }
     
      while(len--)
      {
        fwrite(" ", 1, 1, fout);
      }
     
      if(xoff >= 0)
      {
        fwrite(" ", 1, 1, fout);
      }
     
      fprintf(fout, "%d, ", xoff);
     
      if(yoff >= 0)
      {
        fwrite(" ", 1, 1, fout);
      }
     
      fprintf(fout, "%d },\n", yoff);
     
      if(cnt1 == 2)
      {
        while(*sptr++ != ' ');
       
        signalid = atoi(sptr);

        if(signalid != 0)
        {
          dptr = 0;
        }

        while(*sptr++ != ' ');

        dptr = signal_name;

        while(*sptr != ' ')
        {
          *dptr++ = *sptr++;
        }

        *dptr = 0;

        sptr++;

        xoff = atoi(sptr);

        while(*sptr++ != ' ');

        yoff = atoi(sptr);

        fprintf(fout, "  { \"%s\",", hdl_name);

        len = 21 - strlen(hdl_name);

        if(len < 0)
        {
          dptr = 0;
        }

        while(len--)
        {
          fwrite(" ", 1, 1, fout);
        }

        fprintf(fout, "\"%s\",", signal_name);

        len = 13 - strlen(signal_name);

        if(len < 0)
        {
          dptr = 0;
        }

        while(len--)
        {
          fwrite(" ", 1, 1, fout);
        }

        if(xoff >= 0)
        {
          fwrite(" ", 1, 1, fout);
        }

        fprintf(fout, "%d, ", xoff);

        if(yoff >= 0)
        {
          fwrite(" ", 1, 1, fout);
        }

        fprintf(fout, "%d },\n", yoff);
      }
     
    }
   
    fprintf(fout, "};\n\n" );
  }
}

int main(int argc, char** argv)
{
  FILE *fin = fopen("al3_10_connection_setup", "r");
  FILE *fout = fopen("al3_10_connection_setup.h", "w");
 
  char line[128];
 
  int nofsections;
  int i,j;
 
  char *sptr;
  char *dptr;
 
  char sectionnames[20][32];
  char sectionids[20];
 
  int id;
  int count;
 
  if(fin && fout)
  {
    fgets(line, 128, fin);
   
    nofsections = atoi(line);
   
    for(i=0;i<nofsections;i++)
    {
      fgets(line, 128, fin);
     
      dptr = sectionnames[i];
      sptr = line;
     
      while(*sptr != ' ')
      {
        *dptr++ = *sptr++;
      }
     
      *dptr = 0;
     
      sptr++;
     
      sectionids[i] = atoi(sptr);
    }

    while(fgets(line, 128, fin))
    {
      //Next bit has an id number and a count
      sptr = line;

      id = atoi(sptr);

      while(*sptr++ != ' ');

      count = atoi(sptr);

      //Match the id to one of the section ids and use the belonging name to make an entry in the h file
      for(i=0;i<nofsections;i++)
      {
        if(id == sectionids[i])
        {
          id = i;
          break;
        }
      }


      //Make a function to read the lines from the file and write them to the h file
      listdatasection(fin, fout, sectionnames[id], count);
    }
   
    fprintf(fout, "//----------------------------------------------------------------------------------------------------------------------------------\n\n");
   
    fclose(fin);
    fclose(fout);
  }
}


It yielded information like below
Code: [Select]
//----------------------------------------------------------------------------------------------------------------------------------

SIGNAL_NAME_MAP iol_tb_0[] =
{
  { "ce",                   "ce0",           0,  0 },
  { "clk",                  "clk_s0",        0,  0 },
  { "di",                   "q0",            0,  0 },
  { "eninr_dyn",            "d3",            0,  0 },
  { "icomp",                "f1",            0,  0 },
  { "itrue",                "f0",            0,  0 },
  { "ocomp",                "b3",            0,  0 },
  { "otrue",                "a3",            0,  0 },
  { "rst",                  "sr0",           0,  0 },
  { "ts",                   "c3",            0,  0 },
};

//----------------------------------------------------------------------------------------------------------------------------------

SIGNAL_NAME_MAP iol_tb_1[] =
{
  { "ce",                   "ce1",           0,  0 },
  { "clk",                  "clk_s1",        0,  0 },
  { "di",                   "q1",            0,  0 },
  { "eninr_dyn",            "d4",            0,  0 },
  { "icomp",                "f2",            0,  0 },
  { "itrue",                "f3",            0,  0 },
  { "ocomp",                "b4",            0,  0 },
  { "otrue",                "a4",            0,  0 },
  { "rst",                  "sr1",           0,  0 },
  { "ts",                   "c4",            0,  0 },
};

//----------------------------------------------------------------------------------------------------------------------------------

SIGNAL_NAME_MAP iol_tb_2[] =
{
  { "ce",                   "ce1",           1,  0 },
  { "clk",                  "clk_s1",        1,  0 },
  { "di",                   "q1",            1,  0 },
  { "eninr_dyn",            "d4",            1,  0 },
  { "icomp",                "f2",            1,  0 },
  { "itrue",                "f3",            1,  0 },
  { "ocomp",                "b4",            1,  0 },
  { "otrue",                "a4",            1,  0 },
  { "rst",                  "sr1",           1,  0 },
  { "ts",                   "c4",            1,  0 },
};

//----------------------------------------------------------------------------------------------------------------------------------

SIGNAL_NAME_MAP iol_tb_3[] =
{
  { "ce",                   "ce0",           1,  0 },
  { "clk",                  "clk_s0",        1,  0 },
  { "di",                   "q0",            1,  0 },
  { "eninr_dyn",            "d3",            1,  0 },
  { "icomp",                "f1",            1,  0 },
  { "itrue",                "f0",            1,  0 },
  { "ocomp",                "b3",            1,  0 },
  { "otrue",                "a3",            1,  0 },
  { "rst",                  "sr0",           1,  0 },
  { "ts",                   "c3",            1,  0 },
};

//----------------------------------------------------------------------------------------------------------------------------------


Now that I have this data I have to make an array with information per tile on which of the tables need to be searched to translate the tile signal name to the hdl signal name.

Offline Kean

  • Supporter
  • ****
  • Posts: 2231
  • Country: au
  • Embedded systems & IT consultant
    • Kean Electronics
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #15 on: August 17, 2022, 03:21:28 am »
Your Python arrays are zero length, so you can't just index into them.

You should probably use something like this.
Code: [Select]
        sectionnames.append(items[0])
        sectionids.append(items[1])

Alternatively, you could pre-fill the arrays just before the for-loop and leave the assignments as-is
Code: [Select]
        sectionnames = [0] * nofsections
        sectionids = [0] * nofsections
 
The following users thanked this post: pcprogrammer

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #16 on: August 17, 2022, 01:59:50 pm »
@Kean: Thanks, that must be it. I expected a high level language to do it for me without special "functions". Thought it was supposed to make things easy :-DD

Took a bit of thinking and fiddling but now I made a reverse table setup via which it is possible to find the HDL name for a signal. Modified the code to test it for the IO pins and it seems to work on my test bitstream. The pins are correctly identified.

Have to turn it in a more general function that returns a HDL name for every signal and use these names in the net list. There is still some ambiguity around embedded memory I need to look into. Because it can be regular, dual port or fifo memory. Guess there will be settings bits for it that will show the type and with that a guide to which translation table needs to be used.

It all requires a lot of thinking to get from the bits back to something useful where the design data is setup for doing it the other way round |O But if it was easy everybody would be doing it 8)

Still a long way to go.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #17 on: August 17, 2022, 05:17:02 pm »
I now have a net list with names that show the kind of block the signal is coming from or going to, like mslice0 or emb2 or pad1.

The first item in a net is always an output and the rest are always inputs. For this gnd is also seen as an output. The hard part is now to translate this into verilog somehow.

Next up is to process the other bits to figure out the configuration of the logic. Already did this for the IO pins, and I should be able to distill a .adc file from it. This is a file with the pin mapping for the Tang Dynasty IDE. Maybe also a top level verilog file to match it.

The fight continues :box:


Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #18 on: August 20, 2022, 01:07:41 pm »
After studying the setup bits I found out a bit more about the logic blocks. For a basic lookup table to create for instance a two input AND gate it fills the complete table (16 entries) with the needed bits. In the data, for a mslice, it looks like below.

Code: [Select]
LUT0_S0_12  MEMORY(SLICE0,LUT0,12)
LUT0_S0_13  MEMORY(SLICE0,LUT0,13)
LUT0_S0_14  MEMORY(SLICE0,LUT0,14)
LUT0_S0_15  MEMORY(SLICE0,LUT0,15)

This turns on the top 4 bits and the routing is done on the C and D input. The F output is where the signal comes out.

For lsices it uses names like "LUTF0_S2_0" and "LUTG0_S2_0" to fill two tables with 16 entries. Combined they make up a 5 input lookup table.

Also found that for the embedded memory there are settings to enable it as a FIFO, dual port or single port memory.

Converting all this information into actually usable verilog will not be easy and might require a lot of manual labor. At the moment the best way forward seems to be to draw a "gate" level schematic, but instead of actual gates it will be the different blocks that can be found in a FPGA. This will take a bit of time.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #19 on: August 23, 2022, 02:02:35 pm »
Still plowing on the data. There is a lot to analyze on the settings part.

I'm working on making a block list that gives insight in the used parts of the FPGA.

Had to fix an oversight first in the mapping of the signal names though. Had to track back to the original tile for specific types of logic to be able to properly name the signals. This is the case with, for instance, embedded memory blocks, where they spread across several tiles, but also for io blocks. The mapping of some signals in the 1013D FPGA onto the memory make more sense now. I saw ADC data bits go into address lines first :palm: With proper mapping it now shows data lines.

Knowing the settings of the blocks makes up for how the verilog should be written. But there are a lot of different settings to consider. Still fun though.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #20 on: August 26, 2022, 04:51:59 pm »
Was a bit of a struggle to match the items on the net list to the blocks, but it looks good now. Only implemented what is used in the FNIRSI 1013D FPGA, so it is not a generic tool.

In the Tang Dynasty IDE there is a schematic viewer that gives a wired block diagram and this gives some idea on what the block should look like. For this I will first make a drawing tool with some table setup for the different blocks and then I will see if I can make a viewer, because an image says more then a 1000 nets :)

There are 891 items in the block list and 1673 in the net list.

A lot of work to be done until there is a verilog file.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #21 on: September 03, 2022, 11:03:58 am »
Back on the job after a couple of days of being preoccupied or to tired.

Still working on making a block schematic and to make it possible had to add code to see if there are connections to the found blocks. It turns out that there are hidden clock routes, which can only be tracked through property bits instead of topology bits. SO these do not show up in the net list.

How this works for the clock input pin is something I have to figure out, because how it sits now it looks like pin 23, which is the 50MHz clock input, is not connected to the logic.

Furthermore the global clock spine is also something that needs to be investigated. I believe it uses the global clock multiplexers but how the connections are made requires looking at all the specific settings on these tile elements.

The amount of data to process is becoming quite big, so more filtering needs to be programmed to bring out the important stuff. More on this story later. Sit back and enjoy  :popcorn:

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #22 on: September 04, 2022, 12:35:28 pm »
Decided to simplify things a bit and will just make a named block schematic instead of a wired one. I will start with just a single block per image and leave some room for adding property information like the logic table for lut's.

I hope this will give a better insight then all the lists I have been making. Although very helpful, I feel is will be easier to see relations with the block schematics.

At first I made the blocks with a bus based drawing and naming style (e.g. dia[8:0]), but to connect them to other signals would need a fan out, so switched to just drawing all the single pins. Attached is the set of blocks I need.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #23 on: September 05, 2022, 08:15:53 am »
First block I draw the schematic for shows an embedded memory block and by the looks of it they used dual port memory to separate between the writing into and reading out of, but what I don't get is why it does not use the lower 3 address bits?

Guess I have to study the properties to see if there is some mode to switch between 1, 2, 4 or 8 (9) bits mode for the memory block at hand. Would make some sense then.

But at least making the block schematics does reveal things like this :)

Have to look into the naming of the nets and blocks to see if more information can be given there.

Offline pcprogrammerTopic starter

  • Super Contributor
  • ***
  • Posts: 4305
  • Country: nl
Re: Reverse engineering Anlogic AL3_10 FPGA
« Reply #24 on: September 07, 2022, 02:10:22 pm »
I analyzed the embedded block memory settings and connections and I think I have the matching IP generated for it. A 32 bit wide 4096 word block of simple dual port memory.

Have to connect signals to it and make a test design to see if it matches the settings I found, but the IP generator estimates it as 15 BRAM(s), which is matching what I found.

It will be a lot of work to analyze the blocks and settings and make verilog based on the findings, but see this as a good study for and test of my verilog knowledge, which is still on beginners level.


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf