Forum Discussion
New IP development
Hello,
I am interested in developing some instructions which can do the bignum operations (like adding two operands of 1024 bit) and hence by plan to implement a simple Full Adder like this: {carry,sum} = OP_A + OP_B; I am a beginner in Altera and realized that I can develop an IP component with Avalon MM slave interface which can talk with the NIOS II processor. I was wondering how to give the bignum values as the operand from the NIOS II processor (master) to the IP component (slave) from the application code? I see only these macros in the generated 'io.h' file: # define IOWR_32DIRECT(BASE, OFFSET, DATA) io_write((BASE_APB_ADDR) + __AVL_TO_APB((alt_u32)((BASE) + (OFFSET))), DATA, (BASE) + (OFFSET)) # define IORD_32DIRECT(BASE, OFFSET) io_read((BASE_APB_ADDR) + __AVL_TO_APB((alt_u32)((BASE) + (OFFSET))), (BASE) + (OFFSET)) I guess these are the 32 bits write and read instructions. So, do I get to clock in the 1024 bits as a single instruction? Or do I have to wait for 32 clock cycles (sampling the 32 bits in a clock cycle, do for 32 clocks. Please say a no to this..) ! Hope that question is clear and someone can respond. Really appreciate it. Thank You, Akhil48 Replies
- Altera_Forum
Honored Contributor
Hello,
Can someone be of assistance to the above question please? That would be a big help. If the question is not clear I can explain it again. Any inputs are appreciated. Thank You, Akhil - Altera_Forum
Honored Contributor
Hello,
I gentle bounce here. Someone please help me. Thank You, Akhil - Altera_Forum
Honored Contributor
The Nios II CPU uses a 32 bit data bus, and a 32-bit data path internally, so it won't be able to process a 1024-bit word with a single instruction. You will have to divide your 1024-bit word in 32*32-bit words when accessing your IP component.
- Altera_Forum
Honored Contributor
Hello Daixiwen,
In the Altera user manual for Avalon interface (sopc builder, not qsys), I have seen the MM interface section. There the 'readdata' and 'writedata' ports can have a data width up to 1024 bits. So does that mean the NIOS II processor (master) can write or read 1024 bit data to the slave component in 32 clock cycles, 32 bit word every clock cycle? Earlier I thought that since the data width is 1024, it might be possible to clock in/out that much data every clock! (I am dumb :( ). And does this also mean that I can have an accumulator (kind of register) in my hardware IP module which keeps sampling the write data for the entire 32 clock cycles? And for read data, which reads the 1024 bits read register, 32 bits every clock cycle, and does the same for 32 clock cycles. I sense a low throughput for performance here (but, with a proper functionality). Please correct me if my assertion is wrong. Thank You, Akhil - Altera_Forum
Honored Contributor
You are right that you can have an Avalon MM bus with a 1024-bit data bus size, and if you connect a master and a slave that both have a 1024-bit data bus size, they will be able to transfer 1024 bits on each clock cycle (see, you aren't dumb ;) ). You need to be careful when using such a bus size, as you increase considerably the resources used on the FPGA.
The problem in your case is that the CPU itself is 32 bit. So even if you connect it to a component with a 1024 bit data bus, the CPU will only be able to read or write 32 bits at a time (using byte enables). If you have a lot of operations to perform on those big words, an idea could be to implement your IP as a full ALU with a bank of 1024 bit registers. Then the CPU would only need to transfer the actual values at the beginning and end of the algorithm, but for all the intermediary steps it would only need to send instructions, and the values itself would stay in your IP component. Of course it depends entirely on what you want to do and how many intermediary values you need. - Altera_Forum
Honored Contributor
Hello,
Appreciate the response :). I will explain my problem description. I was planning to make the NIOS II processor do some bigdigit instructions so that it can support the encryption schemes (like an RSA) from an application code. An RSA needs to handle some bigdigits operation like arbitrary precision integer multiplication, modulus operation etc and there are FPGA hardware modules which implements that. However there is no work done in the area where one can execute the RSA from a NIOS II application code (from the Eclipse IDE). So I thought it will be nice if we can develop some instructions the NIOS II processor can call and execute for doing some bigdigits math. I tried to look into more custom instructions but those were very much constrained. Then I came across the IP development concept, however the base issue is the same as you pointed out. It is not possible to give a data type which is more than 32 bit wide from NIOS II to any component since the processor itself is 32 bits wide (the data path). One approach is to give 32 * 32 data bits and have logic inside my custom IP to handle those. However waiting for 32 clock cycles for a 1024 bit data can affect the throughput of the custom IP instruction that I am planning to implement. Will discuss this matter with my professor and I can update you as well. Hope my problem description is clear. Thank You, Akhil - Altera_Forum
Honored Contributor
It is also worth remembering that the Nios cpu stalls during Avalon MM transfers - IIRC this is at least 2 extra clocks.
In addition any read value isn't available for the next two clocks. So if you actually want to do high performance wide arithmetic you need may not get the performance you expect. If you are just doing an acedemic excercise then it doesn't matter. - Altera_Forum
Honored Contributor
You probably have your work cut out for you just getting started, and toward that end going simple with e.g. an Avalon-MM Slave interface which your NIOS software will use to write the 32-bit registers one at a time is probably simplest. As dsl said, if it's academic you can be satisfied in knowing that you could always make it faster if you chose.
Once you get it working, the performance you will achieve will depend on how much work (complication) you want to invest. As Daixiwen already noted, the 32-bit nature of the NIOS is a significant bottleneck. Although SGDMA is a bit better, you are probably on the right track thinking about Avalon-MM Master interfaces with larger bus width. For example, you could implement bursting master with 64/128/256-bit width to stream operands (and opcodes, if you like) from SDRAM. Ideally, limit the NIOS to control activity only. If you only have a handful of operands you want to use (but frequently), then you could possibly look into using dual port onchip memory, with the NIOS/SGDMA on one port for reading/writing results, and the other port dedicated for your Avalon-MM Master to use. If it will fit in your device, a RAM width of 1024-bits might provide the highest throughput. As far as how to control your new IP, you could do something like add custom instructions which take 32-bit addresses (pointers) to the operands which your new logic would independently fetch/store results. - Altera_Forum
Honored Contributor
Hello,
Really appreciate for the response. --- Quote Start --- If you only have a handful of operands you want to use (but frequently), then you could possibly look into using dual port onchip memory, with the NIOS/SGDMA on one port for reading/writing results, and the other port dedicated for your Avalon-MM Master to use. If it will fit in your device, a RAM width of 1024-bits might provide the highest throughput. --- Quote End --- Akhil>> I did not clearly understand the above concept. is it possible for you to explain it please? --- Quote Start --- As far as how to control your new IP, you could do something like add custom instructions which take 32-bit addresses (pointers) to the operands which your new logic would independently fetch/store results. --- Quote End --- Akhil>> I did not clearly understand the above as well. is it possible for you to explain it please? Best, Akhil - Altera_Forum
Honored Contributor
Attached below is a quick/simplistic diagram that maybe better explains.
The NIOS/SGDMA store operand data into the onchip RAM, and the "BIGNUM" block implements custom instructions for add/subtract/multiply/divide operations on those operands. The purpose of the dual port memory is to keep all the x32 masters on one port, and x1024 masters on the other. Use of the custom instructions in C code might end up looking like:
This is similar to what Daixiwen mentioned, with a bank of 1024-bit registers; except you're just using RAM (with associated latencies) instead. The simplistic diagram is the same if you use a bursting master and external memory (SDRAM, DDR) except you would not have the BIGNUM component implement a 1024-bit master width (x64 or x128 is more manageable, but depends on your memories).bignum_t dst, srcA, srcB; ... ... BIGNUM_ADD(&dst, &srcA, &srcB); BIGNUM_MPY(&dst, &srcA, &srcB); ... ...