北航计算机组成原理课程设计-2020秋 PreProject-Logisim-Logisim仿真与调试&应用与挑战

北航计算机学院-计算机组成原理课程设计-2020秋

PreProject-Logisim-Logisim仿真与调试&应用与挑战


本系列所有博客,知识讲解、习题以及答案均由北航计算机学院计算机组成原理课程组创作,解析部分由笔者创作,如有侵权联系删除。


从本节开始,课程组给出的教程中增添了很多视频讲解。为了避免侵权,本系列博客将不会搬运课程组的视频讲解,而对于文字讲解也会相应地加以调整,重点在于根据笔者自己的理解给出习题的解析。因此带来的讲解不到位敬请见谅。


Logisim仿真

当搭建好一个时序电路后,我们可以使用菜单栏里Simulate中的选项来帮助我们对电路进行仿真。选中其中的Ticks Enable后,可以使时钟自动地周期性变化。如果你觉得时钟变化太快或太慢,可以修改Tick Frequency选项来修改时钟变化周期。

另外,在仿真前一定记得要选中Simulation Enable,否则电路不会进行仿真。

在这里插入图片描述

快捷键的使用

熟练使用相关快捷键能带给电路调试很大的便利。对于 Clock 元件,使用哪个快捷键能使其电位改变一次?

A. Ctrl + T

B. Ctrl + R

A. Ctrl + K

A. Ctrl + I

答案:A. Ctrl + T

使用哪个快捷键能使电位连续改变?

A. Ctrl + T

B. Ctrl + R

A. Ctrl + K

A. Ctrl + I

答案:C. Ctrl + K

在这里插入图片描述
如上图,打开Simulate就可以查看到仿真功能中对应功能的快捷键。Tick Once改变一次电位使用Ctrl+T,Ticks Enabled连续改变电位使用Ctrl+K。


Step Simulation

Simulate菜单中有一项Step Simulation,这个选项在平时我们并不常用,但使用它能看到Logisim对电路仿真的细节,所以有时对调试是很有帮助的。这个选项在Simulation Enable被选中时是不可用的,所以使用前记得关闭Simulation Enable。

每当我们点击一次Step Simulation,电路就会向前仿真一步。注意这里的一步并不是时钟改变一次,而是Logisim进行了一次它仿真的最小粒度。比如下面这个电路,在初始时它的状态除了两个输入管脚都是不确定的,然后每进行一次Step Simulation,电路变化如图片所示。

在这里插入图片描述

从每一幅的电路变化可以看出,每个基本逻辑门元件的状态变化需要一次Step Simulation的延迟才能完成,而pin、wire等元件的状态变化则没有这种延迟。

这种细致的仿真有时对我们很有用,比如我们不小心错误地把RS锁存器搭成了下面的样子

在这里插入图片描述

然后点击两次S管脚,Logisim会立刻出现下面的错误(出现振荡)。

在这里插入图片描述

如果你一直在跟着教程做,你会发现什么都没有看清错误就出现了,因为电路运行地太快了,人眼根本看不到发生了什么。这时我们就可以使用Step Simulation功能,一步步地跟踪电路的行为。通过几次的Step Simulation,我们发现在S被改变两次后,~Q会自主地在0、1状态间交替改变。Logisim监测到了这种周期性改变,认为电路发生了振荡,从而终止了仿真。

另外,Logisim的帮助文档中提到了另外一种有趣的现象:

在这里插入图片描述

这个电路正常来说应该始终输出0,但在Logisim中,其输入每改变两次,输出就会改变一次。你可以尝试自己搭建这个电路,然后使用Logisim的Step Simulation功能来探究其中的原因。


子电路的调试

随着电路的复杂化,我们的电路中很可能嵌套着很多子电路。如果在仿真时出现了下面这种情况,我们就会猜测子电路存在问题。

在这里插入图片描述

我们可以采取几种办法来进入到子电路中,观察子电路仿真的详细情况:

1、点击左上角的在这里插入图片描述,然后直接双击想要进入的子电路。

