J
Jeff Patterson
I'm learning ruby by writing a hardware simulator. Since the users will
be first year EE majors with no software skills, it is important that
the syntax they will use to describe circuits be as clean and intuitive
as possible. With some helpful hints obtained in an earlier post on this
forum, I've got the netlist description down to this
=================
class Top < NetList
def initialize(name);super
#instantiate the blocks
create 'Nco', NCO
create 'clk', Clk
create 'fifo1',ShiftReg,4
#provide a control interface
create 'nCnfg', CtrlInfc, { # :field =>length (lsb ->
msb)
:AngMod => 1,
:AngModTyp => 1,
:AngModScl => 5,
hsRnd => 1,
:AmpRnd => 1,
:SpurElim => 1,
:SwpTyp => 1,
:Swp => 1,
:BbSrc => 1,
:MrkSrc => 1,
nPolySel => 1
}
#wire 'em up
@clk.bind(@Nco[:Clk_in])
@clk.bind(@fifo1[:Clk])
@nCnfg[:ANGMOD].bind(@Nco[:freq])
@nCnfg[:BV].bind(@fifo1[])
end
#read control cmds from stdin
#run method inherited from Netlist super class
def run()
cmd=''
print "ready>"
while((cmd=gets) !~ /^\.$/)
begin
eval cmd,binding()
rescue Exception=>e
puts e.message
end
print "ready>"
end
end
end
sim=Simulation.new(Top.new("DDS"))
sim.run()
=======================
The simulation can be controlled either interactively or from a file
that might look like:
@Nco[:Rst].set(true)
@nCnfg[:bv]=0
yield 1
@Nco[:Rst].set(false)
@nCnfg[:AngMod]=1
yield 10
@nCnfg.setAngMod =>0.01,:ModType =>0)
yield 10
these command are read in the run method above which pass them to eval
to set certain nodes in the simulation to certain values. A yield
command advances the simulation by yielding to the simulator's run
method which advances the indicated number of steps.
So far so good. But eval seems to barf if I give it more than one
command per line. I.e. what I want to be able to do pass in a command
something like
10.times{ some_node.set(some_value);yield 1;n+=1}
and have it work as expected. Instead the eval gives
/systemR.rb:24: warning: multiple values for a block parameter (0 for
1)
and the simulation does not advance.
In case it helps, here's the simulators run method that is being yielded
to:
@sim.run{|cyc|
while (cyc>0)
puts "\n#@cycles"
#update the system clocks-causes scheduled clock outputs to update
@clks.each{|x| x.update}
#update asynchronous elements-causes their listners to schedule an
update
@elements.each{|x| x.update}
#empty the scheduler queue
@elements=[]
@cycles += 1
cyc -= 1
end
}
end
I think the basic problem boils down to this: I need the method and
block to cooperate like
block statement #1
block block statement #1
block block yield
<---- method returns here
block block end
block statement #2
block yield
<----- method returns here
when blocks are nested
Any ideas?
Thanks in advance
Jeff
be first year EE majors with no software skills, it is important that
the syntax they will use to describe circuits be as clean and intuitive
as possible. With some helpful hints obtained in an earlier post on this
forum, I've got the netlist description down to this
=================
class Top < NetList
def initialize(name);super
#instantiate the blocks
create 'Nco', NCO
create 'clk', Clk
create 'fifo1',ShiftReg,4
#provide a control interface
create 'nCnfg', CtrlInfc, { # :field =>length (lsb ->
msb)
:AngMod => 1,
:AngModTyp => 1,
:AngModScl => 5,
hsRnd => 1,
:AmpRnd => 1,
:SpurElim => 1,
:SwpTyp => 1,
:Swp => 1,
:BbSrc => 1,
:MrkSrc => 1,
nPolySel => 1
}
#wire 'em up
@clk.bind(@Nco[:Clk_in])
@clk.bind(@fifo1[:Clk])
@nCnfg[:ANGMOD].bind(@Nco[:freq])
@nCnfg[:BV].bind(@fifo1[])
end
#read control cmds from stdin
#run method inherited from Netlist super class
def run()
cmd=''
print "ready>"
while((cmd=gets) !~ /^\.$/)
begin
eval cmd,binding()
rescue Exception=>e
puts e.message
end
print "ready>"
end
end
end
sim=Simulation.new(Top.new("DDS"))
sim.run()
=======================
The simulation can be controlled either interactively or from a file
that might look like:
@Nco[:Rst].set(true)
@nCnfg[:bv]=0
yield 1
@Nco[:Rst].set(false)
@nCnfg[:AngMod]=1
yield 10
@nCnfg.setAngMod =>0.01,:ModType =>0)
yield 10
these command are read in the run method above which pass them to eval
to set certain nodes in the simulation to certain values. A yield
command advances the simulation by yielding to the simulator's run
method which advances the indicated number of steps.
So far so good. But eval seems to barf if I give it more than one
command per line. I.e. what I want to be able to do pass in a command
something like
10.times{ some_node.set(some_value);yield 1;n+=1}
and have it work as expected. Instead the eval gives
/systemR.rb:24: warning: multiple values for a block parameter (0 for
1)
and the simulation does not advance.
In case it helps, here's the simulators run method that is being yielded
to:
@sim.run{|cyc|
while (cyc>0)
puts "\n#@cycles"
#update the system clocks-causes scheduled clock outputs to update
@clks.each{|x| x.update}
#update asynchronous elements-causes their listners to schedule an
update
@elements.each{|x| x.update}
#empty the scheduler queue
@elements=[]
@cycles += 1
cyc -= 1
end
}
end
I think the basic problem boils down to this: I need the method and
block to cooperate like
block statement #1
block block statement #1
block block yield
<---- method returns here
block block end
block statement #2
block yield
<----- method returns here
when blocks are nested
Any ideas?
Thanks in advance
Jeff