Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ML605 (Virtex-6) + ISE 12.2 + VHDL
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
Radio_Head
Здравствуйте товарищи! Помогите решить учебную задачу. Я только начинаю работать с ПЛИС.
Имеем: отладочную плату 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";

iosifk
Цитата(Radio_Head @ Aug 2 2010, 17:26) *
Здравствуйте товарищи! Помогите решить учебную задачу. Я только начинаю работать с ПЛИС.
Имеем: отладочную плату ML605 (Virtex-6).
Задача: помигать светодиодами.


Сдаётся мне, что при создании проекта я задаю неверные установки, но перелистав их несколько раз, не могу найти ошибку… Подскажите, на какие грабли я наступаю, где искать спасения? Ну и советы какие-нибудь, тоже рад был бы услышать.

Начните с более постой вещи. Присвойте значение 1 паре светодиодов. И загрузите такой проект. Научитесь компилить и грузить. Потом поменяйте на пару других светодиодов...

Потом, к примеру, задействуйте кнопку напрямую на светодиод... Загрузили - горит, нажали - не горит... Без триггеров, напрямую...

Ну вот только после этого будете подключать генераторы, счетчики и прочие умные вещи...
Удачи!

Ну а мне, если не лень, то в личку напишите, где Вас этому учат...
Radio_Head
Не залился даже такой примитив как этот:

Код
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, но кажись чего-то проглядел sad.gif


Iosifk, спасибо за ответ. Вам ответить не могу, т.к. мне "запрещено отправлять сообщения"… Сдаётся мне, это из-за давнишней регистрации и «молчания». Читал, и на все вопросы находил ответы, необходимости создавать ветки не было. Администрация/Модераторы, если вы видите это сообщение, включите мне возможность отправлять сообщения. Пожалуйста!

P/S/ заливать кажись умею, по крайней мере готовый файл из аппнота залить получилось и он тест прошёл. Поэтому самым слабым звеном остаётся файл прошивки на выходе ISE.
"Wrong configuration stream for device" sad.gif

Нажмите для просмотра прикрепленного файла
Koluchiy
Эммм...
А в проекте правильная микросхема установлена? blush.gif
Radio_Head
Вот настройки проекта:



На плате стоит XC6VLX240T-1FFG1156. "сомневаться не приходиться"(с)
Koluchiy
Я очень извиняюсь.
Но XC6V_L_X240T-1FFG1156 и XC6V_С_X240T-1FFG1156 - это 2 разные микросхемы.
Правда-правда...
Radio_Head
«Чёрт побери»...
Спасибо большое, Koluchiy! 08.gif Завтра проверю, отпишусь.
Radio_Head
действительно, выставил другую ИМС и всё заработало... проклятая невнимательность... Ещё раз, Koluchiy, спасибо большое! ткнул, что называется, носом biggrin.gif
Radio_Head
Товарищи, а кто-нибудь работал с 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;


Нажмите для просмотра прикрепленного файла
Нажмите для просмотра прикрепленного файла

_____________________


отловил ошибку. вопрос снимается :D
Koluchiy
.
Radio_Head
Товарищи, подскажите пожалуйста в каких задачах целесообразнее всего использовать процессорные ядра, а в каких можно обойтись конечным автоматом? (не пинайте за глупые вопросы smile.gif )
Koluchiy
Отвечу так.
Если конечный автомат приобретает размеры процессорного ядра, или время на его создание и отладку превышает допустимые пределы, то надо ставить процессорное ядро.
dm.pogrebnoy
Цитата
Ну а мне, если не лень, то в личку напишите, где Вас этому учат...


Присоединяюсь к вопросу smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.