polarfire-soc / polarfire-soc-documentation

PolarFire SoC Documentation
Other
37 stars 19 forks source link

Warings regarding AXI Bus and SRAM #82

Closed kevinkiener closed 2 years ago

kevinkiener commented 2 years ago

Hello,

Just after loading the reference Design I am getting multiple warnings first. I just tried to ignore them and program the icicle kit with the reference design and then access the SRAM via the register 0x61000000U. However, as soon as I get to the line of code in the softconsole, the application just skips everything and does nothing anymore. It is as if the SRAM with the AXI BUS was not implemented properly. In Libero there are multiple warnings regarding the AXI Bus after pressing Generate Component for the MPFS_ICICLE_KIT_BASE_DESIGN. I have listed the ones which caught my attention here:

Target 'PCIE:AXI_1_SLAVE' with address space 0x20_0000_0000 - 0x2F_FFFF_FFFF cannot be accessed by initiator address space 0x60000_0000 - 0x7FFF_FFFF
Target 'MSS_LSRAM:AXI4_Slave' with address space 0x6100_0000 - 0x6100_1000 cannot be accessed by initiator address space 0x20_0000_0000 - 0x2F_FFFF_FFFF
Target 'DMA_CONTROLLER:AXI4SlaveCtrl_IF' with address space 0x6002_0000 - 0x6002_0470 cannot be accessed by initiator address space 0x20_0000_0000 - 0x2F_FFFF_FFFF
SmartDesign "MPFS_ICICLE_KIT_BASE_DESIGN' design rules check succeeded, but with warnings
There is an ID width mismatch between DMA_INITIATOR:AXI4mslave0:SLAVE0_AWID[0-8] and ICICLE_MSS:FIC_1_AXI4_AWID[0-3] which may result in a loss of data
There is an ID width mismatch between FIC0_INITIATOR:AXI4mslave0:SLAVE0_AWID[0-8] and MSS_LSRAM:AXI4_Slave:AWID[0-7] which may result in a loss of data
...

And there are even more ID width mismatches. Might this be the problem that I cannot access the SRAM from the Hardcore? What can I do to solve those errors?

Best Kevin

hughbreslin commented 2 years ago

Hi Kevin,

I think this is a reset issue - can you confirm that your bare metal application enables the FIC0 clock, takes FIC0 out of reset and also takes the FPGA fabric out of reset?

You should be able to do this using the following:

SYSREG->SUBBLK_CLOCK_CR |= (SOFT_RESET_CR_FIC0_MASK);
SYSREG->SOFT_RESET_CR   &= (uint32_t)~(SOFT_RESET_CR_FIC0_MASK);
SYSREG->SOFT_RESET_CR   &= (uint32_t)~(SOFT_RESET_CR_FPGA_MASK);

The behavior you described matches what occurs when you try to access a peripheral in reset - the read / write doesn't return. There is a Linux example using the SRAM available here. The warnings you mentioned will be resolved in a future release.

Please let me know if this resolves your issue.

Kind regards, Hugh

hughbreslin commented 2 years ago

I've also opened this issue for tracking to update the HAL to better support the FPGA reset bit which needs to be set

kevinkiener commented 2 years ago

Hi Hugh,

Thank you very much for your quick reply. So now it works with your reset code. Is there maybe a list or something similar to know what to do and to initialize when using certain interfaces with the Polarfire? Also regarding the clock of the AXI Bus, in the MSS Configurator it says that the AXI Bus has a frequency of 300MHz but in the actual Libero Design only a clock with 125MHz is connected. How do I set the clock properly and why is there a difference?

Now regarding the LIM Debug, sometimes I get an OCD error saying that it had a problem examining the code. But the problem simply is that it is unable to halt hart1. I then have to restart the board multiple times and eventually it works. Do you know a work-around or the cause of this problem?

Furthermore, do you maybe have some resources or a hint on how to use the SRAM as a shared memory between a custom ip and multiple harts? What is the best way to enable the FIC 0 interface on multiple harts?

Thank you very much in advance for your help. Your first answer already helped me a lot.

Best regards, Kevin

hughbreslin commented 2 years ago

Sweet I'm glad that got it 🥳

No unfortunately we don't have a specific document for which resets to unset, it's more awkward as the fabric configuration can change and the reset structure is design dependent. On the todo list for the reference design is adding a clock and reset structure diagram which may help. We could also add a reset source column to the memory map table to make it clearer as to what is actually driving the reset to each peripheral. I'll keep it in mind and see what can be done, would these help in your opinion?

Re the fic clocks, there's a bit to this, the setting in the MSS configurator are for the internal AXI switch in the MSS block itself (300MHz). The FIC clock provided to the MSS from the fabric is used for CDC. The FIC on the fabric side can run up to 250MHz and in the reference design we use 125MHz as it meets timing easily and allows us sufficient throughput. If your fabric clock is going to be >= 125MHz you will need to enable DLL for the FIC in the configurator.

On the open OCD error I'm not sure without seeing it first hand. If you have an idea of where it is in the code or if you have some empty loops waiting for something you could add a NOP in to offset the code a bit and see if it makes a difference, but I'm not sure off the top of my head.

To share the sram, if you're using the pmps make sure there's a window to access the sram from all contexts, otherwise without the pmps all harts should have access to the FIC and SRAM. Once the reset is enabled by one hart (really this is a job for the HSS / E51) you don't have to do it on others. You could add your custom IP as an initiator on the interconnect for the SRAM and that way it will be accessible from the FIC and the IP. 😊

kevinkiener commented 2 years ago

Thanks for your detailed answer.😊

Yes anything that provides an easy overview helps. Yeah another column for the resets in reference to the peripherals sounds great. Your other idea with a clock and reset structure diagram is also good.