2、点击左上角的在这里插入图片描述,这时左侧的电路列表就会变成下面这种父电路嵌套子电路的形式。双击要进入的电路即可。这种方法可以方便地进入嵌套较深的子电路。

在这里插入图片描述

3、使用Simulate栏中的go in to state/go out to state选项。这种方法可以方便地在父子电路间反复切换。

子电路

一般情况下,在子电路中能否直接改变输入管脚的值?

答案:否

一般情况下,在子电路中能否直接对其结构进行修改?

答案:是

子电路的结构与C语言中子函数的设计非常相似,对于传入的信号是不可以直接改变的,换句话说在子电路中修改其输入不会对上层电路产生影响,这使得我们可以放心地调试子电路,而子电路中可以直接修改其结构。


ROM与RAM的使用

ROM使用

对于ROM元件,如果想通过导入文件的方式来改变其内容,需要在文件的头部加入什么语句才能使Logisim正确识别该文件(请回顾之前章节对ROM的讲解)?

答案:v2.0 raw

RAM使用

使用下面的电路运行0x25个周期以后,RAM中存储单元数值为0x23的地址为(注:图中左侧放行元件为Counter)(答案请使用十六进制形式,不加0x前缀)?

在这里插入图片描述

答案:0xff

RAM可以设置分端口存取模式,该模式下左侧有用于存储的两个端口,A代表存储地址,D代表存储数据。电路左侧counter开始逐个递增,直到0x23时,D端口存入0x23,而上面的A端口地址是当前数据值和0x23作XNOR运算的结果,按位XNOR时每一位相异为0,相同为1,此时两路输入均为0x23,因此计算结果为0xff,那么存储数值0x23的地址即为0xff。


应用与挑战


Logging模块

Logging模块,是一个可以记录仿真过程中各个部件的状态及数据的模块,在大规模电路仿真的过程中,可以将每一步的状态记录下来,这样不仅仅更直观,并且,起到步进仿真的效果。

在菜单的simulate栏目下,可以选择logging模块,根据当前电路,选择需要跟踪的元器件。

对于子模块,可以选择相应的输入输出,进行相应的记录,以下是一个不是很好的示例:

在这里插入图片描述

    • Add将左面的端口,加入到待检测的集合中
    • Change Radix 更改检测数据的进制
    • Move up/down 更改检测端口的相应位置
    • Remove 将一个待检测的端口,取消检测

在这里,可以看到,在上面的例子中,部分有标签名字,而部分只是Output等类型标识,这在logging过程中用于记录是极其不利的,大家在建立电路时,尽可能给每个元器件建立一个相应的标签名字label,这样大家在logging过程中将会更加的直观。

下图展示,具有标签名称的logging表,看起来十分的直观。

在这里插入图片描述

Table页的相关检测数据,需要在simulate状态下才会进行更新,所以大家在检测过程中请先打开simulate模式。


Logisim 设计指南

1.对电路进行标识(Label)

善用 Label 工具,没有 Label 的电路就像没有注释的代码一样,毫无可读性。

2.使用适当的多路选择器(Multiplexer)

以单周期数据通路中的 ALU 为例,没有必要使用一个16输入的多路选择器(不要让多路选择器存在悬空的输入)。

3.不要使用常量来扩展信号

不要用分线器(Splitter)和常量来扩展信号,扩展器(Bit Extender)才是简洁、易懂的选择。

在这里插入图片描述

在电路中尽量避免使用常量。

4.不要将信号和它取反的结果作为多路选择器(Multiplexer)的输入

左侧的电路可以被一个异或门(XOR Gate)替代。

在这里插入图片描述

5.适当使用常量

正如3中提到的,在通常情况下,你绘制的电路不应需要任何常量。两种例外的情况是:(a)子电路需要的输入比你需要使用的多(b)常量能使你的电路更加简单。每当你想要向电路中添加一个常量时,思考一下能否通过使用其他门电路来优化掉这个常量。

在这里插入图片描述

上图中左右两侧的电路是等价的。

