cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Adventurer
Adventurer
4,340 Views
Registered: ‎05-12-2016

Full reprogrammation in HDL (equivalent to PROG_B)

Jump to solution

Hi

 

I want to force an Artix7 to reprogramm itself exactly the same as if I had switched the PROG_B pin. The board is already designed, so I can't use any other pin to loop back to the PROG_B pin, so I was hoping there was a primitive that would allow me to order the FPGA a full reset (reading bitfile from SPI flash memory, as it does on powerup).

 

Thanks!

0 Kudos
Reply
1 Solution

Accepted Solutions
Xilinx Employee
Xilinx Employee
6,416 Views
Registered: ‎10-11-2007

Here is a piece of VHDL that should do the trick. You simply assert the "go" interface signal and the part will reboot from address 0. It's for Ultrascale, but should work just fine if you replace ICAPE3 with ICAPE2 (the 7-series ICAP version).

 

----------------------------------------------

library ieee;

Library UNISIM;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

use UNISIM.vcomponents.all;

 

entity iprog_icap is

  port (

    go    : in  std_logic;

    clk   : in  std_logic

  );

end iprog_icap;

 

architecture iprog of iprog_icap is

 

  attribute mark_debug : string;

  attribute keep : string;

 

   constant  CCOUNT      : integer := 8;

  

   signal    cnt_bitst   : integer range 0 to CCOUNT := 0;

   attribute keep of cnt_bitst: signal is "true";

   signal    reboot      : std_logic := '0';

   attribute keep of reboot: signal is "true";

   signal    reprog      : std_logic := '0';

   attribute keep of reprog: signal is "true";

   signal    icap_cs     : std_logic := '1';

   signal    icap_rw     : std_logic := '1';

   signal    d           : std_logic_vector(31 downto 0) :=X"FBFFFFAC";

   signal    bit_swapped : std_logic_vector(31 downto 0) :=X"FFFFFFFF";

 

begin

 

ICAPE3_inst: ICAPE3

port map (

   AVAIL   => open,

   O       => open,

   PRDONE  => open,

   PRERROR => open,

   CLK     => clk,           -- Icap Clock Input

   CSIB    => icap_cs,       -- Active-Low ICAP Enable

   I       => bit_swapped,   -- Configuration data input bus

   RDWRB   => icap_rw        -- Read/Write Select input 1= Write

);

 

process(clk)

begin

   if rising_edge (clk) then

      if (go = '1') then reboot <= '1'; end if;

     

      if (reboot = '0') then

        icap_cs  <= '1';

        icap_rw  <= '1';

        cnt_bitst  <= 0;

      else

        if(cnt_bitst /= CCOUNT)  then

            cnt_bitst <= cnt_bitst + 1;

        end if;

 

        case cnt_bitst is

            when  0 => icap_cs <= '0'; icap_rw <= '0';

            -- using registers for now

            when  1 => d <= x"FFFFFFFF";   -- Dummy Word

            when  2 => d <= x"AA995566";   -- Sync Word

            when  3 => d <= x"20000000";   -- Type 1 NO OP

            when  4 => d <= x"30020001";   -- Type 1 Write 1 Word to WBSTAR

            when  5 => d <= x"00000000";   -- Warm Boot Start Address

            when  6 => d <= x"20000000";   -- Type 1 NO OP

            when  7 => d <= x"30008001";   -- Type 1 Write 1 Words to CMD

            when  8 => d <= x"0000000F";   -- IPROG Command

            -- Bye, bye

            when others => icap_cs <= '1'; icap_rw <= '1';

        end case;

      end if;  -- if go

   end if;

end process;

 

-- Bit swap the ICAP bytes

bit_swapped(31 downto 24) <= d(24)&d(25)&d(26)&d(27)&d(28)&d(29)&d(30)&d(31);

bit_swapped(23 downto 16) <= d(16)&d(17)&d(18)&d(19)&d(20)&d(21)&d(22)&d(23);

bit_swapped(15 downto 8)  <= d(8)&d(9)&d(10)&d(11)&d(12)&d(13)&d(14)&d(15);

bit_swapped(7 downto 0)   <= d(0)&d(1)&d(2)&d(3)&d(4)&d(5)&d(6)&d(7);

 

end iprog;

View solution in original post

4 Replies
Adventurer
Adventurer
4,313 Views
Registered: ‎02-24-2012

Hi @a.gamez,

 

you are looking for FPGA warm boot. There is a XAPP, which demonstrates this feature:

 

