基于logisim的运动码表设计

运动码表属于一个小型的数字系统,既然是基于logisim的设计,自然是全部用原理图方式实现的。我觉得虽然业界HDL的设计方式很常见,但是基于原理图的设计经过这个项目以后我认为算是一个基本功,基于原理图设计可以大大加深对数字电路底层的认知,使你的verilog似乎有了灵魂,也算是一种“内功修炼”吧。
总结出来以下几点:

  1. 数字系统一定要模块化设计
  2. 设计流程: 设计需求分析(外部数据,控制输入,输出,显示)-> 拆分为功能模块 -> 功能模块的数据通路(此时不考虑控制信号,只要数据链路通了就行)-> 构建控制单元(如何从外部控制输入转化到内部的控制信号)。
    以上需要注意的是尽量设计moore型电路,输出只与状态有关;melay型电路属于异步电路了。

这个题目来自华科的谭志虎老师MOOC第二章,强烈推荐大家去看一下。
需求分析

模块划分:

首先码表的计数功能得有,你得有从0 - 9999的BCD计数器
接着从数字到数码管的显示,你需要数码管显示驱动
store是存储的功能,需要寄存器;尝试更新记录那么肯定就需要数据,那么比较器不可少;另外数码管显示驱动有两个数据来源:BCD计数器和寄存器,需要一个MUX。汇总列个表:
在这里插入图片描述

模块实现

时间计数器

BCD计数器一共有4位,每位都是0到9。 用verilog写so easy,那基于原理图的设计呢?BCD计数器是一个状态机!
verilog里面三段式状态机:产生次态,产生输出,状态切换。
原理图设计时一模一样,10个状态0-9,状态编码0000-1001(对应verilog parameter);求状态转换方程组(对应verilog case)和输出方程组(对应verilog 三段式写在最后的产生输出);说到这里数字电路基础好一些的应该都知道怎么设计了,直接上图:
在这里插入图片描述
1位的BCD计数器做好了,设计的时候添加了en和carry位,每当计数到9的时候carry=1,注意moore电路输出只与状态有关,所以carry=1会维持计数 = 9整个状态! carry用于多位BCD计数器级联!
4位的怎么做呢?
能carry接下一级的clk吗?不能!因为那样的话下一级刚到9,上一级就会加1,举个例子,你会看到 09 直接到19的现象!
应该是carry接下一级的en,但是这洋还有问题,4个BCD计数器位3,2,1,0。这样做第0位到第1位没问题,当你计数到90,你会发现你的位2也开始加了,这很显然是不正确的!
位2的en需要用位1和位0过与门得到!位3同理!如下图:
在这里插入图片描述
时间计数器设计完毕!

数码管驱动

数码管驱动是将数字0-9转化为数码管的 0 - 9 输出;
数码管元件有a - g七根管加一个小数点共8位输入! 小数点可以单独处理,我们设计驱动电路的时候4输入,7输出即可,纯组合逻辑;
在logisim中可以借助真值表自动生成组合逻辑电路,在logisim里面把真值表填完就行了,每一个输入数字对应一个数码管图形!
组合电路非常庞大, 就不放啦,也没啥好看的。
在我们的数字系统中,需要有16位的输入(4乘4),32位输出(4*7 + 4个小数点,只有第3位的数码管需要小数点),如下图:
在这里插入图片描述

16位寄存器

其实就是16个 D触发器 并联(我见过挺多并联级联混用的,我很反对),不过为了画图方便一些,也体现出模块化设计思想;分成4 组4位寄存器即可;
如下图:
在这里插入图片描述

16位无符号数比较器

这里也分成4组 4位无符号数比较器 来进行设计;
4位无符号数比较器设计 基于 logisim自带组件 1位无符号数比较器来设计。
如下图:
在这里插入图片描述
注意一下great,equal,less的逻辑即可,不算难。
16位的无符号数比较器的图其实就是把上面那个图的一位比较器换成4位比较器,其他部分不变,如下图:
在这里插入图片描述

