Altera_Forum
Honored Contributor
11 years agoAvalon MM Slave waitrequest signal modus-operandi
Greetings, everyone.
I'm trying to integrate a custom peripheral in the HPS system using an Avalon MM Slave and the Lightweight H2F bridge, but I'm having s little trouble with the sync of the reading operation. To learn how the MM Slave works, I designed a simple module that does a sum of the squares of two float numbers. The input is written into 2 registers, then a start command is sent to a control register. The result is written into a result register. The operation costs 13 clocks to be complete, using MegaWizards FP units. Then, the result is read back. In software, it is translated into 3 write operations and 1 read operation. I used the following codelet to do so:alt_write_word(PERIPHERAL_ADDRESS_A, a); //The address of the first input register
alt_write_word(PERIPHERAL_ADDRESS_B, b); //The address of the second input register
alt_write_word(PERIPHERAL_ADDRESS_C, 1); //The address of the control register
alt_read_word(PERIPHERAL_ADDRESS_D); //Reading the result register My problem is with the waitrequest signal. If I understood correctly, if the master executes a read request while waitrequest is assigned, it holds the operation until it the signal is deasserted, then completes the request in the next clock cycle. Then, I designed the signal to be asserted until the result is saved in the result register. Thus, the software code above should give me the result, as the read operation would be hold until the 13 clocks have passed and the result register updated with the correct result, even with the clock speed difference between the HPS and the FPGA (800MHz and 200MHz, respectively). But it not happens this way. When I run the code, I get the previous result, or 0, if it is the first run. It seems like the read operation is carried on before the peripheral is done with the calculations, even if the waitrequest signal is asserted. It was verified in ModelSim that the waitrequest signals works properly. I tested it with the following: c = a * a + b * b;
alt_write_word(PERIPHERAL_ADDRESS_A, a); //The address of the first input register and the first value
alt_write_word(PERIPHERAL_ADDRESS_B, b); //The address of the second input register and the second value
alt_write_word(PERIPHERAL_ADDRESS_C, 1); //The address of the control register and the start command
counter = 0;
while(c != d)
{
d = alt_read_word(PERIPHERAL_ADDRESS_D); //Reading the result register
++counter;
} It always took 2 iterations to have the correct value returned. The question is, why it is happening this way? The problem is in the waitrequest signal or the alt_read_word macro? There are some cache process that I am unaware of? How to ensure I'm getting the correct result? At first, I had thought to use a interrupt to return the processed data to the software, but It should not be necessary if the reading operation code is a blocking one. Should I use the interrupt then? Just to be known, this is a just a test to learn how to design and integrate custom peripherals. The real one that I should develop will be more complicated, taking even thousands of clock cycles to complete. Thank you and good work to everyone.