Счетчик несоответствия сигнала "счетчик и подрамник" - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть небольшое несоответствие в моем коде VHDL. Я делаю сигнал на носилках, используя счетчик часов. В основном я получаю внешний сигнал как «старт», после того, как синхронизирую его с синхронизатором 2 ff и использую этот «syncrhro-start» для моего fsm. Он прочитал значение в регистре и позволил «воротам» открыться для числа, которое я установил в рег. Мои часы имеют период 25 нс (тактовая частота 40 МГц). Поэтому, когда я устанавливаю значение «0» в регистр, у меня нет никакого сигнала (как и ожидалось). Если я установлю «1», у меня будет сигнал 50 нс вместо 25 нс. Если я установлю «2», у меня будет выходной сигнал 75 нс. Концептуально он работает (2, в двоичном виде - 01, поэтому он начинает считать с 0, поэтому 0-1-2 - 3 такта / 75 нс).

Но мне нужно иметь с "1" сигнал 25 нс, с 2 50 нс и т. Д.

Вот мой код:

                 library IEEE;
               use IEEE.STD_LOGIC_1164.ALL;
               use IEEE.numeric_std.ALL;

entity gate is
Port (
    start : in STD_LOGIC := '0'; --segnale di start
    clk : in  STD_LOGIC; --clock di ingresso
    reset  : in  STD_LOGIC; --ff reset
    gate: out STD_LOGIC; --gate in uscita 
    lenght: in std_logic_vector (7 downto 0)        
);
end gate;

architecture behavioral of gate is
--type state_type is (idle, gate_up, final);
type state_type is (idle, stretching);
signal state : state_type;


begin


process (reset, clk, start)
variable index : integer :=0;
variable gate_v: std_logic;
variable gatelen : integer;

begin
gatelen := to_integer(unsigned(lenght));

if reset = '1' then  
  gate_v := '0';
  index := 0;
else
    if rising_edge(clk) then
    case state is
      when idle =>
        index := 0;
        gate_v :='0';

        if(start = '1') then
          state <= stretching;
        else
          state <= idle;
        end if;

        when stretching =>
        if index = gatelen then
        state <=idle;
       else
        gate_v := '1';
        index := index + 1;
        state <= stretching;
        end if;            

      when others => null;
    end case;

 end if;
  end if;     
   gate <= gate_v;
   end process; 


  end Behavioral;

Я могу частично исправить вещи с помощью этого мода

gatelen: = to_integer (без знака (длина)) - 1;

но в этом случае, если я поставлю «1» в реестре, у меня не будет никакого сигнала, а если я поставлю «2», у меня будет выходной сигнал 50 нс. Выходной сигнал 25 нс по-прежнему отсутствует.

Любая помощь будет очень признателен!

Edit:

Спасибо за ответ, по запросу, я также добавлю код моего тестового стенда.

library ieee;
use ieee.std_logic_1164.all;

entity gate_tb is
end gate_tb;

architecture behavioral of gate_tb is

signal master_clk : std_logic := '0';
signal global_rst : std_logic := '0';
signal gate_on : std_logic := '0';
signal gate_out : std_logic := '0';
constant clk_period : time := 25 ns; --40ns
signal lenght_tb : std_logic_vector (7 downto 0);

component gate is 
    port( 
        clk : in std_logic;  
        reset : in std_logic;         
        start : in std_logic;
        gate: out std_logic;
        lenght: in std_logic_vector ( 7 downto 0)
    );
  end component gate;


begin
 uut : gate port map (
        clk => master_clk,
        reset => global_rst,
        start => gate_on,
        gate => gate_out,
        lenght => lenght_tb

        );

       gate_process : process
       begin

         master_clk <= '0';
         wait for clk_period/2;  --for 10 ns signal is '0'.
         master_clk <= '1';
         wait for clk_period/2;  --for next 10 ns signal is '1'.


end process;  

--stimulus

  stim : process 
  begin
  lenght_tb <= "00000001";
  wait for 50 ns;
  global_rst <= '1';
wait for 30 ns;
global_rst <= '0';
wait for 50 ns;
gate_on <= '1';
wait for 35 ns;
gate_on <= '0';
wait for 150 ns;
gate_on <= '1';
wait for 35 ns;
gate_on <= '0';
wait for 150 ns;
gate_on <= '1';
wait for 35 ns;
gate_on <= '0';
wait for 150 ns;
gate_on <= '1';
wait for 35 ns;
gate_on <= '0';
wait for 150 ns;





end process;

end behavioral;

Так что если в этом ТБ я установлю lenght_tb <= "00000000"; выход 0 я установлен lenght_tb <= "00000001"; выходной сигнал 50 нс, а не 25 нс. </p>

1 Ответ

0 голосов
/ 03 сентября 2018

Проблема в состоянии растяжение , ищите например для reg = 1:

  1. Start = 1, затем перейти в состояние растяжения
  2. При растяжении вы увеличиваете индекс, поэтому теперь index = 1 и gate = 0
  3. Следующий передний фронт (прошло 1 такт) index = gatelen, так что перейдите в режим ожидания
  4. Следующий передний фронт (еще один час, так что прошло 2 часа) gate = 0

Вы должны установить gate = 0 при проверке, если index = gatelen:

when stretching =>
        if index = gatelen then
            gate_v :=  '0';
        state <=idle;
       else
        gate_v := '1';
        index := index + 1;
        state <= stretching;
        end if;   
...