Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Updating EPCS with new configuration via FPGA

Hi all,

Currently I am trying to develop a way of updating the EPCS memory connected to a stratix II device dynamically via the FPGA. The idea is that an external processor will send the configuration file in the relevant format to the FPGA, which will then in turn write it to the flash so that upon subsequent power ups, a new configuration will be loaded.

I have been doing some reading both here and in various altera datasheets, but there are several things that I do not have clear.

I was initially looking at the serial flashloader (AN370). In this document (page 3) it talks about when the SFL image is present in the FPGA, but offers no explanation as to what to do. It only seems to offer examples of how to update the EPCS via the JTAG interface.

I believe I am misinterpreting something here and that perhaps there is no ready made solution for what I want to do.

Can someone please confirm for me that it is possible to do what I plan and what solution is available.

Many thanks for the help

10 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    We use the SFL stuff (AN370) here in the company.

    You need to check AN425 on how to implement the "JAM player" into your processor. I've asked our software guy; he said it's quite easy .

    Regards,

    Michael
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Review ALTASMI_PARALLEL MegaFunction.

    --- Quote End ---

    Thanks for the reply. I have been studying this megafunction but either I am not understanding properly its function or there is insufficient information. Nowhere in the user guide does it talk about how to send a configuration file to the EPCS, just about how to write a byte or a page. It´s not entierly clear that the intended function of this megafunction is to update the design configuration as I want to to do.

    Also on page 2 of the user guide there is a warning which says "Do not access the configuration memory in the EPCS device. Doing so risks corrupting the configuration bits."

    I assume this refers to teh actual binary being stored. I am a little confused as to why this is not explained in further detail in the user guide. Is it that unusual to want to do something like this?

    --- Quote Start ---

    We use the SFL stuff (AN370) here in the company.

    You need to check AN425 on how to implement the "JAM player" into your processor. I've asked our software guy; he said it's quite easy .

    --- Quote End ---

    Thanks Michaels. Unfortunately I don´t have a processor in the design and was hoping to avoid using a NIOS, as this is a last minute request from someone to a design more or less finalized.

    Many thanks for the help so far.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    A configuration file is written by programming the rbf file starting from EPCS address 0.

    It seems like Stratix II also supports the more sophisticates update functionality of the ALTREMOTE_UPDATE MegaFunction, that can be used in combination with ALTASMI_PARALLEL.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    A configuration file is written by programming the rbf file starting from EPCS address 0.

    --- Quote End ---

    Many thanks for the reply. Can you let me know where you found this info? Is it contained in some application note or user guide? I´d like to study it a little more, as I have a few other things I don´t understand, like for example how many pages of memory a .rbf file will occupy.

    Thanks again.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Ardni,

    you don't need something like NIOS.

    My understanding was that you have an "external" processor on your PCB connected to the FPGA via JTAG interface. If this is true you can use the scheme provided in AN370 / AN425.

    Regards,

    Michael
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    SFL roadmap:

    1. SFL implementation in VHDL:

    -- declaration

    component SFL PORT ( noe_in : IN STD_LOGIC );

    end component;

    --instantiation

    SFL_inst : SFL PORT MAP ( noe_in => '0');

    2. Creation of JAM file

    a) convert SOF-file to JIC

    b) use Quartus programmer tool to convert JIC to JAM

    3. Software side ...depends on your system...

    here is just a code snippet showing some JAM wrapper routines for lower level bit banging functions you have to do, anything else is from Altera, an experienced C guy will implement/verify it within a day

    ...

    static BYTE TckLevel=0;

    static BYTE TmsLevel=1;

    static BYTE TdiLevel=1;

    # ifdef FAST_JTAG_PROGRAMMING# define TCK_GPO_BIT (1L<<17)# define TDI_GPO_BIT (1L<<26)# define TDO_GPIO_BIT (1L<<8)# endif

    void JamInit(void) {

    # ifdef FPGA_EEPROM

    UWORD32 u32_low = 0;

    UWORD32 u32_high = 1;

    bySetDirectionVio(JTAG_TMS, IOCTRL_DIR_OUTPUT_DONTCARE);

    # if SDI_OUT_OPTION == SDI_2972

    bySetVioBurst(SPI_CS_SDI_OUT, &u32_high, 1);

    # endif

    // TCK=0

    TckLevel=0;

    bySetVioBurst(JTAG_TCK, &u32_low, 1);

    // TMS=1

    TmsLevel=1;

    bySetVioBurst(JTAG_TMS, &u32_high, 1);

    // TDI=1

    TdiLevel=1;

    bySetVioBurst(JTAG_TDI, &u32_high, 1);

    # endif

    }

    void JamClose(void) {

    # ifdef FPGA_EEPROM

    bySetDirectionVio(JTAG_TMS, IOCTRL_DIR_INPUT);

    # endif

    }

    void JamTmsHigh(void) {

    # ifdef FPGA_EEPROM

    UWORD32 u32_high = 1;

    if(TmsLevel != 1) bySetVioBurst(JTAG_TMS, &u32_high, 1);

    TmsLevel = 1;

    # endif

    }

    void JamTmsLow(void) {

    # ifdef FPGA_EEPROM

    UWORD32 u32_low = 0;

    if(TmsLevel != 0) bySetVioBurst(JTAG_TMS, &u32_low, 1);

    TmsLevel = 0;

    # endif

    }

    void JamTdiHigh(void) {

    # ifdef FPGA_EEPROM

    # ifdef FAST_JTAG_PROGRAMMING

    UWORD32 u32;

    if(TdiLevel != 1) {

    GET_REG(GP_OUTPUT,u32);

    u32 |= TDI_GPO_BIT;

    SET_REG(GP_OUTPUT,u32);

    }

    TdiLevel = 1;

    # else

    UWORD32 u32_high = 1;

    if(TdiLevel != 1) bySetVioBurst(JTAG_TDI, &u32_high, 1);

    TdiLevel = 1;

    # endif

    # endif

    }

    void JamTdiLow(void) {

    # ifdef FPGA_EEPROM

    # ifdef FAST_JTAG_PROGRAMMING

    UWORD32 u32;

    if(TdiLevel != 0) {

    GET_REG(GP_OUTPUT,u32);

    u32 &= ~TDI_GPO_BIT;

    SET_REG(GP_OUTPUT,u32);

    }

    TdiLevel = 0;

    # else

    UWORD32 u32_low = 0;

    if(TdiLevel != 0) bySetVioBurst(JTAG_TDI, &u32_low, 1);

    TdiLevel = 0;

    # endif

    # endif

    }

    void JamTckHigh(void) {

    # ifdef FPGA_EEPROM

    # ifdef FAST_JTAG_PROGRAMMING

    UWORD32 u32;

    if(TckLevel != 1) {

    GET_REG(GP_OUTPUT,u32);

    u32 |= TCK_GPO_BIT;

    SET_REG(GP_OUTPUT,u32);

    }

    TckLevel = 1;

    # else

    UWORD32 u32_high = 1;

    if(TckLevel != 1) bySetVioBurst(JTAG_TCK, &u32_high, 1);

    TckLevel = 1;

    # endif

    # endif

    }

    void JamTckLow(void) {

    # ifdef FPGA_EEPROM

    # ifdef FAST_JTAG_PROGRAMMING

    UWORD32 u32;

    if(TckLevel != 0) {

    GET_REG(GP_OUTPUT,u32);

    u32 &= ~TCK_GPO_BIT;

    SET_REG(GP_OUTPUT,u32);

    }

    TckLevel = 0;

    # else

    UWORD32 u32_low = 0;

    if(TckLevel != 0) bySetVioBurst(JTAG_TCK, &u32_low, 1);

    TckLevel = 0;

    # endif

    # endif

    }

    int JamTdoRead(void) {

    # ifdef FPGA_EEPROM

    # ifdef FAST_JTAG_PROGRAMMING

    UWORD32 u32_1, u32_2;

    do {

    GET_REG(GPIO_EXT_PORTA,u32_1);

    GET_REG(GPIO_EXT_PORTA,u32_2);

    } while(u32_1 != u32_2);

    if(u32_1 & TDO_GPIO_BIT) return 1;

    else return 0;

    # else

    UWORD32 u32_res;

    byGetVioBurst(JTAG_TDO, &u32_res, 1);

    if(u32_res) return 1;

    else return 0;

    # endif

    # endif

    }
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The original post suggests, that the processor is not connected through JTAG rather than an application specific interface, e.g. a parallel or serial bus as in most FPGA systems incorporating an external processor.

    In this case, ALTASMI_PARALLEL and optionally ALTREMOTE_UODATE is offering the functionality to program a serial configuration flash in FPGA user mode.

    The configuration image size, which is also the rbf file size, is different in compressed and uncompressed mode. In uncompressed mode, it's always the maximum size for the specfic FPGA type that can be found in the device hnadbook. In compressed mode it's only the required size, varying with FPGA utilization.

    If no advanced configuration schemes (e.g. multiple images for remote update) are used, the EPCS flash contains exactly the configuration bitstream to be send to the FPGA.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Many thanks for the replies.

    Michaels, unfortunately the interface between the FPGA and the processor is not via JTAG. You´re solution would be ideal, but unfortunately it won´t be possible for us to do it. Many thanks for your suggestion though.

    After doing some further study today, I think I am going to have a go at using only the ALTASMI_PARALLEL megafunction only to update the configuration in the EPCS.

    I will attempt to do the following to reconfigure the flash:

    1) Perform a bulk erase of the EPCS64.

    2) Begin writing at adress H'000000 in the EPCS the first 256 bytes (1 page) of the .rbf file.

    3) Once the 1st page has been written, alter offset the address by +256 and begin writing the 2nd page in the EPCS.

    4) Continue writing pages until the entire .rbf file has been successfully written to the EPCS.

    It would be great if someone could confirm if the above process will work or if I have misinterpreted something.

    Many thanks for the help.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I can confirm that I have programmed serial flash this way, but by connecting the EPCS pins directly, not through FPGA and ALTASMI_PARALLEL. I remember an issue with bit order, EPCS commands had to be shifted out MSB first, but rbf data LSB first. I guess, this point is already handled by the ALTASMI_PARALLEL MegaFunction, because it has a byte interface.