|
|
  |
ML605 (Virtex-6) + ISE 12.2 + VHDL, Первые шаги в мире ПЛИС |
|
|
|
Aug 2 2010, 13:26
|
Группа: Новичок
Сообщений: 8
Регистрация: 2-10-08
Из: Москва
Пользователь №: 40 657

|
Здравствуйте товарищи! Помогите решить учебную задачу. Я только начинаю работать с ПЛИС. Имеем: отладочную плату ML605 (Virtex-6). Задача: помигать светодиодами. Беру клок от встроенного генератора (200МГц), и пишу к нему два делителя частоты на 100 и 1’000’000 (думаю не принципиально, сколько и как делить). Подключаем последовательно, и на выходе получаем клок в 2Гц. Этим клоком тактируем сдвиговый регистр (в котором изначально записано “00001”). Изначально клок от генератора идёт по дифференциальной паре, поэтому ещё один компонент обязан это исправить (IBUFDS). Код library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity BPI_MultiBoot_Module_A is Port ( sys_clk_in_pn : in std_logic_vector(1 downto 0); --- Differential 200 Mhz clock input LED_REVXX : out std_logic_vector(4 downto 0)--- LED ); end BPI_MultiBoot_Module_A;
architecture Behavioral of BPI_MultiBoot_Module_A is
--- --- объявление компонентов удалено ---
begin ----- Instantiation of all modules -------
--Differential Clock input 200Mhz -- Inst_CLOCK_DIFF_IN: CLOCK_DIFF_IN PORT MAP( diff_clock_in => sys_clk_in_pn, Master_clock => CLK_Single_Out ); --- Clock divide by ------ Inst_Clock_200mhz_div_10: Clock_200mhz_div_10 PORT MAP( clock_200mhz_in => CLK_Single_Out, clock_2mhz_out => CLK_IN );
--- Clock divide by for LED display------ Inst_clk_div_10k: clk_div_10k PORT MAP( clk_in_4_div => CLK_IN, div_10k_out => CLK_MST_OUT );
-- LED Status -- Inst_LED_Disp_assign: LED_Disp_assign PORT MAP( led_out => LED_REVXX, clk => CLK_MST_OUT ); -- LED Status --
end Behavioral; Код architecture Behavioral of LED_Disp_assign is
signal led_pattern : std_logic_vector(4 downto 0):= "00001";
begin led_display: process(clk) begin if clk'event and clk='1' then led_pattern <= led_pattern(3 downto 0) & led_pattern(4); end if; led_out <= led_pattern; end process led_display; end Behavioral; Код синтезируется (хотя есть варнинг по поводу того, что led_pattern не включён в список чувствительности led_display: process(clk)). При implementation проекта вываливается ещё варнинга, что неплохо бы было использовать вход CE. После после создания прошивки пытаюсь залить через iMPACT идёт долгий процесс записи (минут 25) памяти конфигуратора (*.mcs), а на 70% процесс обрывается ошибкой. При попытке конфигурирования кристалла (*.bin) через JTAG ChipScope тут же выдаёт что ERROR: Wrong configuration stream for device ERROR: Configuration failed. Сдаётся мне, что при создании проекта я задаю неверные установки, но перелистав их несколько раз, не могу найти ошибку… Подскажите, на какие грабли я наступаю, где искать спасения? Ну и советы какие-нибудь, тоже рад был бы услышать. P/S/ IO настроил следующим через *.ucf Код # differential clock input 200Mhz NET "sys_clk_in_pn<0>" LOC = "J9"; NET "sys_clk_in_pn<1>" LOC = "H9";
NET "LED_REVXX<0>" LOC = "AD21"; NET "LED_REVXX<1>" LOC = "AH28"; NET "LED_REVXX<2>" LOC = "AH27"; NET "LED_REVXX<3>" LOC = "AE21"; NET "LED_REVXX<4>" LOC = "AP24";
|
|
|
|
|
Aug 2 2010, 13:37
|
Гуру
     
Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369

