0%

109:一生一芯F3(2)

接着学习F3的内容

整数的机器级表示

主要讲了原码、补码、反码,这些是计算机组成的基本知识,就不做过多赘述。

F3.6.1 搭建4位减法器

根据4位加法器的设计思路, 尝试在Logisim中通过门电路搭建一个4位减法器, 用七段数码管按十六进制显示减法器的两个输入和结果, 并用一个LED灯指示减法结果是否产生借位. 搭建后, 通过仿真检查你的方案是否正确.

这里的话我们先从一位减法器开始实现,实现的原理实际上和全加器是一样的。只不过这里需要注意借位的条件,全加器和减法器的区别就在于进位和借位信号的实现,以下是一个简单的一位减法器实现:

image.png

在此基础之上,我们实现四位的减法器:(实现同加法器)

image.png

F3.6.2 搭建4位原码加法器

理解原码加法器的工作原理后, 尝试用加法器, 减法器和多路选择器等部件, 在Logisim中搭建一个4位原码加法器. 为了显示符号位, 你可以额外实例化一个七段数码管, 结果为负数时显示负号-, 否则不显示. 搭建后, 通过仿真检查你的方案是否正确.

实现原码加法器需要进行分类讨论的情况:

  • A B同号,对数值位进行加法即可,符号位不变
  • A B异号,对数值位的绝对值进行减法运算,根据借位结果来判断符号位。(这里我用了两个减法器来处理这一部分,对于符号的判断,则用到了互斥的原理实现)
image.png

F3.6.3 搭建4位反码加法器

尝试按照上述思路, 在Logisim中搭建一个4位反码加法器. 搭建后, 通过仿真检查你的方案是否正确.

我们只需要对输入进行预处理,将反码转换为原码作为输入就可以了。转换电路的实现也很简单,如果反码是正数则保持不变,如果是负数,则翻转数值位,保持符号位。

image.png

F3.6.4 检测补码加法是否发生溢出

将上述真值表补充完整, 尝试列出溢出条件的逻辑表达式. 然后在Logisim中在4位加法器的基础上添加溢出判断逻辑. 添加后, 通过仿真检查你的方案是否正确.

image.png

首先完成表格:

As Bs Cin Cout Ss 溢出
0 0 0 0 0
0 0 1 0 1
0 1 0 0 1
0 1 1 1 0
1 0 0 0 1
1 0 1 1 0
1 1 0 1 0
1 1 1 1 1

我们注意到只有CinCout不同时,才会有溢出现象。所以我们可以通过简单的异或来判断溢出的现象:

image.png

时序电路

之前所设计的模块有一个特点,就是当前的电路状态完全由当前的输入状态决定。但只是这样子,我们并没办法实现大多数的功能。所以时序电路的设计就显得尤为重要。所以我们需要设计一种新的电路满足以下的两个要求:

  • 可以读出电路的旧状态
  • 可以更新电路的状态

具备上述特性的电路称为时序逻辑电路, 它可以存储状态, 其输出由当前输入和旧状态共同决定;而先前的电路我们成为组合逻辑电路。

F3.7.1 搭建SR锁存器

尝试在Logisim中通过门电路搭建一个SR锁存器. 搭建后, 通过仿真检查你的方案是否正确.

由于手工操作时, 无法通过一次点击直接将两个拨码开关从11变成00. 为了触发亚稳态, 你可以在SR锁存器前额外增加若干与门, 让另一个拨码开关同时控制这些与门的其中一个输入端, 这样就可以通过这一个拨码开关来让SR锁存器的两个输入端同时变成0了. 如果你成功触发了亚稳态, Logisim会在窗口底部显示Oscillation apparent的信息. 此时仿真将无法继续, 你需要通过Logisim的菜单重置仿真.

这里可以通过在模拟暂停的后设置输入的行为来触发亚稳态,可以看到电路中发生了振荡状态。

image.png

F3.7.3 分析D锁存器的行为

尝试根据电路结构图列出真值表, 分析D锁存器的行为.

image.png

真值表如下:

D WE Q
0 0 X
0 1 0
1 0 X
1 1 1

F3.7.4 搭建D锁存器

尝试在Logisim中通过门电路搭建一个D锁存器. 搭建后, 通过仿真检查你的方案是否正确.

image.png

F3.7.5 搭建带复位功能的D锁存器

尝试为D锁存器添加一个用于复位的输入端和复位功能. 当复位信号有效时, D锁存器中存放的值将变为0.

设置一个Reset信号,当Reset信号触发时,写入数据0就好了。

image.png

F3.7.6 用D锁存器实现位翻转功能

实例化一个带复位功能的D锁存器, 并将其输出取反后作为输入. 我们预期看到D锁存器的输出将在01之间反复变化, 但你应该在仿真过程中看到Oscillation apparent的信息, 请分析原因.

由于循环依赖的问题输入数据D和输出Q此时应该是高频闪动的现象,但是仿真器无法模拟这个环节,所以会报错明显的震荡

image.png

F3.7.7 搭建D触发器

尝试在Logisim中通过门电路搭建一个D触发器. 搭建后, 将时钟端口与一个按钮相连, 按钮的按下和释放分别会产生高低电平, 因此点击一次按钮可产生一个脉冲, 以此来充当时钟信号. 尝试长按按钮, 来观察主从式D触发器的工作过程.

image.png

F3.7.7 搭建带复位功能的D触发器

尝试为D触发器添加一个用于复位的输入端和复位功能. 当复位信号有效时, D触发器中存放的值将变为0.

image.png

F3.7.8 用D触发器实现位翻转功能

实例化一个带复位功能的D触发器, 并将其输出取反后作为输入. 我们预期看到D触发器的输出将在01之间反复变化. 尝试和上文D锁存器的结果进行对比.

和D锁存器的结果不同,由于D触发器的存储只在时钟的上升沿发生改变,所以形成了有规律的振荡。

image.png

F3.7.11 搭建带使能端的D触发器

尝试在Logisim中通过D触发器和若干电路, 搭建一个带使能端的D触发器. 搭建后, 通过仿真检查你的方案是否正确.

也就是需要一个WE信号控制时钟的值是否有效,和reset的实现差不多,加个与门就好了:

image.png

F3.7.12 搭建4位寄存器

尝试在Logisim中通过D触发器搭建一个4位的寄存器, 具备复位功能. 搭建后, 尝试从拨码开关向寄存器写入4位数据, 并将寄存器的输出接到七段数码管进行显示.

image.png

F3.7.13 搭建4位计数器

通过上述4位寄存器和之前搭建的加法器, 实现一个4位计数器, 每次时钟到来时, 寄存器中的值加1, 加到最大值时重新从0开始. 在Logisim中, 你可以通过元件库中的Wiring(线路)类别下的Constant(常数)元件实例化一个常数, 具体使用方式请RTFM.

有点像D触发器的反转,只不过每次需要自增一次在输出值:

image.png

F3.7.14 设计数列求和电路

尝试通过寄存器和加法器, 计算出1+2+...+10的结果. 为了容纳计算结果, 你可以考虑实现8位的寄存器和加法器.

使用两个寄存器,一个寄存器自增提供加数;另一个寄存器累加作为累加器:

image.png

F3.7.15 实现电子时钟

利用寄存器和七段数码管, 实现一个电子时钟, 具备”分”和”秒”的功能.

因为时序问题卡了好久

image.png