Forum Discussion
Altera_Forum
Honored Contributor
15 years agoUsing custom instruction from uCLinux user app on nios2mmu
Hello,
Is it possible to use a custom instruction from an user application running on NIOS2MMU - uCLinux. I'm trying to run the CRC design example on uCLinux. When I try to compile the software application I get "macros undefined error" which I thought would be a part of the cross compilers standard header files. Creation of BSP which in turn generates "System.h" file will fail as the BSP tool doesn't support NIOS2 with MMU. Is there anyway to achieve this? Thanks, Chetan16 Replies
- Altera_Forum
Honored Contributor
Since a BSP is not used, you have to write the macros for the custom instructions yourself or use the builtins, which should be defined by the cross compiler.
For example:/* Opcode for the byteswap custom instruction provided by Altera. * This may change if other custom instructions are present. */ # define ALT_CI_BYTESWAP_N 0x00 # define ALT_CI_BYTESWAP(x) __builtin_custom_ini(ALT_CI_BYTESWAP_N, (x)) - Altera_Forum
Honored Contributor
Ykozlov,
Thanks for the reply. The kernel compiled fine after manually defining the macros. Chetan - Altera_Forum
Honored Contributor
Do you really want to use the custom instructions in the Kernel, not just in a userland application ?
-Michael - Altera_Forum
Honored Contributor
Michael,
I meant to say the user application compiled without any errors after defining the macros. I'm not using custom instruction in the kernel, but only in the user application. Thanks, Chetan - Altera_Forum
Honored Contributor
FWIW, if you are doing CRC16 (the usual one for hdlc comms) then a custom instruction for the following C can be used:
The 4 levels of xor easily execute in a single clock. My notes suggest that the above C compiles to 11 instructions, and a lookup table version to 7 (with the table base in a global register).static __inline__ uint32_t crc_step(uint32_t crc, uint32_t byte_val) { uint32_t t = crc ^ (byte_val & 0xff); t = (t ^ t << 4) & 0xff; return crc >> 8 ^ t << 8 ^ t << 3 ^ t >> 4; } - Altera_Forum
Honored Contributor
Why not do a real hardware CRC generator in a custom instruction ?
I would not do this just with bytes but have the custom instruction use a 32 value and (optionally) do four bytes at a time. This could be done with 32 single shift steps or in a more optimized way with cascades XORs. Calculation time should not be relevant, as it could run in the background having the processor only stall when the next value is inserted and the logic is still busy or when the result is extracted and the logic is still busy. So I would do those custom instructions: 1) define polynomial 2) reset / set start value 3) insert value (one Register = value, one Register = bit count 1..32) (blocks when busy) 4) get current result (blocks when busy) -Michael - Altera_Forum
Honored Contributor
If you are going to do that, I'd make require the software have to wait itself - then you can use a combinatorial custom instruction and avoid the register file delays on the read value.
You could also use the 'rB' field as a sub-opcode (set poly, new value etc). In my case I was doing 64 channels of hdlc from a TDM stream - so had individual bytes to process. If you have a buffer, then you want a dma based engine.... - Altera_Forum
Honored Contributor
--- Quote Start --- If you have a buffer, then you want a dma based engine.... --- Quote End --- +1 -Michael - Altera_Forum
Honored Contributor
To correct myself ... (if the whole thing works the way I suspect it does)
You can't let a combinatorial custom set state (it can return state) as the logic is 'executed' for every instruction fetched (there is no 'enable' line to the instruction). The custom opcode (etc) only affect the value selected and written back to the register file. Every time I think about the custom instructions, I get more and more convinced that the 'rA' and 'rB' bits are ignored by the nios cpu core. - Altera_Forum
Honored Contributor
???
The complete custom instruction is "ignored" by the NIOS CPU core. Your hardware just is supplied with the rA, rB and rC information. As well the three number as the values of 2 of the appropriate registers, and it is (optionally) supposed to output the value, the NIOS implementation is supposed to write into the third register. -Michael