Перейти к содержанию
    

Здравствуйте!

Дана задача - реализовать счетчик, работающий в двоично-десятич. коде, заданном таблицей:

0000, 0001, 0010 и т.д. Счетчик до 9 (1001), после девяти сброс на 0000.

По данной таблицу сделала карты карно и минимизацию функций.

Пытаюсь реализовать на 4-х d-триггерах с синхронным сбросом. Но куда добавлять минимизированные функции - не

знаю. (среда - Quartus II, язык - vhdl)

Вот схема от руки:

 

DSC_0057.jpg

 

Код компонента (триггера)

library IEEE;
use IEEE.std_logic_1164.all;
-- компонент D-триггер с тактовым сигналом по переднему фронту и с асинхронным сбросом
entity dff_n is
    port (D, clk, rst : in std_logic;
          Q : out std_logic);
end dff_n;

architecture arch_dff of dff_n is
begin
    process (clk, rst) 
    begin
        if (rst = '0') 
            then Q <= '0';
        elsif (clk'event and clk = '1') 
            then Q <= D;
        end if;
    end process;
end arch_dff;

 

Основной (вот здесь и не разобраться!) - просто путаница.

 

library IEEE;
use IEEE.std_logic_1164.all;

entity counter is
    port(clock : in STD_LOGIC;
         reset : in STD_LOGIC;
         q0, q1, q2, q3 : in STD_LOGIC; 
         Q_0, Q_1, Q_2, Q_3 : out STD_LOGIC); 
end counter;

architecture arch_counter of counter is

component dff_n
    port (D, clk, rst : in std_logic;
          Q : out std_logic);
end component;

  -- port (
       -- a : in STD_LOGIC;
       -- b : out STD_LOGIC
  -- );
-- end component;
signal t0, t1, t2, t3 : STD_LOGIC;
begin
    
    
    t0 <= '0';
    t1 <= '0';
    t2 <= '0';
    t3 <= '0';
    process(clock)
    begin
        if (clock'event and clock = '1') then
            t0 <= not(q0);
            t1 <= not((not(q0 and not(q1) and not(q3)))and(not(not(q0)and q1)));
            t2 <= not((not(not(q1)and q2))and(not(q1 and q0 and not(q2)))and(not(not(q0)and q2)));
            t3 <= not(not(not(q0)and q3)and not(q0 and q1 and q2));
            
            Q_0 <= t0;
            Q_1 <= t1;
            Q_2 <= t2;
            Q_3 <= t3;

        end if;
    end process;

    DFF1 : dff_n
    port map(
       D => q0,
       Q => Q_0,
       clk => clock,
       rst => reset);

DFF2 : dff_n
    port map(
       D => q1,
       Q => Q_1,
       clk => clock,
       rst => reset);

DFF3 : dff_n
    port map(
       D => q2,
       Q => Q_2,
       clk => clock,
       rst => reset);

DFF4 : dff_n
    port map(
       D => q3,
       Q => Q_3,
       clk => clock,
       rst => reset);

end arch_counter;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте!

Дана задача - реализовать счетчик, работающий в двоично-десятич. коде, заданном таблицей:

0000, 0001, 0010 и т.д. Счетчик до 9 (1001), после девяти сброс на 0000.

По данной таблицу сделала карты карно и минимизацию функций.

Пытаюсь реализовать на 4-х d-триггерах с синхронным сбросом. Но куда добавлять минимизированные функции - не

знаю. (среда - Quartus II, язык - vhdl)

 

А почему именно на D-триггерах?

Почему не сразу? Кажется на VHDL берется переменная, инкрементируется, и ее значение передается регистру. На Верилоге и того проще...

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

Это курсовик или для себя?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да-да, в триггеры зря ударилась....

Курсовик. Уже встречали подобное?

 

Граф состояний очень простой

 

 

DSC_0059.jpg

 

Просто на триггерах хорошо получается, например, просто в лоб решить данную задачу

 

 library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity primer is
  port (
   rst : in  STD_LOGIC;
   clk : in  STD_LOGIC;
   d   : out STD_LOGIC_VECTOR(3 downto 0));
end primer;

architecture AA of primer is
  signal d_i,d_t : STD_LOGIC_VECTOR(3 downto 0);
begin
  p1: process (clk, rst)
  begin
    if rst = '1' then
      d_t <= (others => '0');
    elsif
        clk'event and clk='1' then d_t <= d_i;
    end if;
  end process p1;
  d_i <=
   "0000" when d_t = "1001" else
   "0001" when d_t = "0000" else
   "0010" when d_t = "0001" else
   "0011" when d_t = "0010" else
   "0100" when d_t = "0011" else
   "0101" when d_t = "0100" else
   "0110" when d_t = "0101" else
   "0111" when d_t = "0110" else
   "1000" when d_t = "0111" else
   "1001" when d_t = "1000" else
   d_t;
d <= d_t;
end AA;

 

и в Quartus все прекрасно отображает...

 

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

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что-то для обычного счетчика до 9 как-то сложно...

надо завести регистр на 4 бита

каждый клок если регистр не равен 9 в регистр записывать регистр + 1, а иначе 0, и по ресету тоже 0, или я чего-то не понимаю?

 

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

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

в явном виде, а какие сигналы по какими и-или соединять это как раз ваши карты карно и скажут.

 

Триггера в вашей задаче только чтобы защелкнуть текущее состояние, чтобы клок корректно отрабатывать.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Самым изящным решением будет вот такое:

module cnt9 (
    input  logic        rst_n,
    input  logic        clk,
    output logic [3:0]    cnt
);

always_ff @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        cnt    <= 0;
    else
        cnt    <= (cnt == 4'b1001) ? '0 : cnt + 1'b1;
end

endmodule

На VHDL то же самое, но чуть больше строк кода.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Реализовала след. способом (в лоб)

 

library IEEE;
use IEEE.std_logic_1164.all;

entity counter06 is
    port(
        q : in STD_LOGIC_VECTOR(3 downto 0); -- íà âñåì óñòðîéñòâå âõîäíûå äàííûå
        q_out : out STD_LOGIC_VECTOR(3 downto 0)); 
end counter06;

architecture arch_counter of counter06 is

signal t: STD_LOGIC_VECTOR(3 downto 0);

begin
    p1: process (t)
    begin
        for i in 0 to 8 loop
            t(0) <= not(q(0)) after 5ns;
            t(1) <= not((not(q(0) and not(q(1)) and not(q(3))))and(not(not(q(0))and q(1)))) after 10ns;
            t(2) <= not((not(not(q(1))and q(2)))and(not(q(1) and q(0) and not(q(2))))and(not(not(q(0))and q(2)))) after 15ns;
            t(3) <= not(not(not(q(0))and q(3))and not(q(0) and q(1) and q(2))) after 20ns;    
            
            q_out(0) <= t(0);
            q_out(1) <= t(1);
            q_out(2) <= t(2);
            q_out(3) <= t(3);        
        end loop;
    end process p1;
end arch_counter;

 

Но при симуляции делает только первый цикл, т.е. при входных 0000 на выходе 0001 и все, остальные не делает. Как q присвоить t?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну очевидно вам не хватает регистра:) чтобы он сохранил данные, а не просто вывел

 

вы сделали схему которая из 0 состояния делает 1, если она правильная то из 1 она сделает 2 и так далее... теперь это состояние надо по клоку сохранить и подать на вход вашей схемы, тогда оно начнет каждый клок меняться на следующее

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, вы в первом сообщении говорили про триггер с синхронным сбросом. А по факту, у вас описан триггер а асинхронным сбросом. Две большие разницы.

Во-вторых, вызывает подозрение вот эта часть кода:

    t0 <= '0';
    t1 <= '0';
    t2 <= '0';
    t3 <= '0';
    process(clock)
    begin
        if (clock'event and clock = '1') then
            t0 <= not(q0);
            t1 <= not((not(q0 and not(q1) and not(q3)))and(not(not(q0)and q1)));
            t2 <= not((not(not(q1)and q2))and(not(q1 and q0 and not(q2)))and(not(not(q0)and q2)));
            t3 <= not(not(not(q0)and q3)and not(q0 and q1 and q2));

 

Присвоение значения tx должно происходить лишь в пределах одного процесса, а у вас в разных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все правильно работает. Во время симуляции подставляя значения q (0,1,2,3) выдает нужные значения, теперь действительно нужно эти значения сохранять и показывать во время симуляции... Попробую решить ..

 

Кстати, вы в первом сообщении говорили про триггер с синхронным сбросом. А по факту, у вас описан триггер а асинхронным сбросом. Две большие разницы.

Во-вторых, вызывает подозрение вот эта часть кода:

    t0 <= '0';
    t1 <= '0';
    t2 <= '0';
    t3 <= '0';
    process(clock)
    begin
        if (clock'event and clock = '1') then
            t0 <= not(q0);
            t1 <= not((not(q0 and not(q1) and not(q3)))and(not(not(q0)and q1)));
            t2 <= not((not(not(q1)and q2))and(not(q1 and q0 and not(q2)))and(not(not(q0)and q2)));
            t3 <= not(not(not(q0)and q3)and not(q0 and q1 and q2));

 

Присвоение значения tx должно происходить лишь в пределах одного процесса, а у вас в разных.

первый вариант уже и не рассматриваю...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Реализовала след. способом (в лоб)

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот рабочая версия

 

только вместо 9-ки 10-ка скорее всего нужно

 

и да всякие after while это несинтезируемые.. используются только для симуляций, а в железе не работает.

 

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity notand is
port
(
    clock : std_logic;
    t0 : out std_logic;
    t1 : out std_logic;
    t2 : out std_logic;
    t3 : out std_logic
);
end notand;

architecture behav of notand is

signal counter : std_logic_vector(3 downto 0) := (others => '0');

begin

process (clock)
begin
    if rising_edge(clock) then
        if counter < 9 then 
            counter <= counter + '1';
        else 
            counter <= (others =>'0')
        end if;
    end if;
end process;

t0<= counter(0);
t1<= counter(1);
t2<= counter(2);
t3<= counter(3);

end behav;

 

ой ; забыл в 29 строке.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не понимаю зачемы вы так сложно все пишите. ведь в плисина и так все в тригеры сохраняет.

 

из этого кода вам нужен только алгоритм counter <= counter + '1'

if-ом ставите ограничение до сколкьи считать и обнуляете

еще добавить ресет, если нужен, только в список чувствительности не забудьте добавить его.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Господа новички, конструкция вида

if counter < 9 then 
            counter <= counter + '1';

и подобные не является ответом на вопрос ТС.

Неужели вы думаете что хренова туча людей на этом форуме не знает как на верилоге или vhdl записать счетчик 1 строчкой?

 

ТС, зачем вам t и q раздельно? Если вы добавили клок, то и сохраняйте из q в q сразу. Начальное состояние q задайте либо сигналом сброса или в секции initital.

 

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

и какая конструкция не синтезируемая? задание начального значения? Уже давно синтезируемая в половине FPGA

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как же карты Карно? :crying: Так красиво все начиналось....

ага . значит нужно сделать сравнение(t0-t3) между собой, после каждого такта клока. и куда-то это значение выводить

 

надо почитать, про карты карно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...