如何生成脉冲序列以通用方式提供输出? [英] How can i generate a pulse train to give output in common way?

查看:202
本文介绍了如何生成脉冲序列以通用方式提供输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on generating a 40 bit length pulse train. I also must be able to adjust the frequency. I tried to make a new low frequency clock and i make a new counter which counts on it's rising edges and give an high output and terminating after 40 bit. It's not working. I tried some other methods. They are not, too.

例如;

    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;

此代码中有32位长度,但我想制作40位,但无论如何,这不是工作也是。我认为这种脉冲序列的方法必须是常见的,并且它们被广泛使用。但是嘿!不幸的是,我找不到任何有用的东西。

There is 32-bit length in this code but i wanna make 40 bit but whatever, this is not working too. I think methods for such a pulse train must be common and they are being used widely. But hey! unluckily i can find nothing useful.

推荐答案

我冒昧地移动了 en 重置到端口信号,也将常量更改为可识别的40位值,并指定范围使其成为局部静态常量。

I took the liberty of moving en and reset to port signals, also changed your constant to a recognizable 40 bit value, and specified the range to make it a locally static constant.

您的计数器的问题在于它不足以解决40位问题。你有 i 指定为5位值,而40位需要6位计数器。

The issue with your counter is that it isn't big enough to address 40 bits. You have i specified as a 5 bit value while 40 bits requires a 6 bit counter.

我还添加了一个第二种架构,i为整数型信号。使用 i 作为无符号值或整数类型,您可能需要在39( i 计数器上滚动code>100111)当第一个位置为0(000000)时。

I also added a second architecture here with i as an integer type signal. With i as either an unsigned value or an integer type you likely need to roll over the i counter at 39 ("100111") when the first position is 0 ("000000").

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;

我还做了一个快速而肮脏的测试平台:

I also did a quick and dirty test bench:

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;

这可以证明正确的输出:

Which can demonstrate the correct output:

回复评论问题的附录

模式 XFEEDFACEDB长40位,取代了常量s的32的全'1值来证明你实际上是在处理 s 数组值的各个元素。

The pattern X"FEEDFACEDB" is 40 bits long and was substituted for the 32 all '1's value for constant s to demonstrate that you are actually addressing individual elements of the s array value.

要停止重复出现的脉冲序列:

To stop the pulse train fro recurring:

对于架构 foo (使用整数类型 i ):

For architecture foo (using an integer type for i):

    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; 

这会使计数器在达到39时停止运作。

This stops the counter from operating when it reaches 39.

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

For architecture behave (using an unsigned type for i):

    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; 

两种体系结构的行为完全相同,停止 i 计数器在39(100111)。

Both architectures behave identically stopping the i counter at 39 ("100111").

通过模拟可以显示计数器已停止:

The counter can be shown to have stopped by simulating:

无需添加额外的控件输入即可获取第二次发生的脉冲流是通过调用重置。

Without adding an additional control input the only way to get the pulse stream to occur a second time would be by invoking reseet.

这篇关于如何生成脉冲序列以通用方式提供输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