|
Цитата(Radio_Head @ Aug 2 2010, 17:26)  Здравствуйте товарищи! Помогите решить учебную задачу. Я только начинаю работать с ПЛИС. Имеем: отладочную плату ML605 (Virtex-6). Задача: помигать светодиодами.
Сдаётся мне, что при создании проекта я задаю неверные установки, но перелистав их несколько раз, не могу найти ошибку… Подскажите, на какие грабли я наступаю, где искать спасения? Ну и советы какие-нибудь, тоже рад был бы услышать. Начните с более постой вещи. Присвойте значение 1 паре светодиодов. И загрузите такой проект. Научитесь компилить и грузить. Потом поменяйте на пару других светодиодов... Потом, к примеру, задействуйте кнопку напрямую на светодиод... Загрузили - горит, нажали - не горит... Без триггеров, напрямую... Ну вот только после этого будете подключать генераторы, счетчики и прочие умные вещи... Удачи! Ну а мне, если не лень, то в личку напишите, где Вас этому учат...
--------------------
www.iosifk.narod.ru
|
|
|
|
|
Aug 2 2010, 14:10
|
Группа: Новичок
Сообщений: 8
Регистрация: 2-10-08
Из: Москва
Пользователь №: 40 657

|
Не залился даже такой примитив как этот: Код library IEEE; use IEEE.STD_LOGIC_1164.ALL;
entity Module_A is Port ( LED: out std_logic_vector(4 downto 0)); end Module_A;
architecture Behavioral of Module_A is signal led_pattern : std_logic_vector(4 downto 0):= "10101"; begin LED<=led_pattern; end Behavioral; Настраивал как в qst.pdf, но кажись чего-то проглядел  Iosifk, спасибо за ответ. Вам ответить не могу, т.к. мне "запрещено отправлять сообщения"… Сдаётся мне, это из-за давнишней регистрации и «молчания». Читал, и на все вопросы находил ответы, необходимости создавать ветки не было. Администрация/Модераторы, если вы видите это сообщение, включите мне возможность отправлять сообщения. Пожалуйста! P/S/ заливать кажись умею, по крайней мере готовый файл из аппнота залить получилось и он тест прошёл. Поэтому самым слабым звеном остаётся файл прошивки на выходе ISE. "Wrong configuration stream for device" 
qst.pdf ( 569.47 килобайт )
Кол-во скачиваний: 296
Сообщение отредактировал Radio_Head - Aug 2 2010, 14:18
|
|
|
|
|
Aug 2 2010, 14:47
|
Группа: Новичок
Сообщений: 8
Регистрация: 2-10-08
Из: Москва
Пользователь №: 40 657

|
Вот настройки проекта:  На плате стоит XC6VLX240T-1FFG1156. "сомневаться не приходиться"(с)
|
|
|
|
|
Aug 2 2010, 20:34
|
Группа: Новичок
Сообщений: 8
Регистрация: 2-10-08
Из: Москва
Пользователь №: 40 657

|
«Чёрт побери»... Спасибо большое, Koluchiy!  Завтра проверю, отпишусь.
|
|
|
|
|
Aug 3 2010, 05:58
|
Группа: Новичок
Сообщений: 8
Регистрация: 2-10-08
Из: Москва
Пользователь №: 40 657

|
действительно, выставил другую ИМС и всё заработало... проклятая невнимательность... Ещё раз, Koluchiy, спасибо большое! ткнул, что называется, носом
|
|
|
|
|
Aug 9 2010, 14:20
|
Группа: Новичок
Сообщений: 8
Регистрация: 2-10-08
Из: Москва
Пользователь №: 40 657

