打印

关于VHDL设计可逆计数器的问题

[复制链接]
4147|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
6666lf|  楼主 | 2008-8-11 21:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

刚刚开始接触VHDL,现在也设计一个可逆的计数器,输入是三个按键,一个复位清零,一个增加,一个减少,输出为4位的二进制数
这时我编的代码:

Library IEEE;
Use IEEE.std_logic_1164.All;
Use IEEE.std_logic_unsigned.All;

Entity test is
    port(up,down: in std_logic;
         reset: in std_logic;
         Q: buffer std_logic_vector(3 downto 0));
end Entity test;

Architecture art of test is
    begin
    process(up,reset)is
        begin
            if reset='0' then
                Q<="0000";
            elsif(up'event and up='1') then
                if Q=9 then                            Q<="0000";
                else Q<=Q+1;
                end if;
            end if;
    end process;
    process(down,reset)is
        begin
                 if reset='0' then
                Q<="0000";
            elsif(down'event and down='1') then
            if Q=0 then                            Q<="1001";
            else Q<=Q-1;
            end if;
            end if;
        end process;    
end Architecture art;

编译的时候提示错误如图
请教高手如何解决?不胜感激!
VHDL语言感觉好别扭啊!

相关帖子

沙发
mr.king| | 2008-8-11 21:05 | 只看该作者

物理结构上,计数器是DFF做的,DFF只有一个时钟端

没法综合出两个时钟的

使用特权

评论回复
板凳
6666lf|  楼主 | 2008-8-11 21:54 | 只看该作者

那楼上前辈,我应该怎么处理?

我应该怎么来设计这个计数器比较好?您给指点一下思路吧

使用特权

评论回复
地板
6666lf|  楼主 | 2008-8-12 10:27 | 只看该作者

谢谢

谢谢前辈指点!
我好好学一下!谢谢!=^_^=

使用特权

评论回复
5
6666lf|  楼主 | 2008-8-14 09:34 | 只看该作者

反馈

这几天又郁闷了,按照qinxg前辈的方法做,编译能通过只有一个警告,但是仿真没有结果
我自作主张将variable改成了signal,结果出来了
不过没有弄明白怎么回事,希望通过慢慢学习,会领会VHDL的!

使用特权

评论回复
6
birenai| | 2008-8-15 17:25 | 只看该作者

应该是对时钟进行加减的

我没学过VHDL,但我看LZ的程序似乎是在对UP和DOWN进行加减的。LS的说的没错,要加个时钟,但我跟他的思想不同,我是让时钟和复位信号为敏感信号,在进程中判断UP和DOWN那个有效,根据状态进行是加还是减。

使用特权

评论回复
7
birenai| | 2008-8-15 17:34 | 只看该作者

不好意思,上面我晕头了

是对UP和DOWN进行计算的,LZ没错。编译出错的原因就该是Q这个变量不能在两个进程中进行赋值,必须放在一个进程中。

使用特权

评论回复
8
wildcat| | 2008-11-5 16:36 | 只看该作者

双时钟

今天刚好在写74ls192,
你遇到的问题是在同一端口,可能出现两次(种)赋值吧

ps我打算用两个文件来做,一个加,一个减,最后在原理图编辑中生成顶层文件,不知道行不行。待会结果出来就来说一嗓子

使用特权

评论回复
9
liuts0129| | 2008-11-7 19:41 | 只看该作者

其实还有更简单的实现方法

其实还有更简单的实现方法,用UP和DOWN启动加减计数器,计数结果相加
程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY counter_up_down IS
 PORT(
       UP,DOWN : IN STD_LOGIC;
       res_n   : IN STD_LOGIC;
       dout    : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END;
ARCHITECTURE bhv OF counter_up_down IS 
SIGNAL up_cnt,down_cnt,cnt : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN

cnt<=up_cnt+down_cnt;--加减计数相加为结果
dout<=cnt;

PROCESS(res_n,UP)--加计数器
BEGIN

IF res_n='0' THEN
   up_cnt<="0000";
ELSIF UP'EVENT AND UP='1' THEN
  IF cnt<15 THEN
   up_cnt<=up_cnt+1;
  END IF;
END IF;

END PROCESS;

PROCESS(res_n,DOWN)--减计数器
BEGIN

IF res_n='0' THEN
   down_cnt<="0000";
ELSIF DOWN'EVENT AND DOWN='1' THEN
  IF cnt>0 THEN
   down_cnt<=down_cnt-1;
  END IF;
END IF;

END PROCESS;

END bhv;

使用特权

评论回复
10
g19860529| | 2008-11-9 13:21 | 只看该作者

这个是我编的,感觉句法上还是比较精炼的,哈哈,,嚣张

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

entity addsub is
port(
    clk,rst : in std_logic;
    sel : in std_logic_vector(1 downto 0);
    q : out std_logic_vector(3 downto 0));
end addsub;

architecture rtl of addsub is
begin
    process(clk,rst,sel)
    variable tmp : std_logic_vector(3 downto 0);
    begin
        if clk'event and clk='1' then
            if rst='1' then
                tmp := "0000";
            else
                case sel is
                    when "01" =>   if tmp = "1001" then
                                        tmp := "0000";
                                    end if;
                                    tmp := tmp + 1;
                    when "10" =>    if tmp = "0000" then 
                                        tmp := "1001";
                                    end if;
                                    tmp := tmp - 1;
                    when others => null;
                end case;
                q <= tmp;
            end if;
        end if;
    end process;
end rtl;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

16

帖子

0

粉丝