Module: HDLRuby::High::Std

Defined in:
lib/HDLRuby/std/clocks.rb,
lib/HDLRuby/std/delays.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/connector.rb,
lib/HDLRuby/std/sequencer.rb,
lib/HDLRuby/ui/hruby_board.rb,
lib/HDLRuby/std/sequencer_func.rb,
lib/HDLRuby/std/sequencer_sync.rb,
lib/HDLRuby/std/sequencer_channel.rb,
lib/HDLRuby/std/function_generator.rb,
lib/HDLRuby/std/task.rb,
lib/HDLRuby/std/bram.rb,
lib/HDLRuby/std/fsm.rb
more...

Defined Under Namespace

Modules: HchannelI, SEnumerable Classes: AnyRange, ArbiterT, Board, ChannelB, ChannelI, ChannelPort, ChannelPortA, ChannelPortB, ChannelPortObject, ChannelPortR, ChannelPortW, ChannelT, DecoderT, FsmT, PipelineT, PriorityArbiterT, PriorityMonitorT, ReconfI, ReconfT, SEnumerator, SEnumeratorBase, SEnumeratorSub, SEnumeratorWrapper, SequencerChannel, SequencerFunctionE, SequencerFunctionI, SequencerFunctionT, SequencerT, SharedSignalI, TaskI, TaskPortA, TaskPortS, TaskPortSA, TaskT

Constant Summary collapse

@@__clocks_rst =

Standard HDLRuby::High library: clocks

nil

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

._included_fixpointObject

[View source]

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+.

[View source]

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+.

[View source]

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.

[View source]

1412
1413
1414
1415
# File 'lib/HDLRuby/std/channel.rb', line 1412

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.

[View source]

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
75
76
77
78
79
80
81
82
83
# 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).as(typ)
                        else
                            ((left.as(bit[isize+fsize*2])*right) >> fsize).as(typ)
                        end
                    end
                    typ.define_operator(:/) do |left,right|
                        if (typ.signed?) then
                            (left.as(signed[isize+fsize*2]) << fsize) / right
                        else
                            (left.as(bit[isize+fsize*2]) << fsize) / right
                        end
                    end
                    # Define the removal of the point.
                    typ.define_singleton_method(:no_point) do
                        if (typ.signed?) then
                            signed[typ.width]
                        else
                            bit[typ.width]
                        end
                    end
                    # Return the resulting typ.
                    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+.

[View source]

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+.

[View source]

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+.

[View source]

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

#arbiter(name, tbl = nil, &ruby_block) ⇒ Object

Declares an arbiter named +name+ with priority table +tbl+ or priority procedure +rubyblock+.

[View source]

341
342
343
# File 'lib/HDLRuby/std/sequencer_sync.rb', line 341

def arbiter(name,tbl = nil, &ruby_block)
    return PriorityArbiterT.new(name,tbl,&ruby_block)
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+.

[View source]

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

#board(name, http_port: 8000, refresh_rate: 100, &block) ⇒ Object

Create a new board named +name+ accessible on HTTP port +http_port+ and whose content is describe in +block+.

[View source]

1106
1107
1108
1109
1110
1111
# File 'lib/HDLRuby/ui/hruby_board.rb', line 1106

def board(name, http_port: 8000, refresh_rate: 100, &block)
  # puts "name=#{name} http_port=#{http_port} refresh_rate=#{refresh_rate} block=#{block}"
  return Board.new(name,
                   http_port: http_port, refresh_rate: refresh_rate,
                   &block)
end

#channel(name, &ruby_block) ⇒ Object

Creates a new channel type named +name+ whose instances are creating executing +ruby_block+.

[View source]

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+.

[View source]

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

[View source]

1416
1417
1418
# File 'lib/HDLRuby/std/channel.rb', line 1416

def channel_port(obj)
    return HDLRuby::High::Std.channel_port(obj)
end

#configure_clocks(rst = nil) ⇒ Object

Initialize the clock generator with +rst+ as reset signal.

[View source]

10
11
12
# File 'lib/HDLRuby/std/clocks.rb', line 10

def configure_clocks(rst = nil)
    @@__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.

[View source]

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

#delayObject

Module describing a simple delay using handshake for working. @param num the number of clock cycles to delay.

[View source]

11
12
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
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/HDLRuby/std/delays.rb', line 11