https://www.xilinx.com/support/documentation/application_notes/xapp1247-multiboot-spi.pdf

 

Best Regards,

 

Stephan

Adventurer
Adventurer
4,306 Views
Registered: ‎05-12-2016

Hi,

 

That seems to be definitely related, but I don't see this is it. This multiboot thing works autonomously when programming a given .bit fails, so it tries to program another one.

 

What I want is to trigger the reconfiguration on demand, for example, through an axi driver connected to a microblaze cpu, or maybe just bringing a primitive input signal up or down to trigger this.

 

Thanks anyhow!

0 Kudos
Reply
Xilinx Employee
Xilinx Employee
6,417 Views
Registered: ‎10-11-2007

Here is a piece of VHDL that should do the trick. You simply assert the "go" interface signal and the part will reboot from address 0. It's for Ultrascale, but should work just fine if you replace ICAPE3 with ICAPE2 (the 7-series ICAP version).

 

----------------------------------------------

library ieee;

Library UNISIM;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

use UNISIM.vcomponents.all;

 

entity iprog_icap is

  port (

    go    : in  std_logic;

    clk   : in  std_logic

  );

end iprog_icap;

 

architecture iprog of iprog_icap is

 

  attribute mark_debug : string;

  attribute keep : string;

 

   constant  CCOUNT      : integer := 8;

  

   signal    cnt_bitst   : integer range 0 to CCOUNT := 0;

   attribute keep of cnt_bitst: signal is "true";

   signal    reboot      : std_logic := '0';

   attribute keep of reboot: signal is "true";

   signal    reprog      : std_logic := '0';

   attribute keep of reprog: signal is "true";

   signal    icap_cs     : std_logic := '1';

   signal    icap_rw     : std_logic := '1';

   signal    d           : std_logic_vector(31 downto 0) :=X"FBFFFFAC";

   signal    bit_swapped : std_logic_vector(31 downto 0) :=X"FFFFFFFF";

 

begin

 

ICAPE3_inst: ICAPE3

port map (

   AVAIL   => open,

   O       => open,

   PRDONE  => open,

   PRERROR => open,

   CLK     => clk,           -- Icap Clock Input

   CSIB    => icap_cs,       -- Active-Low ICAP Enable

   I       => bit_swapped,   -- Configuration data input bus

   RDWRB   => icap_rw        -- Read/Write Select input 1= Write

);

 

process(clk)

begin

   if rising_edge (clk) then

      if (go = '1') then reboot <= '1'; end if;

     

      if (reboot = '0') then

        icap_cs  <= '1';

        icap_rw  <= '1';

        cnt_bitst  <= 0;

      else

        if(cnt_bitst /= CCOUNT)  then

            cnt_bitst <= cnt_bitst + 1;

        end if;

 

        case cnt_bitst is

            when  0 => icap_cs <= '0'; icap_rw <= '0';

            -- using registers for now

            when  1 => d <= x"FFFFFFFF";   -- Dummy Word

            when  2 => d <= x"AA995566";   -- Sync Word

            when  3 => d <= x"20000000";   -- Type 1 NO OP

            when  4 => d <= x"30020001";   -- Type 1 Write 1 Word to WBSTAR

            when  5 => d <= x"00000000";   -- Warm Boot Start Address

            when  6 => d <= x"20000000";   -- Type 1 NO OP

            when  7 => d <= x"30008001";   -- Type 1 Write 1 Words to CMD

            when  8 => d <= x"0000000F";   -- IPROG Command

            -- Bye, bye

            when others => icap_cs <= '1'; icap_rw <= '1';

        end case;

      end if;  -- if go

   end if;

end process;

 

-- Bit swap the ICAP bytes

bit_swapped(31 downto 24) <= d(24)&d(25)&d(26)&d(27)&d(28)&d(29)&d(30)&d(31);

bit_swapped(23 downto 16) <= d(16)&d(17)&d(18)&d(19)&d(20)&d(21)&d(22)&d(23);

bit_swapped(15 downto 8)  <= d(8)&d(9)&d(10)&d(11)&d(12)&d(13)&d(14)&d(15);

bit_swapped(7 downto 0)   <= d(0)&d(1)&d(2)&d(3)&d(4)&d(5)&d(6)&d(7);

 

end iprog;

View solution in original post

Visitor
Visitor
2,810 Views
Registered: ‎01-27-2018

By my reading, it looks like that VHDL code will never perform case 0, which sets icap_cs and icap_rw low.  Shouldn't incrementing cnt_bitst be below the case statement?

0 Kudos
Reply