1
votes

I have a for loop in process, which works fine with std_logic arrays, but not with record arrays. I use Xilinx ISE along with ISIM and the code is vhdl-93. The target will be a Spartan 3.

Here is the record definition:

TYPE spi_rx_t IS RECORD
CS      : std_logic;
MOSI    : std_logic;
CLK     : std_logic;
END RECORD;
constant SYNC_LATCHES   : integer := 2;

Here is the array definition and declaration:

type spi_rx_array_t is array (0 to SYNC_LATCHES) of spi_rx_t;
signal spi_in_array : spi_rx_array_t;

Below is the process:

    spi_in_array(0).MOSI <= SPI_MOSI;
    spi_in_array(0).CLK <= SPI_CLK;
    spi_in_array(0).CS <= SPI_CS;    

    sync_p: process (clk_100)
        begin
            if rising_edge(clk_100) then
--                for I in 1 to SYNC_LATCHES loop
--                  spi_in_array(I) <= spi_in_array(I - 1);
--                end loop;
                spi_in_array(1) <= spi_in_array(0);
                spi_in_array(2) <= spi_in_array(1);
            end if;
        end process;

The 2 lines below the commented code works exactly as expected (allowing me to synchronize external signals to clk_100), but I'd rather implement them as a for loop (such the commented one).

However, these commented lines does not produce the same result in my ISIM test bench (spi_in_array stays in unknown state when using the for loop). Why?

Please kindly help me with this.

1
Are there any warnings or error messages if you use the commented out lines?mkrieger1
I don't know if it's relevant, but what VHDL standard are you using when simulating this?mkrieger1
This is a property of VHDL-2002, described in section "12.6.1 Drivers", as the VHDL concept "longest static prefix"; thus not a bug in ISIM. Please see the reference to this SO answer in my suggestion to close this question as duplicate.Morten Zilmer
I've added an answer. Many thanks to Morten Zilmer :)Victor

1 Answers

1
votes

As commented by Morten Zilmer, this is due to the VHDL concept "longest static prefix". This SO answer is similar to my issue.

In my case, the simplest way to resolve the issue was to move the assignment of the first element of the array into the same process as the for loop. I also had to decrease SYNC_LATCHES constant from 2 to 1, because spi_in_array(0) is now latched with clk_100.

sync_p: process (clk_100)
begin
    if rising_edge(clk_100) then
        spi_in_array(0).MOSI <= SPI_MOSI;
        spi_in_array(0).CLK <= SPI_CLK;
        spi_in_array(0).CS <= SPI_CS;
        for I in 1 to SYNC_LATCHES-1 loop
            spi_in_array(I) <= spi_in_array(I - 1);
        end loop;
    end if;
end process;