2

I think my title says it all. I am running a software on a NIOS2 processor on an Altera FPGA. Is there some way to detect which is the FPGA that the software is running on?

To answer the question in the comment: Why do I care which FPGA I am on? For production we use a design with EPCS controller to program everything. This programming flow is not sensitive to Quartus versions, unlike the .jic flow using Quartus programmer. Unfortunately, for new EPCQ devices you have to correctly program the non-volatile register of the EPCQ with the proper wait states and addressing mode so that the FPGA will configure correctly. The NIOS shell tools don't have the capability to do that (Quartus programmer with .jic flow does it) so I wrote a small piece of software that does that. There is a table in the EPCQ datasheet that says what the wait states should be according to FPGA family and size of EPCQ. Size of EPCQ I can ask the EPCQ. FPGA family I don't know who to ask. Thus, now for each project I have its personal piece of software with data hard coded to FPGA type. I want the software to be generic and not FPGA specific thus I need to know which FPGA I am on.

  • Is there a reason your porgram wants to know the device it's on? – wilcroft Jun 29 '15 at 23:05
  • Where is your "small piece of software" running? On the FPGA itself? If so, is the FPGA design developped by you or given? – mbschenkel Jul 01 '15 at 10:31
  • So you're trying to determine which FPGA you're targeting using the Nios II flow? The way you're question was phrased, it appeared as though you wanted the a program running on the Nios II Processor to determine which device type it was running on, which doesn't make sense for trying to program it. – wilcroft Jul 01 '15 at 18:56
  • What exact information about FPGA would you like to now? Is the device family name enough? – Qiu Jul 04 '15 at 20:13
  • You will need to build a different firmware for each FPGA-type anyway, so why can't you just include a unique ID for each design or build? Interestingly though, an "Altera Unique Chip ID" IP block exists, but that is a per-chip not per-FPGA-type distinction. As an alternative you could try to access the FPGAs own JTAG chain, but that would probably need to be done in hardware and seems overly complicated to me. (And please don't post your comments as "answers" but use comments or adjusted the question instead!) – mbschenkel Jul 06 '15 at 11:08
  • I agree that I need to build a different firmware for each FPGA, but I don't want to have a different ID block. Moreover, if the information exists and can be readable by JTAG it must be readable in another way. The goal, in the end is to have one software that can do whatever is necessary without modifying it for each project. – Ofer Saferman Jul 07 '15 at 13:44
  • I assume that with "but I don't want to have a different ID block" you mean, that you don't want to have different HDL source files for each design. With Quartus you can set [a generic from the project](https://www.doulos.com/knowhow/fpga/Setting_Generics_Parameters_for_Synthesis/) and pass it down to your "ID-block" which can then be exactly the same source for all projects, even though it will pass a different ID to the NIOS. Only the project needs to be different - which it will be in any case. – mbschenkel Jul 15 '15 at 20:33
  • It will be helpful to do it elegantly without the need to add additional HDL like an ID block. Since the data is available and accessible through JTAG there must be a way to access this data internally from HDL or software. If anybody knows of a way to access the FPGA ID that is read by JTAG to detect the FPGA type internally please share. – Ofer Saferman Jul 17 '15 at 06:25

1 Answers1

2
  • If you have access to the JTAG port of the FPGA, clock through the IDCODE register and decode it.
  • If you have access to the FPGA bitstream file, (which it seems you must, since you are about to program it) in the sparsely-documented header are bytes which describe the target device. Decode them.
  • Since the bitstreams will be device specific anyway, expose a custom NIOS instruction, or a known memory location (over the Avalon-MM bus) in the firmware that reports the device type to the NIOS.

Details on the 3rd opion

You could use TCL at synthesis time (e.g. some QSYS magic) to inject the project wide DEVICE_FAMILY property into a HDL module as a parameter (device_family), then switch on this inside the generated logic to output a value for each family.

E.g. this I've based on adv_seu_detection_common.v and adv_seu_detection_core_hw.tcl (find them in the Quartus ip directory):

module crcblock_atom ( regout );
    parameter device_family = "Stratix III";
    output wire [7:0] regout;

    generate
        if  ( (device_family == "Stratix III") ||
              (device_family == "Arria II GZ") ||
              (device_family == "Stratix IV") ) begin: generate_crcblock_atom1

            assign regout = 1;
        end
        else if ( (device_family == "Arria V") ||
                  (device_family == "Cyclone V") ) begin: generate_crcblock_atom2
            assign regout = 2;
        end
        else begin: generate_crcblock_atom
            assign regout = 3;
        end
    endgenerate
endmodule

You then need to set the parameter device_family appropriately. You can do this in the ip-core wrapper by using the following partially-undocumented code in xxxxx_hw.tcl that makes the parameter hidden and auto populates it from the project settings:

# | device_family
add_parameter device_family STRING
set_parameter_property device_family VISIBLE false
set_parameter_property device_family SYSTEM_INFO {DEVICE_FAMILY}
set_parameter_property device_family HDL_PARAMETER true
set_parameter_property device_family AFFECTS_GENERATION true

You'd still have to wrap this up as a custom NIOS instruction, or make it look like an Avalon-MM rom, but you get the idea.

Once you've wired it up in the QSYS system for each project and rebuilt them all, it would do what you've asked. It's still pretty ugly though.

For another treatment of this question see http://www.alteraforum.com/forum/archive/index.php/t-33948.html

shuckc
  • 2,766
  • 1
  • 22
  • 17
  • I would like to do this internally and in a generic way without doing anything that is project specific, like looking at bit streams or exposing custom NIOS instructions which have to be changed for each project. As you said, the data is available to JTAG in the form of the IDCODE register. It would be helpful if someone has any idea how to access this IDCODE register internally in HDL or software. If this is possible in HDL, then it can be connected through Avalon MM to NIOS software and it will be generic. The connection is custom but it will be an identical add-on for all projects. Thanks. – Ofer Saferman Jul 17 '15 at 06:31
  • Software can't have general access to the hardware JTAG chains - it's a stateful machine and is expected to be driven by a single master on external pins, arbitration isn't possible if the masters expect the bus in different states. However if you are willing to give up some I/O pins and don't need the bus for anything else, by all means do loopback on the board. But hardware designers would probably agree this is a ridiculous waste of the JTAG machinery, given the HDL is synthesised differently for each project anyhow – shuckc Jul 17 '15 at 11:43
  • shuckc, Thanks for the script suggestion, but it is very awkward to implement. I was looking for an easier solution. There is a way to connect to JTAG from HDL without using loopback pins, but it is only semi-helpful. You can use altera_soft_core_jtag_io. For some strange reason, after Altera finally provided a tool to internally connect to the JTAG chain it has its own IDCODE, so that can't be the solution either. I am still looking for the right solution. BTW, the provided link seems to look for the same solution as I am but none was provided there either. – Ofer Saferman Jul 18 '15 at 12:55