Перейти к содержанию
    

проблемы при синтезе

Не могу никак понять почему в тестбенч поведение модели правильное. а зашиваешь на FPGA дизайн ведет себя не правильно. Например, с помощью шаманства, дизайн работает правильно, а при уменьшении (!) разрадности счетчика опять все слетает т.е. работает не правильно %\

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не могу никак понять почему в тестбенч поведение модели правильное. а зашиваешь на FPGA дизайн ведет себя не правильно. Например, с помощью шаманства, дизайн работает правильно, а при уменьшении (!) разрадности счетчика опять все слетает т.е. работает не правильно %\

 

Ну? И где код? Хотя бы на счетчик, шаманский:). А вообще говорилось 2^inf раз, что дизайн должен быть полностью синхронен, тогда и чудес поменьше будет:).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну? И где код? Хотя бы на счетчик, шаманский:). А вообще говорилось 2^inf раз, что дизайн должен быть полностью синхронен, тогда и чудес поменьше будет:).

 

Вот, например, мой проект... В ucf только перечисление пинов

f_new_fn4.v

f_new_fv4.v

main.v

main_test.v

Изменено пользователем SpellDrive

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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;
------------------------------------------------------------------------------------
entity adc_dac_top is
    Port (         spi_sck : out std_logic   :='0';
                   spi_sdo : in std_logic;
                   spi_sdi : out std_logic   := '0';
                spi_rom_cs : out std_logic    := '1';
                spi_amp_cs : out std_logic    := '1';
              spi_adc_conv : out std_logic    := '0';
                spi_dac_cs : out std_logic     := '1';
              spi_amp_shdn : out std_logic    := '0';
               spi_amp_sdo : in std_logic;
               spi_dac_clr : out std_logic   := '1';
            strataflash_oe : out std_logic    := '1';
            strataflash_ce : out std_logic    := '1';
            strataflash_we : out std_logic    := '1';
          platformflash_oe : out std_logic    := '0';
                       led : out std_logic_vector(7 downto 0);
                     clk50 : in std_logic);
    end adc_dac_top;

------------------------------------------------------------------------------------
-- Start of test architecture
architecture Behavioral of adc_dac_top is

signal int_count        : integer range 0 to 63 :=0;
signal clka        : std_logic := '1';

signal dac_B_en, dac_set_en, dac_en, amp_en, adc_en ,val_data, dac_set_tmp_en : std_logic :='0';

signal amp_count, adc_count, dac_count : integer range -1 to 62 :=0;
signal arb_count : integer range 0 to 16383 :=0;

signal data, dac_B_data, dac_A_data, orig_ADC_data, ADC_data_plus,ADC_data_minus       : std_logic_vector(11 downto 0);
signal tmp1         : std_logic_vector(10 downto 0);
signal tmp2      : std_logic_vector(9 downto 0);
signal tmp3      : std_logic_vector(7 downto 0);
signal dac_data      : std_logic_vector(19 downto 0);
signal adc_data, reg      : std_logic_vector(13 downto 0);
signal clk : std_logic:='0';

signal dac_spi_sdi, amp_spi_sdi : std_logic:='0';

signal v_up, v_dn :boolean :=false;
signal dac_set, dac_set_tmp :integer range 1 to 3 :=2;
constant cc :integer :=7;
constant ca :integer :=0;
  signal data_en : std_logic :='0';