system :delay do |num|
    # Checks and process the number of clock to wait.
    num = num.to_i
    raise "The delay generic argument must be positive: #{num}" if (num < 0)

    input  :clk     # The clock to make the delay on.
    input  :req     # The handshake request.
    output :ack     # The handshake acknoledgment.

    # The process of the delay.
    if (num == 0) then
        # No delay case.
        ack <= req
    else
        # The is a delay.
        inner run: 0               # Tell if the deayl is running.
        [num.width+1].inner :count # The counter for computing the delay.
        par(clk.posedge) do
            # Is there a request to treat?
            hif(req & ~run) do
                # Yes, intialize the delay.
                run <= 1
                count <= 0
                ack <= 0
            end
            # No, maybe there is a request in processing.
            helsif(run) do
                # Yes, increase the counter.
                count <= count + 1
                # Check if the delay is reached.
                hif(count == num-1) do
                    # Yes, tells it and stop the count.
                    ack <= 1
                    run <= 0
                end
            end
        end
    end
end

#delaypObject

Module describing a pipeline delay (supporting multiple successive delays) using handshake for working. @param num the number of clock cycles to delay.

[View source]

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/HDLRuby/std/delays.rb', line 56

system :delayp do |num|
    # Checks and process the number of clock to wait.
    num = num.to_i
    raise "The delay generic argument must be positive: #{num}" if (num < 0)

    input  :clk          # The clock to make the delay on.
    input  :req          # The handshake request.
    output :ack          # The handshake acknoledgment.

    if (num==0) then
        # No delay.
        ack <= req
    else
        # There is a delay.

        [num].inner state: 0 # The shift register containing the progression
                             # of each requested delay.

        # The acknoledgment is directly the last bit of the state register.
        ack <= state[-1]


        # The process controlling the delay.
        seq(clk.posedge) do
            # Update the state.
            if (num > 1) then
                state <= state << 1
            else
                state <= 0
            end
            # Handle the input.
            ( state[0] <= 1 ).hif(req)
        end
    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.

[View source]

532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
# File 'lib/HDLRuby/std/fsm.rb', line 532

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.
    options, args = args.partition {|arg| arg.is_a?(Symbol) }
    # Create the fsm.
    fsmI = FsmT.new(name,*options)
    
    # 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

#initialize_lut(func, otyp, awidth, xrange, yrange) ⇒ Array

Make an array consists of a point of any activation function.

Parameters:

  • lut_size (Integer)

    the lut_size of LUT

Returns:

  • (Array)

    table an array consists of a point of tanh

[View source]

125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/HDLRuby/std/function_generator.rb', line 125

def initialize_lut(func, otyp, awidth, xrange, yrange)
    # Compute the x step between discret values.
    xstep = (xrange.last-xrange.first)/(2 ** awidth)

    # Generate the discrete set of x values.
    x_values = xrange.step(xstep)
    # Generate the table.
    table = x_values.map do |x_value|
        ((func.call(x_value)-yrange.first)/(yrange.last-yrange.first)*
         2**otyp.width).to_i.to_expr.as(otyp)
    end

    return table
end

#make_2edge_clock(event, times) ⇒ Object

Creates a clock inverted every +times+ occurence of an +event+ and its everted.

[View source]

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/HDLRuby/std/clocks.rb', line 119

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 
        if (times == 1) then
          AnyError.new("Clock multiplier must be >= 2.") 
        end

        # Create the event counter.
        # Create the name of the counter.
        name = HDLRuby.uniq_name
        # Declare the counter.
        if @@__clocks_rst then
            # There is a reset, so no need to initialize.
            [times.width].inner(name)
        else
            # There is no reset, so need to initialize.
            [times.width].inner(name => 0)
        end
        # 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.
        if @@__clocks_rst then
            # There is a reset, so no need to initialize.
            [times.width].inner(name)
        else
            # There is no reset, so need to initialize.
          [times.width].inner(name => 0)
        end
        # 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.
        if @@__clocks_rst then
            # There is a reset, so no need to initialize.
            bit.inner(name)
        else
            # There is no reset, so need to initialize.
            bit.inner(name => 0)
        end
        # Get the signal of the clock.
        clock = get_inner(name)

        # Control the even counter.
        par(event) do
            if @@__clocks_rst then
                hif(@@__clocks_rst)        { counter <= 0 }
                helsif(counter == times-1) { counter <= 0 }
                helse                      { counter <= counter + 1 }
            else
                hif(counter == times-1)     { counter <= 0 }
                helse                      { counter <= counter + 1 }
            end
        end

        # Control the odd counter.
        par(event.invert) do
            if @@__clocks_rst then
                hif(@@__clocks_rst)        { counter_inv <= 0 }
                helsif(counter == times-1) { counter_inv <= 0 }
                helse                      { counter_inv <= counter_inv + 1 }
            else
                hif(counter == times-1)     { counter_inv <= 0 }
                helse                      { counter_inv <= counter_inv + 1 }
            end
        end

        clock <= ((counter > (times/2)) | (counter_inv > (times/2)))
    end
    # Return the clock.
    return clock
end

#make_clock(event, times) ⇒ Object

Create a clock inverted every +times+ occurence of an +event+.

