I am playing with the attaching various configuration flash devices to the Altera Cyclone 3. In particular, I want to replace EPCS16 (2MB) with W25Q128 (16MB) - for both size and cost reasons.

Is seems that Altera/Intel does not like people doing this; and there's scarce information about command set accepted by the EPCS devices - I suspect there're more commands than listed in the datasheet. I also read at some other place that EPCS devices are just relabelled devices not made by Altera (as they do not make flash devices for quite a time).

Anyway, datasheet would be very useful when you want to develop your own configuration flash interface IP; at this point I am using ALTASMI_PARALLEL which seem to work properly with W25Q chip.

However this megafunction only allows reading silicon ID (command 0xAB, read_sid), and device identification (command 0x9F, the "capacity ID" part, read_rdid). Both requests work for me using ALTASMI, with SID returning 0x14 (EPCS16) and RDID returning 0x15 (2^21 = 2MB).

Comparing EPCS and W25Q datasheets, I see that both chips report 3 bytes for the command 0x9F (command is called JEDEC ID), but EPCS datasheet says that first two bytes are "dummy". These bytes are expected to hold manufacturer ID and upper 8 bits of device ID.

I suspect EPCS device returns something within these bytes; but Altera did not bother to implement them fetching from the ASMI megafunction as they expect (or want/force) developers using their branded EPCS devices.

Looking to the files created by megafunction I see instance of asmi_altasmi_parallel_pio2_component, only 8 bits of which are used as RDID, and I am unable to find any further infomration (for example, may this submodule be returning 24-bit vector, not only 8 used by ALTASMI module?) this module in the same "asmi" file created by the megafunction :).

Anyone had been dealing with such issue? Reading full JEDEC ID would help definitely identify the flash chip attached.

The good thing is that, with current implementation, I still have capacity ID returned by RDID command, thus at least can know the size of flash (I need it because its first 512K must be write protected). All other info identifying exact chip is not critical and a kind of "cosmetic" just to display it on the screen (at least I do not see how I can use/apply it within current environment).

P.S. Alteraforum migrated to Intel forums. There were more or less independent people there sharing their knowledge, now I get business-protective replies like "not supported" or "you are fool customer". That's why I ask question here in hope there're still independent experts around!


1 Answer 1


After several hours of searching in the dark of ASMI code and trying several ways to understand and inject into existing code I have the following code working properly added into asmi_altasmi_parallel_* module:

// Added circuit to shift all 24-bit data within stage 3 (transfer after opcode shift)
reg [23:0] r_mfr_and_id;                                // should contain all 3 bytes: manufacturer's code, ID[15:0]
reg [23:0] r_mfr_and_id_out;                            // output latched byte
always@(posedge clkin_wire or posedge reset)
    if(reset == 1'b1) r_mfr_and_id[23:0] <= {24{1'b0}};
        else if((stage3_wire & do_read_rdid) == 1'b1)           // stage 3 in progress (3 bytes after opcode sent)
        r_mfr_and_id[23:0] <=
            { r_mfr_and_id[22:0], data0out_wire };              // capture all 24 bits shifting left

always@(negedge clkin_wire or posedge reset)
    if(reset == 1'b1) r_mfr_and_id_out[23:0] <= {24{1'b0}};
    else if(rdid_load == 1'b1)
            r_mfr_and_id_out[23:0] <= r_mfr_and_id[23:0];

It appeared that state stage2 is sending opcode to the AS device, stage3 is used for both sending address or receiving data (3 bytes after opcode), and stage4 is for data I/O.

And I decided, instead of injecting into existing code, to make additional registers and two always statements, partially duplicating already existing internals. Good thing that I do not depend on any intricate logic within existing code, and that the modification is just an addition of code. Bad thing is that I add some registers and logic already existing in the project - but let compiler optimize, I am more interested in reliability rather than small footprint overhead.

Additional task is to ensure r_mfr_and_id_out[23:0] wires go up to the ASMI high level module which then can be used in upper level module.

By the way, Altera/Intel proposed to use Generic Serial Flash Interface Intel FPGA IP, but it is not supported for Cyclone III family.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.