------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Start of circuit description
begin
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Clock for Amp  
  ----------------------------------------------------------------------------------------------------------------------------------
  clkaa: process(clk50)
  begin  
    if (clk50'event and clk50='1') then
      if int_count=50 then
         int_count <= 0;
         clka <= not clka;
       else
         int_count <= int_count + 1;
      end if;
    end if;
  end process clkaa;
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Amp  
  ----------------------------------------------------------------------------------------------------------------------------------
  amp_clk: process(clka, amp_en)
  begin  
  
  if  (clka'event and clka='1') then
  if  amp_en='1' then
       amp_count <= amp_count + 1;
  else
       amp_count <= 0;
  end if;
  end if;
  end process amp_clk;
  
  amp: process(clka, amp_count)
  begin
  if (clka'event and clka='0') then
  
    case amp_count-1 is
       when 0 => 
          spi_amp_cs <= '0';
            amp_spi_sdi <= '0';          
       when 1 =>
            spi_amp_cs <= '0';        
          amp_spi_sdi <= '0';
       when 2 => 
          spi_amp_cs <= '0';
          amp_spi_sdi <= '0';
       when 3 => 
          spi_amp_cs <= '0';
          amp_spi_sdi <= '1';
       when 4 => 
          spi_amp_cs <= '0';
          amp_spi_sdi <= '0';
       when 5 => 
          spi_amp_cs <= '0';
          amp_spi_sdi <= '0';
       when 6 => 
          spi_amp_cs <= '0';
          amp_spi_sdi <= '0';
       when 7 => 
          spi_amp_cs <= '0';
          amp_spi_sdi <= '1';
       when 8 =>
          spi_amp_cs <= '1';
        amp_spi_sdi <= 'Z';        
        when others =>
          null;
     end case;
  end if;
  end process amp;
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Serial to Parallel  
  ----------------------------------------------------------------------------------------------------------------------------------
--  s_to_p: process(clk, val_data)
--  begin
--    if clk'event and clk='0' and adc_en='1' then
--       reg <= reg (1 to 13) & spi_sdo;
--     end if;
--  end process s_to_p;
  ----------------------------------------------------------------------------------------------------------------------------------
  -- ADC  
  ----------------------------------------------------------------------------------------------------------------------------------
  adc_clk: process(clk, adc_en)
  begin  
  if (clk'event and clk='1') then
    if  adc_en='1' then
         adc_count <= adc_count + 1;
    else
         adc_count <= 0;
    end if;
  end if;
  end process adc_clk;
  
  adc:process(clk, adc_count)
  begin
  if (clk'event and clk='0') then     
    case adc_count-1 is
       when 0 =>
            data_en    <='0';
          spi_adc_conv <= '1';
       when 1 => 
            data_en    <='0';
          spi_adc_conv <= '0';

        when 4=>
            data_en    <='0';
        spi_adc_conv <= '0';
          reg(13) <= spi_sdo;
       when 5=>
            data_en    <='0';
        spi_adc_conv <= '0';
          reg(12) <= spi_sdo;
       when 6=>
            data_en    <='0';
        spi_adc_conv <= '0';
          reg(11) <= spi_sdo;
       when 7=>
            data_en    <='0';        
        spi_adc_conv <= '0';
          reg(10) <= spi_sdo;
       when 8=>
            data_en    <='0';        
        spi_adc_conv <= '0';
          reg(9) <= spi_sdo;
       when 9=>
            data_en    <='0';        
        spi_adc_conv <= '0';
          reg(8) <= spi_sdo;
       when 10=>
            data_en    <='0';        
        spi_adc_conv <= '0';
          reg(7) <= spi_sdo;
       when 11=>
            data_en    <='0';        
        spi_adc_conv <= '0';
          reg(6) <= spi_sdo;
       when 12=>
            data_en    <='0';        
        spi_adc_conv <= '0';
          reg(5) <= spi_sdo;
       when 13=>
            data_en    <='0';        
        spi_adc_conv <= '0';
          reg(4) <= spi_sdo;
       when 14=>
            data_en    <='0';        
        spi_adc_conv <= '0';
          reg(3) <= spi_sdo;
       when 15=>
            data_en    <='0';        
        spi_adc_conv <= '0';
          reg(2) <= spi_sdo;
       when 16=>
            data_en    <='0';        
        spi_adc_conv <= '0';
          reg(1) <= spi_sdo;
       when 17=>
            data_en    <='1';        
        spi_adc_conv <= '0';
          reg(0) <= spi_sdo;
        when 18=>
            data_en    <='0';        
        spi_adc_conv <= '0';
        when others =>
          null;
     end case;
  end if;
  end process adc;

  ----------------------------------------------------------------------------------------------------------------------------------
  -- DAC
  ----------------------------------------------------------------------------------------------------------------------------------
dac_clk: process(clk, dac_en)
  begin
   if clk'event and clk='0' then
      if dac_en='1' then
         dac_count <= dac_count + 1;
      else    
           dac_count <= 0;
      end if;
    end if;
end process dac_clk;

dac: process(dac_count)
   begin 
       case dac_count-1 is
         when 0 => 
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(19);
          when 1 =>
              spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(18);
          when 2 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(17);
          when 3 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(16);
          when 4 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(15);
          when 5 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(14);
          when 6 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(13);
          when 7 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(12);
          when 8 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(11);
          when 9 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(10);
          when 10 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(9);
          when 11 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(8);
          when 12 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(7);
          when 13 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(6);
          when 14 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(5);
          when 15 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(4);
          when 16 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(3);
          when 17 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(2);
          when 18 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(1);
          when 19 =>
            spi_dac_cs <='0';
             dac_spi_sdi <= dac_data(0);
          when 20 =>
            spi_dac_cs <='0';
            dac_spi_sdi <= 'Z';
          when 24 =>
            spi_dac_cs <='1';
            dac_spi_sdi <= 'Z';
        when others =>
            null;
       end case;

   end process dac;
        
    
  ----------------------------------------------------------------------------------------------------------------------------------
  -- Arbitor  
  ----------------------------------------------------------------------------------------------------------------------------------
  spi_sdi <= amp_spi_sdi when amp_en = '1' else dac_spi_sdi;                 
  arbitor: process(clk)
  begin
            if clk'event and clk='0' then

             arb_count <= arb_count+1;                
                 case arb_count is
                when 1 =>
                   dac_set_en <='0';
                    amp_en <= '1'; 
                    adc_en <= '0'; 
                    dac_en <= '0';
                    dac_B_en <='0';
                    dac_set_tmp_en <='0';
                when 1000 =>  -- start loop ADC
                   dac_set_en <='0';
                    amp_en <= '0';
                    adc_en <='1';
                    dac_en <='0';
                    dac_B_en <='0';
                    dac_set_tmp_en <='0';
                when 1019+cc =>    -- DAC B
                   dac_set_en <='1';
                    amp_en <= '0';
                    adc_en <='0';
                    dac_en <='1';
                    dac_B_en <='1';
                    dac_set_tmp_en <='0';
                when 1020+cc =>    -- DAC B
                   dac_set_en <='0';
                    amp_en <= '0';
                    adc_en <='0';
                    dac_en <='1';
                    dac_B_en <='1';
                    dac_set_tmp_en <='1';
                when 1021+cc =>    -- DAC B
                    dac_set_en <='0';
                    amp_en <= '0';
                    adc_en <='0';
                    dac_en <='1';
                    dac_B_en <='1';
                    dac_set_tmp_en <='0';
               when 1044+cc =>    -- restart DAC
                    dac_set_en <='0';
                    amp_en <= '0';
                    adc_en <='0';
                    dac_en <='0';
                    dac_B_en <='0';
                    dac_set_tmp_en <='0';
                when 1045+cc =>    -- DAC A
                   dac_set_en <='0';
                    amp_en <= '0';
                    adc_en <='0';
                    dac_en <='1';
                    dac_B_en <='0';
                    dac_set_tmp_en <='0';
                when 1070+cc =>    -- return 1069
                   dac_set_en <='0';
                    amp_en <= '0';
                    adc_en <='0';
                    dac_en <='0';
                    dac_B_en <='0';
                    dac_set_tmp_en <='0';
                when 16383 =>    -- return 1069
                    dac_set_en <='0';
                    amp_en <= '0';
                    adc_en <='0';
                    dac_en <='0';
                    dac_B_en <='0';
                    dac_set_tmp_en <='0';
                    arb_count <= 1000;
        when others =>
            null;
         end case;
            end if;
            

  end process arbitor;

    adc_data <= reg when data_en='1' else adc_data;


  ----------------------------------------------------------------------------------------------------------------------------------
  -- SPI CLOCK
  ----------------------------------------------------------------------------------------------------------------------------------

clk <= clk50;
spi_sck <= clka when amp_en='1' else clk;


data <= adc_data(13 downto 2) xor "100000000000";

  led <= data(11 downto 4);

  tmp1 <= not data(11 downto 1);
  tmp2 <= tmp1(10 downto 1);
  orig_ADC_data <= "000111110000" + tmp1 + tmp2;
  ADC_data_plus <= orig_ADC_data + "001001101100";
  ADC_data_minus <= orig_ADC_data - "001001101100";
  
  dac_A_data <= ADC_data_minus when dac_set=1 else 
                ADC_data_plus when dac_set=3 else 
                     orig_ADC_data;
  
  
  dac_data <= "00100001" & dac_B_data  when dac_B_en='1' else  "00100000" & dac_A_data;
                                    

tmp3 <= data(11 downto 4);
  v_up <= true when tmp3 < "00111101" else false; --ADC > 2.3
  v_dn <= true when tmp3 > "11100010" else false; --ADC < 0.7
  
  dac_B_data <= "010011011001" when dac_set=1 else --DAC_B = 1
                "100110110010" when dac_set=3 else --DAC_B = 2
                     "011101000101"; --DAC_B = 1.5

  
  dac_set_tmp <= 
                1 when    dac_set_en = '1' and v_up and dac_set=2 else 
                2 when   dac_set_en = '1' and v_up and dac_set=3 else
                3 when   dac_set_en = '1' and v_dn and dac_set=2 else
                2 when   dac_set_en = '1' and v_dn and dac_set=1;
                
    dac_set <= dac_set_tmp when dac_set_tmp_en='1' else dac_set;


                 spi_rom_cs <= '1';
              spi_amp_shdn <= '0';
               spi_dac_clr <= '1';
            strataflash_oe <= '1';
            strataflash_ce <= '1';
            strataflash_we <= '1';
          platformflash_oe <= '0';
end Behavioral;

попробую пояснить, что этот дизайн делает.

1. Есть арбитр (счетчик arb_count), который управляет 2мя spi устройтсвамм (АЦП и ЦАП).

2. происходит считывание данных их АЦП.

3. производиться некоторая АСИНХРОННАЯ обработка данных, после чего получается два кода для ЦАП.

4. Первый код передается на ЦАП - устанавливает заданное кодом напряжение на первом выходе ЦАП

5. Второй код передается на ЦАП - устанавливает заданное кодом напряжение на втором выходе ЦАП

6. переход на шаг 2 при достижении счетчиком определнного значения.

 

Так вот если умешать разрядность счетчика arb_count - перестает адекватно АЦП на изменение напряжения работать - выдает не правильные данные. Такая же ситуация происходит если увеличивать число тактов между работой АЦП и ЦАП. Вот такая ситуевина :\ хочеться дизайн усложнить, а начинаешь что-то менять престает правильно работать %\

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем Вы плодите клоки? И по фронту, и по срезу ... Ужас. Скажу в 2^inf+1 раз - дизайн должен быть синхронным. Если Вы этого не поймете, будете шаманить и дальше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем Вы плодите клоки? И по фронту, и по срезу ... Ужас. Скажу в 2^inf+1 раз - дизайн должен быть синхронным. Если Вы этого не поймете, будете шаманить и дальше.

 

А как же иначе?! :05: По срезу выставляем данные, по фромту ЦАП их забирает. А в АЦП наоборот: АЦП выставляет данные по фронту, а забираем данные по срезу.

Синхронность это означает, что или ТОЛЬКО все по срезу или ТОЛЬКО все по фронту? Получается чтобы мне работать с максимальной частотой обращения к АЦП = 50 МГц частототу клока дизайна надо иметь = 100МГц минимум? На АЦП подавать 50МГц (половину частоты дизайна), а на 100МГц успевать забирать и выставлять данные?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем Вы плодите клоки? И по фронту, и по срезу ... Ужас. Скажу в 2^inf+1 раз - дизайн должен быть синхронным. Если Вы этого не поймете, будете шаманить и дальше.

 

Соглашусь с Vadim'ом - с клоками у Вас явно перебор:). И дело наверно даже не в том, что используется и фронт и срез клока, это нормально (с оговорками, что клок есть меандр), а в том что для формирования дерева клоков использовать делители частоты на счетчиках не совсем корректно. Вообще, клок в проекте должен быть один, а на основе этого клока должны формироваться сигналы РАЗРЕШЕНИЯ работы необходимых узлов проекта. А еще лучше действительно уйти от заднего фронта, 100МГц не такая уж и большая частота:).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Соглашусь с Vadim'ом - с клоками у Вас явно перебор:). И дело наверно даже не в том, что используется и фронт и срез клока, это нормально (с оговорками, что клок есть меандр), а в том что для формирования дерева клоков использовать делители частоты на счетчиках не совсем корректно.

 

Делитель частоты на счетчике применен только для одного компонента в дизайне - задать начальные условия предварительному усилителю (не может он работать бестрее), который стоит перед АЦП. Условия задаються только один раз, а потом все крутиться (АЦП-ЦАП-ЦАП -- АЦП-...) на частоте ВНЕШНЕГО цварца = частоте дизайна = максимальной возможной частоте работы АЦП = 50МГц.

 

Вообще, клок в проекте должен быть один, а на основе этого клока должны формироваться сигналы РАЗРЕШЕНИЯ работы необходимых узлов проекта. А еще лучше действительно уйти от заднего фронта, 100МГц не такая уж и большая частота:).

 

Хорошо, а если, допустим, я поставлю кварц на 100МГц = частоте дизайна и на шине SPI CLK мне нужно будет выдавать 50МГц. Тогда правильно ли будет выставлять данные на SPI шину таким кодом(при фронте clk50 данные будут забираться ЦАПом):

i<=0;
if ((clk100'event and clk100='1') and (clk50='0')) then
   i<=i+1; 
   spi_sdi <= data(i);
end if;

clk100 - 100МГц - частота дизайна.

clk50 - 50МГц полученное делнием clk100.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не надо так делать. Ваш SPI контроллер должен тактироваться от одного клока (в данном случае 100 МГц).

А клок в 50 МГц, который Вы выдаёте на выход чипа надо формировать как обычный сигнал данных.

 

- по 1-ому фронту 100 МГц клока выводите наружу бит данных.

- по 2-ому фронту 100 МГц клока выводите "1" на линию SPI_CLK (ЦАП бит забирает).

- по 3-ему фронту 100 МГц клока выводите наружу следующий бит данных и инвертируете SPI_CLK.

- по 4-ому фронту 100 МГц клока сново инвертируете SPI_CLK (второй бит защелкивается в ЦАП).

 

... и так, пока не будет передано нужное количество бит. При таком подходе максимально возможная частота

SPI_CLK будет в 2 раза меньше частоты дизайна (в данном случае 100/2 = 50 МГц). И глюков никогда не будет !

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не надо так делать. Ваш SPI контроллер должен тактироваться от одного клока (в данном случае 100 МГц).

А клок в 50 МГц, который Вы выдаёте на выход чипа надо формировать как обычный сигнал данных.

 

- по 1-ому фронту 100 МГц клока выводите наружу бит данных.

- по 2-ому фронту 100 МГц клока выводите "1" на линию SPI_CLK (ЦАП бит забирает).

- по 3-ему фронту 100 МГц клока выводите наружу следующий бит данных и инвертируете SPI_CLK.

- по 4-ому фронту 100 МГц клока сново инвертируете SPI_CLK (второй бит защелкивается в ЦАП).

 

... и так, пока не будет передано нужное количество бит. При таком подходе максимально возможная частота

SPI_CLK будет в 2 раза меньше частоты дизайна (в данном случае 100/2 = 50 МГц). И глюков никогда не будет !

 

спасибо! уже пробую... только вот фронты получаеться надо отдельным клоком еще считать :\

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...