[View source]

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
75
76
77
78
79
80
81
82
83
# 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 - 1
        if (times == 0) then
          AnyError.new("Clock multiplier must be >= 2.") 
        end

        # Create the counter.
        # Create the name of the counter.
        name = HDLRuby.uniq_name
        # Declare the counter.
        if @@__clocks_rst then
            # There is a reset, so no need to initialize.
            [times.width].inner(name)
        else
            # There is no reset, so need to initialize.
          [times.width].inner(name => times)
        end
        # 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.
        if @@__clocks_rst then
            # There is a reset, so no need to initialize.
            bit.inner(name)
        else
            # There is no reset, so need to initialize.
            bit.inner(name => times)
        end
        # Get the signal of the clock.
        clock = get_inner(name)
        
        # Control it.
        par(event) do
            if @@__clocks_rst then
                # There is a reset, handle it.
                hif(@@__clocks_rst) do
                  counter <= times
                    clock <= 0
                end
                helsif(counter.to_expr == 0) do
                    counter <= times 
                    clock   <= ~ clock
                end
                helse do
                    counter <= counter - 1
                end
            else
                # There is no reset.
                hif(counter == 0) do
                    counter <= times 
                    clock   <= ~ clock
                end
                helse do
                    counter <= counter - 1
                end
            end
        end
    end
    return clock
end

#monitor(name, tbl = nil, &ruby_block) ⇒ Object

Declares a monitor named +name+ with priority table +tbl+ or priority procedure +rubyblock+.

[View source]

347
348
349
# File 'lib/HDLRuby/std/sequencer_sync.rb', line 347

def monitor(name,tbl = nil, &ruby_block)
    return PriorityMonitorT.new(name,tbl,&ruby_block)
end

#pipeline(name) ⇒ Object

Declare a new pipeline with +name+.

[View source]

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+.

[View source]

62
63
64
65
# File 'lib/HDLRuby/std/reconf.rb', line 62

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.

[View source]

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.

[View source]

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

#schannel(typ, size, &access) ⇒ Object

Creates an abstract channel over an accessing method. NOTE: Works like an enumerator or a memory access, but can be passed as generic arguments and generates a different enumerator per sequencer (memory access is identical for now though).

  • +typ+ is the data type of the elements.
  • +size+ is the number of elements.
  • +access+ is the block implementing the access method.
[View source]

86
87
88
# File 'lib/HDLRuby/std/sequencer_channel.rb', line 86

def schannel(typ,size,&access)
    return SequencerChannel.new(typ,size,&access)
end

#sdef(name, depth = nil, overflow = nil, &ruby_block) ⇒ Object

Declares a sequencer function named +name+ using +ruby_block+ as body. You can specify a stack depth with +depth+ argument and a HDLRuby block to execute in case of stack overflow with the +overflow+ argument.

[View source]

517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
# File 'lib/HDLRuby/std/sequencer_func.rb', line 517

def sdef(name, depth=nil, overflow = nil, &ruby_block)
    # Create the function.
    funcT = SequencerFunctionT.new(name,depth,overflow,&ruby_block)
    # Register it for calling.
    if HDLRuby::High.in_system? then
        define_singleton_method(name.to_sym) do |*args|
            funcT.call(*args)
        end
    else
        define_method(name.to_sym) do |*args|
            funcT.call(*args)
        end
    end
    # Return the create function.
    funcT
end

#senumerator(typ, size = nil, &access) ⇒ Object

Creates an sequencer enumerator using a specific block access.

  • +typ+ is the data type of the elements.
  • +size+ is the number of elements, nil if not relevant.
  • +access+ is the block implementing the access method. def senumerator(typ,size,&access)
[View source]

2345
2346
2347
# File 'lib/HDLRuby/std/sequencer.rb', line 2345

def senumerator(typ,size = nil,&access)
    return SEnumeratorBase.new(typ,size,&access)
end

#sequencer(clk, start, &ruby_block) ⇒ Object

Creates a sequencer of code synchronised of +clk+ and starting on +start+.

[View source]

2336
2337
2338
# File 'lib/HDLRuby/std/sequencer.rb', line 2336

def sequencer(clk,start,&ruby_block)
    return SequencerT.new(clk,start,&ruby_block)
end

#sreturn(val) ⇒ Object

Returns value +val+ from a sequencer function.

[View source]

535
536
537
538
539
540
541
542
543
544
# File 'lib/HDLRuby/std/sequencer_func.rb', line 535

def sreturn(val)
    # HDLRuby::High.top_user.hprint("sreturn\n")
    # Get the top function.
    funcI = SequencerFunctionI.current
    unless funcI then
        raise "Cannot return since outside a function."
    end
    # Applies the return on it.
    funcI.make_return(val)
end

#task(name, &ruby_block) ⇒ Object

Creates a new task type named +name+ whose instances are creating executing +ruby_block+.

[View source]

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+.

[View source]

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+.

[View source]

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