MUX

1位的MUX如下图:
在这里插入图片描述
logisim中的逻辑门是支持多位宽的,例如与门都是16位输入是可以的;
这里可以直接修改与门的位宽吗?不可以,因为sel只有1位,不可以将1位的sel输入16位的逻辑与门。不过现实中的逻辑与门器件并不支持多位宽。
基于1位MUX构建16位MUX,就直接上图了:
在这里插入图片描述

模块封装图

基本模块都是实现了的,以前数电老师说数电就像下围棋,现在总算有点感觉了!用基本模块去搭建数据通路!!
放一下模块封装图:
在这里插入图片描述

数据通路构建

根据你的功能把总体的数据通路给构建出来,把每个部件的数据来源想清楚!!!
构思一下:计数器在不停地加1,数据可以直接给到码表驱动吗?不合适,因为码表驱动还需要接受来自寄存器的数据;明显就需要加入MUX了;
store的功能需要仔细想想,在没有计数的情况下直接store应该显示99.99,在有计数的情况下应该更新记录并且显示,可以肯定的是寄存器的数据来源肯定得有99.99,也得有计时器;
更新记录的实现方式为,将store的输入和计时器输入送入比较器,得到小于输出时,将寄存器的使能打开,否则不打开即可实现更新。
总体框图如下:
在这里插入图片描述

控制单元构建

控制单元将外部的输入转换为内部的控制信号,是整个设计里面最难的部分;先放一个框图:
在这里插入图片描述
控制单元本质上也是一个状态机,而且要设计成moore型的,输出只与状态有关;那都有哪些状态?状态直接怎么切换?状态有对应着什么输出呢?
我经过反复思索,觉得状态的规划通过输出来进行确定,一个输出对应一个状态,输入导致了状态的切换,这是一个整体构思的过程,就像列写状态转换图一样。
复位后的状态作为起始态,每个输入都会切换状态;不过这里输入太多(我们经常写的序列检测器只有0/1两种输入,这里有5个输入),每个输入产生一个次态,次态之后又接受输入产生次态,能把人给绕晕了,所以要进行状态切换的简化,我手写了一份状态转换/输出表,也算是状态规划表吧:
在这里插入图片描述
可以看到我一共规划了7个状态,编码0到6,为什么会有这些状态?完全从输出出发!,一个状态对应一个输出!
举例说明:RST状态下,五个输入分别为 0 1 1 1 0;一旦收到start,应当把RST变0,TMen变1,输出变化了,就算下一个状态,命名为状态1;同理,收到store,显示99.99,对应5个输入为 1 1 1 0 0,命名为状态2;
有人会问,假如状态0收到stop怎么处理,我的做法是这个算当前状态下的无效输入,不处理,保持原来的状态,通过这种做法可以大大减少状态的数量。
在1态下(start计数状态),只认识stop(收到stop进入3态)和rst,其他保持原态;
在2态下(store状态,显示99.99),只认识start和rst,其他保持原态;
这个4态是干什么的? 4态是 0 1 1 1 1,用于start清0,因为注意需求那里有一个start的清零效果,4态会自动跳到1态(收到rst还是跳0),4态只会维持一个时钟周期。
在3态下(start -> stop状态),可以start,进入4态;可以store,下面就要判断NewRecord了(通过比较器产生),有New信号,打开寄存器使能SDen,否则关闭,分别对应5态和6态;
5,6两个只认为start和rst有效;

码表控制器还是一个三段式状态机,具体如下:
在这里插入图片描述
我起初很郁闷状态转换单元为什么会有8个输入? 因为状态机需要状态反馈! 数电老师以前讲过,时序电路需要反馈!可惜当初只随意听了听,我看那个8输入愣了好久,实在是惭愧,惭愧,惭愧。
我又手写了一份状态转换表帮助理解:
在这里插入图片描述
产生输出的组合逻辑并不难,用卡诺图用真值表都行;
产生次态的组合逻辑8输入,3输出,真值表有2^8 = 256行,我是一行一行填的,说多了都是泪(logisim有真值表产生组合逻辑的功能);
真值表有含RST的128行直接归0,4态会直接跳1态(除非RST),无效输入保持原来的状态,真正有效的行数没有多少
这里写一段verilog感叹verilog大法好(就写个梗概意思,状态切换部分简单明了太多了):

