If statement 如何生成一个脉冲序列,以普通方式输出?

If statement 如何生成一个脉冲序列,以普通方式输出?,if-statement,vhdl,fpga,pulse,If Statement,Vhdl,Fpga,Pulse,我正在研究生成一个40位长的脉冲序列。我还必须能够调整频率。我试着做一个新的低频时钟,我做了一个新的计数器,它的上升沿计数,并提供高输出,在40位后终止。它不起作用了。我尝试了一些其他的方法。他们也不是 比如, library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.all; entity con40 is port(clk:in std_ulogic; q:out std_ulogic); end entity

我正在研究生成一个40位长的脉冲序列。我还必须能够调整频率。我试着做一个新的低频时钟,我做了一个新的计数器,它的上升沿计数,并提供高输出,在40位后终止。它不起作用了。我尝试了一些其他的方法。他们也不是

比如,

    library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.all;

entity con40 is port(clk:in std_ulogic; q:out std_ulogic); 
end entity con40; 

architecture Behaviour of con40 is 
    constant s:std_ulogic_vector:="11111111111111111111111111111111"; 
    signal i:unsigned(4 downto 0):="00000"; 
     signal en:std_logic:='1';
     signal reset:std_logic:='0';
begin 
    q<=s(to_integer(i)); 

    process(reset,clk) is begin 
        if reset='1' then 
          i<=(others=>'0'); 
        elsif rising_edge(clk) then 
            if en='1' then 
                i<=i+1; 
                end if; 
        end if; 
    end process; 
end architecture Behaviour;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.NUMERIC_STD.all;
实体con40为端口(clk:in标准逻辑;q:out标准逻辑);
终端实体con40;
con40的架构行为是
常数s:std_ulogic_vector:=“11111111111111111111”;
信号i:无符号(4到0):=“00000”;
信号en:std_逻辑:='1';
信号复位:标准逻辑:='0';
开始

以下代码可能是生成脉冲序列的简单实现。该模块需要启动脉冲(StartSequence),并用“SequenceCompleted”确认生成的序列

