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
item.action()
}
}
def run(){
afterDelay(0){
println("*** simulation stated,time= "+currentTime+"***")
}
while(!agenda.isEmpty) next()
}
}
abstract class BasicCircuitSimulation extends Simulation{
def IverterDelay: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 foreach(_())
}
def addAction(a:Action)={
actions=a::actions
a()
}
}
def inverter(input:Wire,output:Wire)={
def invertAction(){
val inputSig=input.getSignal
afterDelay(IverterDelay){
output setSignal !inputSig
}
}
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)
}
}
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)
}
}
o1 addAction orAction
o2 addAction orAction
}
def probe(name:String,wire:Wire){
def probeAction(){
println(name +" "+ currentTime +" new-value= "+ wire.getSignal)
}
wire addAction probeAction
}
}
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)
}
}
object MySimulation extends CircuitSimulation{
def IverterDelay=1
def AndGateDelay=1
def OrGateDelay=1
//defined module MySimulation
def main(args:Array[String]){
val input1,input2,sum,carry=new Wire
probe("sum",sum)
probe("carry",carry)
input1 setSignal true
input2 setSignal true
halfAdder(input1,input2,sum,carry)
run()
input2 setSignal false
input1 setSignal false
halfAdder(input1,input2,sum,carry)
run()
}
}
深刻理解scala模拟电路
猜你喜欢
转载自blog.csdn.net/zhbzhbzhbbaby/article/details/88718311
今日推荐
周排行