Module: HDLRuby::High::Std
- Defined in:
- lib/HDLRuby/std/clocks.rb,
lib/HDLRuby/std/linear.rb,
lib/HDLRuby/std/reconf.rb,
lib/HDLRuby/std/channel.rb,
lib/HDLRuby/std/decoder.rb,
lib/HDLRuby/std/counters.rb,
lib/HDLRuby/std/fixpoint.rb,
lib/HDLRuby/std/pipeline.rb,
lib/HDLRuby/std/task.rb,
lib/HDLRuby/std/fsm.rb
Defined Under Namespace
Modules: HchannelI Classes: ChannelB, ChannelI, ChannelPort, ChannelPortA, ChannelPortB, ChannelPortObject, ChannelPortR, ChannelPortW, ChannelT, DecoderT, FsmT, PipelineT, ReconfI, ReconfT, TaskI, TaskPortA, TaskPortS, TaskPortSA, TaskT
Class Method Summary collapse
- ._included_fixpoint ⇒ Object
-
.channel(name, &ruby_block) ⇒ Object
Creates a new channel type named +name+ whose instances are creating executing +ruby_block+.
-
.channel_instance(name, *args, &ruby_block) ⇒ Object
Creates directly an instance of channel named +name+ using +ruby_block+ built with +args+.
-
.channel_port(obj) ⇒ Object
Wrap object +obj+ to act like a channel port.
-
.included(base) ⇒ Object
Redefines the include to add fixed point generation through the Type class.
-
.task(name, &ruby_block) ⇒ Object
Creates a new task type named +name+ whose instances are creating executing +ruby_block+.
-
.task_instance(name, *args, &ruby_block) ⇒ Object
Creates directly an instance of task named +name+ using +ruby_block+ built with +args+.
Instance Method Summary collapse
-
#after(init, rst = $rst, clk = $clk, &code) ⇒ Object
Sets a counter to +init+ when +rst+ is 1 that is decreased according to +clk+.
-
#before(init, rst = $rst, clk = $clk, &code) ⇒ Object
Sets a counter to +init+ when +rst+ is 1 that is decreased according to +clk+.
-
#channel(name, &ruby_block) ⇒ Object
Creates a new channel type named +name+ whose instances are creating executing +ruby_block+.
-
#channel_instance(name, *args, &ruby_block) ⇒ Object
Creates directly an instance of channel named +name+ using +ruby_block+ built with +args+.
- #channel_port(obj) ⇒ Object
-
#configure_clocks(rst = $rst) ⇒ Object
Initialize the clock generator with +rst+ as reset signal.
-
#decoder(*args, &ruby_block) ⇒ Object
Declare a new decoder.
-
#fsm(*args, &ruby_block) ⇒ Object
Declare a new fsm.
-
#make_2edge_clock(event, times) ⇒ Object
Creates a clock inverted every +times+ occurence of an +event+ and its everted.
-
#make_clock(event, times) ⇒ Object
Create a clock inverted every +times+ occurence of an +event+.
-
#pipeline(name) ⇒ Object
Declare a new pipeline with +name+.
-
#reconf(name, &ruby_block) ⇒ Object
Creates a new reconfigurable component type named +name+ whose instances are creating executing +ruby_block+.
-
#req_ack(clk_e, req, ack, port) ⇒ Object
Encapsulate a task for integrating a control with simple request and acknowledge (+ack+) signals, synchronised on +clk_e+.
-
#rst_req_ack(clk_e, rst, req, ack, port) ⇒ Object
Encapsulate a task for integrating a control with simple reset (+rst+), request and acknowledge (+ack+) signals, synchronised on +clk_e+.
-
#task(name, &ruby_block) ⇒ Object
Creates a new task type named +name+ whose instances are creating executing +ruby_block+.
-
#task_instance(name, *args, &ruby_block) ⇒ Object
Creates directly an instance of task named +name+ using +ruby_block+ built with +args+.
-
#with_counter(init, rst = $rst, clk = $clk, &code) ⇒ Object
Sets a counter to +init+ when +rst+ is 1 that is decreased according to +clk+.
Class Method Details
._included_fixpoint ⇒ Object
10 |
# File 'lib/HDLRuby/std/fixpoint.rb', line 10 alias_method :_included_fixpoint, :included |
.channel(name, &ruby_block) ⇒ Object
Creates a new channel type named +name+ whose instances are creating executing +ruby_block+.
62 63 64 |
# File 'lib/HDLRuby/std/channel.rb', line 62 def self.channel(name,&ruby_block) return ChannelT.new(name,&ruby_block) end |
.channel_instance(name, *args, &ruby_block) ⇒ Object
Creates directly an instance of channel named +name+ using +ruby_block+ built with +args+.
74 75 76 77 |
# File 'lib/HDLRuby/std/channel.rb', line 74 def self.channel_instance(name,*args,&ruby_block) # return ChannelT.new(:"",&ruby_block).instantiate(name,*args) return self.channel(:"",&ruby_block).instantiate(name,*args) end |
.channel_port(obj) ⇒ Object
Wrap object +obj+ to act like a channel port.
1371 1372 1373 1374 |
# File 'lib/HDLRuby/std/channel.rb', line 1371 def self.channel_port(obj) return obj if obj.is_a?(ChannelPort) # No need to wrap. return ChannelPortObject.new(obj) end |
.included(base) ⇒ Object
Redefines the include to add fixed point generation through the Type class.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/HDLRuby/std/fixpoint.rb', line 15 def self.included(base) # Performs the previous included res = self.send(:_included_fixpoint,base) # Now modify the Type class if not already modified. unless ::HDLRuby::High::Type.instance_methods.include?(:"_[]_fixpoint") then ::HDLRuby::High::Type.class_eval do # Saves the former type generation method. alias_method :"_[]_fixpoint", :[] # Redefine the type generation method for supporting fixed point # type generation. def [](*args) if args.size == 1 then return self.send(:"_[]_fixpoint",*args) else # Handle the arguments and compute the fix point sizes. arg0,arg1 = *args if arg0.respond_to?(:to_i) then isize = arg0 else isize = (arg0.first-arg0.last).abs+1 end if arg1.respond_to?(:to_i) then fsize = arg1 else fsize = (arg1.first-arg1.last).abs+1 end # Build the type. case(self.name) when :bit typ = bit[isize+fsize].typedef(::HDLRuby.uniq_name) when :unsigned typ = unsigned[isize+fsize].typedef(::HDLRuby.uniq_name) when :signed typ = signed[isize+fsize].typedef(::HDLRuby.uniq_name) else raise "Invalid type for generating a fixed point type: #{self.name}" end # Redefine the multiplication and division for fixed point. typ.define_operator(:*) do |left,right| if (typ.signed?) then (left.as(signed[isize+fsize*2])*right) >> fsize else (left.as([isize+fsize*2])*right) >> fsize end end typ.define_operator(:/) do |left,right| if (typ.signed?) then (left.as(signed[isize+fsize*2]) << fsize) / right else (left.as([isize+fsize*2]) << fsize) / right end end typ end end return res end end end |
.task(name, &ruby_block) ⇒ Object
Creates a new task type named +name+ whose instances are creating executing +ruby_block+.
60 61 62 |
# File 'lib/HDLRuby/std/task.rb', line 60 def self.task(name,&ruby_block) return TaskT.new(name,&ruby_block) end |
.task_instance(name, *args, &ruby_block) ⇒ Object
Creates directly an instance of task named +name+ using +ruby_block+ built with +args+.
72 73 74 75 |
# File 'lib/HDLRuby/std/task.rb', line 72 def self.task_instance(name,*args,&ruby_block) # return TaskT.new(:"",&ruby_block).instantiate(name,*args) return self.task(:"",&ruby_block).instantiate(name,*args) end |
Instance Method Details
#after(init, rst = $rst, clk = $clk, &code) ⇒ Object
Sets a counter to +init+ when +rst+ is 1 that is decreased according to +clk+. When this counter reaches 0, +code+ is executed. When not within a block, a behavior will be created which is activated on the rising edge of +clk+.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/HDLRuby/std/counters.rb', line 65 def after(init, rst = $rst, clk = $clk, &code) with_counter(init,rst,clk) do |counter| seq do hif(rst.to_expr == 1) do counter.to_ref <= init.to_expr end helsif(counter.to_expr == 0) do # code.call instance_eval(&code) end helse do counter.to_ref <= counter.to_expr - 1 end end end end |
#before(init, rst = $rst, clk = $clk, &code) ⇒ Object
Sets a counter to +init+ when +rst+ is 1 that is decreased according to +clk+. As long as this counter does not reach 0, +code+ is executed. When not within a block, a behavior will be created which is activated on the rising edge of +clk+.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/HDLRuby/std/counters.rb', line 45 def before(init, rst = $rst, clk = $clk, &code) with_counter(init,rst,clk) do |counter| seq do hif(rst.to_expr == 1) do counter.to_ref <= init.to_expr end helsif(counter.to_expr != 0) do counter.to_ref <= counter.to_expr - 1 # code.call instance_eval(&code) end end end end |
#channel(name, &ruby_block) ⇒ Object
Creates a new channel type named +name+ whose instances are creating executing +ruby_block+.
68 69 70 |
# File 'lib/HDLRuby/std/channel.rb', line 68 def channel(name,&ruby_block) HDLRuby::High::Std.channel(name,&ruby_block) end |
#channel_instance(name, *args, &ruby_block) ⇒ Object
Creates directly an instance of channel named +name+ using +ruby_block+ built with +args+.
81 82 83 |
# File 'lib/HDLRuby/std/channel.rb', line 81 def channel_instance(name,*args,&ruby_block) HDLRuby::High::Std.channel_instance(name,*args,&ruby_block) end |
#channel_port(obj) ⇒ Object
1375 1376 1377 |
# File 'lib/HDLRuby/std/channel.rb', line 1375 def channel_port(obj) return HDLRuby::High::Std.channel_port(obj) end |
#configure_clocks(rst = $rst) ⇒ Object
Initialize the clock generator with +rst+ as reset signal.
10 11 12 |
# File 'lib/HDLRuby/std/clocks.rb', line 10 def configure_clocks(rst = $rst) @@__clocks_rst = rst end |
#decoder(*args, &ruby_block) ⇒ Object
Declare a new decoder. The arguments can be any of (but in this order):
- +name+:: name.
- +expr+:: the expression to decode.
If provided, +ruby_block+ the fsm is directly instantiated with it.
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/HDLRuby/std/decoder.rb', line 194 def decoder(*args, &ruby_block) # Sets the name if any unless args[0].respond_to?(:to_expr) then name = args.shift.to_sym else name = :"" end # Create the decoder. decoderI = DecoderT.new(name) # Is there a ruby block? if ruby_block then # Yes, generate the decoder. decoderI.build(*args,&ruby_block) else # No return the decoder structure for later generation. return decoderI end end |
#fsm(*args, &ruby_block) ⇒ Object
Declare a new fsm. The arguments can be any of (but in this order):
- +name+:: name.
- +clk+:: clock.
- +event+:: clock event.
- +rst+:: reset. (must be declared AFTER clock or clock event).
If provided, +ruby_block+ the fsm is directly instantiated with it.
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 |
# File 'lib/HDLRuby/std/fsm.rb', line 486 def fsm(*args, &ruby_block) # Sets the name if any unless args[0].respond_to?(:to_event) then name = args.shift.to_sym else name = :"" end # Get the options from the arguments. , args = args.partition {|arg| arg.is_a?(Symbol) } # Create the fsm. fsmI = FsmT.new(name,*) # Process the clock event if any. unless args.empty? then fsmI.for_event(args.shift) end # Process the reset if any. unless args.empty? then fsmI.for_reset(args.shift) end # Is there a ruby block? if ruby_block then # Yes, generate the fsm. fsmI.build(&ruby_block) else # No return the fsm structure for later generation. return fsmI end end |
#make_2edge_clock(event, times) ⇒ Object
Creates a clock inverted every +times+ occurence of an +event+ and its everted.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/HDLRuby/std/clocks.rb', line 84 def make_2edge_clock(event,times) clock = nil # The resulting clock # Enters the current system HDLRuby::High.cur_system.open do # Ensure times is a value. times = times.to_value # Create the event counter. # Create the name of the counter. name = HDLRuby.uniq_name # Declare the counter. [times.width].inner(name) # Get the signal of the counter. counter = get_inner(name) # Create the inverted event counter. # Create the name of the counter. name = HDLRuby.uniq_name # Declare the counter. [times.width].inner(name) # Get the signal of the counter. counter_inv = get_inner(name) # Create the clock. # Create the name of the clock. name = HDLRuby.uniq_name # Declare the clock. bit.inner(name) # Get the signal of the clock. clock = get_inner(name) # Control the event counter par(event) do hif(@@__clocks_rst | counter.to_expr == 0) do counter.to_ref <= times.to_expr/2 + 1 end end # Control the inverteed event counter par(event.invert) do hif(@@__clocks_rst | counter_inv.to_expr == 0) do counter_inv.to_ref <= times.to_expr/2 + 1 end end # Compute the clock. clock.to_ref <= (counter.to_expr == times.to_expr/2 + 1) | (counter_inv.to_expr == times.to_expr/2 + 1) end # Return it. return clock end |
#make_clock(event, times) ⇒ Object
Create a clock inverted every +times+ occurence of an +event+.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/HDLRuby/std/clocks.rb', line 15 def make_clock(event, times) clock = nil # The resulting clock # Enters the current system HDLRuby::High.cur_system.open do # Ensures times is a value. times = times.to_value # Create the counter. # Create the name of the counter. name = HDLRuby.uniq_name # Declare the counter. [times.width].inner(name) # Get the signal of the counter. counter = get_inner(name) # Create the clock. # Create the name of the clock. name = HDLRuby.uniq_name # Declares the clock. bit.inner(name) # Get the signal of the clock. clock = get_inner(name) # Control it. par(event) do hif(@@__clocks_rst) do counter.to_ref <= times.to_expr clock.to_ref <= 0 end helsif(counter.to_expr == 0) do counter.to_ref <= times.to_expr clock.to_ref <= ~ clock.to_expr end helse do counter.to_ref <= counter.to_expr + 1 end end end return clock end |
#pipeline(name) ⇒ Object
Declare a new pipeline with +name+.
216 217 218 |
# File 'lib/HDLRuby/std/pipeline.rb', line 216 def pipeline(name) return PipelineT.new(name) end |
#reconf(name, &ruby_block) ⇒ Object
Creates a new reconfigurable component type named +name+ whose instances are creating executing +ruby_block+.
59 60 61 62 |
# File 'lib/HDLRuby/std/reconf.rb', line 59 def reconf(name,&ruby_block) # puts "reconf with ruby_block=#{ruby_block}" return ReconfT.new(name,&ruby_block) end |
#req_ack(clk_e, req, ack, port) ⇒ Object
Encapsulate a task for integrating a control with simple request and acknowledge (+ack+) signals, synchronised on +clk_e+. +port+ is assumed to return a TaskPortSA. If +clk_e+ is nil, work in asynchronous mode.
846 847 848 |
# File 'lib/HDLRuby/std/task.rb', line 846 def req_ack(clk_e,req,ack,port) rst_req_ack(clk_e,nil,req,ack,port) end |
#rst_req_ack(clk_e, rst, req, ack, port) ⇒ Object
Encapsulate a task for integrating a control with simple reset (+rst+), request and acknowledge (+ack+) signals, synchronised on +clk_e+. +port+ is assumed to return a TaskPortSA. If +clk_e+ is nil, work in asynchronous mode. If +rst+ is nil, no reset is handled.
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 |
# File 'lib/HDLRuby/std/task.rb', line 814 def rst_req_ack(clk_e,rst,req,ack,port) if clk_e then # Ensures clk_e is an event. clk_e = clk_e.posedge unless clk_e.is_a?(Event) par(clk_e) do # Handle the reset. hif(rst) { port.reset } if rst ack <= 0 # Control the start of the task. hif(req) { port.run } # Control the end of the task: set ack to 1. port.finish { ack <= 1 } end else par do # Handle the reset hif(rst) { port.reset } if rst # Control the start of the task. hif(req) { port.run } ack <= 0 # Control the end of the task: set ack to 1. port.finish { ack <= 1 } end end end |
#task(name, &ruby_block) ⇒ Object
Creates a new task type named +name+ whose instances are creating executing +ruby_block+.
66 67 68 |
# File 'lib/HDLRuby/std/task.rb', line 66 def task(name,&ruby_block) HDLRuby::High::Std.task(name,&ruby_block) end |
#task_instance(name, *args, &ruby_block) ⇒ Object
Creates directly an instance of task named +name+ using +ruby_block+ built with +args+.
79 80 81 |
# File 'lib/HDLRuby/std/task.rb', line 79 def task_instance(name,*args,&ruby_block) HDLRuby::High::Std.task_instance(name,*args,&ruby_block) end |
#with_counter(init, rst = $rst, clk = $clk, &code) ⇒ Object
Sets a counter to +init+ when +rst+ is 1 that is decreased according to +clk+. +code+ will be applied on this counter. When not within a block, a behavior will be created which is activated on the rising edge of +clk+.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/HDLRuby/std/counters.rb', line 13 def with_counter(init, rst = $rst, clk = $clk, &code) # Are we in a block? if HDLRuby::High.top_user.is_a?(HDLRuby::High::SystemT) then # No, create a behavior. behavior(clk.posedge) do with_counter(init,rst,clk,&code) end else # Ensure init is a value. init = init.to_value # Creates the counter # counter = HDLRuby::High::SignalI.new(HDLRuby.uniq_name, # TypeVector.new(:"",bit,init.width), # :inner) # Create the name of the counter. name = HDLRuby.uniq_name # Declare the counter. [init.width].inner(name) # Get the signal of the counter. counter = HDLRuby::High.cur_block.get_inner(name) # Apply the code on the counter. # code.call(counter) instance_exec(counter,&code) end end |