使用Java语言实现数字电路模拟器

 此项目代码已上传到GitHub,仓库地址为

GitHub - Ran-a/A-Simulator-for-Digital-Circuits: 使用java语言实现了SICP中第三章中的数字电路模拟器,考虑了时间延迟。

1  项目背景

      《Structure and Interpretation of Computer Programs》(缩写为SICP,中文名为《计算机程序的构造和解释》)这本书中的3.3.4小节"A Simulator for Digital Circuits"(数字电路模拟器)提供了设计一个数字电路模拟器的思路以及使用JavaScript语言的实现代码。在阅读并理解了这一章节的内容后,根据书中的描述和代码使用java语言实现了半加器的模拟器。

2  数字电路模拟器的介绍

       设计复杂的数字系统(digital systems),例如计算机,是一种非常重要的工程活动。数字系统都是通过一些简单元件构造起来的。虽然这些元件单独看起来功能都很简单,它们连接起来形成的网络就可能产生非常复杂的行为。对数字电路使用计算机程序模拟,是一种数字系统工程师广泛使用的重要工具。

        本项目是通过event-driven simulation(事件驱动的模拟)模拟的。事件驱动的模拟意思是一些事件(“活动”)的发生引发一些其他事件的发生,这些事件的发生又会引发随后事件的发生,并如此继续下去。

       本项目中的数字电路模拟器是使用Java语言编写的计算机程序,模拟数字电路中的半加器。半加器的特点有

  • 由1个非门、1个或门、2个与门和6根导线组成;
  • 暴露给用户的导线为图1中的A、B、C、S;
  • A、B为输入导线,用来输入信号值;
  • C、S是输出导线;
  • C导线上信号值为A导线上信号值和B导线上信号值之和向高位的进位;
  • S导线上信号值为A导线上信号值和B导线上信号值之和;
  • 半加器不考虑来自低位的进位;
  • 半加器的真值表如表1所示;
  • 由于组成半加器的逻辑门存在时间延迟,所以半加器存在时间延迟;                                    

         图1所示为半加器的电路图,该图来自书籍《Structure and Interpretation of Computer Programs》。

半加器电路图
图1 半加器电路图
表1 半加器真值表
A B S C
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

 3  实现思路

        上文提到半加器由与门、非门和或门这些基本逻辑门以及导线组成。以下是这些组成部分的功能和特点。

        导线可以传递数字信号,一个数字信号在任何时刻都只能为0或1;

        基本逻辑门根据输入信号计算出相应的输出信号。基本逻辑门的计算需要时间,所以输出信号具有时间延迟,具体延迟时间依赖于基本逻辑门的种类。

        例如非门是一种基本逻辑门,它会对输入信号做非操作。如果一个非门的输入信号为1,那么在一个非门的延迟时间单位之后,这个非门就输出信号值为0的信号;如果一个非门的输入信号为0,那么在一个非门的延迟时间单位之后,这个非门就输出信号值为1的信号。

        我们可以将基本逻辑门通过导线连接起来,构造出更复杂的功能。

        连接方法就是将一个基本逻辑门的输出导线作为其他基本逻辑门的输入导线,例如图1所示半加器的电路。由于延迟的存在,这些输出可能在不同的时间产生。

        我们可以根据图1半加器的电路图,将1个非门、2个与门和1个或门通过导线连接起来。若使用Java语言编写计算机程序来模拟将以上提到的基本部件通过导线连接起来的过程,那么我们需要分别实现非门类Inverter类、与门AndGate类、或门类OrGate类和导线类Wire类作为实现半加器的基本部件。将以上部件通过导线连接起来形成半加器类后,半加器类又可以作为更复杂的电路的部件。

        假设我们已经实现了基本部件与门类(AndGate类)、或门类(OrGate类)、非门类(Inverter类)和导线类(Wire类),那么我们可以将AndGate类的对象作为组成半加器的与门,将OrGate类的对象作为组成半加器的或门,将Inveter类的对象作为组成半加器的非门,再通过将Wire类的对象作为基本逻辑门类构造函数的参数,实现模拟通过导线连接各个基本逻辑门从而组成半加器的过程。

        关键代码如下。

    Wire a = new Wire();
    Wire b = new Wire();
    Wire s = new Wire();
    Wire c = new Wire();
    Wire d = new Wire();
    Wire e = new Wire();
    AndGate andGateLeft = new AndGate(a, b, c);
    OrGate orGate = new OrGate(a, b, d);
    Inverter inverter = new Inverter(c, e);
    AndGate andGateRight = new AndGate(d, e, s);

        实现半加器的代码又可以封装起来作为半加器类(HalfAdder 类)成为更复杂电路的基本部件。 例如2个半加器与1个或门又可以组成全加器。如图2所示为全加器的电路图,该图来自书籍《Structure and Interpretation of Computer Programs》。

图2 全加器电路图

        由图2所示,实现全加器时需要初始化2个半加器类HalfAdder的对象、1个或门类OrGate的对象和8根导线类Wire的对象作为组成全加器的部件。

        其中,A、B、C_{in}、SUM、C_{out}为暴露给用户的导线;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值