UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Adventurer
Adventurer
298 Views
Registered: ‎04-21-2018

MIG VC707 write path

Jump to solution

Hello,

I'm using the VC707 board and i face some problems reading what i wrote on the MIG

The write path is rather unclear

What i do is that i register the data in app_wdf_data asserting app_wdf_wren when app_wdf_rdy is high

Then i assert app_en when app_rdy is high. Some times between the two assertions i wait for a couple of cycles waiting for app_rdy to get high.

The values that i write are incremented by 1 and the address that i'm writing on are also incremented by 1, so i expect when i read the memory incrementing the address read by 1 to see incrementing values on app_rd_data when app_rd_data_valid is high. But it is not what i see

I have 3 main questions

1) It is said in the Guide that i can register the data before the app_cmd is asserted but is there a maximum delay?

2) If app_rdy = '1' for a moment and on the next rising edge(1) of ui_clk i assert app_en and on the next risng edge(2)  of ui_clk i deassert app_en and i realize that app_rdy is ='0' before that last rising edge (2) of ui_clk , I assume that app_cmd has not been validated right?

3) If app_en = '1'for a moment and after the rising edge (1) of ui_clk app_rdy gets high and stays high and on the next rising edge(2) of ui_clk i deassert app_en while app_rdy is still high , How many app_cmd have been validated here one or two?

Here is an image to clarify

Here is my MIG controller which asserts the different signals:

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 25.07.2018 11:25:05
-- Design Name: 
-- Module Name: MIG_CONTROLLER - Behavioral
-- Project Name: 
-- Target Devices: 
-- Tool Versions: 
-- Description: 
-- 
-- Dependencies: 
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
----------------------------------------------------------------------------------


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity MIG_CONTROLLER is
    Port ( ui_clk                    : IN     std_logic;
           ACTIVE_TX                 : in     std_logic;
           rx_dv                     : in     STD_LOGIC;
           rx_byte                   : in     STD_LOGIC_VECTOR (7 downto 0);
           TX_Done                   : in     STD_LOGIC;
           TX_DV                     : out    STD_LOGIC;
           TX_Byte                   : out    STD_LOGIC_VECTOR(7 downto 0);
           missing_pkts              : in     std_logic;
           missing_pkts_read         : out    std_logic;
           rd_en_fifo1               : out    std_logic;
           dout_fifo1                : in     std_logic_vector(31 downto 0);
           wr_en_fifo2               : out    std_logic;
           empty_fifo2               : in     std_logic;
           empty_fifo1               : in    std_logic;
           write_mig_complete        : out    std_logic;
           final_address             : out    std_logic_vector( 24 downto 0);
           prog_full_FIFO3           : in     STD_LOGIC;
           ethernet_done             : in     std_logic;
           read_mig_complete         : out    STD_LOGIC;
           rst_fifo                  : out    STD_LOGIC;
           wr_rst_busy               : in     STD_LOGIC;
           rd_rst_busy               : in     STD_LOGIC;
           transfer_done             : out    STD_LOGIC;
           app_addr                  : OUT    std_logic_vector(27 downto 0);
           app_cmd                   : OUT    std_logic_vector(2 downto 0);
           app_en                    : OUT    std_logic;
           app_wdf_data              : OUT    std_logic_vector(511 downto 0);
           app_wdf_end               : OUT    std_logic;
           app_wdf_mask              : OUT    std_logic_vector(63 downto 0);
           app_wdf_wren              : OUT    std_logic;
           app_rd_data               : IN     std_logic_vector(511 downto 0);
           app_rd_data_end           : IN     std_logic;
           app_rd_data_valid         : IN     std_logic;
           app_rdy                   : IN     std_logic;
           app_wdf_rdy               : IN     std_logic;
           RESET                     : IN     std_logic;
           debug_etat                : out    std_logic_vector(7 downto 0);
           init_calib_complete       : IN     std_logic
           );
end MIG_CONTROLLER;

architecture Behave of MIG_CONTROLLER is