我使用一个基本的RS触发器来代替状态机,它具有
set=StartSequence
rst=SequenceCompleted\u I
。我还将过程分为两个过程:

  • 状态控制-如果需要,可以扩展到完整的FSM
  • 用于计数器
  • 最初,默认情况下,模块会在每次序列生成后发出脉冲_序列(0)。因此,如果你想发出40个1,否则设置为零
    脉冲序列:=(0=>'0',1到40=>'1')

    该模块在PULSE_序列的位计数中是可变的,因此我需要包含一个名为log2ceil的函数,该函数根据PULSE_序列的长度属性计算2s对数aka所需位。 因此,在
    'length=41的情况下,位
    计数器的范围为(5到0)

    实体脉冲雨是
    一般的(
    脉冲序列:标准逻辑向量
    );
    港口(
    时钟:标准逻辑;
    开始顺序:在标准逻辑中;
    SequenceCompleted:输出标准逻辑;
    输出:输出标准逻辑
    ); 
    终端实体;
    PulseTrain的体系结构rtl是
    函数log2ceil(arg:正)返回自然值
    变量tmp:正:=1;
    变量日志:自然:=0;
    开始
    如果arg=1,则返回0;如果结束;
    而arg>tmp循环
    tmp:=tmp*2;
    log:=log+1;
    端环;
    返回日志;
    末端功能;
    信号状态:标准逻辑:='0';
    信号计数器:无符号(log2ceil(脉冲串长度)-1到0):=(其他=>'0');
    信号序列i:标准逻辑;
    开始
    进程(时钟)是
    开始
    如果上升沿(时钟),则
    如果(StartSequence='1'),则
    
    State我自由地将
    en
    reset
    移动到端口信号,还将常量更改为可识别的40位值,并指定范围使其成为局部静态常量

    您的计数器的问题是,它不够大,无法处理40位。您将
    i
    指定为5位值,而40位需要6位计数器

    我还在这里添加了第二个架构,其中I是整数类型的信号。使用
    i
    作为无符号值或整数类型,当第一个位置为0(
    “000000”
    )时,可能需要在39(
    “100111”
    )处滚动
    i
    计数器

    这会在计数器达到39时停止运行

    对于架构行为(对
    i
    使用无符号类型):

    elsif上升沿(clk)和en='1',然后
    --如果i=“100111”,则
    
    --正如@fru1tbat所提到的,什么“不起作用”以及你真正打算做什么并不清楚。如果您真的只想生成一个脉冲序列,那么您可能会认为您想要生成一系列交替的“1”和“0”,而不是您发布的代码中的所有“1”

    另外,
    i
    计数器只进行计数,只能通过使用
    reset
    信号将其重置为“0”,只要您希望这样做就可以了

    如果要生成“1”和“0”的序列,则需要类似的内容(未经测试,但应符合以下要求):

    要调整频率,只需在
    clk
    输入中提供较高或较低的频率即可。这可以由另一个PLL、分频器或任何其他可用的振荡电路产生。只需将其输出提供给
    时钟


    希望这能有所帮助。

    对于初学者来说,
    q但这不是答案。不,只是一个评论。从你的问题来看,我并不清楚你的参数是什么,但如果你至少解决了一些突出的问题,你可能会取得一些进展。我有两个选择来实现这一点。首先,生成一个新的慢时钟(可调的),并从慢时钟的前沿生成一个信号,然后执行40次并退出。您说您想要一个脉冲序列(我假设您的意思是您想要一个40脉冲序列,即40个
    '1'
    /
    '0'
    周期),但是,将一个只有40个
    '1'
    s的向量移出,将得到一个40时钟长的脉冲(因为你永远不会移出
    '0'
    )。这还不清楚。你想要哪个?但是你的if语句提供了一个无止境的循环。当数字为39时,它返回开始并继续运行。我只想要一个40倍的1-0然后停下来。此外,我不理解“feedfacedb”。这是什么,它是如何工作的?参见答案的附录,在一次发生后停止脉冲序列。选择模式
    X“FEEDFACEDB”
    ,以证明常数的输出顺序正确。感谢您的响应。还有一个问题。为什么您的测试台模拟显示q是任意的,而不是40倍的方波?因为关于它的代码显示你使用了相等的延迟。为什么会出现这种情况?您的原始设计
    entity PulseTrain is
      generic (
        PULSE_TRAIN       : STD_LOGIC_VECTOR
      );
      port (
        Clock             : in  STD_LOGIC;
        StartSequence     : in  STD_LOGIC;
        SequenceCompleted : out STD_LOGIC;
        Output            : out STD_LOGIC
      ); 
    end entity; 
    
    architecture rtl of PulseTrain is
      function log2ceil(arg : POSITIVE) return NATURAL is
        variable tmp : POSITIVE := 1;
        variable log : NATURAL  := 0;
      begin
        if arg = 1 then  return 0; end if;
        while arg > tmp loop
          tmp := tmp * 2;
          log := log + 1;
        end loop;
        return log;
      end function;
    
      signal State               : STD_LOGIC                                           := '0';
      signal Counter_us          : UNSIGNED(log2ceil(PULSE_TRAIN'length) - 1 downto 0) := (others => '0');
      signal SequenceCompleted_i : STD_LOGIC;
    
    begin 
      process(Clock) is
      begin 
        if rising_edge(Clock) then
          if (StartSequence = '1') then
            State <= '1';
          elsif (SequenceCompleted_i = '1') then
            State <= '0';
          end if;
        end if;
      end process;
    
     SequenceCompleted_i <= '1' when (Counter_us = (PULSE_TRAIN'length - 1)) else '0';
     SequenceCompleted   <= SequenceCompleted_i;
    
      process(Clock)
      begin
        if rising_edge(Clock) then
          if (State = '0') then
            Counter_us <= (others => '0');
          else
            Counter_us <= Counter_us + 1;
          end if;
        end if;
      end process;
    
      Output <= PULSE_TRAIN(to_integer(Counter_us));
    end;
    
    library ieee;
    use ieee.std_logic_1164.all;
    
    entity con40 is 
        port(
            reset:  in  std_ulogic;
            clk:    in  std_ulogic;
            en:     in  std_ulogic;
            q:      out std_ulogic
        ); 
    end entity con40; 
    
    architecture foo of con40 is 
        constant s: std_ulogic_vector (0 to 39) := x"feedfacedb"; 
        signal i:   natural range 0 to 39;
    begin 
        q <= s(i); 
    
        process (reset, clk) 
        begin     
            if reset = '1' then 
              i <= 0; 
            elsif rising_edge(clk) and en = '1' then 
                if i = 39 then 
                    i <= 0;
                else
                    i <= i + 1; 
                end if; 
            end if; 
        end process; 
    end architecture;
    
    library ieee;
    use ieee.numeric_std.all;
    
    architecture behave of con40 is 
        constant s: std_ulogic_vector (0 to 39) := x"feedfacedb"; 
        signal i:   unsigned (5 downto 0);
    begin 
        q <= s(to_integer(i)); 
    
        process (reset, clk) 
        begin     
            if reset = '1' then 
              i <= "000000"; 
            elsif rising_edge(clk) and en = '1' then 
                if i = "100111" then 
                    i <= "000000";
                else
                    i <= i + 1; 
                end if; 
            end if; 
        end process; 
    end architecture;
    
    library ieee;
    use ieee.std_logic_1164.all;
    
    entity tb_con40 is
    end entity;
    
    architecture foo of tb_con40 is
        signal clk:     std_ulogic := '0';
        signal reset:   std_ulogic := '1';
        signal en:      std_ulogic := '0';
        signal q:       std_ulogic;
    begin
    
    DUT:
        entity work.con40
            port map  (
                reset => reset,
                clk => clk,
                en => en,
                q => q
            );
    
    CLOCK:
    process
    begin
        for i in 0 to 46 loop
            wait for 20 ns;
            clk <= not clk;
            wait for 20 ns;
            clk <= not clk;
        end loop;
        wait;
    end process;
    
    STIMULUS1:
        reset <= '0' after 40 ns;
    
    STIMULUS2:
        en <= '1' after 60 ns;
    
    end architecture;
    
        elsif rising_edge(clk) and en = '1' then 
            -- if i = 39 then
            --     i <= 0;
            -- else
            if i /= 39 then  -- added
                i <= i + 1; 
            end if; 
    
        elsif rising_edge(clk) and en = '1' then 
            -- if i = "100111" then
            --     i <= "000000";
            -- else
            if i /= "100111" then  -- added
                i <= i + 1; 
            end if; 
        end if; 
    
    architecture behaviour of con40 is
        constant trainLength:positive:=80;
        signal i:unsigned(6 downto 0):=(others=>'0');
        ...
    begin
        process(reset,clk) is begin 
            if reset then 
                i<=(others=>'0');
                q<='0';
            elsif rising_edge(clk) then
                q<='0';    -- default assignment.
                           -- Defaults to '0' when if-statement fails.
    
                if i<trainLength then
                    i<=i+1;
                    q<=not q;
                end if;
            end if;
        end process;
    end architecture behaviour;
    
    signal i_q: std_ulogic;
    ...
    i_q<=not i_q;  -- use internal signal for logic instead.
    q<=i_q;        -- drive output from internal signal.