6564|6

4

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请教:用VHDL实现计算器的连加连减功能 [复制链接]

我现在在做毕设,实现了单个的加减运算,不能实现连加的,请大家给一个好的思路!有点小问题解决不了!请高手指教啊!
此帖出自FPGA/CPLD论坛

最新回复

程序看的晕晕的 把你自己编程的连加的思路说一下即可 。 关于连加电路的设计,我的思路是: 假设加法器的两个输入分别是A和B,而外部的两个输入分别是M和N,加法器的输出是Q。 再定义一个状态标志FLAG,当加法器有输出是该标志为1,加法器没有输出时为0(同样也是上电复位后的电平值)。 加法器的A输入直接来自外部输入M; 加法器的B输入端口,有些不一样。B的得到是一个二输入的选择器的输出,这个二输入的选择器的两个输入分别是:外部输入信号N和加法器输出信号Q;选择器的控制信号为FLAG标志信号。 我觉得这么做能行 仅供参考。  详情 回复 发表于 2010-5-25 08:56
点赞 关注
 

回复
举报

732

帖子

0

TA的资源

纯净的硅(高级)

沙发
 
楼主把问题描述清楚啊。
连加连减是什么意思?
比如
A + B + C 这样的连加
A - B - C 这样的连减?
此帖出自FPGA/CPLD论坛
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

回复 沙发 tx_xy 的帖子

你好!就是实现1+2+4-1这样的式子,我的程序有些问题不能解决!如果你能帮忙的话,请加我QQ:475943663.非常感谢!
此帖出自FPGA/CPLD论坛
 
 
 

回复

732

帖子

0

TA的资源

纯净的硅(高级)

4
 
你是自己在做加法器么 用硬件电路设计还是语言描述?
我不知道你想要的连加是什么意思 比如1+2+4-1
你是想在一个clk时钟内就完成? 如果是这样的话 你就需要3个加法器同时工作 。
如果不需要在一个clk时间内完成的话,那你可以就用一个加法器按照括号提示的顺序(((1+2)+4)-1)去计算。
此帖出自FPGA/CPLD论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

5
 

回复 4楼 tx_xy 的帖子

天哪!有这么多弯弯啊!用VHDL语言描述,就是平常用的通用计算器一样,实现连续的加减运算,你说的后者的情况!比如12+34+5,先运算12+34=46,再运算46+5=51,中间的46要显示出来!你什么时候在啊?
此帖出自FPGA/CPLD论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

6
 

回复 4楼 tx_xy 的帖子

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

entity cal is
  port(clk:in std_logic;  --输入时钟信号
       num:in std_logic_vector(9 downto 0);--数字按键
       plus:in std_logic;--加法按键
       subt:in std_logic;--减法按键
       mult:in std_logic;--乘法按键
       mdiv:in std_logic;--除法按键
       equal:in std_logic;--等号键
       c:in std_logic;    --清零键,异步置位键
       onum1,onum2,onum3:out std_logic_vector(0 to 6)); --3个七段译码显示管
end cal;


architecture a of cal is

signal flag:std_logic;  --表示是否有是第一个数的输入标识flag
signal fl:std_logic;    --表示是否开始第二个数的标识fl
signal acc:std_logic_vector(7 downto 0):=x"00"; --用于存放第一个数的累加器
signal reg:std_logic_vector(7 downto 0):=x"00"; --用于存放第二个以及以后的数字的寄存器
signal keep:std_logic_vector(7 downto 0);--用于放显示数字的暂存器
signal ans:std_logic_vector(7 downto 0); --用于放各步计算结果的寄存器,不包括除法结果
signal dans:std_logic_vector(3 downto 0);
--用于存放除法结果的寄存器
signal dan:std_logic_vector(3 downto 0);
signal numbuff:std_logic_vector(3 downto 0);--数字缓存
signal vf:std_logic;--表示是否是最后结果的标识
signal strdiv:std_logic;--除法计算开始的信号
signal numclk:std_logic;--将数字想哦那个缓存numbuff放入累加器acc或寄存器reg的信号
signal clear:std_logic; --清零reg中数字的信号
signal inplus:std_logic;
signal insubt:std_logic;
signal inmult:std_logic;
signal inmdiv:std_logic;
signal inequal:std_logic;--同步加减乘除等于信号
signal cou:std_logic_vector(1 downto 0);--用来记忆是第几次计算的信号




component numdecoder is  --引用数字按键的译码电路
   port(reset:in std_logic;
        inclk:in std_logic;
        innum:in std_logic_vector(9 downto 0);
        outnum:buffer std_logic_vector(3 downto 0);
        outflag:out std_logic);
end component;

component display is--引用数字的显示电路
   port(c,clk:in std_logic;
        keep:in std_logic_vector(7 downto 0);
        onum1,onum2,onum3:out std_logic_vector(0 to 6));
end component;


component div is --引用除法器
  port(a:in std_logic_vector(7 downto 0);
       b:in std_logic_vector(3 downto 0);
       clk:in std_logic;
       str:in std_logic;
       s:out std_logic_vector(3 downto 0);
       y:out std_logic_vector(3 downto 0));
end component;

begin
innum1:numdecoder port map (c,clk,num,numbuff,numclk);--按键后产生相对应的数字