type type_etat is (INIT,RESETFIFO, DETECTFULL, FIFOREADY, WAIT_TRANSFER, SEND_SERIAL, TEMPO_SERIAL,
                   SEND_SERIAL1, TEMPO_SERIAL1,
                   CALIB_COMPLETE,READ_FIFO2,RF_WM,WM,CHECK,TEMPO_WM, SEND_WORD1,TEMPO1, TEMPO_READ1,
                   TEMPO_READ2,TEMPO_READ3,WDF_END,CHECK_WDF,APP_ENV,CHECK_APP_ENV,
                   READ_MISSING_PKTS,       
                   READ_FIFO_ADD_MP ,       TEMPO_READ_FIFO2,
                   READ_MIG_MP      ,       
                   CHECK_READ_MP    ,                       
                   TEMPO_NO_INCREMENT_MP   ,     WAIT_DATA_VALID,                     
                   READ_MIG_MP_NO_INCREMENT,READ_MIG_MP_COMPLETE,TEMPO_READ_MIG_MP_COMPLETE,
                   READ_MIG,CHECK_READ,TEMPO_NO_INCREMENT,READ_MIG_NO_INCREMENT,
                   READ_COMPLETE,WAIT_ETHERNET,ETHERNET_COMPLETE
                   );
signal etat : type_etat;

signal tb_WORD : std_logic_vector(23 downto 0);

signal tb_word_to_write : unsigned(23 downto 0);

signal tb_dout_fifo1 : std_logic_vector(31 downto 0);

signal enable : std_logic;

signal address    : unsigned (24 downto 0) := "0000000000000000000000000";
signal tb_address    : unsigned (24 downto 0) := "0000000000000000000000000";
signal tb_final_address : unsigned (24 downto 0) :=  "0000000000000000000000000";

signal count : unsigned (23 downto 0):= x"000000";

signal compt1     : unsigned (2 downto 0) := "000";

signal raz        : std_logic;

begin

tb_dout_fifo1(7 downto 0)  <= dout_fifo1(31 downto 24);
tb_dout_fifo1(15 downto 8) <= dout_fifo1(23 downto 16);

tb_dout_fifo1(23 downto 16) <= dout_fifo1(15 downto 8);
tb_dout_fifo1(31 downto 24) <= dout_fifo1(7 downto 0);

app_addr <= std_logic_vector(address)&"000";

final_address <= std_logic_vector(tb_final_address);
app_wdf_mask  <= (others=>'0');
app_wdf_data (511 downto 24) <= (others=>'0');
app_wdf_data(23 downto 0) <= std_logic_vector(tb_word_to_write);

process (ui_clk)
begin
if rising_edge(ui_clk) then
    if raz ='1' then
        compt1 <= "000";
    else
        compt1 <= compt1 + 1;
    end if;
