control icap in Partial Reconfiguration

408 views Asked by At

I'm going to implement partial reconfiguration on virtex5 Xilinx Board. I've written 3 modules(top module and up-counter and down-counter) and created bit streams by Plan-ahead.The result is shown by 2 LEDs(up or down count). My problem is how to exchange counter partitions? or how to control icap by time or an external signal? I prefer to don't use Microblaze so write state machine for icap as below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;


library UNISIM;
use UNISIM.VComponents.all;
Library UNIMACRO;
use UNIMACRO.vcomponents.all;

entity Main is
    port(
            Clk: in std_logic;
            Output: out std_logic_vector(2 downto 0)
            );
end Main;

architecture Behavioral of Main is
    signal Q: std_logic_vector(47 downto 0);
    signal Load, Clk1hz, Clk1 : std_logic;
    signal Local : std_logic_vector(1 downto 0);
    component ROM  ------------------------------ ROM Component Decleration
    port (
            Clka: in std_logic;
            Addra: in std_logic_vector(11 downto 0);
            Douta: out std_logic_vector(31 downto 0));
    end component;  -------------------------------------------------------End
    signal ROM_Address, ROM_Address_Init : std_logic_vector(11 downto 0);  -------- ROM and ICAP Signals Decleration
    signal ROM_Data : std_logic_vector(31 downto 0);
    signal ICAP_Din, ICAP_Dout : std_logic_vector(31 downto 0);
    signal ICAP_CE, ICAP_Clk, ICAP_Clk1, En, ROM_Clk, ROM_Clk1, ICAP_WR : std_logic; --------------------------------------End
begin

    Clk1Hz <= Clk1;
    process(clk)
    begin
        if (rising_edge(Clk)) then
            if (Q=x"000005F5E100") then
                Load <= '1';
                Clk1 <= not Clk1;
            else
                Load <= '0';
            end if;
        end if;
    end process;
    Output(0) <= not(En);
    Output(2 downto 1) <= not(Local);
    ----------------------------------------------------
    ----------------------------------------------------
    U_UpDown: entity work.Counter
    port map(
            Clk => Clk1Hz, En => '1', Output => Local
            );
    ----------------------------------------------------
    ----------------------------------------------------
    U1 : COUNTER_LOAD_MACRO
   generic map (
      COUNT_BY => X"000000000001", -- Count by value
      DEVICE => "VIRTEX5",         -- Target Device: "VIRTEX5", "VIRTEX6", "SPARTAN6" 
      WIDTH_DATA => 48)            -- Counter output bus width, 1-48
   port map (
      Q => Q,                 -- Counter output, width determined by WIDTH_DATA generic 
      CLK => CLK,             -- 1-bit clock input
      CE => '1',               -- 1-bit clock enable input
      DIRECTION => '1', -- 1-bit up/down count direction input, high is count up
      LOAD => LOAD,           -- 1-bit active high load input
      LOAD_DATA => x"000000000000", -- Counter load data, width determined by WIDTH_DATA generic 
      RST => '0'              -- 1-bit active high synchronous reset
   );

    --------------------------------------------
    --------------------------------------------
    process(Clk1Hz)  -------------------------------------------- ROM and ICAP Modules and Related Codes
    variable Count : integer range 0 to 6:=0;
    begin
        if (rising_edge(Clk1Hz)) then
            Count := Count + 1;
            if (Count = 2) then
                En <= '1';
                ROM_Address_Init <= conv_std_logic_vector(0,12);
            else
                En <= '0';
            end if;
        end if;
    end process;
    --------------------------------------------
    --------------------------------------------
    U_ROM: ROM
    port map (Clka => ROM_Clk1, Addra => ROM_Address, Douta => ROM_Data);
    BUFG_inst : BUFG
   port map (
      O => ROM_Clk1,     -- Clock buffer output
      I => ROM_Clk      -- Clock buffer input
   );
    BUFG_inst1 : BUFG
   port map (
      O => ICAP_Clk1,     -- Clock buffer output
      I => ICAP_Clk      -- Clock buffer input
   );

    ICAP_VIRTEX5_inst : ICAP_VIRTEX5
   generic map (
      ICAP_WIDTH => "X32") -- "X8", "X16" or "X32" 
   port map (
      BUSY => open,   -- Busy output
      O => ICAP_Dout,         -- 32-bit data output
      CE => ICAP_CE,       -- Clock enable input
      CLK => ICAP_Clk1,     -- Clock input
      I => ICAP_Din,         -- 32-bit data input
      WRITE => ICAP_WR  -- Write input
   );
--  ICAP_Din(31 downto 8) <= x"000000";  -------------------------------End
    U_ICAP_SM: block  -------------------------------------
        type State_Type is (State0, State00, State1, State2, State3, State4, State5, State6);
        signal Pr_State, Nx_State : State_Type;
    begin
        Process(En,Clk)
        begin
            if (En = '0') then
                Pr_State <= State0;
            elsif (rising_edge(Clk)) then
                Pr_State <= Nx_State;
            end if;
        end process;
        process(Pr_State)
        begin
            case Pr_State is --*****
            when State0 =>
                Nx_State <= State00;
                ROM_Address <= x"000";
                ICAP_WR <= '1';
                ROM_Clk <= '0';
                ICAP_Clk <= '0';
                ICAP_CE <= '1';
            when State00 =>
                Nx_State <= State1;
                ICAP_WR <= '0';
            when State1 =>
                Nx_State <= State2;
                ICAP_CE <= '0';
                ROM_Clk <= '1';
            when State2 =>
                Nx_State <= State3;
                ICAP_Din <= ROM_Data;
                ROM_Clk <= '0';
            when State3 =>
                Nx_State <= State4;
                ICAP_Clk <= '1';
            when State4 =>
                Nx_State <= State5;
                ICAP_Clk <= '0';
            when State5 =>
                if (ROM_Address = conv_std_logic_vector(3134,12)) then
                    Nx_State <= State6;
                    ICAP_CE <= '1';
                    ROM_Address <= X"000";
                else
                    Nx_State <= State1;
                    ROM_Address <= (ROM_Address + 1);
                end if;
            when State6 =>
                ICAP_WR <= '1';
            end case;
        end process;
    end Block U_ICAP_SM;  -----------------------------------
end Behavioral;

I saved the bit stream (.coe file) of one of the counter (for example up-counter) in ROM. By default circuit is down counting, but when I exchange bit stream by icap (load .coe file of up-counter from ROM) nothing happens and circuit is counting down. (***** in the code) how can I fix it?

0

There are 0 answers