Top Level Namespace
- Includes:
- HDLRuby, HDLRuby::High::Std, HDLRuby::Low, HDLRuby::Verilog
Defined Under Namespace
Modules: HDLRuby Classes: Array, CPU, CPUSimu, FalseClass, Float, Handshaker, Hash, Integer, MEI8, Numeric, Range, String, Symbol, TemplateExpander, TrueClass
Constant Summary collapse
- Ns =
The various combinations of bit strings to test.
[ $n0, $n1, $n2, $n3, $n4, $n5 ]
- NNs =
NLs = [ $n0l, $n1l, $n2l, $n3l, $n4l, $n5l ]
[ $n0n, $n1n, $n2n, $n3n, $n4n, $n5n ]
- Zs =
[ $z0, $z1, $z2, $z3, $z4, $z5, $z6 ]
- Xs =
ZLs = [ $z0l, $z1l, $z2l, $z3l, $z4l, $z5l, $z6l ]
[ $x0, $x1, $x2, $x3, $x4, $x5, $x6 ]
- Ms =
XLs = [ $x0l, $x1l, $x2l, $x3l, $x4l, $x5l, $x6l ]
[ $m0, $m1, $m2, $m3, $m4, $m5, $m6, $m7 ]
- STRs =
MLs = [ $m0l, $m1l, $m2l, $m3l, $m4l, $m5l, $m6l, $m7l ]
Ns + Zs + Xs + Ms
Constants included from HDLRuby::Low
HDLRuby::Low::Base, HDLRuby::Low::Bignum, HDLRuby::Low::FmI, HDLRuby::Low::Integer, HDLRuby::Low::Natural, HDLRuby::Low::Real, HDLRuby::Low::TruncersI, HDLRuby::Low::VERILOG_BASE_TYPES, HDLRuby::Low::VERILOG_REGS
Constants included from HDLRuby
HDLRuby::FIELDS_OF_REF, HDLRuby::FIELDS_TO_EXCLUDE, HDLRuby::FROM_BASICS_REFS, HDLRuby::Infinity, HDLRuby::REF_ARG_NAMES, HDLRuby::TO_BASICS, HDLRuby::TO_BASICS_TYPES, HDLRuby::TO_BASIC_NAMES, HDLRuby::VERSION
Class Method Summary collapse
-
.booting? ⇒ Boolean
Tells HDLRuby has finised booting.
-
.configure_high ⇒ Object
Enters in HDLRuby::High mode.
Instance Method Summary collapse
- #after(number, clk = $clk, rst = $rst, &code) ⇒ Object
-
#bw ⇒ Object
Module generating a neuron bias or weight.
- #connect8(i0, i1, i2, i3, i4, i5, i6, i7, o0, o1, o2, o3, o4, o5, o6, o7) ⇒ Object
-
#counter ⇒ Object
Module generating the sample counter.
-
#eName2Exp(name) ⇒ Object
Generate an expression from a signal or constant name.
-
#forward ⇒ Object
Module Generating a foward propagation structure of a NN.
-
#forward_sub ⇒ Object
A fully specified forward module with 8.24-bit fixed point computation and 4.4bit table-based sigmoid activation function.
- #hello_mix(u, v, w) ⇒ Object
- #hello_out ⇒ Object
-
#lut84(content, addr) ⇒ Object
A test of def.
-
#make_reg(name, &blk) ⇒ Object
Function generating a register declaration.
-
#make_reg_body(typ) ⇒ Object
Function generating the body of a register description.
-
#mem ⇒ Object
Module generating a lookup table memory.
-
#rand_array(geometry, width) ⇒ Object
Generates a N-dimension array described by +geometry+ filled with +width+ bit values.
-
#rand_signed(width) ⇒ Object
Generate a +width+ bit (signed) random value.
-
#rom_gen(addr, &func) ⇒ Object
Rom access generator, def case.
-
#selector ⇒ Object
Module generating the selector that decides if a neuron is to update or not.
- #sigmoid(a_width, a_point, d_width, d_point, addr) ⇒ Object
-
#times_loop(clk_e, num, &ruby_block) ⇒ Object
Loop +num+ times executing +ruby_block+.
-
#which(cmd) ⇒ Object
Locate an executable from cmd.
-
#while_loop(clk_e, init, condition = nil, &ruby_block) ⇒ Object
A simplified loop: loops until +condition+ is met execution +ruby_block+.
-
#while_task ⇒ Object
While loop: loops until +condition+ is met execution +ruby_block+.
-
#xcd_generator(top, path) ⇒ Object
Generates a xcd file from the HDLRuby objects from +top+ using their 'xcd' properties.
-
#z ⇒ Object
Module generating a neuron sum.
Methods included from HDLRuby::High::Std
_included_fixpoint, #before, channel, #channel, channel_instance, #channel_instance, channel_port, #channel_port, #configure_clocks, #decoder, #fsm, included, #initialize_lut, #make_2edge_clock, #make_clock, #pipeline, #reconf, #req_ack, #rst_req_ack, task, #task, task_instance, #task_instance, #with_counter
Methods included from HDLRuby::Low
Methods included from HDLRuby::Verilog
Methods included from HDLRuby
basic_to_value, const_reduce, #error_manager, from_yaml, is_basic_HDLRuby?, #make_bit, show, show!, show?, uniq_name, value_to_basic, verbosity=
Class Method Details
.booting? ⇒ Boolean
Tells HDLRuby has finised booting.
4982 4983 4984 |
# File 'lib/HDLRuby/hruby_high.rb', line 4982 def self.booting? false end |
.configure_high ⇒ Object
Enters in HDLRuby::High mode.
4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 |
# File 'lib/HDLRuby/hruby_high.rb', line 4944 def self.configure_high if $HDLRuby_configure then # Already configured. return end # Now HDLRuby will be configured. $HDLRuby_configure = true include HDLRuby::High class << self # For main, missing methods are looked for in the namespaces. def method_missing(m, *args, &ruby_block) # print "method_missing in class=#{self.class} with m=#{m}\n" # Is the missing method an immediate value? value = m.to_value return value if value and args.empty? # puts "Universe methods: #{Universe.namespace.methods}" # Not a value, but maybe it is in the namespaces if Namespaces[-1].respond_to?(m) then # Yes use it. Namespaces[-1].send(m,*args,&ruby_block) else # puts "here: #{m}" # No, true error raise NotDefinedError, "undefined HDLRuby construct, local variable or method `#{m}'." end end end # Initialize the this. set_this # Generate the standard signals $clk = Universe.scope.inner :__universe__clk__ $rst = Universe.scope.inner :__universe__rst__ # Tells HDLRuby has finised booting. def self.booting? false end end |
Instance Method Details
#after(number, clk = $clk, rst = $rst, &code) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/HDLRuby/high_samples/paper_after.rb', line 5 def after(number, clk = $clk, rst = $rst, &code) if in_behavior? and cur_behavior.on_edge? then counter = HDLRuby.uniq_name counter = [Math::log2(number).to_i+1].inner counter hif(rst) { counter <= 0 } helsif(counter < number) do counter <= counter + 1 end # hif(counter >= number) { code.call } hif(counter >= number) { instance_eval(&code) } else counter = HDLRuby.uniq_name cur_system.open do counter = [Math::log2(number).to_i+1].inner counter par(clk.posedge,rst.posedge) do hif(rst) { counter <= 0 } helse { counter <= counter + 1 } end end # hif(counter >= number) { code.call } hif(counter >= number) { instance_eval(&code) } end end |
#bw ⇒ Object
Module generating a neuron bias or weight. Params:
- +typ+: the data type of the neural signals.
- +init_bw+: initial value of the bias/weight.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/HDLRuby/hdr_samples/neural/bw.rb', line 6 system :bw do |typ,init_bw| # The control signals. input :clk, :reset # Clock and reset input :select_initial # Initialization of the bias/weight input :select_update # Update of the bias/weight # Update of the bias/weight typ.input :dbw # Output of the bias/weight typ.output :bwo # Behavior controlling the bias/weight par(clk.posedge) do hif(reset == 1) { bwo <= 0 } helsif(select_initial == 1) { bwo <= init_bw } helsif(select_update == 1) { bwo <= bwo+dbw } end end |
#connect8(i0, i1, i2, i3, i4, i5, i6, i7, o0, o1, o2, o3, o4, o5, o6, o7) ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 |
# File 'lib/HDLRuby/hdr_samples/with_to_array.rb', line 2 def connect8(i0,i1,i2,i3,i4,i5,i6,i7, o0,o1,o2,o3,o4,o5,o6,o7) o0 <= i0 o1 <= i1 o2 <= i2 o3 <= i3 o4 <= i4 o5 <= i5 o6 <= i6 o7 <= i7 end |
#counter ⇒ Object
Module generating the sample counter. Params:
- +num+: the number of samples.
5 6 7 8 9 10 11 12 13 14 15 16 |
# File 'lib/HDLRuby/hdr_samples/neural/counter.rb', line 5 system :counter do |typ,num| # The input control signals. input :clk, :reset # The output counter. typ.output :out par(clk.posedge) do hif(reset == 1) { out <= 0 } helsif(out == num-1) { out <= 0 } helse { out <= out+1 } end end |
#eName2Exp(name) ⇒ Object
Generate an expression from a signal or constant name
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/HDLRuby/test_hruby_low.rb', line 258 def eName2Exp(name) # puts "eName2Exp with name=#{name}" ref = $refs.find do |ref| if ref.ref.respond_to?(:name) then ref.ref.name == name.to_sym else ref.name == name.to_sym end end # puts "ref=#{ref}" unless ref return Value.new($bit8,name.to_i) end return ref end |
#forward ⇒ Object
Module Generating a foward propagation structure of a NN. Params:
- +typ+: the data type for standard computations.
- +arch+: the architecture of the NN as a array of columns sizes
- +samps+: the NN input and expected outputs samples as a 3D array
- +b_init+:the bias initial values as a 2D array
- +w_init+:the weights initial values as a 3D array
- +actP+: the activation proc, default: ReLU
- +sopP+: the sum of production function, default: basic operators
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 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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/HDLRuby/hdr_samples/neural/forward.rb', line 19 system :forward do |typ,arch,samps,b_init,w_init, actP = proc { |z| mux(z < 0, 0, z) }, sopP = proc do |xs,ws| xs.zip(ws).map{ |x,w| x*w }.reduce(:+) end | ### # The interface signals # The control signals input :clk, :reset input :din, :select_initial # The input signals for updating of the weights and biases, # and the output signals giving the corresponding current values. cap_bs = [] bs = [] cap_ws = [] ws = [] arch[1..-1].each.with_index do |col,i| cap_bs << [] bs << [] # The biase update inputs and value outputs col.times do |j| cap_bs[-1] << ( typ.input :"cap_b#{i+1}_#{j+1}" ) bs[-1] << ( typ.output :"b#{i+1}_#{j+1}" ) end # The weigh update inputs and value outputs cap_ws << [] ws << [] col.times do |j0| cap_ws[-1] << [] ws[-1] << [] arch[i].times do |j1| cap_ws[-1][-1] << ( typ.input :"cap_w#{i+1}_#{j0+1}#{j1+1}" ) ws[-1][-1] << ( typ.output :"w#{i+1}_#{j0+1}#{j1+1}" ) end end end # The output signals giving each neuron output. as = [] arch[1..-1].each.with_index do |col,i| as << [] col.times do |j| as[-1] << ( typ.output :"a#{i+1}_#{j+1}" ) end end # The output signals indicating the current NN input and expected # answer (they are provided by an inner memory). ks = [] arch[0].times do |i| # NN input ks << ( typ.output :"k#{i+1}" ) end ts = [] arch[-1].times do |i| # NN expected answer ts << ( typ.output :"t#{i+1}" ) end ### # The inner signals # The control signals inner :select_update typedef(:outT) { [Math::log2(samps[0][0].size).ceil] } # Sample counter type outT.inner :out # The neurons sum results. zs = [] arch[1..-1].each.with_index do |col,i| zs << [] col.times do |j| zs[-1] << ( typ.inner :"z#{i+1}_#{j+1}" ) end end ### # The structural description (instantiation of thre neuron computation # systems) # Sample counter counter(outT,samps[0][0].size).(:counterI).(clk, reset, out) # Neuron update selector, the skip size is (NN depth)*4+1 # (4-cycle neurons and one addition sync cycle). selector(arch.size*4+1).(:selectorI).(clk, reset, select_update) # Input and expected output memories arch[0].times do |i| # Samples for input i mem(typ,outT,samps[0][i]).(:"k#{i+1}I").(clk, din, out, ks[i]) end arch[-1].times do |i| # Expected values for output i mem(typ,outT,samps[1][i]).(:"t#{i+1}I").(clk, din, out, ts[i]) end # Biases and weights arch[1..-1].each.with_index do |col,i| # Biases col.times do |j| bw(typ,b_init[i][j]). (:"b#{i+1}_#{j+1}I").(clk, reset, cap_bs[i][j], select_initial, select_update, bs[i][j]) end # Weights col.times do |j0| arch[i].times do |j1| bw(typ,w_init[i][j0][j1]). (:"w#{i+1}_#{j0+1}#{j1+1}I").(clk,reset,cap_ws[i][j0][j1], select_initial, select_update, ws[i][j0][j1]) end end end # Weighted Sums # First column arch[1].times do |j| z(typ,ks.size,sopP).(:"z2_#{j+1}I"). (clk, reset, *ks, *ws[0][j], bs[0][j], zs[0][j]) end # Other columns arch[2..-1].each.with_index do |col,i| col.times do |j| z(typ,as[i].size,sopP).(:"z#{i+3}_#{j+1}I"). (clk, reset, *as[i], *ws[i+1][j], bs[i+1][j], zs[i+1][j]) end end # Activations arch[1..-1].each.with_index do |col,i| col.times do |j| a(typ,actP).(:"a#{i+1}_#{j+1}I").(clk, reset, zs[i][j], as[i][j]) end end end |
#forward_sub ⇒ Object
A fully specified forward module with 8.24-bit fixed point computation and 4.4bit table-based sigmoid activation function. Structure: 2 inputs, one 3-column hidden layer and 2 outputs.
9 10 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 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/HDLRuby/hdr_samples/neural/forward_sub.rb', line 9 system :forward_sub, forward( signed[31..0], # Data type [2,3,2], # NN structure [ # Input samples. # First input. [[_sh08000000, _sh08000000, _sh05000000, _sh05000000, *([_sh00000000]*28)], # Second input. [_sh08000000, _sh05000000, _sh08000000, _sh05000000, *([_sh00000000]*28)]], # Expected outputs # First output [[_sh01000000, _sh00000000, _sh00000000, _sh00000000, *([_sh00000000]*28)], # Second output [_sh00000000, _sh01000000, _sh01000000, _sh01000000, *([_sh00000000]*28)]] ], # Biases initial values [ # Second column [_shFF000000, _shFF000000, _shFF000000], # Third column [_shFF000000, _shFF000000] ], # Weights initial values [ # Second column [ # First neuron [ _sh00199999, _sh00666666 ], # Second neuron [ _sh004CCCCC, _sh00800000 ], # Third neuron [ _sh00999999, _sh00199999 ] ], # Third column [ # First neuron [ _sh00B33333, _sh00333333, _sh0014CCCC ], # Second neuron [ _sh00333333, _sh00800000, _sh01199999 ] ] ], # The activation function. proc{|addr| sigmoid(8,4,32,24,addr)}, # The sum of production function. proc do |xs,ws| (xs.zip(ws).map { |x,w| x*w }.reduce(:+))[27..20] end ) do end |
#hello_mix(u, v, w) ⇒ Object
10 11 12 13 14 15 16 |
# File 'lib/HDLRuby/high_samples/functions.rb', line 10 def hello_mix(u,v,w) puts "hello_mix" par do inner :something w <= u - v end end |
#hello_out ⇒ Object
6 7 8 |
# File 'lib/HDLRuby/high_samples/functions.rb', line 6 def hello_out puts "hello_out" end |
#lut84(content, addr) ⇒ Object
A test of def.
2 3 4 5 |
# File 'lib/HDLRuby/hdr_samples/with_def.rb', line 2 def lut84(content,addr) bit[8][-4].inner tbl? => content.to_a tbl![addr] end |
#make_reg(name, &blk) ⇒ Object
Function generating a register declaration.
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/HDLRuby/high_samples/registers.rb', line 123 def make_reg(name,&blk) system name do |*arg| input :clk, :rst blk.(*arg).input :d blk.(*arg).output :q,:qb qb <= ~q (q <= d & [~rst]*blk.(*arg).width).at(clk.posedge) end end |
#make_reg_body(typ) ⇒ Object
Function generating the body of a register description.
87 88 89 90 91 92 93 94 |
# File 'lib/HDLRuby/high_samples/registers.rb', line 87 def make_reg_body(typ) input :clk, :rst typ.input :d typ.output :q,:qb qb <= ~q (q <= d & [~rst]*typ.width).at(clk.posedge) end |
#mem ⇒ Object
Module generating a lookup table memory. Params:
- +inT+: the data type of the input (address).
- +outT+: the data type of the output (data).
- +ar+: the contents of the memory as an array.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/HDLRuby/hdr_samples/neural/mem.rb', line 7 system :mem do |inT,outT,ar| # The control signals. input :clk # Clock input :din # Read enable # The interface signals. inT.input :addr # Address outT.output :data # Data # The memory. outT[ar.size].inner :contents # Fills the memory (static) # ar.each.with_index do |val,i| # contents[i] <= val # end contents <= ar # Handle the access to the memory. par(clk.posedge) do hif(din == 1) { data <= contents[addr] } helse { data <= :"_#{"z"*outT.width}" } end end |
#rand_array(geometry, width) ⇒ Object
Generates a N-dimension array described by +geometry+ filled with +width+ bit values.
8 9 10 11 12 13 14 15 16 |
# File 'lib/HDLRuby/hdr_samples/neural/random.rb', line 8 def rand_array(geometry,width) if geometry.is_a?(Array) then # Geometry is hierarchical, recurse on it. return geometry.map {|elem| rand_array(elem,width) } else # Geometry is a size of a 1-D array, generate it. return geometry.times.map { |i| rand_signed(width) } end end |
#rand_signed(width) ⇒ Object
Generate a +width+ bit (signed) random value.
2 3 4 |
# File 'lib/HDLRuby/hdr_samples/neural/random.rb', line 2 def rand_signed(width) :"_s#{width.times.map { Random.rand(0..1).to_s }.join }".to_expr end |
#rom_gen(addr, &func) ⇒ Object
Rom access generator, def case.
2 3 4 5 |
# File 'lib/HDLRuby/hdr_samples/rom_nest.rb', line 2 def rom_gen(addr,&func) bit[8][-8].constant tbl? => 8.times.map {|i| func.(i).to_i } tbl![addr] end |
#selector ⇒ Object
Module generating the selector that decides if a neuron is to update or not. Params:
- +skip+: the number of clocks to skip.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/HDLRuby/hdr_samples/neural/selector.rb', line 5 system :selector do |skip| input :clk, :reset output :enable_update # The clock counter. [Math::log2(skip).ceil].inner :counter # The behavior handling the skip counter par(clk.posedge) do hif(reset == 1) { counter <= 0 } helse do hif(counter == skip-1) { counter <=0 } helse {counter <= counter + 1 } end end # The behavior handling the update signal par(clk.posedge) do hif(reset == 1) { enable_update <= 0 } helse do hif(counter == skip-1) { enable_update <= 1 } helse { enable_update <= 0 } end end end |
#sigmoid(a_width, a_point, d_width, d_point, addr) ⇒ Object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/HDLRuby/hdr_samples/neural/sigmoid.rb', line 1 def sigmoid(a_width, a_point, d_width, d_point, addr) # Initialize the result to force it as a ruby variable. High.cur_system.open do sub do # Generates the rom [d_width][2**a_width].inner :contents contents <= (2**a_width).times.map do |i| # Converts i to a float i = i.to_f * 2**(-a_point) # Compute the sigmoid sigm = (1.0 / (1+Math.exp(i))) # Convert it to fixed point (sigm * 2**d_point).to_i end # Use it for the access contents[addr[(a_point+d_width-1-d_point)..a_point-d_point]] end end end |
#times_loop(clk_e, num, &ruby_block) ⇒ Object
Loop +num+ times executing +ruby_block+. The loop is synchronized on +clk_e+.
91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/HDLRuby/std/loop.rb', line 91 def times_loop(clk_e, num, &ruby_block) # Compute the width of the counter. width = num.respond_to?(:width) ? num.width : num.type.width # Declares the counter. cnt = [width].inner(HDLRuby.uniq_name) # Create the loop. return while_loop(clk_e, proc{cnt<=0}, cnt<num) do cnt <= cnt + 1 ruby_block.call end end |
#which(cmd) ⇒ Object
Locate an executable from cmd.
256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/HDLRuby/hdrcc.rb', line 256 def which(cmd) # Get the possible exetensions (for windows case). exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] # Look for the command within the executable paths. ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| exts.each do |ext| exe = File.join(path, "#{cmd}#{ext}") return exe if File.executable?(exe) && !File.directory?(exe) end end nil end |
#while_loop(clk_e, init, condition = nil, &ruby_block) ⇒ Object
A simplified loop: loops until +condition+ is met execution +ruby_block+. The loop is synchronized on +clk_e+ and initialized by +init+. If +condition+ is nil, then +init+ is used as +condition+.
80 81 82 83 84 85 86 87 |
# File 'lib/HDLRuby/std/loop.rb', line 80 def while_loop(clk_e, init, condition = nil, &ruby_block) # Create the loop task. tsk = while_task(clk_e,init,condition,ruby_block).(HDLRuby.uniq_name) # Create the inner access port. prt = tsk.inner HDLRuby.uniq_name # Return the access port. return prt end |
#while_task ⇒ Object
While loop: loops until +condition+ is met execution +ruby_block+. The loop is synchronized on +clk_e+ and initialized by +init+. If +condition+ is nil, then +init+ is used as +condition+.
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/HDLRuby/std/loop.rb', line 13 HDLRuby::High::Std.task(:while_task) do |clk_e, init, condition, ruby_block| # Ensure clk_e is an event, if not set it to a positive edge. clk_e = clk_e.posedge unless clk_e.is_a?(Event) # Ensures there is a condition. unless condition then condition = init init = nil end # Transform condition into a proc if it is not the case. unless condition.is_a?(Proc) then condition_expr = condition condition = proc { condition_expr } end # Ensures init to be a proc if not nil init = init.to_proc unless init == nil # Declares the signals for controlling the loop. inner :req # Signal to set to 1 for running the loop. # Declares the runner signals. runner_output :req par(clk_e) do # Performs the loop. hif(req) do # By default the loop is not finished. # If the condition is still met go on looping. hif(condition.call,&ruby_block) end # # if (init) then # # # There is an initialization, do it when there is no req. # # helse do # # init.call # # end # # end end # The code for reseting the task. if (init) then # reseter(&init) reseter do req <= 0 init.call end end # The code for running the task. runner do # top_block.unshift { req <= 0 } req <= 1 end # The code for checking the end of execution. finisher do |blk| hif(~condition.call,&blk) end end |
#xcd_generator(top, path) ⇒ Object
Generates a xcd file from the HDLRuby objects from +top+ using their 'xcd' properties. The file is saved in +path+ directory.
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 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 |
# File 'lib/HDLRuby/drivers/xcd.rb', line 11 def xcd_generator(top, path) # Ensure top is a system. if top.is_a?(HDLRuby::Low::SystemI) then top = top.systemT elsif !top.is_a?(HDLRuby::Low::SystemT) then raise "The 'xcd_generator' driver can only be applied on SystemT objects." end # Get the name of the resulting file if any. if (top.properties.key?(:xcd_file)) then xcd_file = top.properties[:xcd_file].join else # Default file name. xcd_file = "default.xcd" end # Get the target template. xcd_target = top.properties[:xcd_target].join xcd_target_name = xcd_target xcd_target_name += ".xcd" unless xcd_target_name.end_with?(".xcd") xcd_target_tries = [ xcd_target_name, File.join(path,xcd_target_name), File.join(File.dirname(__FILE__),"xcd",xcd_target_name) ] xcd_target_file = xcd_target_tries.find { |fname| File.exist?(fname) } unless xcd_target_file then raise "XCD target template not found for #{xcd_target}." end # Load the template. template = File.read(xcd_target_file) # Gather the signals by xcd key. xcd2sig = top.each_signal.reduce([]) do |ar,sig| ar += sig.properties.each_with_key(:xcd).map do |val| [val,sig.name.to_s] end end # Create the template expander that will generate the xcd file. = TemplateExpander.new([ [ /^\?.*(\n|\z)/, proc do |str| # Signal link to port if xcd2sig.any? do |match,rep| if str.include?(match) then str = str.gsub("<>",rep)[1..-1] else false end end then str else "" end end ] ]) # # Generate the xcd file. # File.open(File.join(path,xcd_file),"w") do |file| # # Generate the signals mapping. # top.each_signal do |signal| # signal.properties.each_with_key(:xcd) do |value| # file << "#{value}\n" # end # end # end # Generate the xcd file. File.open(File.join(path,xcd_file),"w") do |file| .(template,file) end end |
#z ⇒ Object
Module generating a neuron sum. Params:
- +typ+: the data type of the neural signals.
- +ary+: the arity of the neuron.
- +sopP+: the sum of product function.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/HDLRuby/hdr_samples/neural/z.rb', line 7 system :z do |typ,ary,sopP| # The control signals. input :clk, :reset # Clock and reset # The inputs of the neuron. ins = [] wgs = [] ary.times do |i| # The input values ins << typ.input(:"x#{i}") end ary.times do |i| # The weights wgs << typ.input(:"w#{i}") end # The bias typ.input :bias # The sum output typ.output :z # Behavior controlling the bias/weight par(clk.posedge) do hif(reset == 1) { z <= 0 } helse { z <= sopP.(ins + [1],wgs + [bias]) } end end |