end if;
end process;

   process (UI_CLK,RESET)
   begin
   
   if RESET = '1' then
       etat <= INIT;
   elsif rising_edge (UI_CLK) then
       case etat is
           when INIT                   => etat <= RESETFIFO;-- if (ACTIVE_TX = '0' ) then etat <= SEND_SERIAL1; end if; debug_etat <= x"00";
           when SEND_SERIAL1            => etat <= TEMPO_SERIAL1;debug_etat <= x"01";
           when TEMPO_SERIAL1           => if ( tx_done = '1' ) then etat <= RESETFIFO; end if;debug_etat <= x"02";
           when RESETFIFO              => if (compt1 = "111") then etat <= DETECTFULL; end if;debug_etat <= x"03";
           when DETECTFULL             => if (wr_rst_busy ='0' and rd_rst_busy='0') then etat <= FIFOREADY; end if;
           debug_etat <= x"04";
           when WAIT_TRANSFER          => if (rx_dv = '1' and rx_byte /= "10010101") then 
                                             etat <= WAIT_TRANSFER; 
                                          elsif (rx_dv = '1' and rx_byte = "10010101" and ACTIVE_TX = '0') then
                                             etat <= SEND_SERIAL;
                                          end if;
           debug_etat <= x"05";                               
           when SEND_SERIAL            => etat <= TEMPO_SERIAL;
           debug_etat <= x"06";
           when TEMPO_SERIAL           => if ( tx_done = '1' ) then etat <= FIFOREADY; end if;
           debug_etat <= x"07";
           when FIFOREADY              =>  if init_calib_complete = '1' then
                                               etat <= CALIB_COMPLETE;
                                           end if;
             debug_etat <= x"08";                              
                                           
           when CALIB_COMPLETE  => etat <= READ_FIFO2;
           debug_etat <= x"09";
           when READ_FIFO2      => if (count = x"000200") then 
                                       etat <= TEMPO_READ1;  
                                   else
                                       etat <= TEMPO_READ_FIFO2;
                                   end if;
           when TEMPO_READ_FIFO2 => etat <= WDF_END;
           when WDF_END         => if (app_wdf_rdy = '1') then etat <= CHECK_WDF; end if;
           when CHECK_WDF       => if (app_wdf_rdy = '1') then
                                       etat <= APP_ENV;
                                   else
                                       etat <= WDF_END;
                                   end if;
           when APP_ENV         => if (app_rdy = '1') then etat <= CHECK_APP_ENV; end if;
           when CHECK_APP_ENV   => if (app_rdy = '1') then
                                       etat <= READ_FIFO2;
                                   else
                                       etat <= APP_ENV;
                                   end if;       
           when TEMPO_READ1              => etat <= TEMPO_READ2;
           debug_etat <= x"0F";
           when TEMPO_READ2              => etat <= TEMPO_READ3;
           debug_etat <= x"10";
           when TEMPO_READ3              => if (app_rdy = '1') then 
                                               etat <= READ_MIG;
                                           end if;
                                           debug_etat <= x"11";
           when READ_MIG                => etat <= CHECK_READ;
           debug_etat <= x"12";
           when CHECK_READ              => if (address = tb_final_address - 1) then etat <= READ_COMPLETE;
                                           elsif (app_rdy = '1'and prog_full_FIFO3 = '0') then etat <= READ_MIG;
                                           elsif (app_rdy = '0'and prog_full_FIFO3 = '0') then etat <= TEMPO_NO_INCREMENT;
                                           end if;
                                           debug_etat <= x"13";
           when TEMPO_NO_INCREMENT      =>  if (address = tb_final_address - 1) then etat <= READ_COMPLETE;
                                            elsif (app_rdy ='1'and prog_full_FIFO3 = '0') then etat <= READ_MIG_NO_INCREMENT; end if;
                                            debug_etat <= x"14";
           when READ_MIG_NO_INCREMENT   => etat <= CHECK_READ;
           debug_etat <= x"15";
           when READ_COMPLETE           => etat <= WAIT_ETHERNET; 
           debug_etat <= x"16";
           when WAIT_ETHERNET           => if (ethernet_done = '1') then etat <= ETHERNET_COMPLETE; 
                                           elsif (missing_pkts = '1') then etat <= READ_MISSING_PKTS; end if;
                                           debug_etat <= x"17";
           when READ_MISSING_PKTS       => etat <= READ_FIFO_ADD_MP;
           debug_etat <= x"18";
           when READ_FIFO_ADD_MP        => etat <= READ_MIG_MP;
           debug_etat <= x"19";
           when READ_MIG_MP             => etat <= CHECK_READ_MP;
           debug_etat <= x"1A";
           when CHECK_READ_MP              => if (empty_fifo1 = '1') then etat <= READ_MIG_MP_COMPLETE;
                                           elsif(app_rdy = '1' ) then etat <= WAIT_DATA_VALID;
                                           elsif (app_rdy = '0') then etat <= TEMPO_NO_INCREMENT_MP;
                                           end if;
                                           debug_etat <= x"1B";
           when TEMPO_NO_INCREMENT_MP      =>  if (empty_fifo1 = '1') then etat <= READ_MIG_MP_COMPLETE;
                                            elsif (app_rdy ='1') then etat <= READ_MIG_MP_NO_INCREMENT; end if; 
                                            debug_etat <= x"1C";  
           when READ_MIG_MP_COMPLETE       =>   etat <= TEMPO_READ_MIG_MP_COMPLETE;
           debug_etat <= x"1D";
           when TEMPO_READ_MIG_MP_COMPLETE =>   if (ethernet_done = '1') then etat <= ETHERNET_COMPLETE; 
                                                elsif (missing_pkts = '1') then etat <= READ_MISSING_PKTS; end if;
                                                  debug_etat <= x"1E";                                       
           when READ_MIG_MP_NO_INCREMENT   => etat <= CHECK_READ_MP;   
           debug_etat <= x"1F";                     
           when WAIT_DATA_VALID              => if (app_rd_data_valid = '1') then  etat <= READ_FIFO_ADD_MP; end if;            
           when ETHERNET_COMPLETE       => etat <= INIT;         
           debug_etat <= x"20";                         
           when others => etat <= INIT; 
       end case;
   end if;
   end process;
   --tb_WORD <= app_rd_data(23 downto 0) when (etat = WAIT_READ_WORD1 and app_rd_data_valid = '1');
   
   process (ui_clk)
   begin
   if rising_edge (ui_clk) then
   if (etat = INIT) then
       raz               <= '1';                                 
       rst_fifo          <= '0';         
       transfer_done     <= '0';
       read_mig_complete <= '0';
       app_en            <= '0';
       app_cmd           <= "000";
       app_wdf_wren      <= '0';
       app_wdf_end       <= '0';
       address           <= (others =>'0');
       tb_word_to_write  <= (others =>'0');
       count             <= x"000000";
       write_mig_complete <= '0';
       missing_pkts_read <= '0';  
       TX_DV   <= '0';
       TX_Byte <= "00000000";   
       rd_en_fifo1   <= '0';
          elsif (etat = SEND_SERIAL1) then
           TX_DV   <= '1';
           TX_Byte <= "01000001";   
       elsif (etat = TEMPO_SERIAL1) then
           TX_DV   <= '0';
           TX_Byte <= "00000000";   
   elsif (etat = SEND_SERIAL) then
       TX_DV   <= '1';
       TX_Byte <= "10101010";   
   elsif (etat = TEMPO_SERIAL) then
       TX_DV   <= '0';
       TX_Byte <= "00000000";   
   elsif (etat = RESETFIFO) then
       raz               <= '0';                                 
       rst_fifo          <= '1';         
       transfer_done     <= '0';
       read_mig_complete <= '0';
       app_en            <= '0';
       app_cmd           <= "000";
       app_wdf_wren      <= '0';
       app_wdf_end       <= '0';
       address           <= (others =>'0');
       tb_word_to_write  <= (others =>'0');
       count             <= x"000000";
   elsif (etat = DETECTFULL) then
       app_en        <= '0';                         
       rst_fifo      <= '0';   
       address       <= (others=>'0');    
       app_wdf_end   <= '0';
       app_wdf_wren  <= '0';   
       app_cmd       <= "000"; 
   elsif (etat = FIFOREADY) then        
       app_en        <= '0';                       
       address       <= (others=>'0');    
       app_wdf_end   <= '0';
       app_wdf_wren  <= '0';   
       app_cmd       <= "000"; 

   elsif (etat = CALIB_COMPLETE)then
       app_en       <= '0';
       app_cmd      <= "000";
       app_wdf_wren <= '0';
       app_wdf_end  <= '0';

   elsif (etat = READ_FIFO2)then
       app_en       <= '0';
       app_cmd      <= "000";
       app_wdf_wren <= '0';
       app_wdf_end  <= '0';
       address      <= address + 1;
       tb_word_to_write <= tb_word_to_write + 1;
       count            <= count + 1;
  elsif (etat = WDF_END)then
                app_en       <= '0';
                app_cmd      <= "000";
                app_wdf_wren <= '1';
                app_wdf_end  <= '1';
                app_cmd      <= "000";
           elsif (etat = APP_ENV)then
                        app_en       <= '1';
                        app_cmd      <= "000";
                        app_wdf_wren <= '0';
                        app_wdf_end  <= '0';
                        app_cmd      <= "000";
        elsif (etat = CHECK_WDF)then
            app_en       <= '0';
            app_cmd      <= "000";
            app_wdf_wren <= '0';
            app_wdf_end  <= '0';
         elsif (etat = CHECK_APP_ENV)then
                app_en       <= '0';
                app_cmd      <= "000";
                app_wdf_wren <= '0';
                app_wdf_end  <= '0';

