2014-11-05 7 views
0

У меня есть система с 3 входами D_in, которая считывается на каждом положительном крае clk. Если я хочу посмотреть, будет ли текущий вход, D_in больше предыдущего D_in, по крайней мере на 2, то счет будет увеличиваться. Как написать это в VHDL?VHDL - Сравнение текущих и прошлых входов

if clk'event and clk = '1' then --read at positive edge 
if D_in > (D_in + 010) then <---I am sure this is wrong. How to write the proper code? 

Entity ABC is 
Port(D_in: in std_logic_vector(2 downto 0); 
    Count: out std_logic_vector(2 downto 0)); 
Architecture ABC_1 of ABC is 
    signal D_last: std_logic_vector(2 downto 0); 
Begin 
    Process(D_in) 
     D_last <= D_in; 
     if clk'event and clk = '1' then 
     if D_last > (D_in + 2) then 
     count <= count + 1; 
end if; 
end process; 
end ABC_1; 
+1

Если D_in, D_last - это 'numeric_std.unsigned' сигналы, то' D_last <= D_in; если D_in> D_last + 2, то ... 'внутри вашей часовой части будет хорошо. –

+0

Извините, но где я объявляю D_last как? В переменной? – Morde

+0

Я сказал, что это сигнал. Если вы объявите переменную D_last переменной, вам необходимо изменить порядок инструкций. Прочитайте разницу между назначением сигналов и переменных, чтобы понять, почему. Например, здесь: http://stackoverflow.com/questions/13954193/is-process-in-vhdl-reentrant/13956532#13956532 –

ответ

1

«хороший» способ, чтобы написать этот процесс состоит в следующем:

process (clk) 
begin 
    if (rising_edge(clk)) then 
    -- store the value for the next time the process will be activated 
    -- Note that D_last value will be changed after the whole process is completed 
    D_last <= D_in; 

    -- compare the actual D_in value with the previous one stored in D_last. 
    -- D_last value is its value at the very beginning of the process activation 
    if (D_in > D_last + 2) then 
     -- increment the counter 
     count <= count + 1; 
    end if; 
    end if; 
end process; 

Обратите внимание, что D_in, D_last и подсчет должен быть объявлен как без знака, а не как std_logic_vector.

Предлагаю вам прочитать this post, в котором объясняется, как фактически работает процесс: когда обновляются сигналы и какое значение сигнала используется в процессе.

Приветствия

[править] Этот ответ должен быть хорошо для вашего вопроса. Но код, который вы показываете, имеет другие ошибки:

  • Сигнал clk должен быть входом для вашего объекта.
  • Счетчик сигналов не может быть прочитан в вашей архитектуре, поскольку он определяется как результат в объекте. Тогда строка «count < = count + 1» не может быть разрешена. Вы должны использовать внутренний сигнал, а затем присваивать его значение «счету» вне процесса:

    count < = count_in;

+0

Спасибо за ответ. Поэтому, если я добавляю еще один оператор, сигнал count_in: std_logic_vector (2 до 0); то в архитектуре я использую count_in = count_in + 1, а затем передаю его обратно для подсчета вне процесса. Это должно быть хорошо? Кроме того, у меня появился еще один вопрос. Если d_in равно 0 для трех последовательных циклов clk, я хочу сбросить счет до 0. Как написать код для представления для 3 циклов clk? Смутно разозлился. – Morde

+0

Вы получили его за первую часть! Не расстраивайтесь с решением Дэвида Кунца о влиянии графа. В своем решении он использует переменную (cnt) вместо сигнала в моей (count_in). Тогда его аффектация происходит внутри процесса, тогда как моя снаружи. Оба решения в порядке, это только привычки кодера. – grorel

0

Есть еще несколько ошибок в вашей спецификации дизайна. Этот ответ пытается ответить на все проблемы в одном месте.

VHDL моделируется путем выполнения процессов в циклах моделирования. Каждый параллельный оператор может быть выражен как эквивалентный процесс оператор или комбинация операторов процесса и операторов блока.

Назначение сигнала представляет собой запрограммированную очередь выходных сигналов для заданного времени. Когда время не указано, это текущее время, и значение будет обновляться до выполнения процессов в следующем цикле моделирования, дельта-цикл, моделирование время развивается, когда нет оставшихся событий, запланированных для текущего времени моделирования .

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

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity abc is 
    port (
     clk: in std_logic;  -- Note 1 
     d_in: in std_logic_vector(2 downto 0); 
     count: out std_logic_vector(2 downto 0) 
    ); 