6.不要将一个信号同时作为多路选择器(Multiplexer)的输入和控制

在这里插入图片描述

左侧的电路可以被一个或门(OR Gate)替换掉。

7.有意义的子电路

如果一个子电路只含有一个内置器件,那么使用子电路将毫无意义,请直接将器件放置在顶层电路中。

在这里插入图片描述

上图中左右两侧的子电路都可以直接被一个内置器件代替,使用子电路毫无意义。

8.学会做全面测试

请确认你提交的电路中不包含任何红色的连线,并且能够通过你自己构造的测试。如果你设计的电路使用二进制补码输入,请务必测试正、负数两种情况。

你构造的测试点至少应包括:正数+正数、正数+负数、负数+负数、负数+正数,另外不要忘记0。

9.不要拥有对外部文件绝对路径的依赖

如果你使用了外部 Logisim 库,请确保将库文件和你的电路设计一同上交,为确保万无一失,你可以在提交前将全部文件复制到一个空文件夹内,以测试电路是否能够正常打开。

10.使用正确的数据流方向

在 Logisim 中,通常的数据流方向是由上至下、由左至右,虽然很多器件可以通过更改朝向来改变输入输出的方向,但多路选择器(Multiplexer)等器件的朝向是不能更改的。如果不合理安排数据流方向,那么你的电路很可能会像下图中左侧的例子一样纠结。

在这里插入图片描述

11.学会编辑子电路外观

通常子电路的默认外观都非常丑陋,接口拥挤,而且没有注释,所以推荐大家尽可能自行编辑子电路外观,这里给出一个示例。

在这里插入图片描述

工具栏包含用于添加其他形状的工具,如下所示,其中包含shift和alt键如何修改工具行为的说明。此外,在按住Ctrl的情况下,单击或拖动鼠标会将鼠标位置附着到最近的网格点。

img选择,移动,复制和粘贴形状。
img添加或编辑文本。
img创建一个线段。Shift-drag使线的角度保持在45°的倍数。
img创建二次曲线。对于第一次拖动,您指定曲线的端点,shift- drag将端点保持为45°的倍数。然后单击以指示控制点的位置; shift-click确保曲线是对称的,而alt-单击则通过控制点绘制曲线。
img创建一系列连接线,其顶点由一连串点击指示。按住Shift键可确保前一个顶点与当前顶点之间的角度为45°的倍数。双击或按Enter键完成形状。
img通过从一个角拖动到对角来创建一个矩形。按住Shift键并拖动以创建正方形,并按住Alt键拖动以从中心开始创建矩形。
img通过从一个角拖动到对角,创建一个圆角矩形。按住Shift键并拖动以创建正方形,并按住Alt键拖动以从中心开始创建矩形。
img通过从其边界框的一个角拖动到对角,创建一个椭圆。按住Shift键并拖动以创建一个圆,然后按住Alt并拖动以从中心开始创建椭圆。
img创建一个任意多边形,其顶点由一连串点击指示。按住Shift键可确保顶点与前一个角度成45°角。双击,按Enter键,或单击起始顶点以完成形状。

logisim 属性栏相关含义介绍

1. Splitter

在这里插入图片描述

  • Facing:表示该元件的朝向(选中该元件,按上下左右键同样可以更改朝向)
  • Fan out:表示将几路数据进行合并,或者将数据分成几路
  • Bit Width In: 总线的数据位宽,这里不一定是输入的位宽,也有可能是合并,输出之后的位宽
  • Appearance:这里表示器件的外观,这里选择的是左手手性,具体的外观,大家可以选择自己喜欢的类型
  • Bit 0-31:这里用于决定总线输入中的某一位数据,将从分线管脚的哪一位输出

2. Pin