elsif (etat = TEMPO_READ1 ) then
    raz           <= '0';            
    app_en        <= '0';                       
    rst_fifo      <= '0';   
    address       <= (others=>'0');    
    app_wdf_end   <= '0';
    app_wdf_wren  <= '0';   
    app_cmd       <= "001"; 
    tb_final_address <= address;
elsif (etat = TEMPO_READ3 ) then
        raz           <= '0';            
        app_en        <= '0';                       
        rst_fifo      <= '0';   
        address       <= (others=>'0');    
        app_wdf_end   <= '0';
        app_wdf_wren  <= '0';   
        app_cmd       <= "001"; 
        write_mig_complete <= '1';
elsif (etat = READ_MIG) then    
    app_en        <= '1';                     
    address       <= address + 1;    
    app_wdf_end   <= '0';
    app_wdf_wren  <= '0';   
    app_cmd       <= "001"; 
elsif (etat = CHECK_READ ) then       
    app_en        <= '0';           
    address       <= address;    
    app_wdf_end   <= '0';
    app_wdf_wren  <= '0';   
    app_cmd       <= "001"; 
elsif (etat = TEMPO_NO_INCREMENT) then
    app_en        <= '0';                     
    address       <= address ;    
    app_wdf_end   <= '0';
    app_wdf_wren  <= '0';   
    app_cmd       <= "001"; 
