Module: HDLRuby::High::Std

Defined in:
lib/HDLRuby/std/clocks.rb,
lib/HDLRuby/std/reconf.rb,
lib/HDLRuby/std/channel.rb,
lib/HDLRuby/std/decoder.rb,
lib/HDLRuby/std/counters.rb,
lib/HDLRuby/std/pipeline.rb,
lib/HDLRuby/std/fsm.rb

Defined Under Namespace

Classes: ChannelI, ChannelPortA, ChannelPortR, ChannelPortW, ChannelT, DecoderT, FsmT, PipelineT, ReconfI, ReconfT

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.channel(name, &ruby_block) ⇒ Object

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



60
61
62
# File 'lib/HDLRuby/std/channel.rb', line 60

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



72
73
74
# File 'lib/HDLRuby/std/channel.rb', line 72

def self.channel_instance(name,*args,&ruby_block)
    return ChannelT.new(:"",&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+.



66
67
68
# File 'lib/HDLRuby/std/channel.rb', line 66

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



78
79
80
# File 'lib/HDLRuby/std/channel.rb', line 78

def channel_instance(name,*args,&ruby_block)
    HDLRuby::High::Std.channel_instance(name,*args,&ruby_block)
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.
    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

#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

#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