06-07-2016 10:56 PM
Hi,what I am trying to do is building myself a InstructionCache Qsys component to use with the NiosII(e) as it lacks one. Since I found the Nios instructions to be 32 bits long and I thought the adress bus was also 32 bits long I designed the cache to store unsigned 32 Bit values. It is a two way set associative cache with 32 sets fo 2 blocks with 64 bytes memory + 21 bit tag + 1 bit valid + 1 bit used flag each block, so overall 4Kb+. I am building this componet based upon the specs of the DE0-nano board (32MB SDRAM 16 bit words) So far I have a Avalon MM slave with adress size of 23 bit (32 MB SDRAM / 4) and 32 bit data size for the NiosII instruction master to connect to. As well as a Avalon MM master with adress size 24 bit (32 MB SDRAM / 2) and 16 bit data size to connect to the SDRAM controller (free Altera SDRAM controller). so what I am basically doing in the fsm of the cache is: init: slave_WaitRequest = 0 main: if slave_Read = 1 slave_WaitRequest = 1 check cache for requested adress if found slave_ReadData = cache data slave_WaitRequest = 0 else calc sdram adress (adr / 2) read block 64 bytes from SDRAM (32 reads 16 bit data) wait for master_WaitRequest = 0 master_Adress = sdram adress master_Read = 1 wait for master_WaitRequest = 0 buffer mem = master_ReadData master_Read = 0 if not block complete increase sdram adress goto start of read block store buffer mem in cache block slave_ReadData = cache data slave_WaitRequest = 0 but I am not sure if reading works like that, if the WaitRequests and Reads are correctly set and cleared. How can I simulate this ? I wanted to do the block read from SDRAM controller as a burst read but as I read everywhere that the Altera SDRAM controller has a fixed BurstCount of 1, I figured I can just do normal reads instead. A problem I encountered is that qsys is complaining about the adres space of the SDRAM controller does not fit in the adrees range of my Avalon MM master. I connected te NiosII DataMaster also to the SDRAM controller so I think what is happening is that the cache got assigned adress space 0 to 32 MB, the SDRAM controller has 32 MB to 64 MB with a base adress of 32 MB assigned. Does this mean my Avalon MM master must have a 32 bit adress space to adress the SDRAM controller? If so how do I know the base adress of the sdram controller, by just hardcoding it ? If I want to read 32 x 16 bit words from the SDRAM controller do I have to set the master_Adress to 32 bit base adress of SDRAM controller + 16 bit real SDRAM adress ? Now for the Nios, the instruction and data adresses are 32 MB apart due to the base adress of the SDRAM controller but in fact via the cache they are physically mapped to the same adress space in the SDRAM so the DataMaster could possibly overwrite the Instructions?!?! To fix this I could connect the Nios DataMaster also to the cache Avalon MM slave but then I wouold need some kind of way to check if the DataMaster is requesting access and than ignoring the cache and directly working withe the SDRAM controller. Is this possible? If you want I can show you the vhdl code for the component... but beware I am very new to this stuff so it might b ugly :) THX Grobi
06-08-2016 08:49 PM
Hi, I managed to get the code compiled without errors for my component BUT now the problem ist it won't fit into the device and I find that a bit strange, maybe somebody can shed some light on it, please.The error message Quartus is giving is : Error (276003): Cannot convert all sets of registers into RAM megafunctions when creating nodes. The resulting number of registers remaining in design exceeds the number of registers in the device or the number specified by the assignment max_number_of_registers_from_uninferred_rams. This can cause longer compilation time or result in insufficient memory to complete Analysis and Synthesis I tried finding out what part of the code could cause this and when I just comment out the
if (currentBockToReplace = '0') then cacheBlocksMemory(currentBlock0MemoryOffset + 15) <= tempBuffer0 & tempBuffer1; cacheTags(currentBlock0DescriptorIndex) <= currentTag; cacheUsed(currentBlock0DescriptorIndex) <= '1'; cacheValids(currentBlock0DescriptorIndex) <= '1'; cacheUsed(currentBlock1DescriptorIndex) <= '0'; else cacheBlocksMemory(currentBlock1MemoryOffset + 15) <= tempBuffer0 & tempBuffer1; cacheTags(currentBlock1DescriptorIndex) <= currentTag; cacheUsed(currentBlock1DescriptorIndex) <= '1'; cacheValids(currentBlock1DescriptorIndex) <= '1'; cacheUsed(currentBlock0DescriptorIndex) <= '0'; end if;part of the buffering case in read_fsm the error is gone and it compiles just fine. I can not wrap my head around why this is happening, can someone have a look please? THX Grobi
06-08-2016 10:06 PM
I have narrowed it further down to :cacheValids(currentBlock0DescriptorIndex) <= '1'; and the cacheValids(currentBlock1DescriptorIndex) <= '1'; Its starting to occur to me that bulding memory with arrays might not be the best idea, how about I scap the internal memory idea and use several Static RAM IPs instead? Two static rams, one for the block memory and one in which I combine the tag + used + valid bit into one vector or better one big vector for both blockdescriptors ?