elsif (etat = READ_MIG_NO_INCREMENT) then
    app_en        <= '1';                  
    address       <= address ;    
    app_wdf_end   <= '0';
    app_wdf_wren  <= '0';   
    app_cmd       <= "001"; 
elsif (etat = READ_COMPLETE) then
    app_en        <= '0';           
    address       <= address ;    
    app_wdf_end   <= '0';
    app_wdf_wren  <= '0';   
    app_cmd       <= "001"; 
    transfer_done <= '0';
    read_mig_complete <= '1';
elsif (etat = WAIT_ETHERNET) then
    app_en        <= '0';           
    address       <= address ;    
    app_wdf_end   <= '0';
    app_wdf_wren  <= '0';   
    app_cmd       <= "001"; 
    transfer_done <= '0';
    read_mig_complete <= '1';
elsif (etat = ETHERNET_COMPLETE) then
    app_en        <= '0';           
    address       <= address ;    
    app_wdf_end   <= '0';
    app_wdf_wren  <= '0';   
    app_cmd       <= "001"; 
    transfer_done <= '1';
elsif (etat = READ_MISSING_PKTS) then
    app_en        <= '0';           
    address       <= address ;    
    app_wdf_end   <= '0';
    app_wdf_wren  <= '0';   
    app_cmd       <= "001"; 
    missing_pkts_read <= '0';  
elsif (etat = READ_FIFO_ADD_MP) then
    rd_en_fifo1   <= '1';
elsif (etat = READ_MIG_MP) then
    rd_en_fifo1   <= '0';
    app_en        <= '1';           
    address       <= unsigned(tb_dout_fifo1(24 downto 0));     
    app_cmd       <= "001"; 
elsif (etat = CHECK_READ_MP) then
    app_en        <= '0';           
    address       <= address ;    
    app_cmd       <= "001";   
elsif (etat = WAIT_DATA_VALID) then
        app_en        <= '0';           
        address       <= address ;    
        app_cmd       <= "001";   
elsif (etat = TEMPO_NO_INCREMENT_MP) then
    app_en        <= '0';           
    address       <= address ;    
    app_cmd       <= "001"; 
elsif (etat = READ_MIG_MP_NO_INCREMENT) then
    app_en        <= '1';           
    address       <= address ;    
    app_cmd       <= "001";      
elsif (etat = READ_MIG_MP_COMPLETE) then
    app_en        <= '0';           
    address       <= address ;    
    app_cmd       <= "001";  
    missing_pkts_read <= '1';  
