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

Как сделать, чтобы регистр сработал 1 раз

Здравствуйте. Использую Xilinx, Spartan3. язык Verilog. Есть сигнал clk, регистр и управляющий сигнал.

Длительность положительного уровня управляющего сигнала 10-50 clk (отрицательного значительно больше 100-500). нужно чтобы регистр проинвертировался по переднему фронту clk при положительном управляющем сигнале, но только 1 раз пока упр. сигнал положительный.

При следующем положительном уровне упр. сигнала опять проинвертировался 1 раз и т.д.

Есть ли 100% надёжная схема такого решения?

Просто если ставить регистр смещения, то иногда он срабатывает быстрее, чем нужный регистр и сигнал пропускается. Частота 33 мгц. Заранее благодарен.

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


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

Здравствуйте. Использую Xilinx, Spartan3. язык Verilog. Есть сигнал clk, регистр и управляющий сигнал.

Длительность положительного уровня управляющего сигнала 10-50 clk (отрицательного значительно больше 100-500). нужно чтобы регистр проинвертировался по переднему фронту clk при положительном управляющем сигнале, но только 1 раз пока упр. сигнал положительный.

При следующем положительном уровне упр. сигнала опять проинвертировался 1 раз и т.д.

Есть ли 100% надёжная схема такого решения?

Просто если ставить регистр смещения, то иногда он срабатывает быстрее, чем нужный регистр и сигнал пропускается. Частота 33 мгц. Заранее благодарен.

 

Может быть для инвертирования регистра вместо переднего фронта клока использовать передний фронт этого управляющего сигнала? Будет то что Вы хотите: регистр будет инвертироваться только один раз при переходе управляющего сигнала из 0 в 1 :)

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


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

Может быть для инвертирования регистра вместо переднего фронта клока использовать передний фронт этого управляющего сигнала? Будет то что Вы хотите: регистр будет инвертироваться только один раз при переходе управляющего сигнала из 0 в 1 :)

 

 

 

Так ведь, я же не могу на синхро-вход триггера вместо clk подать сигнал с комбинаторной логики

 

Verilog я не знаю, а схемотехнически это вроде вот так делают.

 

 

Спасибо, за схему. Реализую. Но, она очень похожа на мою.

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


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

Так ведь, я же не могу на синхро-вход триггера вместо clk подать сигнал с комбинаторной логики

Но можете на enable.

 

input clk, control;
output reg Out;

reg control_r;
wire ControlPosEdge = (control) & (~control_r);

always @(posedge clk) begin
    control_r<=control;
    //
    if (ControlPosEdge)
        Out<=~Out;
end

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


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

Я бы предложил с подавлением метастабильности:

input clk, control;
output reg Out;

reg [2 : 0] control_r;

always @(posedge clk) begin
    control_r <= {control, control_r[2 : 1]};
    //
    if (control_r[1 : 0] == 2'b10)
        Out <= ~Out;
end

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


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

Здравствуйте. Использую Xilinx, Spartan3. язык Verilog. Есть сигнал clk, регистр и управляющий сигнал.

Длительность положительного уровня управляющего сигнала 10-50 clk (отрицательного значительно больше 100-500). нужно чтобы регистр проинвертировался по переднему фронту clk при положительном управляющем сигнале, но только 1 раз пока упр. сигнал положительный.

При следующем положительном уровне упр. сигнала опять проинвертировался 1 раз и т.д.

Есть ли 100% надёжная схема такого решения?

Просто если ставить регистр смещения, то иногда он срабатывает быстрее, чем нужный регистр и сигнал пропускается. Частота 33 мгц. Заранее благодарен.

 

Пришла вот какая идея в голову: Вам нужно чтобы ваш выход принимал противоположное состояние по первому переднему фронту clk когда управляющий сигнал устанавливается в 1? Тогда используйте 2 триггера: 1й для синхронизации управляющего сигнала с фронтом clk. А второй триггер включите в счётном режиме и на его вход тактирвания подайте Ваш засинхронизированный управляющий сигнал.

Правда возможна небольшая задержка между фронтом clk и установлением состояния выхода.

P.S. На рисунке оба триггера типа "d-триггер"

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


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

А второй триггер включите в счётном режиме и на его вход тактирвания подайте Ваш засинхронизированный управляющий сигнал.
Это все хорошо, но неправильно, во всяком случае для реализации на ПЛИС, где все по возможности желательно тактировать одной системной частотой. Как посоветовали выше, лучше использовать вход разрешения тактирования триггера.

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


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

описание цифрового устройства на VHDL (FSM), формирующего одиночный импульс длительностью равной периоду тактовой частоты.

 

Описание портов:

clk − вход тактовой частоты;

rst – вход асинхронного сброса;

inp – вход;

outp – выход.

 

1) по переднему фронту входного сигнала:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity rise_fsm is
port(clk : in std_logic;
rst : in std_logic;
inp : in std_logic;
outp : out std_logic );
end rise_fsm;

architecture behavior of rise_fsm is

