kpiter 0 2 июля, 2007 Опубликовано 2 июля, 2007 · Жалоба Не могу никак понять почему в тестбенч поведение модели правильное. а зашиваешь на FPGA дизайн ведет себя не правильно. Например, с помощью шаманства, дизайн работает правильно, а при уменьшении (!) разрадности счетчика опять все слетает т.е. работает не правильно %\ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SpellDrive 0 2 июля, 2007 Опубликовано 2 июля, 2007 · Жалоба Вот и у меня та же проблема в ISE9.1 в предыдушей теме... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Самурай 12 2 июля, 2007 Опубликовано 2 июля, 2007 · Жалоба Не могу никак понять почему в тестбенч поведение модели правильное. а зашиваешь на FPGA дизайн ведет себя не правильно. Например, с помощью шаманства, дизайн работает правильно, а при уменьшении (!) разрадности счетчика опять все слетает т.е. работает не правильно %\ Ну? И где код? Хотя бы на счетчик, шаманский:). А вообще говорилось 2^inf раз, что дизайн должен быть полностью синхронен, тогда и чудес поменьше будет:). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SpellDrive 0 2 июля, 2007 Опубликовано 2 июля, 2007 (изменено) · Жалоба Ну? И где код? Хотя бы на счетчик, шаманский:). А вообще говорилось 2^inf раз, что дизайн должен быть полностью синхронен, тогда и чудес поменьше будет:). Вот, например, мой проект... В ucf только перечисление пинов f_new_fn4.v f_new_fv4.v main.v main_test.v Изменено 2 июля, 2007 пользователем SpellDrive Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kpiter 0 2 июля, 2007 Опубликовано 2 июля, 2007 · Жалоба 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 - перестает адекватно АЦП на изменение напряжения работать - выдает не правильные данные. Такая же ситуация происходит если увеличивать число тактов между работой АЦП и ЦАП. Вот такая ситуевина :\ хочеться дизайн усложнить, а начинаешь что-то менять престает правильно работать %\ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vadim 0 4 июля, 2007 Опубликовано 4 июля, 2007 · Жалоба Зачем Вы плодите клоки? И по фронту, и по срезу ... Ужас. Скажу в 2^inf+1 раз - дизайн должен быть синхронным. Если Вы этого не поймете, будете шаманить и дальше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kpiter 0 4 июля, 2007 Опубликовано 4 июля, 2007 · Жалоба Зачем Вы плодите клоки? И по фронту, и по срезу ... Ужас. Скажу в 2^inf+1 раз - дизайн должен быть синхронным. Если Вы этого не поймете, будете шаманить и дальше. А как же иначе?! :05: По срезу выставляем данные, по фромту ЦАП их забирает. А в АЦП наоборот: АЦП выставляет данные по фронту, а забираем данные по срезу. Синхронность это означает, что или ТОЛЬКО все по срезу или ТОЛЬКО все по фронту? Получается чтобы мне работать с максимальной частотой обращения к АЦП = 50 МГц частототу клока дизайна надо иметь = 100МГц минимум? На АЦП подавать 50МГц (половину частоты дизайна), а на 100МГц успевать забирать и выставлять данные? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Самурай 12 4 июля, 2007 Опубликовано 4 июля, 2007 · Жалоба Зачем Вы плодите клоки? И по фронту, и по срезу ... Ужас. Скажу в 2^inf+1 раз - дизайн должен быть синхронным. Если Вы этого не поймете, будете шаманить и дальше. Соглашусь с Vadim'ом - с клоками у Вас явно перебор:). И дело наверно даже не в том, что используется и фронт и срез клока, это нормально (с оговорками, что клок есть меандр), а в том что для формирования дерева клоков использовать делители частоты на счетчиках не совсем корректно. Вообще, клок в проекте должен быть один, а на основе этого клока должны формироваться сигналы РАЗРЕШЕНИЯ работы необходимых узлов проекта. А еще лучше действительно уйти от заднего фронта, 100МГц не такая уж и большая частота:). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kpiter 0 4 июля, 2007 Опубликовано 4 июля, 2007 · Жалоба Соглашусь с 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Лёха 0 5 июля, 2007 Опубликовано 5 июля, 2007 · Жалоба Не надо так делать. Ваш SPI контроллер должен тактироваться от одного клока (в данном случае 100 МГц). А клок в 50 МГц, который Вы выдаёте на выход чипа надо формировать как обычный сигнал данных. - по 1-ому фронту 100 МГц клока выводите наружу бит данных. - по 2-ому фронту 100 МГц клока выводите "1" на линию SPI_CLK (ЦАП бит забирает). - по 3-ему фронту 100 МГц клока выводите наружу следующий бит данных и инвертируете SPI_CLK. - по 4-ому фронту 100 МГц клока сново инвертируете SPI_CLK (второй бит защелкивается в ЦАП). ... и так, пока не будет передано нужное количество бит. При таком подходе максимально возможная частота SPI_CLK будет в 2 раза меньше частоты дизайна (в данном случае 100/2 = 50 МГц). И глюков никогда не будет ! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kpiter 0 6 июля, 2007 Опубликовано 6 июля, 2007 · Жалоба Не надо так делать. Ваш SPI контроллер должен тактироваться от одного клока (в данном случае 100 МГц). А клок в 50 МГц, который Вы выдаёте на выход чипа надо формировать как обычный сигнал данных. - по 1-ому фронту 100 МГц клока выводите наружу бит данных. - по 2-ому фронту 100 МГц клока выводите "1" на линию SPI_CLK (ЦАП бит забирает). - по 3-ему фронту 100 МГц клока выводите наружу следующий бит данных и инвертируете SPI_CLK. - по 4-ому фронту 100 МГц клока сново инвертируете SPI_CLK (второй бит защелкивается в ЦАП). ... и так, пока не будет передано нужное количество бит. При таком подходе максимально возможная частота SPI_CLK будет в 2 раза меньше частоты дизайна (в данном случае 100/2 = 50 МГц). И глюков никогда не будет ! спасибо! уже пробую... только вот фронты получаеться надо отдельным клоком еще считать :\ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Лёха 0 6 июля, 2007 Опубликовано 6 июля, 2007 · Жалоба Что Вы имеете в виду ? Никакого отдельного клока тут не надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться