07-31-2019 11:30 PM
I am starting in the FPGA world, I am doing a tutorial (http://antonpotocnik.com/?p=514765) which tries to communicate the fpga with the BRAMs.
I am trying to understand why in this code displayed below the value of the address which is pointing to a particular register of the BRAM is negative (-2) line 146. I think that this value is the next-to-last address of the BRAM (applying complement 2) but I don't get that in the next clock step, this value is added 1 and is converted to the register 0 instead the last register of the BRAM.. in the simulation provided in the tuto is shown this behaviour.
The BRAM is initialize as TRUE dual port RAM, with a 32 bits with and 1024 depth (so addresses with 10 bits), in the other hand, the AXI bus described in the code below is saying that the address can be up to 16 bits so in the code -2 means the address 1111 1111 1111 1110 but this address is out of range from the memory which can be 11 1111 1111 (1023), why in the simulation the register int_addrA_reg is 2047 when putting that register to -2?
08-01-2019 05:41 AM
Hi @alexrp92 ,
I had a quick look at the page that you referenced and this question has been answered there.
They said: If you look at the simulation results (projects/5_averager/sim/Sim2_a.png) you can see that this results in the correct behavior, so that after next increment the address is 0
08-01-2019 05:56 AM
I've already checked that. My question is why it goes from -2 to 0 in 1 cycle, without taking a -1 value.
I want to understand the process involved to get that.. I want to know why if you take -2, the address is 2047 instead of 1023 cause the address memory is set with 10 bits not 11
08-01-2019 05:59 AM
08-01-2019 06:04 AM
Hi! The simulation image is an image loaded from the tutorial, and the file to simulate that is not provided.. Is my first week working with FPGAs so I still don't have how to simulate a specific block of the whole system..
08-01-2019 06:10 AM
I thought something like that but in the graph state shown in the code I put in m first post says that the address is increased 1 by 1.
The RAM is a true dual port RAM with 32 bits length and 1024 depth.. so I understand that each address (from 0 to 1023) save 32 bits of data
08-02-2019 12:46 AM
If your depth is 1024, it doesn't make sense an address of -2047, that has at least 12 bits.
I think the problem is you cast the address into a type with more than 10 bits, the extra ones show as '1' and are interpreted as a minus sign. Still not clear why they don't increase by one, though, but that could be fixed with a proper translation of the address.
08-02-2019 12:55 AM
Just to clarify, this is a tutorial and it works perfectly, the thing is, I want to understand what is happening..
About the addess.. I think that at the beggining although the AXI address bus is set to 16 bits as we limit the memory to have 1024 locations, the register where the address is saved goes up to 10 bits, until the state case reach 2. At this moment the register detects a negative number so an extra bit is added (10 to 11 bits) and therefore it goes up to 2048 locations. Assuming this is correct, I don't understand that a -2 which is saved as 111 1111 1110 (Complement 2) goes to 000 0000 0000 in the next clock cycle.. it should take the 111 1111 1111 value. Isn't it? Or the last location of a true dual port memory is reserved for other things?
08-02-2019 01:08 AM
"the register detects a negative number so an extra bit is added (10 to 11 bits)"
No, no, and no. Registers are neither that smart or allowed to modify its width.
"111 1111 1110 (Complement 2) goes to 000 0000 0000 in the next clock cycle"
If your depth is 10 bit and you show 11 bits, there must be one unused. Could it be the LSb then your jump is from "111 1111 111" to "000 0000 000" and it all makes sense? I know it sounds a bit of a dodgy explanation but if you have specified your depth as 10-bit you cannot have 11-bit addresses otherwise you would have more memory than what you stated.
08-02-2019 03:34 AM
"If your depth is 10 bit and you show 11 bits, there must be one unused. Could it be the LSb then your jump is from "111 1111 111" to "000 0000 000" and it all makes sense? I know it sounds a bit of a dodgy explanation but if you have specified your depth as 10-bit you cannot have 11-bit addresses otherwise you would have more memory than what you stated."
I don't know.. looking into the specs(page 45) says that the architecture Zynq with the promitive 8kx2 (the algorithm used is minimum area) can use promitives of 8kx2 or 16kx2. So assumingthat there are 2 memories of 16k (it has a total of 32 k --> 2^15 ) it can be divided in 10 bits for adderssing and 5 bits for the width of each register (divided in 2 register?) So it could be that the LSB indicates the memory (between 2 of them) and the 10 MSB indicates the address? so it keeps increment 1 by 1 but for adderssing only is important the 10 MSB?
If this is true, if you put the register to -2 --> 111 1111 1110 and you add 1 to the address part you will get overflow and coming back to 000 0000 0000
does it make any sense?
000 0000 0000
000 0000 0001
000 0000 0010
000 0000 0011
000 0000 0101
000 0000 0110
111 1111 1110
111 1111 1111
not taking into account the LSB
000 0000 0000
000 0000 0010
000 0000 0101
111 1111 1110
08-02-2019 03:58 AM
ok.... tbh I didn't read the code (how many people do you expect to go through a 100+ lines code?) or went to the tutorial...
So your question is actually philosophical about how the code is written, not an actual error in firmware (I though you found that -2 in the simulation you attached)
Well, in that case, the answer is simple: ask the author instead of having third party people analyzing that code.
If you want more, and without putting anyone down, it's an amateur page, what can you expect? I have seen so many freebies that they even don't work out of the box...
Sometimes, we tweak things 'to get them to work' and don't care about the beauty of the technique. At the end of the day, is not code what we deliver. I haven't dived that code but my suspicion is that -2 is some reset value that gets incremented by 2 before it's used the first time.