2016-05-05 2 views
0

Я недавно почти закончил свой проект (мне нужно создать делитель частоты (50MHZ-> 1HZ (1s)) и закончить семисегментный дисплейный декодер). Мой проект состоит из таймера (отсчет до 00:00 вызывает тревогу и подсчитывается, если текущее состояние 00:00). Проект хорошо работает на Active HDL Simulator, но я не знаю, работает ли он на FPGA. Я написал код, используя поведенческий метод, используя 1 процесс. Мой вопрос: работает ли мой код на FPGA, если я закончу делитель частоты? Если нет, то как я могу изменить код для работы?VHDL Работает ли мой код на FPGA?

Мой код:

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 
use IEEE.STD_LOGIC_unsigned.all; 
use IEEE.STD_LOGIC_arith.all; 

entity Timer is 
    port(start_stop,M,S : in std_logic; --Start/Stop , Minutes,Seconds 
    clk : in std_logic; -- clock 1 MHz 
    alarm : out std_logic; -- alarm/buzzer 
    s1,s2,m1,m2 : inout std_logic_vector(6 downto 0)); --BCD to 7segment display representation for seconds and minutes 
end Timer; 
--}} End of automatically maintained section 

architecture Timer of Timer is 
signal sec1,sec2,min1,min2 : std_logic_vector(3 downto 0); 
signal T : std_logic := '0';  
signal done : std_logic; 
signal cu : std_logic; 
component seg7 is 
    port(bcd : in std_logic_vector(3 downto 0); 
    output : out std_logic_vector(6 downto 0) 
    ); 
end component; 

begin 
P0 : process(clk,start_stop,M,S) 
variable temp1,temp2,temp3,temp4 : std_logic_vector(3 downto 0); 
variable carry_s,carry_m : std_logic; 
variable alarm_counter : std_logic_vector(3 downto 0) := "1111"; -- buzzer/alarm counter 
begin        
    if(M = '1'and S = '1' and start_stop = '0') 
    then 
    temp1 := "0000"; 
    temp2 := "0000"; 
    temp3 := "0000"; 
    temp4 := "0000"; 
    sec1 <= temp1; 
    sec2 <= temp2; 
    min1 <= temp3; 
    min2 <= temp4; 
    alarm <= '0'; 
    done <= '0'; 
    T <= '0';--RESET when you press M and S 
    elsif(M = '0' and S = '1' and start_stop = '0') 
     then 
     temp1 := temp1 + "0001"; 
     if(temp1 = "1010") 
      then 
      temp1 := "0000"; 
      carry_s := '1'; 
     else 
      carry_s := '0'; 
     end if; 
     if(carry_s = '1') 
      then 
      temp2 := temp2 + "0001"; 
      if(temp2 = "0110") 
       then 
       temp2 := "0000"; 
       carry_s := '0'; 
      end if; 
     end if; 
     sec1 <= temp1; 
     sec2 <= temp2;-- Increment seconds when you press M 
    elsif(M = '1' and S = '0' and start_stop = '0') 
     then 
     temp3 := temp3 + "0001"; 
     if(temp3 = "1010") 
      then 
      temp3 := "0000"; 
      carry_m := '1'; 
     else 
      carry_m := '0'; 
     end if; 
     if(carry_m = '1') 
      then 
      temp4 := temp4 + "0001"; 
      if(temp4 = "1010") 
       then 
       temp4 := "0000"; 
       carry_m := '0'; 
      end if; 
     end if; 
     min1 <= temp3; 
     min2 <= temp4;-- Increment minutes when you press M 
    elsif(S = '0' and M = '0' and start_stop = '1') 
     then 
     alarm <= '0'; 
     T <= T xor '1';-- T Flip Flop behaviour 
     if(sec1 /= "0000" or sec2 /= "0000" or min1 /= "0000" or min2 /= "0000") 
     then 
     cu <= '0'; 
    else 
     cu <= '1'; 
     end if; -- counting directions 
    elsif(T = '1' and RISING_EDGE(clk)) 
     then 
     if(cu = '0') 
      then 
      done <= '0'; 
      temp1 := temp1 - "0001"; 
      if(temp1 = "1111") 
       then 
       temp2 := temp2 - "0001"; 
       temp1 := "1001"; 
      end if; 
      if(temp2 = "1111") 
       then 
       temp2 := "0101"; 
       carry_s := '1'; 
      else 
       carry_s := '0'; 
      end if; 
      if(carry_s = '1') 
       then 
       temp3 := temp3 - "0001"; 
       if(temp3 = "1111") 
        then 
        temp4 := temp4 - "0001"; 
        temp3 := "1001"; 
       end if; 
      end if; 
      if(temp1 = "0000" and temp2 = "0000" and temp3 = "0000" and temp4 = "0000") 
       then 
       done <= '1'; 
      end if; 
      sec1 <= temp1; 
      sec2 <= temp2; 
      min1 <= temp3; 
      min2 <= temp4;-- counting down 
     else 
      temp1 := temp1 + "0001"; 
      if(temp1 = "1010") 
       then 
       temp1 := "0000"; 
       temp2 := temp2 + "0001"; 
      end if; 
      if(temp2 = "0110") 
       then 
       temp2 := "0000"; 
       carry_s := '1'; 
      else 
       carry_s := '0'; 
      end if;   
      if(carry_s = '1') 
       then 
       temp3 := temp3 + "0001"; 
       if(temp3 = "1010") 
        then 
        temp3 := "0000"; 
        temp4 := temp4 + "0001"; 
        if(temp4 = "1010") 
         then 
         temp4 := "0000"; 
         T <= '0'; 
         end if; 
        end if; 
       end if; 
      sec1 <= temp1; 
      sec2 <= temp2; 
      min1 <= temp3; 
      min2 <= temp4;-- counting up 
     end if; 

    end if; 

     if(done = '1') 
      then 
      T <= '0'; 
      alarm_counter := alarm_counter - "0001"; 
      alarm <= '1'; 
      if(alarm_counter = "0000") 
       then 
       done <= '0'; 
       alarm <= '0'; 
       end if; 
     else 
      alarm_counter := "1111"; 
      alarm <= '0'; 
     end if;-- when the alarm starts 

