这两个VHDL的问题终于解决了!

这个星期做EDA的课程设计,终于得用VHDL写一些东西了,而不仅仅是实验课的时候那样十几行就能解决了。

写长一点的时候,发现两个相当棘手的禁令啊:

1、一个进程内不能进行两次边沿检测。

2、不同进程不能对同一信号进行赋值。

正因为这两条“禁令”,让本来看上去很简单的东西搞得我焦头烂额了。

于是,我打算把事情简单化,做了两个这样的练习:

1、两个按键,分别控制一个值的加和减。(这个主要是为了解决“禁令1”)

2、一个按键,按下按键输出一个固定时间脉冲。(解决“禁令2”)

我先做的是第二个练习。如果没有禁令,我的想法是,一个进程内检测到按键信号上升沿的时候对信号A写‘1’,然后另外一个进程检测到信号A为‘1’时开始用时钟信号计时并输出,到时间后对这个信号A写‘0’。看上去十分简单,天衣无缝,但是因为“禁令2”,这个简单的方法不能实现。

我的解决方法是用了两个信号,并且还有优先级的区别:

 1 Library IEEE;
 2 Use IEEE.STD_LOGIC_1164.ALL;
 3 
 4 Entity KeyClk Is
 5     Port(
 6     clk:in std_logic;
 7     c_in:in std_logic;
 8     c_out:out std_logic
 9     );
10 End;
11 
12 Architecture one of keyclk is
13     signal out_flag,stop_flag:std_logic;
14     begin
15     
16     
17     process(c_in,out_flag)
18         begin
19         if c_in='1' then
20             out_flag<='1';    
21         elsif stop_flag='1' then
22             out_flag<='0';
23         end if;
24     end process;
25     
26     c_out<=in_flag;
27     
28     process(clk,in_flag)
29         variable cnt:integer range 0 to 100;
30         begin
31         if rising_edge(clk) then
32             if out_flag='1' then
33                 stop_flag<='0';
34                 if cnt<5 then
35                     cnt := cnt+1;
36                     
37                 else
38                     cnt := 0;
39                     stop_flag<='1';
40                 end if;
41             end if;
42         end if;
43     end process;
44 end;

第二个练习是这样的,貌似有点纠结:

 1 library ieee;
 2 use ieee.std_logic_1164.all;
 3 use ieee.std_logic_unsigned.all;
 4 
 5 entity twokey is
 6     port(
 7     clk:in std_logic;
 8     key1,key2:in std_logic;
 9     key_rst:in std_logic;
10     qout:out std_logic_vector(7 downto 0)
11     );
12 end entity;
13 
14 architecture one of twokey is
15         signal key1_down,key2_down:std_logic;
16         signal qout2:std_logic_vector(7 downto 0);
17     begin
18     process(key1,key2,key_rst,clk)
19         begin
20         if rising_edge(clk) then 
21             if key_rst='1' then
22                 qout2<=(others=>'0');
23             else
24                 if key1='1' and key1_down='0' then
25                     key1_down<='1';
26                     qout2<=qout2+'1';
27                 elsif key1='0' then
28                     key1_down<='0';
29                 end if;
30                 if key2='1' and key2_down='0' then
31                     key2_down<='1';
32                     qout2<=qout2-'1';
33                 elsif key2='0' then
34                     key2_down<='0';
35                 end if;
36             end if;
37         end if;
38     end process;
39     qout<=qout2;
40 end;
原文地址:https://www.cnblogs.com/fwindpeak/p/3118457.html