在这里插入图片描述

  • Output?:这里决定该Pin管脚,属于输入管脚还是输出管脚、
  • Data Bits:数据位宽
  • Three-state?:表示是否支持三状态:0,1,x
  • Pull Behavior:是否增加上,下拉电阻。对于输入引脚,该属性指定应如何处理来自父级电路的浮空值。 在“unchanged”的情况下,浮空值将作为浮动值发送至父级电路中;“pull up”:浮空值在被送入父级电路之前被转换为1;“pull down”:浮空值在被送到父级电路之前被转换为0。 该属性可以实现加法器的进位输入为x状态(或者不连)时,默认进位是0(自建加法器时会用到)。
  • Label:名字标签
  • Label Location:标签位置
  • Label Font:标签字体

3. Probe

在这里插入图片描述

  • Radix:数据显示的进制

4. Tunnel

在这里插入图片描述

  • Tunnel属性较为简单,不详述

5. clock

在这里插入图片描述

  • High Duration/Low Duration:这里的含义是高点平与低电平的持续时间,例如,如果选择High Duration为2 tick,则在一个周期内,高点平持续2/3周期,低电平持续1/3周期。在我们的实验中,默认选择1 tick即可。

6. 门电路元件

在这里插入图片描述

  • 数据位宽,输入数目等较简单不详述
  • Negate1-5:如图,该选项表示在输入端口增加一个非门
  • 特别的,多输入的异或门,运算时是按照顺序进行异或运算,最终得到最后的结果的,大家可以实验以下看看效果

7. 多选器

在这里插入图片描述

  • Disabled Output:若选择无数据输入,则输出值的表现,可选择浮空值,或者是0
  • Include Enable?:是否增加使能端。如果增加使能端,在使能端有效的时候或者处于浮空状态时,均可正常工作,但若使能端处于0状态时,输出端口将会成为浮空状态。

8. Comparator

在这里插入图片描述

  • Numeric Type:表示数据的数据种类,可选择的有,二进制的补码形式和无符号类型。

注意:请大家在使用该器件的时候,一定要明确所需要的比较数据的类型,否则会出现难以查找的错误。

9. Shifter

在这里插入图片描述

  • Shift Type:移位的多种模式

    • Logical Left:逻辑左移
    • Logical Right:逻辑右移
    • Arithmetic Right:算数右移
    • Rotate Left:循环左移
    • Rotate Right:循环右移

这里包含两很多的移位的方式,可以供大家选择,对于不同的移位方式的含义和具体的效果,这里不再详述,大家可以自行探索。

10. Register

在这里插入图片描述

  • Trigger:触发模式

    • Rising Edge:上升沿存入
    • Falling Edge:下降沿存入
    • High Level:高电平存入
    • Low Level:低电平存入

这里的触发模式是一个很重要的特性,表示何时存入数据,这对电路的构造有着很大的影响,同学们在学习时空图的时候可以看出不同的触发模式所带来的不同影响,请大家选择不同的模式,思考不同模式下可能产生的影响。在我们的实验过程中,我们统一采用上升沿存入的模式。

logisim在这里已经给出了相应的模式供大家选择,而在后续的Verilog实现过程中,需要大家对这些模式有清楚的认识,并且自己实现。

11. RAM

在这里插入图片描述

在RAM的相关的属性设置中,我们要求大家选择的数据接口模式为:Separate load and store ports

思考题:这里将其余两种模式的含义交给大家思考,思考其余两种模式的具体含义,以及三种模式各有什么特点,为什么选择第三种模式。

提示:大家可以选择不同的模式,观察端口的变化。

至此,我们已经讲述了大部分器件的相关属性,想必你也对器件的属性,以及Logisim所提供的各种功能有了清楚的了解。在之后的实验中,选择一个正确的器件,以及正确的功能模式,对于我们的实验至关重要,请大家重视本节的学习,并且多动手实践。


Logisim 自动化方法概览

本节内容属于选学内容,且方法并不完善,请各位同学适当参考!

自动化方法概览

在此之前我们使用Logisim搭建我们使用的数字电路时,都是在图形化界面(GUI)中进行操作,但在面临较为复杂,还有诸多重复性部件的电路时,如通用寄存器堆(GPR)等,如果全部使用手工搭建,会非常耗时。但如果我们考察电路的实际储存形式,可以发现它只是xml代码,因此可以使用代码自动生成的方法简化操作,达到提高效率的目的,接下来我们就对方法本身进行介绍,并针对某个具体问题进行讲解。

