tag 标签: 计算器

相关博文
  • 热度 25
    2014-8-23 21:47
    3024 次阅读|
    1 个评论
    最近在北京至芯科技参加20140712届的FPGA培训,其中夏老师课程的第一个项目就是设计一个基于FPGA的简易计算器,要求能够实现0—999999以内的整数+、-、*、/运算,并支持连续运算(连加、连减、连乘、连除)。接到题目后,我首先对设计需要的硬件进行了初步划分,初步确定了如图(1)所示的板级硬件结构。 图(1)板级硬件结构   当板级硬件结构确定之后,就该设计具体的计算器架构了。这里有两种观点,观点一是由顶自下的设计方式,即先设计顶层模块,然后再一级一级的往下设计。这种设计观念是有着多年丰富工程实践经验的李凡老师所推荐的,另一种观点是我自己的观点,也是结合本设计题目的实际情况,因为系统中涉及到了5个外设硬件模块的驱动,虽然此前还在大学里时已经都做过这些模块的驱动设计,但此次来到至芯科技,我决定还是依照夏老师讲的规范科学的设计方法,重新来设计所有的模块驱动。因为以前自己做的时候,模块设计意识不是很强,设计出来的模块不便于移植,因此,此番重做也是理所应当,既然要设计,就要设计一系列通用性强,便于移植的模块,方便以后使用。于是,接下来的任务,首先就是设计5个硬件模块的驱动。 关于驱动设计的先后顺序,是一个值得思考的地方。数码管设计可以采用仿真加板级验证的方式来设计,数码管模块的仿真比较容易做,也容易验证,led、蜂鸣器的验证就更简单,难点在于按键驱动的验证。因为按键在按下的过程中必然存在抖动,要想能够确保设计的正确性,除了仿真外,实际观察按键效果会是一个更加有效的验证方式。而观察按键效果,可以采用将按键检测模块检测到的按键信息显示在数码管或led上来实现。因此,我在设计的时候,首先设计的是数码管模块。(led模块由于过于简单,实在没必要单独为其建一个模型) 数码管的硬件电路目前在实验室的机器上,暂时没工夫再去绘制一份,所以今天先把代码贴上来,等明天把图弄来了再补上。 以下是代码片段: //数码管扫描模块 module shumaguan(data,i_clk,rst_n,o_seg,o_sel);  input data;  input i_clk;  input rst_n;  output o_seg;  output o_sel;  parameter cnt1_WIDTH = 15;  parameter cnt1_MAX = 24999;  reg cnt1;  reg clk_1K;//扫描时钟,1KHz  reg sel_r;//数码管位选  reg seg_r;//数码管段选  reg disp_data;//单位显示数据缓存  //1KHz时钟分频计数器  always@(posedge i_clk)  begin   if(!rst_n)cnt1=0;   else if(cnt1==cnt1_MAX)cnt1=0;   else cnt1=cnt1+1'b1;  end  //得到1KHz时钟  always@(posedge i_clk)  begin   if(!rst_n)clk_1K=0;   else if(cnt1==cnt1_MAX)    clk_1K=~clk_1K;   else ;  end  //位选信号控制  always@(posedge clk_1K)  begin   if(!rst_n)sel_r=3'd0;   else    if(sel_r == 3'd6)     sel_r=3'd0;    else     sel_r=sel_r+1'b1;  end  //根据不同的数码管位选择不同的待显示数据  always@(*)  begin   case(sel_r)    0:disp_data=data ;    1:disp_data=data ;    2:disp_data=data ;    3:disp_data=data ;    4:disp_data=data ;    5:disp_data=data ;    default :disp_data=4'd0;   endcase  end  //数据译码,将待显示数据翻译为符合数码管显示的编码  always@(disp_data)  begin   case(disp_data)    4'd0:  seg_r=8'hc0;    4'd1:  seg_r=8'hf9;    4'd2:  seg_r=8'ha4;    4'd3:  seg_r=8'hb0;    4'd4:  seg_r=8'h99;    4'd5:  seg_r=8'h92;    4'd6:  seg_r=8'h82;    4'd7:  seg_r=8'hf8;    4'd8:  seg_r=8'h80;    4'd9:  seg_r=8'h90;    4'd10: seg_r=8'h88;    4'd11: seg_r=8'h83;    4'd12: seg_r=8'hc6;    4'd13: seg_r=8'ha1;    4'd14: seg_r=8'h86;    4'd15: seg_r=8'h8e;    default : seg_r=8'hff;   endcase  end  assign o_seg = seg_r;  assign o_sel = sel_r; endmodule   因为今天准备比较仓促,到时很多仿真文件都不在手头,等明天去教室把需要的资料弄好之后再来系统的写。 初次写博客,确实感觉准备不足,不过初稿写了,总会有这样那样的不足,于是就非得去丰富去改正所以,这样下去,我相信,我会很快习惯并爱上写博客的。
  • 热度 4
    2010-3-1 14:55
    2492 次阅读|
    2 个评论
    有时用计算器进行连续计算时,前面经过了多步的连续运算,得到了一个位数很多的数 A 。这时,需要用另外一个数 B 来除以 A 。那么,由于 A 太位数太多了,你不得不把它在另一个地方记起来,然后再用计算器进行 A ÷ B 的运算。但是计算器如果有“反除以”功能和“反除以号”。问题就很简单了。比如把“:”作为“反除以号”,那么, B : A 等于 A ÷ B 。在计算时即可一气呵成。建议把“÷”旋转 90 度后作为“反除以号”。
相关资源