module HDLRuby::High::Std ## # Standard HDLRuby::High library: connectors between channels # ######################################################################## # Function for generating a connector that duplicates the output of # channel +in_ch+ and connect it to channels +out_chs+ with data of # +typ+. # The duplication is done according to event +ev+. function :duplicator do |typ, ev, in_ch, out_chs| ev = ev.poswedge unless ev.is_a?(Event) inner :in_ack, :in_req out_acks = out_chs.size.times.map { |i| inner(:"out_ack#{i}") } typ.inner :data par(ev) do in_req <= 1 out_acks.each { |ack| ack <= 0 } out_acks.each do |ack| hif(ack == 1) { in_req <= 0 } end hif(in_req) do in_ack <= 0 in_ch.read(data) { in_ack <= 1 } end hif(in_ack) do out_chs.zip(out_acks).each do |ch,ack| hif(ack == 0) { ch.write(data) { ack <= 1 } } end hif (out_acks.reduce(_1) { |sum,ack| ack & sum }) do out_acks.each { |ack| ack <= 0 } end end end end # Function for generating a connector that merges the output of # channels +in_chs+ and connects the result to channel +out_ch+ with # data of +typ+. # The merge is done according to event +ev+. function :merger do |typs, ev, in_chs, out_ch| ev = ev.posedge unless ev.is_a?(Event) inner :out_ack in_reqs = in_chs.size.times.map { |i| inner(:"in_req#{i}") } in_acks = in_chs.size.times.map { |i| inner(:"in_ack#{i}") } datas = typs.map.with_index { |typ,i| typ.inner(:"data#{i}") } par(ev) do in_reqs.each { |req| req <= 1 } out_ack <= 0 hif(out_ack == 1) { in_reqs.each { |req| req <= 0 } } hif(in_reqs.reduce(_1) { |sum,req| req & sum }) do in_chs.each_with_index do |ch,i| in_acks[i] <= 0 ch.read(datas[i]) { in_acks[i] <= 1 } end end hif(in_acks.reduce(_1) { |sum,req| req & sum }) do hif(out_ack == 0) { out_ch.write(datas) { out_ack <= 1 } } hif (out_ack == 1) { out_ack <= 0 } end end end end