Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Источник импульсов
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
Vehfl
Не опытен в разработки на ПЛИС и поэтому прошу совета.

Мне нужно разработать источник импульсов такого вида:

Прямоугольный импульс длится время t, следующий такой импульс появляется через 19*t. t=6 нс.



Пытался сделать такой генератор с помощью блоков System Generator в Simulink.



Блок counter считывает содержимое памяти (вектор 100000000000000000000) с заданной частотой. Импульсы выводил на пин.
После загрузки получившейся прошивки на плату измерительный прибор показывает не то что надо.

Возможно я не правильно реализую то, что мне нужно? Или может выводить на пин не целесообразно? Как лучше сделать такой генератор?
Vacik
Привет!

А тактовая какая?
Если 6 нс, то могу написать модулек на VHDL.

Код
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date:    16:38:07 12/27/2012
-- Design Name:
-- Module Name:    Generator_1_19 - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Generator_1_19 is
    Port ( clk : in  STD_LOGIC;
           dann_out : out  STD_LOGIC);
end Generator_1_19;

architecture Behavioral of Generator_1_19 is
signal reg:std_logic:='0';
signal count:integer range 0 to 20:=0;
begin
dann_out<=reg;
p1:process(clk)
begin
if (clk'event and clk='1') then
    if (count=19) then
        reg<='1';
        count<=0;
    else
        reg<='0';
        count<=count+1;
    end if;
    
end if;
end process;

end Behavioral;
doublekey
Код
module top (
  input clk,    // 50 MHz clock input.
  input rst,

  output reg imp // Signal pulse.
  );
  
  parameter SYS_CLK_MHZ     = 50;  // System clock frequency, MHz.
  parameter PULSE_WIDTH_NS  = 200; // Pulse width, ns.
  parameter PULSE_PERIOD_US = 100; // Pulse period, us.
  
  localparam PULSE_WIDTH = (SYS_CLK_MHZ * PULSE_WIDTH_NS) / 1000; // Pulse width, clock cycles.
  localparam PULSE_PERIOD = (SYS_CLK_MHZ * PULSE_PERIOD_US); // Pulse period, clock cycles.
  
  localparam PULSE_PERIOD_W = $clog2(PULSE_PERIOD); // Pulse period counter width.
  
  reg [PULSE_PERIOD_W - 1 :0] period_cntr; // Pulse period counter.
  
  always_ff @(posedge clk, posedge rst)
  if (rst)
    begin
      period_cntr <= '0;
      imp <= '1;
    end
  else
    begin
      period_cntr <= period_cntr + 1;
      if (PULSE_PERIOD == period_cntr) period_cntr <= '0;
      if (PULSE_WIDTH == period_cntr)  imp <= '0;
      if (PULSE_PERIOD == period_cntr) imp <= '1;
    end

endmodule
Vehfl
Цитата(doublekey @ Dec 27 2012, 19:18) *
Код
module top (
  input clk,    // 50 MHz clock input.
  input rst,

  output reg imp // Signal pulse.
  );
  
  parameter SYS_CLK_MHZ     = 50;  // System clock frequency, MHz.
  parameter PULSE_WIDTH_NS  = 200; // Pulse width, ns.
  parameter PULSE_PERIOD_US = 100; // Pulse period, us.
  
  localparam PULSE_WIDTH = (SYS_CLK_MHZ * PULSE_WIDTH_NS) / 1000; // Pulse width, clock cycles.
  localparam PULSE_PERIOD = (SYS_CLK_MHZ * PULSE_PERIOD_US); // Pulse period, clock cycles.
  
  localparam PULSE_PERIOD_W = $clog2(PULSE_PERIOD); // Pulse period counter width.
  
  reg [PULSE_PERIOD_W - 1 :0] period_cntr; // Pulse period counter.
  
  always_ff @(posedge clk, posedge rst)
  if (rst)
    begin
      period_cntr <= '0;
      imp <= '1;
    end
  else
    begin
      period_cntr <= period_cntr + 1;
      if (PULSE_PERIOD == period_cntr) period_cntr <= '0;
      if (PULSE_WIDTH == period_cntr)  imp <= '0;
      if (PULSE_PERIOD == period_cntr) imp <= '1;
    end

endmodule

Я так понимаю, это программа является решением моим. А могли бы Вы объяснить зачем в строке, описывающей PULSE_WIDTH надо делить на 1000. И еще, я читал $clog2 берет логарифм по основанию е. Я так понимаю, в моем же случае нужен логарифм по основанию 2?
doublekey
Это не совсем ваше решение, а несколько модифицированный кусок моего когда.
Вам необходимо подумать, каким образом правильно рассчитать значение счётчиков, до которого нужно считать, в тактах. Похоже на то, что сейчас длительность импульса и расстояние между импульсами на 1 такт больше.
При расчёте параметра PULSE_WIDTH делим на тысячу для того, чтобы получить количество тактов тактовой частоты, поскольку частота задаётся в МГц, а период в нс, (это видно из комментариев).
$clog2 вычисляет двоичный логарифм, тут всё правильно.
Dmitriyspb
Цитата(Vehfl @ Dec 27 2012, 15:37) *
Возможно я не правильно реализую то, что мне нужно? Или может выводить на пин не целесообразно? Как лучше сделать такой генератор?


Здравствуйте, увжаймый автор вопроса!=)

Прочел форум и не смог понять, с какой тактовой частотой будет работать ваше цифровое устройство?

А если решить вашу задачу качественно, то на ум приходит самое рациональное и самое простое решение. Смысл его заключается в следующем.
При условии если ваш период дискретизации будет кратен 6 нс, т.е. тактовая частота составит порядка 167 МГц или половину от неё!

Имея заданную тактовую частоту с помощью счётчика прореживаем ровно в 20 раз, т.е. увеличиваем в 20 раз путём дешифрации выходного регистра счётчика.

ВНИМАНИЕ! Сложность не реализовать схему, а получить заданную тактовую последовательность.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.