/***************************************************************************** Custom Instruction Example - Saturation Add with Memory ======================================================= Simon Moore, May 2010 This package provides an example of a NIOS custom instruction which computes saturation add on unsigned 32-bit numbers (i.e. adding two very large numbers doen't overflow but instead results in the maximum integer). Extended to provide an internal memory (a bit pointless, but tests the full operand interface. *****************************************************************************/ package CustomInstruction_SaturationAddMem; import FIFO::*; import GetPut::*; import ClientServer::*; import CustomInstructionNIOS::*; import Clocks::*; import RegFile::*; // module which describes the the functionality of new instruction module mkSaturationAddMem(Get#(NIOS_All_OperandsT) operands, Put#(Maybe#(NIOSwordT)) result, Empty inf); // Vector#(Exp#(SizeOf(Custom_RegT)), Reg#(NIOSwordT)) rf <- replicateM(mkReg(0)); RegFile#(Custom_RegT,NIOSwordT) rf <- mkRegFile(0,31); rule do_instruction; let ops <- operands.get(); // get operands let opa = ops.readOpA ? ops.opA : rf.sub(ops.rA); let opb = ops.readOpB ? ops.opB : rf.sub(ops.rB); UInt#(33) res = extend(unpack(pack(opa))) + extend(unpack(pack(opb))); if((res>>32) == 1) res = (1<<32)-1; if(!ops.result2nios) begin rf.upd(ops.rC, unpack(pack(truncate(res)))); result.put(tagged Invalid); end else result.put(tagged Valid unpack(pack(truncate(res)))); endrule endmodule // top-level module which glues the Bluespec wrapper (from CustomIntructionNIOS) // to the new instruction module (* synthesize, clock_prefix = "nios_custom_instruction_slave_clk", reset_prefix = "nios_custom_instruction_slave_reset" *) module mkCustomInstruction_SaturationAddMem(NIOS_All_Operands_Physical_Embedded_Ifc); // expose and the invert reset since Bluespec uses a negative reset // and the NIOS interface uses a negative reset Reset rst <- exposeCurrentReset; Reset rst_n <- mkResetInverter(rst); // instantiate the wrapper NIOS_All_Operands_Instruction_Ifc physical <- mkNIOS_All_Operands_Custom_Instruction(reset_by rst_n); // instantiate the new instruction implementation Empty my_instruction <- mkSaturationAddMem(physical.client.request, physical.client.response, reset_by rst_n); // N.B. don't put any rules here since they will receive the // wrong reset signal and will be held permenatnly in reset interface nios_custom = physical.nios_custom; endmodule endpackage: CustomInstruction_SaturationAddMem