pacecal:process(c,clk)--产生同步运算符号
begin
if c='1' then
inplus<='0';insubt<='0';inmult<='0';inmdiv<='0';
elsif clk'event and clk='1' then
    if plus='1' then
          inplus<='1';insubt<='0';inmult<='0';inmdiv<='0';
    elsif subt='1' then
          inplus<='0';insubt<='1';inmult<='0';inmdiv<='0';
    elsif mult='1' then
          inplus<='0';insubt<='0';inmult<='1';inmdiv<='0';
    elsif mdiv='1' then
          inplus<='0';insubt<='0';inmult<='0';inmdiv<='1';
    end if;
end if;
end process pacecal;

ctrflag:process(c,clk)--用于产生flag信号,其实flag也只在整个运算中
--输入第一个数字时flag=0,输完时为1
begin
if c='1' then--异步置位
flag<='0';
elsif clk'event and clk='1' then
     if inplus='1' or insubt='1' or inmult='1' or inmdiv='1' then
     flag<='1';
     else
         flag<='0';
     end if;
end if;
end process ctrflag;

ctrfirstnum:process(c,numclk)--第一个运算数,放入acc中
begin
if c='1' then
acc<="00000000";
elsif numclk'event and numclk='0' then
     if flag='0' then--第一个数正在输入
     acc<=acc+acc+acc+acc+acc+acc+acc+acc+acc+acc+numbuff;--相当于acc<=acc*10+numbuff
     end if;
end if;       
end process ctrfirstnum;

ctrsecondnum:process(c,clk,numclk)--输入第二个数及以后的数,放入reg中
begin
if  c='1' or  clear='1' then
    reg<="00000000";fl<='0';
elsif numclk'event and numclk='0' then
     if flag='1' then
     fl<='1'; --表示正在输入第二个数
     reg<=reg+reg+reg+reg+reg+reg+reg+reg+reg+reg+numbuff;
     end if;   
end if;
end process ctrsecondnum;

ctrclear:process(c,clk)--产生clear信号
begin
if c='1' then
clear<='0';
else
   if inequal'event and inequal='0' then
  
   clear<='1';
   end if;
  

end if;
end process ctrclear;


ctrinequal:process(c,clk)--运算时钟
begin
if c='1' then
inequal<='0';
elsif clk'event and clk='1' then
     if plus='1' or subt='1' or mult='1' or mdiv='1' or equal='1' then
     inequal<='1';
     else inequal<='0';
     end if;
end if;
end process ctrinequal;

ctrcou:process(c,clk)
begin
if c='1' then
cou<="00";
elsif inequal'event and inequal='1' then
     if cou="10" then
         cou<=cou;
     else cou<=cou+1;
     end if;
end if;
end process ctrcou;

ctrcal:process(c,inequal)--下面是运算进程
begin
if c='1' then
    ans<="00000000";
    strdiv<='0';
elsif inequal'event and inequal='1' then
     if flag='1' then
        if inplus='1' then
            if cou="10" then
               ans<=ans+reg;
            else ans<=acc+reg;
            end if;
        elsif insubt='1' then
            if cou="10" then
               ans<=ans-reg;
            else ans<=acc-reg;
            end if;
        elsif inmult='1' then
            if acc<="00001111" and reg<="00001111" then
                  ans<=acc(3 downto 0)*reg(3 downto 0);
            else ans<="00000000";
            end if;
        elsif inmdiv='1' then
             strdiv<='1';
        end if;
     else strdiv<='0';
     end if;

end if;
end process ctrcal;

d1:div port map (acc,reg(3 downto 0),clk,strdiv,dans,dan);

ctrvf:process(c,equal)
begin
if c='1' then
    vf<='0';
elsif equal'event and equal='1' then
    vf<='1';
end if;
end process ctrvf;

ctrkeep:process(c,clk)--用于存放显示数的keep寄存器,时段不同,用于显示不同寄存器的内容
begin
if c='1' then
    keep<="00000000";
elsif clk'event and clk='1' then
    if flag='0' then
        keep<=acc;
    elsif flag='1' and fl='1' and vf='0' then
        keep<=reg;
    elsif flag='1' and fl='0' and vf='0' and cou="10" then
        keep<=ans;
    elsif flag='1' and vf='1' then
       if inmdiv='0' then
           keep<=ans;
       else
           keep(3 downto 0)<=dans;
       end if;
    end if;
end if;
end process ctrkeep;

v1: display port map (c,clk,keep,onum1,onum2,onum3);--调用显示模块,把8位二进制转化为整数

end a;

这是我的实体模块,如果可以请帮忙看一下吧!
此帖出自FPGA/CPLD论坛
 
 
 

回复

732

帖子

0

TA的资源

纯净的硅(高级)

7
 
程序看的晕晕的 把你自己编程的连加的思路说一下即可 。

关于连加电路的设计,我的思路是:

假设加法器的两个输入分别是A和B,而外部的两个输入分别是M和N,加法器的输出是Q。
再定义一个状态标志FLAG,当加法器有输出是该标志为1,加法器没有输出时为0(同样也是上电复位后的电平值)。
加法器的A输入直接来自外部输入M;
加法器的B输入端口,有些不一样。B的得到是一个二输入的选择器的输出,这个二输入的选择器的两个输入分别是:外部输入信号N和加法器输出信号Q;选择器的控制信号为FLAG标志信号。

我觉得这么做能行 仅供参考。
此帖出自FPGA/CPLD论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表