reg [2:0] state,nextstate;
parameter S0=3'b000,S1=3'b001,S2=3'b010,S3=3'b011;
parameter S4=3'b100,S5=3'b101,S6=3'b110;

always@(posedge clk or posedge rst)
	if(rst) state <= S0;
	else state <= nextstate;

always@(state or start or stop or store or rst or NewRecord)
begin
	case(state)
	S0: 
		begin
			if(rst)
				nextstate = S0;
			else if(start)
				nextstate = S1;
			else if(store)
				nextstate = S2;
			else 
				nextstate = S0;
		end
	S1: 
		begin
			if(rst)
				nextstate = S0;
			else if(stop)
				nextsate = S3;
			else
				nextstate = S1;
		end
	S2:
		begin
			if(rst)
				nextstate = S0;
			else if(start)
				nextstate = S4;
			else
				nextstate = S2;
		end
	S3:
		begin
			if(rst)
				nextstate = S0;
			else if(start)
				nextstate = S4;
			else if(store)
				begin
					if(NewRecord)
						nextstate = S5;
					else 
						nextstate = S6;
				end
			else
				nextstate = S3;
		end
	S4:
		begin
			if(rst)
				nextstate = S0;
			else 
				nextstate = S1;
		end
	S5:
		begin
			if(rst)
				nextstate = S0;
			else if(start)
				nextstate = S4;
			else 
				nextstate = S5;				
		end
	S6:
		begin
			if(rst)
				nextstate = S0;
			else if(start)
				nextstate = S4;
			else 
				nextstate = S6;				
		end
	default: nextstate = S0;
	endcase
end 

总结

以上就是运动码表设计的全部,有兴趣探讨的同学可以私聊我或者直接评论,我就把的circ文件直接上传到CSDN 资源吧,链接如下:
运动码表circ

  • 31
    点赞
  • 211
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
针对运动码表设计题目,首先需要了解码表的基本设计要求和功能需求。 1. 组件设计运动码表主要包括显示屏、计时器、操作按钮和电源开关等功能组件。可以考虑使用LCD显示屏,它具有较大的显示面积和清晰度,便于用户观察和操作。 2. 计时功能:码表需要具备准确的计时功能,包括秒表、倒计时和计次等功能。秒表功能可通过记录开始和结束时间来计算耗时,倒计时功能则可以设置预定的时间段,提醒用户进行活动。 3. 操作按钮:码表应配备易于操作的按钮,例如开始、暂停和重置按钮,用户通过简单的点击操作即可控制计时器的启动、暂停和复位。 4. 记录历史数据:码表可以记录运动者过去的活动时间和成绩,以便用户随时查阅和对比。可以将这些数据保存在内部存储器或外部存储器中,方便用户管理。 5. 电源管理:为了保障码表的正常运行,应设计适当的电源管理系统,包括低电量提醒和省电模式等功能。 6. 用户友好性:在设计过程中,需要考虑用户的使用习惯和操作起来的便利性。应该尽量减少复杂的操作流程,提供直观的界面和提示信息,以方便用户的使用。 基于上述设计要求和功能需求,可以开始设计运动码表,包括硬件和软件两个层面。硬件设计需要选用合适的组件并搭建电路板,而软件设计则需要实现使用者与运动码表之间的交互界面和功能逻辑。这两个部分需要紧密配合,以确保码表满足用户需求。 最后,为了提高设计的质量和性能,可以进行一些功能的扩展和优化。例如,添加数据分析功能,帮助用户了解自己的运动情况和进步程度。此外,还可以考虑码表与手机或其他设备的连接,方便记录和分享运动数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值