• 【SCALA】3、模拟电路


    Simulation

    package demo17
    
    abstract class Simulation {
    
      type Action = () => Unit
      case class WorkItem(time: Int, action: Action)
    
      private var curtime = 0
    
      def currentTime: Int = curtime
    
      //日程,记录所有未执行的工作项目
      private var agenda: List[WorkItem] = List()
    
      //更新排序
      private def insert(ag: List[WorkItem], item: WorkItem): List[WorkItem] = {
        //如果头部时间大于当前时间,那么直接头插
        if(ag.isEmpty || item.time < ag.head.time) {
          item :: ag
        } else {
          //否则遍历递归到合适位置
          ag.head :: insert(ag.tail, item)
        }
      }
    
      //向日程添加工作项,第二个参数是传名参数
      def afterDelay(delay: Int)(block: => Unit) = {
        val item = WorkItem(currentTime + delay, () => block)
        agenda = insert(agenda, item)
      }
    
      private def next() = {
        (agenda: @unchecked) match {
          case item :: rest =>
            agenda = rest
            curtime = item.time
            //执行这个工作项的操作
            //这里一定要带括号,不然就是相当于get操作
            item.action()
        }
      }
    
      def run() = {
        //插入方法
        afterDelay(0) {
          println("*** simulation started, time = " + currentTime + " ***")
        }
        //执行所有的操作
        while(!agenda.isEmpty) next()
      }
    
    }

    BasicCircuitSimulation

    package demo17
    
    abstract class BasicCircuitSimulation extends Simulation {
    
      //用来做门的延迟
      def InverterDelay: Int
      def AndGateDelay: Int
      def OrGateDelay: Int
    
      //线
      class Wire {
    
        private var sigVal = false
        private var actions: List[Action] = List()
    
        def getSignal = sigVal
        def setSignal(s: Boolean) = {
          if(s != sigVal) {
            sigVal = s
            //这里是对actions每一个元素应用=》_ () 操作也就是f => f(),每次线的状态变化的时候,执行actions
            actions foreach (_ ())
          }
        }
    
        def addAction(a: Action) = {
          //加入载头部
          actions = a :: actions
          //并执行一次a
          a()
        }
      }
    
      //非门,也就是翻转器,在uinput和output之间建立饭庄器
      def inverter(input: Wire, output: Wire) = {
        def invertAction() = {
          val inputSig = input.getSignal
          //在制定的延迟之后执行对应的方法
          afterDelay(InverterDelay) {
            //设置输出线信号为input相反
            output setSignal !inputSig
          }
          //test
    //      output setSignal !inputSig
        }
        //添加动作到input线
        input addAction invertAction
      }
    
      //与门,输入两个线信号的&操作
      def andGate(a1: Wire, a2: Wire, output: Wire) = {
        def andAction() = {
          val a1Sig = a1.getSignal
          val a2Sig = a2.getSignal
          afterDelay(AndGateDelay) {
            output setSignal (a1Sig & a2Sig)
          }
          //test
    //      output setSignal (a1Sig & a2Sig)
        }
        a1 addAction andAction
        a2 addAction andAction
      }
    
      def orGate(o1: Wire, o2: Wire, output: Wire) = {
        def orAction() = {
          val o1Sig = o1.getSignal
          val o2Sig = o2.getSignal
          afterDelay(OrGateDelay) {
            output setSignal (o1Sig | o2Sig)
          }
          //test
    //      output setSignal (o1Sig | o2Sig)
        }
        o1 addAction orAction
        o2 addAction orAction
      }
    
      //用来观察线的型号变化
      def probe(name: String, wire: Wire) = {
        def probeAction() = {
          println(name + " " + currentTime + " new-value = " + wire.getSignal)
        }
        wire addAction probeAction
      }
    
    
    }

    CircuitSimulation

    package demo17
    
    abstract class CircuitSimulation extends BasicCircuitSimulation {
    
      def halfAdder(a: Wire, b: Wire, s: Wire, c: Wire) = {
        val d, e = new Wire
        orGate(a, b, d)
        andGate(a, b, c)
        inverter(c, e)
        andGate(d, e, s)
      }
    
      def fullAdder(a: Wire, b: Wire, cin: Wire, sum: Wire, cout: Wire) = {
        val s, c1, c2 = new Wire
        halfAdder(a, cin, s, c1)
        halfAdder(b, s, sum, c2)
        orGate(c1, c2, cout)
      }
    
    }

    MySimulation

    package demo17
    
    object MySimulation extends CircuitSimulation {
      def InverterDelay: Int = 1
    
      def AndGateDelay: Int = 3
    
      def OrGateDelay: Int = 5
    
    }

    测试结果:

    package demo17
    
    import demo17.MySimulation._
    
    object Demo18Test {
      def main(args: Array[String]): Unit = {
        val input1, input2, sum, carry = new Wire
        probe("sum", sum)
        probe("carry", carry)
        halfAdder(input1, input2, sum, carry)
        input1 setSignal true
        run()
        input2 setSignal true
        run()
        println("over")
      }
    }

    测试结果:

    模拟电路的半加器

     

  • 相关阅读:
    1060. Are They Equal (25)
    1063. Set Similarity (25)
    Java基础学习总结(20)——基础语法
    Java基础学习总结(19)——Java环境变量配置
    Java基础学习总结(19)——Java环境变量配置
    Java基础学习总结(18)——网络编程
    Java基础学习总结(18)——网络编程
    Java基础学习总结(17)——线程
    Java基础学习总结(17)——线程
    Java基础学习总结(16)——Java制作证书的工具keytool用法总结
  • 原文地址:https://www.cnblogs.com/cutter-point/p/11094272.html
Copyright © 2020-2023  润新知