VHDL如何编写代码消除竞争与冒险(毛刺)

题目描述

编写一个十进制加法器,为上升沿触发一次加法,输出每五次翻转一次方向。

产生毛刺的程序

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY fractional_frequency IS
	PORT(
		CLKIN: IN BIT;
		CLKOUT: OUT BIT
	);
END;

ARCHITECTURE bhv OF fractional_frequency IS
	SIGNAL A: INTEGER RANGE 0 to 15;
BEGIN

PROCESS(CLKIN) BEGIN
	IF (CLKIN'EVENT AND CLKIN='1') THEN
		IF (A < 9) THEN 
			A <= A + 1;
		ELSE
			A <= 0;
	    END IF;
	END IF;	
	
	IF (A < 5) THEN 
		CLKOUT <= '1';
	ELSE
		CLKOUT <= '0';
	END IF;   	
END PROCESS;

END bhv;

输出波形为
(上面为CLKIN,下面为CLKOUT)

明显可见,在CLKOUT为低电平时,出现了竞争与冒险的情况,

竞争与冒险发生的原因

  • 这里为什么会出现竞争与冒险呢?:

    在CLKOUT为低电平时,A的值大于等于5,假如在第六个上升沿触发时,A做加法运算,A的值由0101,变成了0110,在变化过程中,0101的低2位由01变成了10,从而使得A的值由5变成了6,但是0101的低2位不会同时翻转(由于电流通过不同的电路的时间可能不同),有可能是第0位的1先变成0,也有可能是第1位的0现变成1,如果是第0位的1先变成0,则A的值先变成了0100,由于A小于5,CLKOUT为高电平,但是A的第1位很快就由0变成1,A的值又变成了0110,A大于5,又变成了低电平,由于第0位和第1位变化的时间间隔很短,所以高电平的时间很短,只是在一瞬间发生了翻转,所以出现如图箭头所示的毛刺,其他毛刺原理相同。

那么我们如何在这一题上解决竞争与冒险呢?

修改程序,消除毛刺。

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY fractional_frequency IS
	PORT(
		CLKIN: IN BIT;
		CLKOUT: OUT BIT
	);
END;

ARCHITECTURE bhv OF fractional_frequency IS
	SIGNAL A: INTEGER RANGE 0 to 15;
BEGIN

PROCESS(CLKIN) BEGIN
	IF (CLKIN'EVENT AND CLKIN='1') THEN
		IF (A < 9) THEN 
			A <= A + 1;
		ELSE
			A <= 0;
	    END IF;
	END IF;	
END PROCESS;
	
PROCESS BEGIN	          
	wait until CLKIN='1'; -- VHDL要求当进程语句中使用wait语句后,就不必列出敏感信号
	IF (A < 5) THEN       -- 含义是:如果CLKIN还不是1,CLKOUT就保持原值不变,直到CLKIN等于1时才对CLKOUT赋值更新
		CLKOUT <= '1';
	ELSE
		CLKOUT <= '0';
	END IF;   	
END PROCESS;

END bhv;


上图可见毛刺消失。

方法2

使组合逻辑电路变成时序逻辑电路

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity half is
	port (clkin: in std_logic;
		  clkout: out std_logic );
end;

architecture bhv of half is
	signal A: integer range 0 to 15;
begin

process(clkin) begin

	if clkin'event and clkin='1' then
		if A<9 then
			A <= A + 1;
		else
			A <= 0;
		end if;
		
		if A<5 then
			clkout <= '1';
		else
			clkout <= '0';
		end if;
	end if;
end process;
end bhv;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值