elsif (etat = TEMPO_READ_MIG_MP_COMPLETE) then
        app_en        <= '0';           
        address       <= address ;    
        app_cmd       <= "001";  
        missing_pkts_read <= '1';  
   else
       app_en       <= '0';
       app_cmd      <= "000";
       app_wdf_wren <= '0';
       app_wdf_end  <= '0';

   end if;
   end if;
end process;

end Behave;

 

app_cmd.png

 

0 Kudos
1 Solution

Accepted Solutions
Voyager
Voyager
238 Views
Registered: ‎02-01-2013

Re: MIG VC707 write path

Jump to solution

I have 3 main questions

1) It is said in the Guide that i can register the data before the app_cmd is asserted but is there a maximum delay?

I don't think so. From the MIG UG586:

app_wdf_data data can be pushed even before app_cmd "write command" is asserted. The only condition is that for every app_cmd "write command," the associated app_wdf_data "write data" must be present.

So there doesn't seem to be a clock-cycle limit on the pre-arrival of data before the associated write command. 

2) If app_rdy = '1' for a moment and on the next rising edge(1) of ui_clk i assert app_en and on the next risng edge(2)  of ui_clk i deassert app_en and i realize that app_rdy is ='0' before that last rising edge (2) of ui_clk , I assume that app_cmd has not been validated right?

Your assumption is (probably) correct. But your actions are wrong. From the MIG UG:

app_rdy

This output indicates to you whether the request currently being submitted to the UI is accepted. If the UI does not assert this signal after app_en is asserted, the current request must be retried.

So while the controller can play peek-a-boo with the app_rdy (and the app_wdf_rdy), your interface logic must maintain your enables until the controller accepts the transaction. You should not "deassert app_en" until the transaction has been accepted by the controller.

3) If app_en = '1'for a moment and after the rising edge (1) of ui_clk app_rdy gets high and stays high and on the next rising edge(2) of ui_clk i deassert app_en while app_rdy is still high , How many app_cmd have been validated here one or two?

I don't follow you narration of events. What does "for a moment" mean?

Here is an image to clarify

You should have labeled the clock edges in your drawing with the edge numbers you used in your questions, if they're supposed to be related...

app_cmd.png

In the first case, 1 DDR command is accepted into the controller; in the second case, 2. 


-Joe G.

 

1 Reply
Voyager
Voyager
239 Views
Registered: ‎02-01-2013

Re: MIG VC707 write path

Jump to solution

I have 3 main questions

1) It is said in the Guide that i can register the data before the app_cmd is asserted but is there a maximum delay?

I don't think so. From the MIG UG586:

app_wdf_data data can be pushed even before app_cmd "write command" is asserted. The only condition is that for every app_cmd "write command," the associated app_wdf_data "write data" must be present.

So there doesn't seem to be a clock-cycle limit on the pre-arrival of data before the associated write command. 

2) If app_rdy = '1' for a moment and on the next rising edge(1) of ui_clk i assert app_en and on the next risng edge(2)  of ui_clk i deassert app_en and i realize that app_rdy is ='0' before that last rising edge (2) of ui_clk , I assume that app_cmd has not been validated right?

Your assumption is (probably) correct. But your actions are wrong. From the MIG UG:

app_rdy

This output indicates to you whether the request currently being submitted to the UI is accepted. If the UI does not assert this signal after app_en is asserted, the current request must be retried.

So while the controller can play peek-a-boo with the app_rdy (and the app_wdf_rdy), your interface logic must maintain your enables until the controller accepts the transaction. You should not "deassert app_en" until the transaction has been accepted by the controller.

3) If app_en = '1'for a moment and after the rising edge (1) of ui_clk app_rdy gets high and stays high and on the next rising edge(2) of ui_clk i deassert app_en while app_rdy is still high , How many app_cmd have been validated here one or two?

I don't follow you narration of events. What does "for a moment" mean?

Here is an image to clarify

You should have labeled the clock edges in your drawing with the edge numbers you used in your questions, if they're supposed to be related...

app_cmd.png

In the first case, 1 DDR command is accepted into the controller; in the second case, 2. 


-Joe G.