Circ文件与标签

Logisim使用的文件是.circ文件,它是使用扩展性标记语言编写的文件,Logisim通过这种文件来存储电路。这是一种描述性文件,和网页用的语言HTML类似,可以通过直接修改文件来更改电路图。作为一种XML文件,它主要是被用于传输数据,而非显示数据,这是与HTML的不同之处,因此它的标签均是可以自定义的。只需满足如bar式的格式即可,在Logisim中同样也是Logisim自行规定了一些标签,通过标签的类型其中比较常见的有:

  • 是电路或子电路的标签,用于标记整个电路
  • 标签,用于连线,通过x-y属性定位,需要自己尝试。
  • 标签,拥有loc和name属性,用于调用库元件

我们的自动化方法其实是一种半自动方法,需要我们去观察使用GUI工具搭建出来的电路,再在这个基础上进行代码生成,其实是一种聪明的复制粘贴。

以内存矩阵为例

下面我们来考虑这么一个问题:

假设我们现在有8位字长,存储容量为256B(8位地址)的ROM芯片,我们需要搭建合理的电路,将其扩展成,32位字长,存储容量为16KB的ROM(12位地址)。ROM芯片如图

在这里插入图片描述

从理论上分析,字长扩展了4倍,地址扩展了4位,因此共需4 * 16 = 64块原芯片,预计是要摆出一个16行4列的芯片矩阵看,面对如此大量的芯片,传统地在logisim中“手撸”一个电路就显得十分繁琐了。因此我们需要采用自动化的方法。

首先我们需使用GUI工具拖放元件,这一步其实是非常重要的,通过合理的尝试,我们可以找到显示效果最漂亮的摆放方式,为之后的编码听过位置信息。

在这里插入图片描述

之后我们需要观察产生的.circ文件,文件中我们可以发现,<comp>标签表示对库元件的调用,用<a>标签表示相关的属性,loc表示位置.每个<comp>标签就是一个一个ROM芯片。我们自动化方法的核心其实就是构造一个可以被重复摆放的最小单元,而且这个最小单元往往通过Tunnel连带着输出一起。在本例中即是这个<comp>标签

在这里插入图片描述

接着我们需要编写脚本去批量生成按照规律摆放的ROM芯片,在此我们使用的较为简单的Python语言去编写脚本。需要知道的是,整个自动化方法的核心就是把摆放电路这件机械重复的事,交由计算机去完成。我们只需要根据前文所确定的最小单元,与摆放的**位置信息,**就能够编写相应的代码来自动生成所要的部分电路xml。

在这里插入图片描述

观察所编写的代码,其实只是将最小单位的位置信息参数化,进行重复输出而已,编写起来应该比较简单。之后我们只需将生成的xml黏贴到源文件中main下合适的部分即可。最终效果如下:

在这里插入图片描述

可以注意到的是,此时我们还没有解决连线的大问题,因此我们就要使用Tunnel简化布线,Tunnel元件直接不用wire连接在部件上组成最小单位,再进行自动化方法即可。效果如图,可以发现Tunnel的名字同样也参数化了,这样就可以通过有规律的Tunnel信号进行操作。

在这里插入图片描述

总结

综上,我们可以发现自动化方法的一般步骤就是 尝试——发现最小单元——编写生成代码——使用xml代码, 适用于减少重复性操作的场景,当然这种方法并不完善有许多值得改进与发展的地方,希望各位加油!


Logisim 自动化测试概览

前面已经讲过logisim的Logging功能,但是logging得出的文本并不直观,也不利于我们做测试,所以需要你通过某种方式来转换一下Logging文本格式。

关于logisim命令行测试,请参考官方文档:http://www.cburch.com/logisim/docs/2.7/en/html/guide/verify/index.html


至此,PreProject的Logisim部分全部介绍完毕。

  • 9
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值