I have a simple combinatorial custom instruction that works fine under quartos 9.1.However (qsys in) quartos 13.1.3 doesn't generate the right logic. I've not tried quartos 14.x because I'm using a cyclone III dev board - not supported in 14.x. The instruction is encoded with 'readrb = 0' and uses the 'b' operand as a sub-opcode (ignoring the 'datab' value itself). (Amongst other operations it does 16bit and 32bit byte reverse.) The RTL viewer shows that the 'b' output from the 'cpu_custom_instruction_master_comb_slave_translater<n>' isn't connected to the custom instruction itself. So the instruction logic itself is fed a constant 0 for 'b'. While I don't need this to work right now (I'm writing some more custom instructions), we'd rather be able to use the same custom instructions as previously.
I haven't had that issue, but from the description, my guess would be the _hw.tcl and moving from SOPC Builder to Qsys. If you haven't already, I would try creating a new one with the current tool.
If Ted's suggestion doesn't correct the problem I recommend attaching the hardware .tcl file for the custom instruction to this post and we can take a look to see if something defined in that file is causing this.
Moving the xxx_hw.tcl file did require that it was edited by qsys and then hand edited.Firstly to remove the unwanted 'clock' line then to add: set_fileset_property QUARTUS_SYNTH TOP_LEVEL I've just created the 'add immediate' instruction below - same problem.
# TCL File Generated by Component Editor 13.1 # Fri Nov 14 15:38:04 GMT 2014 # DO NOT MODIFY # # add_imm "add_imm" v1.0 # 2014.11.14.15:38:04 # add immediate # # # request TCL package from ACDS 13.1 # package require -exact qsys 13.1 # # module add_imm # set_module_property DESCRIPTION "add immediate" set_module_property NAME add_imm set_module_property VERSION 1.0 set_module_property INTERNAL false set_module_property OPAQUE_ADDRESS_MAP true set_module_property GROUP "Custom Instruction Modules" set_module_property AUTHOR "" set_module_property DISPLAY_NAME add_imm set_module_property INSTANTIATE_IN_SYSTEM_MODULE true set_module_property EDITABLE true set_module_property ANALYZE_HDL AUTO set_module_property REPORT_TO_TALKBACK false set_module_property ALLOW_GREYBOX_GENERATION false # # file sets # add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" "" # dsl - line below added by hand set_fileset_property QUARTUS_SYNTH TOP_LEVEL add_imm set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false add_fileset_file add_imm.vhd VHDL PATH add_imm.vhd TOP_LEVEL_FILE # # parameters # # # display items # # # connection point cis0 # add_interface cis0 nios_custom_instruction end set_interface_property cis0 clockCycle 0 set_interface_property cis0 operands 2 set_interface_property cis0 ENABLED true set_interface_property cis0 EXPORT_OF "" set_interface_property cis0 PORT_NAME_MAP "" set_interface_property cis0 CMSIS_SVD_VARIABLES "" set_interface_property cis0 SVD_ADDRESS_GROUP "" add_interface_port cis0 ncs_cis0_dataa dataa Input 32 add_interface_port cis0 ncs_cis0_result result Output 32 add_interface_port cis0 ncs_cis0_b b Input 5
-- add_imm.vhd library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity add_imm is port ( ncs_cis0_dataa : in std_logic_vector(31 downto 0) := (others => '0'); -- cis0.dataa ncs_cis0_result : out std_logic_vector(31 downto 0); -- .result ncs_cis0_b : in std_logic_vector(4 downto 0) := (others => '0') -- .b ); end entity add_imm; architecture rtl of add_imm is begin ncs_cis0_result <= ncs_cis0_dataa + (B"000000000000000000000000000" & ncs_cis0_b); end architecture rtl; -- of add_imm
Hmmm that's very odd indeed. It might be caused by the register file index (b) being passed in without datab being present. Maybe try adding datab to the .tcl and VHDL implementation to see if that helps, but your first post suggests you may have that test case already.Another workaround would be to send 'b' using 'datab' instead but I suspect the reason why you want to use 'b' is to avoid having a Nios II holding register for the datab value. If you don't use up all 256 'n' locations perhaps you could use the 'n' field to send the value for 'b' instead while this bug is being fixed.
I don't think adding datab makes any difference.Using 'b' also generates a lot less logic than having multiple instructions. Last time I was 'playing around' with custom instructions I also used 'readrb' to mux between 'b' and 'datab'.
I just found the problem. The custom instruction slave translator terminates the 'b' input when 'readrb' is not present. So you might need to add readrb to the custom instruction and just not use it so that the 'b' signal gets hooked up correctly.I just looked at the Nios II custom instruction userguide and there is very little information about which signals need other signals to be present so if adding readrb doesn't solve the problem then I suspect you'll have to add 'readra', 'a', 'writerc', and 'c'. The slave translator makes it look like a, b, and c are all independent but I'm not sure if the tools keep them seperate or if it's an all or nothing paramerization that it performs. Either way I'll create a bug report since at a minimum this behavior should be at least documented.
I think this is a case where the documentation isn't explicit that you can't do it, but your use of 'b' is not what they were expecting.Taking your code as-is, both Qsys and Quartus have warnings about 'b' (for example, "Explicitly unconnected" in the Quartus Port Connectivity Checks report). I'm using 14.0 but if you read the top-level Qsys file, you'll see the port not connected. If you add the 'readrb', the warnings go away and the port is connected in the top-level. Not sure if it will behave as you expect however.
Thanks, probably easier for you to raise the the bug than for us to try to do so.Adding 'readrb' makes the RTL viewer show some reasonable contents for my instruction. That 'add immediate' instruction I wrote as a quick example isn't entirely stupid. Although you'd probably want to add an extra 1 (adding 32 is more useful than adding 0) and maybe sign extend to give -16..+16.