|
|
  |
проблемы при синтезе |
|
|
|
Jul 2 2007, 12:46
|
Группа: Новичок
Сообщений: 9
Регистрация: 2-07-07
Пользователь №: 28 829

|
Вот и у меня та же проблема в ISE9.1 в предыдушей теме...
|
|
|
|
|
Jul 2 2007, 12:52
|
Местный
  
Группа: Участник
Сообщений: 468
Регистрация: 4-03-05
Пользователь №: 3 066

|
Цитата(KPiter @ Jul 2 2007, 16:23)  Не могу никак понять почему в тестбенч поведение модели правильное. а зашиваешь на FPGA дизайн ведет себя не правильно. Например, с помощью шаманства, дизайн работает правильно, а при уменьшении (!) разрадности счетчика опять все слетает т.е. работает не правильно %\ Ну? И где код? Хотя бы на счетчик, шаманский  . А вообще говорилось 2^inf раз, что дизайн должен быть полностью синхронен, тогда и чудес поменьше будет  .
|
|
|
|
|
Jul 2 2007, 13:08
|
Группа: Новичок
Сообщений: 9
Регистрация: 2-07-07
Пользователь №: 28 829

|
Цитата(Самурай @ Jul 2 2007, 16:52)  Ну? И где код? Хотя бы на счетчик, шаманский  . А вообще говорилось 2^inf раз, что дизайн должен быть полностью синхронен, тогда и чудес поменьше будет  . Вот, например, мой проект... В ucf только перечисление пинов
Сообщение отредактировал SpellDrive - Jul 2 2007, 13:09
Прикрепленные файлы
f_new_fn4.v ( 123.45 килобайт )
Кол-во скачиваний: 69
f_new_fv4.v ( 34.71 килобайт )
Кол-во скачиваний: 73
main.v ( 3.37 килобайт )
Кол-во скачиваний: 58
main_test.v ( 1.65 килобайт )
Кол-во скачиваний: 53
|
|
|
|
|
Jul 2 2007, 13:29
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 22-09-06
Из: NN
Пользователь №: 20 592

|
Код 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 - перестает адекватно АЦП на изменение напряжения работать - выдает не правильные данные. Такая же ситуация происходит если увеличивать число тактов между работой АЦП и ЦАП. Вот такая ситуевина :\ хочеться дизайн усложнить, а начинаешь что-то менять престает правильно работать %\
|
|
|
|
|
Jul 4 2007, 09:41
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 22-09-06
Из: NN
Пользователь №: 20 592

|
Цитата(Vadim @ Jul 4 2007, 13:32)  Зачем Вы плодите клоки? И по фронту, и по срезу ... Ужас. Скажу в 2^inf+1 раз - дизайн должен быть синхронным. Если Вы этого не поймете, будете шаманить и дальше. А как же иначе?!  По срезу выставляем данные, по фромту ЦАП их забирает. А в АЦП наоборот: АЦП выставляет данные по фронту, а забираем данные по срезу. Синхронность это означает, что или ТОЛЬКО все по срезу или ТОЛЬКО все по фронту? Получается чтобы мне работать с максимальной частотой обращения к АЦП = 50 МГц частототу клока дизайна надо иметь = 100МГц минимум? На АЦП подавать 50МГц (половину частоты дизайна), а на 100МГц успевать забирать и выставлять данные?
|
|
|
|
|
Jul 4 2007, 10:23
|
Местный
  
Группа: Участник
Сообщений: 468
Регистрация: 4-03-05
Пользователь №: 3 066

|
Цитата(Vadim @ Jul 4 2007, 13:32)  Зачем Вы плодите клоки? И по фронту, и по срезу ... Ужас. Скажу в 2^inf+1 раз - дизайн должен быть синхронным. Если Вы этого не поймете, будете шаманить и дальше. Соглашусь с Vadim'ом - с клоками у Вас явно перебор  . И дело наверно даже не в том, что используется и фронт и срез клока, это нормально (с оговорками, что клок есть меандр), а в том что для формирования дерева клоков использовать делители частоты на счетчиках не совсем корректно. Вообще, клок в проекте должен быть один, а на основе этого клока должны формироваться сигналы РАЗРЕШЕНИЯ работы необходимых узлов проекта. А еще лучше действительно уйти от заднего фронта, 100МГц не такая уж и большая частота  .
|
|
|
|
|
Jul 4 2007, 11:13
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 22-09-06
Из: NN
Пользователь №: 20 592

|
Цитата(Самурай @ Jul 4 2007, 14:23)  Соглашусь с 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.
|
|
|
|
|
Jul 5 2007, 17:14
|
Участник

Группа: Свой
Сообщений: 73
Регистрация: 18-06-04
Из: Минск
Пользователь №: 55

|
Не надо так делать. Ваш SPI контроллер должен тактироваться от одного клока (в данном случае 100 МГц). А клок в 50 МГц, который Вы выдаёте на выход чипа надо формировать как обычный сигнал данных.
- по 1-ому фронту 100 МГц клока выводите наружу бит данных. - по 2-ому фронту 100 МГц клока выводите "1" на линию SPI_CLK (ЦАП бит забирает). - по 3-ему фронту 100 МГц клока выводите наружу следующий бит данных и инвертируете SPI_CLK. - по 4-ому фронту 100 МГц клока сново инвертируете SPI_CLK (второй бит защелкивается в ЦАП).
... и так, пока не будет передано нужное количество бит. При таком подходе максимально возможная частота SPI_CLK будет в 2 раза меньше частоты дизайна (в данном случае 100/2 = 50 МГц). И глюков никогда не будет !
|
|
|
|
|
Jul 6 2007, 13:10
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 22-09-06
Из: NN
Пользователь №: 20 592

|
Цитата(Леха @ Jul 5 2007, 21:14)  Не надо так делать. Ваш SPI контроллер должен тактироваться от одного клока (в данном случае 100 МГц). А клок в 50 МГц, который Вы выдаёте на выход чипа надо формировать как обычный сигнал данных.
- по 1-ому фронту 100 МГц клока выводите наружу бит данных. - по 2-ому фронту 100 МГц клока выводите "1" на линию SPI_CLK (ЦАП бит забирает). - по 3-ему фронту 100 МГц клока выводите наружу следующий бит данных и инвертируете SPI_CLK. - по 4-ому фронту 100 МГц клока сново инвертируете SPI_CLK (второй бит защелкивается в ЦАП).
... и так, пока не будет передано нужное количество бит. При таком подходе максимально возможная частота SPI_CLK будет в 2 раза меньше частоты дизайна (в данном случае 100/2 = 50 МГц). И глюков никогда не будет ! спасибо! уже пробую... только вот фронты получаеться надо отдельным клоком еще считать :\
|
|
|
|
|
Jul 6 2007, 14:13
|
Участник

Группа: Свой
Сообщений: 73
Регистрация: 18-06-04
Из: Минск
Пользователь №: 55

|
Что Вы имеете в виду ? Никакого отдельного клока тут не надо.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|