Triggers 基于触发信号的单时钟周期脉冲
我正在制作一个midi接口。UART工作正常,它向控制单元发送8位消息和标志。当标志变高时,该装置将把信息存储在寄存器中,并使clr_标志变高,以便再次将UART标志设置为低。问题是我不能使这个clr_标志长一个周期。我需要它是一个周期长,因为这个信号还控制一个状态机,它指示正在存储什么类型的消息,例如note\u on->key\u note->velocity 我这里的问题是,在这种情况下,信号标志如何仅触发一个时钟周期的脉冲?我现在所做的几乎是在一个时钟周期内产生一个脉冲,但我做了两次,因为标志还没有变成0。我尝试了很多方法,现在我有了:Triggers 基于触发信号的单时钟周期脉冲,triggers,vhdl,clock,pulse,Triggers,Vhdl,Clock,Pulse,我正在制作一个midi接口。UART工作正常,它向控制单元发送8位消息和标志。当标志变高时,该装置将把信息存储在寄存器中,并使clr_标志变高,以便再次将UART标志设置为低。问题是我不能使这个clr_标志长一个周期。我需要它是一个周期长,因为这个信号还控制一个状态机,它指示正在存储什么类型的消息,例如note\u on->key\u note->velocity 我这里的问题是,在这种情况下,信号标志如何仅触发一个时钟周期的脉冲?我现在所做的几乎是在一个时钟周期内产生一个脉冲,但我做了两次,因
get_data:process(clk, flag)
begin
if reset = '1' then
midi <= (others => '0');
clr_flag <= '0';
control_flag <= '0';
elsif ((clk'event and clk='1') and flag = '1') then
midi <= data_in;
clr_flag <= '1';
control_flag <= '1';
elsif((clk'event and clk='0') and control_flag = '1') then
control_flag <= '0';
elsif((clk'event and clk='1') and control_flag = '0') then
clr_flag <= '0';
end if;
end process;
这个双脉冲或大于一个周期脉冲的问题在此之前,我有一个东西使clr_标志成为两个周期的clk脉冲,就是系统将经历两种状态,而不是每个标志一种状态
简言之:当一个信号变高而与变低无关时,应在一个时钟周期内产生一个脉冲
感谢您的帮助。要使设计只针对一个周期,有几个问题需要解决 脉冲使用触发器寄存器 首先,通常通过VHDL构造在硬件中使用触发器 遵循如下结构:
process (clk, reset) is
begin
-- Clock
if rising_edge(clk) then
-- ... Flip flops to update at rising edge
end if;
-- Reset
if reset = '1' then
-- Flip flops to update at reset, which need not be all
end if;
end process;
因此,get_数据过程应相应更新,因此:
灵敏度列表应仅包含时钟时钟和复位
带有if on事件的嵌套结构应如上所述
只应使用clk的上升沿,因此不对clk='0'进行检查
当clr_标志变高时,可使用
标志上的同步“0”到“1”检测器,使用的标志版本为
延迟一个周期,称为下面的flag_ff,然后检查flag=
1和标志_ff='0'
生成的代码可能如下所示:
get_data : process (clk, reset) is
begin
-- Clock
if rising_edge(clk) then
flag_ff <= flag; -- One cycle delayed version
clr_flag <= '0'; -- Default value with no clear
if (flag = '1') and (flag_ff = '0') then -- Detected flag going from '0' to '1'
midi <= data_in;
clr_flag <= '1'; -- Override default value making clr_flag asserted signle cycle
end if;
end if;
-- Reset
if reset = '1' then
midi <= (others => '0');
clr_flag <= '0';
-- No need to reset flag_ff, since that is updated during reset anyway
end if;
end process;
产生单周期脉冲的诀窍在于认识到,产生脉冲后,只要触发器输入高,就必须等待,然后才能返回开始。基本上,您正在构建一个非常简单的状态机,但是只有两个状态,您可以使用简单的布尔值来区分它们 Morten关于需要采用一种标准模式来实现计时流程的观点是正确的;我选择了另一个同样有效的
get_data:process(clk, reset)
variable idle : boolean;
begin
if reset = '1' then
idle := true;
elsif rising_edge(clk) then
clr_flag <= '0'; -- default action
if idle then
if flag = '1' then
clr_flag <= '1'; -- overrides default FOR THIS CYCLE ONLY
idle <= false;
end if;
else
if flag = '0' then
idle := true;
end if;
end if;
end if;
end process;
下面是从至少持续一个时钟周期的信号flag1创建正好持续一个时钟周期的信号flag2的方法
我不使用VHDL编程~以下是我通常在Verilog中为相同建议所做的:
always @(posedge clk or negedge rst) begin
if(~rst) flgD <= 1'b0;
else flgD <= flg;
end
assign trg = (flg^flgD)&flgD;
我是verilog新手,这是用于触发的示例代码。希望这能达到你的目的。您可以在VHDL中尝试相同的逻辑
module main(clk,busy,rd);
input clk,busy; // busy input condition
output rd; // trigger signal
reg rd,en;
always @(posedge clk)
begin
if(busy == 1)
begin
rd <= 0;
en <= 0;
end
else
begin
if (en == 0 )
begin
rd <= 1;
en <= 1;
end
else
rd <= 0;
end
end
endmodule
下面的verilog代码应精确保存一个时钟周期的信号值
module PulseGen #(
parameter integer BUS_WIDTH = 32
)
(
input [BUS_WIDTH-1:0] i,
input clk,
output [BUS_WIDTH-1:0] o
);
reg [BUS_WIDTH-1:0] id_1 = 0 ;
reg [BUS_WIDTH-1:0] id_2 = 0 ;
always @(posedge clk)begin
id_1 <= i;
id_2 <= id_1;
end
assign o = (id_1 & ~id_2);
实现这一点的方法是创建一个去抖动电路。如果您需要一个D触发器从0变为1,仅针对第一个时钟,只需在其输入之前添加一个与门,如下图所示: 这里你们可以看到一个D触发器和它的去盎司电路 p.S.电路使用。同步和FSM边缘检测创建 当检测到这些事件时,上升、边缘和下降输出将选通一个周期。输入和输出是同步的,用于有限状态机 实体同步器 通用的 REG_SIZE:natural:=3-同步寄存器中的默认位数。 ; 港口城市 时钟:标准逻辑; 复位:在标准逻辑中; 异步_-in:in标准_逻辑:='0'; 同步输出:输出标准逻辑:='0'; 上升输出:输出标准输出逻辑:='0'; fall_out:out标准逻辑:='0'; 边缘输出:输出标准逻辑:='0' ; 终止 SynchronizerBIT的架构V1是 常量MSB:natural:=REG_SIZE-1; 信号同步:标准逻辑向量降到0:=其他=>0; 别名sync_in:std_逻辑为sync_regMSB; 信号上升、下降、边缘、上一次同步:标准逻辑:='0'; 开始 资产注册大小>=2报告注册大小应>=2。严重错误; 进程时钟,重置 开始 如果重置,则 同步注册“0”;
在上一篇文章中,我只开始学习vhdl,这对我来说有一些魔力,这就是我在评论中回答的原因。尝试从elsif中删除clk事件。有时这对我很有帮助。我相信你只需要两个状态机,因为低位是空闲状态。显式显示两个状态不是更好,而不是使用idle和not idle吗?@Ayubbargach你可以,但在什么意义上更好?如果您查看布尔类型的定义,您将看到一个具有两个值的枚举类型;形式相同,只是名称不同。你在哪里声明了clr_标志和标志变量?@Unknown123它们不是变量,我只是假设了问题中的声明。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--input of minimum 1 clock pulse will give output of wanted length.
--load number 5 to PL input and you will get a 5 clock pulse no matter how long input is.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all ;
entity fifth is
port (clk , resetN : in std_logic;
pdata : in integer range 0 to 5; --parallel data in. to choose how many clock the out pulse would be.
din : in std_logic;
dout : out std_logic
) ;
end fifth ;
architecture arc_fifth of fifth is
signal count : integer range 0 to 5;
signal pl : std_logic; --trigger detect output.
signal sample1 : std_logic;
signal sample2 : std_logic;
--trigger sync proccess.
begin
process(clk , resetN)
begin
if resetN = '0' then
sample1<='0';
sample2<='0';
elsif rising_edge(clk) then
sample1<=din;
sample2<=sample1;
end if;
end process;
pl <= sample1 and (not sample2); --trigger detect output. activate the counter.
--counter proccess.
process ( clk , resetN )
begin
if resetN = '0' then
count <= 0 ;
elsif rising_edge(clk) then
if pl='1' then
count<=pdata;
else
if count=0 then
count<=count;
else
count<=count-1;
end if;
end if;
end if ;
end process ;
dout<='1' when count>0 else '0';--output - get the wanted lenght pulse no matter how long is input
end arc_fifth ;