Re FIC clock thanks that makes sense.

Okay I will check the OCD error again and come back to you if I don't figure it out.

Thank you very much I will try to implement it with without pmp.

I highly appreciate your help🙂

kevinkiener commented 2 years ago

Hey Hugh, I am sorry to bother you again. I now created a custom design with just the SRAM as you can see in the attached pictures. But it seems like I have a clock problem again because the code doesn't return again after accessing the SRAM. There are also some warnings which look concerning to me: Removing sequential instance MSS_SRAM_AXI_0.COREAXI4SRAM_0.genblk1U_MSS_SRAM_AXI_COREAXI4SRAM_MAINCTRL.genblk2.raddrchset_mc because it is equivalent to instance MSS_SRAM... arready_mc ... Found inferred clock PF_CCC_C0_PF_CCC_C0_0_PF_CCC|pll_inst_0_clkint_0_inferred_clock with period 10.00ns. Please declare a user-defined clock on net Clocks_and_resets_0.PF_CCC_C0...

I have auto generated the timing constrain for the design and kept the configuration of the AXI initiator and the SRAM equal to the reference design provided by microchip. The PLL converts the 160MHz input to a 125MHz output.

Here is the code of the timing constraint:

create_clock -name {Clocks_and_resets_0/CLK_160MHz_0/CLK_100MHz_0/I_OSC_160/CLK} -period 6.25 [ get_pins { Clocks_and_resets_0/CLK_160MHz_0/CLK_100MHz_0/I_OSC_160/CLK } ]

create_generated_clock -name {Clocks_and_resets_0/PF_CCC_C0_0/PF_CCC_C0_0/pll_inst_0/OUT0} -multiply_by 25 -divide_by 32 -source [ get_pins { Clocks_and_resets_0/PF_CCC_C0_0/PF_CCC_C0_0/pll_inst_0/REF_CLK_0 } ] -phase 0 [ get_pins { Clocks_and_resets_0/PF_CCC_C0_0/PF_CCC_C0_0/pll_inst_0/OUT0 } ]

set_false_path -through [ get_nets { FIC0_Initiator_AXI_0/ARESETN* } ]

image image The FIC0_Initiator is connected to FIC0 of the MSS.

hughbreslin commented 2 years ago

Hmm in the clocks and resets block I would try connecting the "PLL_POWERDOWN_B" output of the "RESET_CLK_125MHz" block to the "PLLPOWERDOWN_N_0" input of your CCC instead of driving it with init done.

In your design, without seeing it fully I can't tell if your CLK_125Hz is connected to the FIC clock or not, it doesn't look like it is based on the wires I can see only going into the interconnect and SRAM. It also looks like the unused FIC clocks are tied to ground but the DLL locks from those FICs are still being used. I don't think the DLLs would lock if the clocks are tied low. It would probably be safer to only use the DLL lock from the FIC thats in use and see if that helps.

hughbreslin commented 2 years ago

Also just to mention we will be moving to use a CCC and PLL as well so we can scale / control the clocks from the MSS

hughbreslin commented 2 years ago

Hey @MrKK11 how are you getting on? I think this issue is resolved now, would you mind closing it if you're happy and you can re-open or create a new one if something else comes up 🙂

Cheers, Hugh

kevinkiener commented 2 years ago

Hey Hugh,

I am currently trying to properly implement an DMA, you can see the Libero Snipped in the attachments. DMA

My simple program just tries to copy data from one SRAM to the other SRAM over the AXI Bus. The data width is always 64bits for the AXI bus and 32 for the AXI-lite Bus. After setting all the registers for the DMA and starting the copy transaction, the interrupt register returns a 1 which, according to the handbook, represents an DMA Write Transaction Error. I tried to access the second SRAM directly and that works fine but for some reason I can’t copy my data using the DMA. What do I do: I write some data in the first SRAM (that works fine and I also checked whether it is written properly) Then I read the DMA version in the version register and that works fine as well, I am using the version 2.0.100

The setup for the descriptor 0 looks the following (I pass this item to a self-written function to set the registers): dma_descriptor_t transfer_test; transfer_test.config = 0b00000000000000001110000000000101; transfer_test.count = 0xffU; transfer_test.source_addr = 0x61000004U; transfer_test.destination_addr = 0x62000000U; transfer_test.next_descriptor = 0U;

Then I am setting the start register to start the transaction. BASE_REG_DMA->start_operation = (uint32_t) 0x01U;

After that I am waiting some ms with the mtime_delay function.

And then I read the interrupt0 register and the value is a 1.

I also tried to read the data in the second SRAM but this as expected from the error code in the interrupt register is all 0.

Do you maybe have a clue what I am doing wrong? Do you need more information about my setup?

PS: The new version 2.1.102 of the DMA doesn’t even compile in Libero because it is missing it’s missing some components. I also checked the library COREAXI4DMACONTROLLER_LIB and this is completely empty for the new version of the DMA

Now my second question: I am also trying to access the LPDDR4 which is already preinstalled on the Icicle Kit. Is it possible to simply access the data at 0x80000000 with a pointer? I tried to do so but when reading the data it does not return so probably again a reset problem? I also set a delay in between but it didn't change anything. Also when locking at the mpfs-hal-ddr-demo I am confused by the internal pdma because we are trying to access the address 0x14_0000_0000 but convert it to an uint_32 pointer this simply results in a 0 pointer. We are then passing the zero pointer to the pdma, how do we actually access the address space with 0x14_0000_0000?

Regarding the access of the LPDDR4 from my external DMA, how would that be possible, can I simply connect my axi initiator slave port to the FIC3? But how do I say that the data going to there should be copied into the LPDDR4?

Thank you in advance. Kevin