type state_type is (S0, S1, S2, S3);
signal curr_state : state_type := S0;
signal next_state : state_type := S0;

begin
comb: process(curr_state, inp)
begin
case curr_state is
when S0 =>
outp <= '0';
if(inp = '0') then
next_state <= S1;
else next_state <= S0;
end if;
when S1 =>
outp <= '0';
if(inp = '0') then
next_state <= S1;
else next_state <= S2;
end if;
when S2 =>
outp <= '1';
next_state <= S3;
when S3 =>
outp <= '0';
if(inp = '0') then
next_state <= S1;
else next_state <= S3;
end if;
end case;
end process comb;

sync: process(clk, rst)
begin
if(clk'event and clk = '1') then
if(rst = '0') then
curr_state <= S0;
else curr_state <= next_state;
end if;end if;
end process sync;

end behavior;

2) по заднему фронту входного сигнала:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity fall_fsm is
   port(clk : in std_logic;
rst : in std_logic;
inp : in std_logic;
outp : out std_logic );
end fall_fsm;

architecture Behavioral of fall_fsm is

type state_type is (S0, S1, S2, S3);
signal curr_state : state_type := S0;
signal next_state : state_type := S0;

begin
comb: process(curr_state, inp)
begin
case curr_state is
when S0 =>
outp <= '0';
if(inp = '1') then
next_state <= S1;
else next_state <= S0;
end if;
when S1 =>
outp <= '0';
if(inp = '1') then
next_state <= S1;
else next_state <= S2;
end if;
when S2 =>
outp <= '1';
next_state <= S3;
when S3 =>
outp <= '0';
if(inp = '1') then
next_state <= S1;
else next_state <= S3;
end if;
end case;
end process comb;

sync: process(clk, rst)
begin
if(clk'event and clk = '1') then
if(rst = '0') then
curr_state <= S0;
else curr_state <= next_state;
end if;
end if;
end process sync;

end Behavioral;

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


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

описание цифрового устройства на VHDL (FSM), формирующего одиночный импульс длительностью равной периоду тактовой частоты.

 

Вы еще NIOS/Microblaze поставте %)))))

 

если надо

 

Длительность положительного уровня управляющего сигнала 10-50 clk (отрицательного значительно больше 100-500). нужно чтобы регистр проинвертировался по переднему фронту clk при положительном управляющем сигнале, но только 1 раз пока упр. сигнал положительный.

При следующем положительном уровне упр. сигнала опять проинвертировался 1 раз и т.д

 

я бы сделал так

 

module ff_unit (input logic clk, reset, in, output logic ff);

  logic [2:0] in_dff;

  always_ff @(posedge clk or posedge reset) begin
    if (reset) begin
      in_dff <= '0;
      ff     <= '0;
    end
    else begin
      in_dff <= (in_dff << 1) | in;
      if (in_dff[1] & !in_dff[2])
        ff <= ~ff;
    end
  end

endmodule

 

Удачи !!!

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


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

Я бы предложил с подавлением метастабильности:

А вообще, если сигнал внешний (для надежности подавления гличей и определения перепада) можно на трех тригеррах сделать мажоритарный "фильтр".

 

 

PS Это вариант будет по солидней чем "подавление метастабильности", но до стейт-машины явно не дотягивает :) .

(2 des00 - из внешнего процессора "Пушка" еще красивей бы вышла :biggrin: )

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


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

Вы еще NIOS/Microblaze поставте %)))))

Удачи !!!

 

Я просто предложил свой вариант.

Мое мнение - слишком громоздкой реализации я не предложил. :)

 

З.Ы. Вариантов решений одной и той же задачи может быть много, просто надо уметь выбирать из множества правильную и оптимальную. Сколько людей - столько мнений и решений. :)

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


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

Здравствуйте. Использую Xilinx, Spartan3. язык Verilog. Есть сигнал clk, регистр и управляющий сигнал.

Длительность положительного уровня управляющего сигнала 10-50 clk (отрицательного значительно больше 100-500). нужно чтобы регистр проинвертировался по переднему фронту clk при положительном управляющем сигнале, но только 1 раз пока упр. сигнал положительный.

При следующем положительном уровне упр. сигнала опять проинвертировался 1 раз и т.д.

Есть ли 100% надёжная схема такого решения?

Просто если ставить регистр смещения, то иногда он срабатывает быстрее, чем нужный регистр и сигнал пропускается. Частота 33 мгц. Заранее благодарен.

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

 

reg ff_1, ff_2, ff_out;

 

always @ (posedge i_clk)

if(i_rst)

ff_1 <= #1 0;

else

ff_1 <= #1 in_sign;

 

always @ (posedge i_clk)

if(i_rst)

ff_2 <= #1 0;

else

ff_2 <= #1 ff_1;

 

always @ (posedge i_clk)

if(i_rst)

ff_out <= #1 0;

else if(ff_1 & ~ff_2)

ff_out <= ~ff_out;

 

Решение проверено на практике.

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


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

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

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

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

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

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

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

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

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

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