|
Товарищи, а кто-нибудь работал с LCD 16x2 с шиной данных 4 бита? Пользуясь datasheet'ом и некоторыми исходниками для 8ми битов написал вариант для ML605, но он работает не стабильно: раз 20 надо нажать кнопку, на которую завязан reset, и появляется верная надпись, ну не то чтоб 20, а совершенно рандомно. Я думаю так, если на экране кракозябра держится весь цикл, и меняется при рестарте, то проблема в тактах или в задержках... Состояния автомата кажись описал верно. ModelSim и iSim дают адекватные результаты моделирования. Подскажите, в чём я опять накосячил? Ради теста, первая половина верхней строки содержит символ 1, вторая 2. CODE library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.std_logic_unsigned.all; use ieee.numeric_std.all;
-- Generic tickNum must be set such that: -- tickNum = 10us / Period clk -- This provides an internal tick every 10us -- Clk: 100 MHz, tickNum: 1000 -- Clk: 50 MHz, tickNum: 500 -- Clk: 32 MHz, tickNum: 320 -- Clk: 10 MHz, tickNum: 100
use Work.Global_pack.all;
entity LCD_iterface is generic ( tickNum: positive := 500); port ( reset : in STD_LOGIC; clk : in STD_LOGIC; clk_enable : in STD_LOGIC; -- new char (dIn - data, charNum - position, wEn - enable write) dIn : in std_logic_vector(7 downto 0); charNum : in std_logic_vector(4 downto 0); -- 32 positions wEn : in std_logic; -- LCD Interface LCD_RS : out STD_LOGIC; LCD_RW : out STD_LOGIC; LCD_E : out STD_LOGIC; LCD_DATA_BUS: out STD_LOGIC_VECTOR (3 DOWNTO 0) ); end LCD_iterface;
architecture Behavioral of LCD_iterface is
-- LCD interface constants constant LCD_READ : std_logic := '1'; constant LCD_WRITE : std_logic := '0'; constant DATA_CODE : std_logic := '1'; constant INSN_CODE : std_logic := '0'; -- LCD characteristic constant LCD_width : integer := 16; constant LCD_height : integer := 2; -- LCD 16x2 constant LCD_length : integer := 32;
-- Tick Generation subtype TICK_COUNTER_TYPE is integer range 0 to tickNum; signal tick : std_logic;
constant WARMUP_DELAY : integer := 4000; -- 10us*2000: 40 ms constant INIT_DELAY_1 : integer := 410; -- 10us*410: 4.1 ms constant INIT_DELAY_2 : integer := 10; -- 10us*10: 100 us constant RETURN_DELAY : integer := 160; -- 10us*160: 1.6 ms constant CHAR_DELAY : integer := 4; -- 10us*4: 40 us constant E_DELAY : integer := 4; -- 10us*4: 40 us
subtype DELAY_TYPE is integer range 0 to WARMUP_DELAY; signal timer : DELAY_TYPE;
type INIT_ROM_TYPE is array (0 to 6) of std_logic_vector(7 downto 0); constant initROM : INIT_ROM_TYPE := (b"00000011", -- Init b"00000011", -- Init b"00000011", -- Init b"0010_1000", -- Function Set: 8 bit, 2 lines, 5x7 characters b"0000_1100", -- Display On/Off Control: Display on, Cursor off, Blink off b"0000_0001", -- Clear Display: Move cursor to home b"0000_0110"); -- Entry Mode Set: Auto increment cursor, don't shift display
type CHAR_RAM_TYPE is array(0 to (LCD_length-1)) of std_logic_vector(7 downto 0);
signal charRAM : CHAR_RAM_TYPE := (0 to 8=>x"31", 16 to 24 =>x"32", others=>x"A0");
signal setLine : std_logic; signal lineNum : integer range 0 to 1; signal initialising : std_logic;
signal initROMPointer : integer range 0 to INIT_ROM_TYPE'high; signal charRAMPointer : integer range 0 to CHAR_RAM_TYPE'high;
type STATE_TYPE is (WARMUP, STAGE1, STAGE2, SEND_UP, SEND_LOW, TOGGLE_E, TOGGLE_E2, DELAY);
signal state : STATE_TYPE; signal next_command : STATE_TYPE;
signal DATA_BUS_LOW : STD_LOGIC_VECTOR (3 DOWNTO 0); signal DATA_BUS_VALUE : STD_LOGIC_VECTOR (7 DOWNTO 0); BEGIN LCD_RW <= LCD_WRITE; TickGen : process(clk) variable tickCounter : TICK_COUNTER_TYPE; begin if (rising_edge(clk) and clk_enable='1') then if (tickCounter = 0) then tickCounter := TICK_COUNTER_TYPE'high-1; tick <= '1'; else tickCounter := tickCounter - 1; tick <= '0'; end if; end if; end process TickGen;
CharRAMWrite : process(clk) variable add : integer range 0 to (LCD_length-1); begin if (rising_edge(clk)) then if (wEn='1') then add := to_integer(unsigned(charNum)); charRAM(add) <= dIn; end if; end if; end process CharRAMWrite; Controller : process (clk) begin if (rising_edge(clk)) then
if (reset='1') then timer <= WARMUP_DELAY; initROMPointer <= 0; charRAMPointer <= 0;
LCD_RS <= INSN_CODE; LCD_E <= '0'; LCD_DATA_BUS <= (others => '0');
initialising <= '1'; setLine <= '0'; lineNum <= 0; state <= WARMUP;
elsif (tick='1') then
case state is
-- Perform initial long warmup delay when WARMUP => if (timer=0) then state <= STAGE1; else timer <= timer - 1; end if;
-- Set the LCD data -- Set the LCD RS -- Initialise the timer with the required delay when STAGE1 => if (initialising='1') then LCD_RS <= INSN_CODE; DATA_BUS_VALUE <= initROM(initROMPointer); if (initROMPointer<3) then state <= SEND_LOW; else state <= SEND_UP; end if;
elsif (setLine='1') then LCD_RS <= INSN_CODE; case lineNum is when 0 => DATA_BUS_VALUE <= b"1000_0000"; -- x00 timer <= CHAR_DELAY; when 1 => DATA_BUS_VALUE <= b"1100_0000"; -- x40 timer <= CHAR_DELAY; end case; state <= SEND_UP;
else timer <= CHAR_DELAY; LCD_RS <= DATA_CODE; DATA_BUS_VALUE <= charRAM(charRAMPointer)(7 downto 0); state <= SEND_UP; end if; --next_command <= STAGE2;
-- Set LCD_E (latching RS and RW) when STAGE2 => if (initialising='1') then if (initROMPointer=INIT_ROM_TYPE'high) then initialising <= '0'; else initROMPointer <= initROMPointer + 1; end if;
elsif (setLine='1') then setLine <= '0';
else
if (charRAMPointer=(LCD_width-1)) then setLine <= '1'; lineNum <= 1;
elsif (charRAMPointer=(LCD_length-1)) then setLine <= '1'; lineNum <= 0; end if;
if (charRAMPointer=CHAR_RAM_TYPE'high) then charRAMPointer <= 0; else charRAMPointer <= charRAMPointer + 1; end if;
end if;
--LCD_E <= '1'; state <= DELAY; --next_command <= STAGE1; -- SEND -- when SEND_UP => LCD_E <= '1'; LCD_DATA_BUS <= DATA_BUS_VALUE(7 downto 4); state <= TOGGLE_E; when SEND_LOW => LCD_E <= '1'; LCD_DATA_BUS <= DATA_BUS_VALUE(3 downto 0); state <= TOGGLE_E2; -- TOGGLE -- // Clear LCD_E (latching data) when TOGGLE_E => LCD_E <= '0'; timer <= E_DELAY; state <= SEND_LOW; when TOGGLE_E2 => LCD_E <= '0'; if (initialising='1') then case (initROMPointer) is when 0 => timer <= INIT_DELAY_1; when 1 => timer <= INIT_DELAY_2; when 2 => timer <= E_DELAY; when 3 => timer <= E_DELAY; when 4 => timer <= E_DELAY; when 5 => timer <= RETURN_DELAY; when 6 => timer <= E_DELAY; end case; else timer <= E_DELAY; end if; state <= STAGE2;
-- Provide delay to allow instruciton to execute when DELAY => if (timer=0) then state <= STAGE1; else timer <= timer - 1; end if;
end case; end if; end if; end process; end Behavioral; 
FPGA_LCD_HD44780.pdf ( 361.43 килобайт )
Кол-во скачиваний: 340
LCD16D2_ST7077U.pdf ( 558.36 килобайт )
Кол-во скачиваний: 237_____________________ отловил ошибку. вопрос снимается :D
Сообщение отредактировал Radio_Head - Aug 9 2010, 14:20
|
|
|
|
|
Aug 11 2010, 11:04
|
Группа: Новичок
Сообщений: 8
Регистрация: 2-10-08
Из: Москва
Пользователь №: 40 657

|
Товарищи, подскажите пожалуйста в каких задачах целесообразнее всего использовать процессорные ядра, а в каких можно обойтись конечным автоматом? (не пинайте за глупые вопросы  )
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|