end process P0; 

C1 : seg7 port map (sec1,s1); 
C2 : seg7 port map (sec2,s2); 
C3 : seg7 port map (min1,m1); 
C4 : seg7 port map (min2,m2); 
-- seven segment display port mapping 
end Timer; 

EDIT: Я установил код

+0

Возможный дубликат [VHDL Как подключить делитель частоты к проекту?] (Http://stackoverflow.com/questions/37036019/vhdl-how-to-attach-a-frequency-divider-to-a- project) – PlayDough

+1

@PlayDough: Этот вопрос не имеет ничего общего с портфолио, о котором спрашивал другой. Да, они принадлежат одному автору и примерно тому же коду, но это не делает их дублирующими. –

+0

@BenVoigt Я не согласен. Другой вопрос касался сопоставления портов, но в конечном счете вопрос не имел к этому никакого отношения, потому что он никогда не спрашивал ничего конкретного о сопоставлении портов (только смутное «[h] ow для использования сопоставления портов»), и b) оно заканчивалось с вопросом о том, является ли он функциональным и синтезируемым. Этот вопрос по существу является одним и тем же вопросом. – PlayDough

ответ

3

Нет, дизайн не синтезируемый.

В частности, у вас есть асинхронная обратная связь здесь:

if(M = '0' and S = '1') 
    then 
    temp1 := temp1 + "0001"; 

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

Попробуйте использовать эту структуру вместо:

if (M = '1' and S = '1') then 
    -- async reset 
elsif RISING_EDGE(clk) then 
    --all other logic for setting modes, counting, limits goes here 
endif 

RISING_EDGE функция примерно такой же, как clk = '1' and clk'event за исключением того, что она является гораздо более значимым для человека, глядя на код, и имеет a few more advantages.

+0

Если я исправлю это, можно реализовать на FPGA? –

+1

Вполне возможно построить будильник такой сложности в FPGA, да. –

+0

Я был бы не доволен этим: 'if (M = '1' и S = ​​'1') then'. Из того, что я могу понять, кратко прочитав код, 'M' и' S' являются функциональными входами («минуты» и «секунды»). Функциональная логика никогда не должна управлять асинхронным сбросом; единственным сигналом, который должен управлять асинхронным сбросом, является выделенный сигнал сброса, единственной функцией которого является включение чипа в известное состояние. Вождение асинхронного сброса с любым другим сигналом не является _синхронным дизайном_. –

Смежные вопросы