end entity; -- Note 2 

architecture foo of abc is 
    signal d_last: std_logic_vector(2 downto 0); 
begin 

DLAST:      -- Note 3 
    process (clk) 
    begin 
     if rising_edge(clk) then -- Note 4 
      d_last <= d_in; 
     end if; 
    end process; 

INC_COUNT: 
    process (clk) 
     variable cnt: unsigned(2 downto 0) := "000"; -- Note 5 
    begin 
     if rising_edge(clk) and 
       unsigned(d_last) > unsigned(d_in) + 2 then -- Mote 6,7 
      cnt := cnt + 1; 
     end if; 
     count <= std_logic_vector(cnt); 
    end process; 

end architecture; 

Примечания

  1. Отсутствует CLK от интерфейса порта
  2. Отсутствует конечное выражение для лица ABC.
  3. Концептуальный взгляд D_last регистрируется отдельно от счетчика счетчиков, чувствительного к clk.(Может быть объединены в одном процессе)
  4. функция rising_edge выражает clk'event и CLK = «1» ('событие и „=“ являются обе функции)
  5. Счетчик должен представлять собой двоичное значение для „+“ для получения двоичного результата
  6. «+» является более высоким приоритетом, чем «>», что более высокий приоритет, чем «и» (вам не нужны круглые скобки)
  7. пакета numeric_std обеспечивают реляционные и добавление операторов для
    знак типа и тип без знака, требующий преобразования типа для D_last
    и D_in.

    В качестве альтернативы использовать Synopsys пакет std_logic_unsigned который зависит от Synopsys пакета std_logic_arith и лечит std_logic_vector как беззнаковое. Это позволяет избежать преобразования типов, а позволяет объявлять типы массивов как тип std_logic_vector.

Переменная cnt может упразднится, если порт count должны были быть объявлены режим buffer и при условии, значение по умолчанию:

 count: buffer std_logic_vector(2 downto 0) :="000" -- Note 5 

и

INC_COUNT: 
    process (clk) 
    begin 
     if rising_edge(clk) and 
       unsigned(d_last) > unsigned(d_in) + 2 then -- Note 6,7 
      count <= std_logic_vector(unsigned(count) + 1); 
     end if; 
    end process; 

Вы не можете использовать Count как режим out, чтобы алгоритмически изменить его собственное значение. Возможность доступа к значению порта вывода режима предназначена для проверки и является функцией IEEE Std 1076-2008.

И теперь вы можете увидеть значение пакета std_logic_unsigned Synopsys, по крайней мере, избегая преобразований типов.

Кроме того, у меня есть еще один вопрос. Если d_in равно 0 для трех последовательных циклов clk, я хочу сбросить счет до 0. Как написать код для представления для 3 циклов clk?

Добавить другой сигнал трубопровода для D_in:

signal d_last: std_logic_vector(2 downto 0) := "000"; 
    signal d_last1: std_logic_vector(2 downto 0) := "000"; 

Примечание они также имеют значения по умолчанию, которые FPGA синтез обычно будет чтить, это представлено состояние триггера в bistream изображение, используемое для программирования ПЛИС.

И изменить, как работает счетчик:

INC_COUNT: 
    process (clk) 
    begin 
     if rising_edge(clk) then 
      if d_in = "000" and d_last = "000" and d_last1 = "000" then 
       count <= "000"; 
      elsif unsigned(d_last) > unsigned(d_in) + 2 then -- Note 6,7 
       count <= std_logic_vector(unsigned(count) + 1); 
      end if; 
     end if; 
    end process; 

Три инкарнации примера все проанализировать, что они не были моделирование и синтез должны быть приемлемыми.

+0

Очень проницательный. Я пытаюсь увеличить свое обучение, медленно добавляя дополнительные условия к вопросу. Это последняя часть моей системы, которую я пытаюсь реализовать. Что, если я хочу утверждать вывод, скажем, сигнал тревоги, если счет достигает 6, и подсчет не увеличится до тех пор, пока он не будет сброшен после 0 для 3 циклов clk? Как перевести не будет увеличиваться с точки зрения VHDL? – Morde

+0

Чтобы уточнить, для D_last1 мне нужно будет объявить новый процесс, который будет выполнен аналогично для D_last правильно? благодаря!!! – Morde

+0

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

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