If statement 如何生成一个脉冲序列,以普通方式输出?
我正在研究生成一个40位长的脉冲序列。我还必须能够调整频率。我试着做一个新的低频时钟,我做了一个新的计数器,它的上升沿计数,并提供高输出,在40位后终止。它不起作用了。我尝试了一些其他的方法。他们也不是 比如,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
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.