ACS Advanced Computer Design
NIOS Custom Instruction Example
This example consists of the following files:
CustomInstructionNIOS.bsv - Bluespec wrapper for the NIOS processor custom instruction interface
CustomInstruction_SaturationAdd.bsv - an example of unsigned saturation-add
sattest.c - an example of using the custom instruction from C
Importing the custom instruction into SOPC Builder
Building CustomInstruction_SaturationAdd.bsv results in mkCustomInstruction_SaturationAdd.v ready to be imported as a custom instruction (note that you can ignore the build warnings - see reset info. below).
In SOPC Builder (assuming you already have a NIOS processor design - if not, see the ):
- double click on your NIOS processor
- select "Custom Instructions"
- hit the "Import" button
select the "HDL Files" tab and "Add..." mkCustomInstruction_SaturationAdd.v, hit "Close"
- inspect the "Signals" and "Interfaces" tabs to see what is going on
hit "Finish..." and say "Yes, Save" to create mkCustomInstruction_SaturationAdd_hw.tcl
- then you hit a bug - your new instruction doesn't appear in the list
- click "Finish", then double click on your processor and look at "Custom Instructions" again and it should appear
- now "Add..." your new instruction
- "Generate" your improved SOPC system and resynthesise the design
Tip - deleting a design and reimporting - this functionality seems to be missing from the GUI. Deleting the instruction can be achieved by removing the mkCustomInstruction_SaturationAdd_hw.tcl and the "File->Refresh System". You may then need to delete the red error info about missing module in your SOPC design.
Reset is positive
Bluespec by default uses a negative reset (i.e. reset=0 means in reset, reset=1 means running). However the NIOS Custom Instruction interface uses positive resets. This is handled by the top-level module in CustomInstruction_SatAdd.bsv:
(* synthesize, clock_prefix = "nios_custom_instruction_slave_clk", reset_prefix = "nios_custom_instruction_slave_reset" *) module mkCustomInstruction_SaturationAdd(NIOS_Two_Operand_Physical_Embedded_Ifc); Reset rst <- exposeCurrentReset; Reset rst_n <- mkResetInverter(rst); NIOS_Two_Operand_Instruction_Ifc physical <- mkNIOS_Two_Operand_Custom_Instruction(reset_by rst_n); Empty my_instruction <- mkSaturationAdd(physical.client.request, physical.client.response, reset_by rst_n); interface nios_custom = physical.nios_custom; endmodule
The incoming reset is nios_custom_instruction_slave_reset which is reviled by exposeCurrentReset and then inverted using mkResetInverter. This new reset signal (rst_n) is passed to the wrapper interface (mkNIOS_Two_Operand_Custom_Instruction) and to the module providing the new instruction functionality (mkSaturationAdd).
- there should be no rules inside the top-level module since these would receive the wrong reset signal which would result in them being held permanently in reset
the inverted reset signal (rst_n) is not exported by the interface and so Bluespec will report warnings which can safely be ignored
For the design, see: /usr/groups/ecad-labs/ACS-ACD-1112/bluespec-examples/CustomInstructionExample
Or see the public web version: NIOS custom instruction in Bluespec