Custom instruction

Custom instruction

by Cédric Oliver Portmann -
Number of replies: 7

Hello,

I would appreciate if someone could explain how exactly one is supposed to implement "ALT_CI_BITSWAP". I did the following so far all according to the course and external Intel documentation:

1) Added to system.h: 

#define ALT_CI_BITSWAP_N 0x00

#define ALT_CI_BITSWAP(A) __builtin_custom_ini(ALT_CI_BITSWAP_N,(A))

2)  Whithin the main loop:

int a = 0x12345678;

int a_swap = 0;

a_swap = ALT_CI_BITSWAP(a);

printf("Conversion as custom instruction gives: %d\n", a_swap);

--------------------------------------------------------------------------------------------

The result is the following:

Value to be swapped: 305419896

Conversion as custom instruction gives: 305419896

---------------------------------------------------------------------------------------------

Why is ALT_CI_BITSWAP mentioned as an already included "ready to use" macro? Are there other macros?

How can I change the "logic/underlaying code" that defines macros?


Thanks

In reply to Cédric Oliver Portmann

Re: Custom instruction

by Cédric Oliver Portmann -

So we managed to implement it by addding the component: "nios_custom_instr_bitswap_0" in Platform Designer but we don't get any insight on how to configure our own version.

A few other questions: How do we implement our own specific custom instruction? Especially how do we make the connection between the C code (system.h file) that gets generated and the actual VHDL code? Are they called parameters, interface or signals? How do we configure them exactly in Platform designer?

Thanks


In reply to Cédric Oliver Portmann

Re: Custom instruction

by René Beuchat -
In reply to René Beuchat

Re: Custom instruction

by Cédric Oliver Portmann -

Yes I did. That's why I decided to ask again since it's not clear to me. 

How can you modify the generation of these in system.h:

#define ALT_CI_NIOS_CUSTOM_INSTR_BITSWAP_0(A) __builtin_custom_ini(ALT_CI_NIOS_CUSTOM_INSTR_BITSWAP_0_N,(A))

#define ALT_CI_NIOS_CUSTOM_INSTR_BITSWAP_0_N 0x0

Based on what are the parameters of this function generated? -> Is it the parameters of my component in Platform Designer or something else? Where are the parameters of the function in C passed to in the VHDL file?

Thanks

In reply to Cédric Oliver Portmann

Re: Custom instruction

by René Beuchat -

Hello,

You have to do yourself the macro for your custom instructions :

the ones here are your custom instruction or the ones provided by IntelFPGA? I think it's the one from IntelFPGA.

You have to do it in a separate file.h or in your program with the syntax seen during the course:

__builtin_custom_ini(...)

  • first i: the output type
  • n a separator (musts be n)
  • second i the output type

That is what is necessary in our case.

It's a job that you have to do.

Best.

RB


In reply to René Beuchat

Re: Custom instruction

by Cédric Oliver Portmann -

Hello,

/*

 * Custom instruction macros

 *

 */


#define ALT_CI_NIOS_CUSTOM_INSTR_BITSWAP_0(A) __builtin_custom_ini(ALT_CI_NIOS_CUSTOM_INSTR_BITSWAP_0_N,(A))

#define ALT_CI_NIOS_CUSTOM_INSTR_BITSWAP_0_N 0x0

This is generated automatically upon BSP generation in Eclipse.

How do we define things(signals/parameters/interface?) in Platform designer such that we can send and receive values (using the macro) to the custom instruction that was implemented as hardware?


Thanks

In reply to Cédric Oliver Portmann

Re: Custom instruction

by Sahand Kashani-Akhavan -

I sense some confusion here. A custom instruction is defined with the following format in Nios assembly:

custom 0, r6, r7, r8

Everything else you see in C code such as macros somehow ultimately emit this instruction when passed through the compiler. There are multiple types of custom instructions. If we take the simplest form which is a combinational CI with just 1 input, it would be exposed to the C programmer as something like this:

__builtin_custom_<CI_idx><arg1_type><arg2_type> (int n, arg1_type dataa, arg2_type datab)

To avoid programmers from calling a complicated function like a __builtin_custom_xxx, the compiler just generates a macro in system.h which wraps this and avoids the programmer from having to supply the number "n" above (the index of the CI as defined in platform designer).

The bitswap instrution you are trying to use is an existing CI that exists in qsys and which you can decide to add to the nios processor if you wish. This instruction should just swap 31..0 to 0..31. I can't say much about how this particular intel-provided CI is implemented as I have not used it. What I know for sure though is that you cannot change its functionality as somewhere there is a VHDL/Verilog file that describes it's design, and this file is not provided by you.

If you want to see how to really create a CI of your own that does this bit swapping, you should write it yourself. To do this, just write a simple VHDL file with the expected interface of the CI as defined in the Custom Instruction User Guide. For example, a simple combinatorial CI that just uses 1 input could look like this:


You can then go to Qsys and create a new component (just as you created slaves in the previous labs). You provide this VHDL file and tell it to analyze it, then you go to the "Signals and Interfaces" tab and you define what the interface looks like to Qsys. In this case we are not defining a slave, but a "Custom Instruction Slave" in the available interface categories. You can then see signal types such as "dataa", "datab", ... in there which you assign to the corresponding ports of the VHDL design above.

Once you do all this and wire this CI to the CPU, it will be assigned a number and a macro will automatically be generated to wrap it's invocation in system.h. You therefore should not need to define the macro yourself, as I understand you are trying to do.