class HDLRuby::BitString

Describes a bit string.

NOTE:

Used to output bitstring. Enhance HDLRuby with generation of verilog code.

Constants

AND_T

And truth table: 0, 1, 2=z, 3=x

BITWISE

Table of bitwise operations

FALSE
GT_T

Greater than truth table: 0, 1, 2=z, 3=x

LT_T

Lower than truth table: 0, 1, 2=z, 3=x

MAJ_T

Majority truth table: 0, 1, 2=z, 3=x

MINUS_ONE
MINUS_THREE
MINUS_TWO
NOT_T

Not truth table

ONE
OR_T

Or truth table: 0, 1, 2=z, 3=x

THREE
TRUE

A few common bit strings.

TWO
UNKNOWN
XOR3_T

Double xor truth table: 0, 1, 2=z, 3=x

XOR_T

Xor truth table: 0, 1, 2=z, 3=x

ZERO

Public Class Methods

bitwise_add(s0,s1) click to toggle source

Bitwise addition

# File lib/HDLRuby/hruby_bstr.rb, line 476
def self.bitwise_add(s0,s1)
    res = ""  # The result list of bits
    c   = "0" # The current carry
    s0.each.zip(s1.each) do |b0,b1|
        res << XOR3_T[b0][b1][c]
        c = MAJ_T[b0][b1][c]
    end
    # Compute the sign extension (the sign bit of s0 and s1 is used
    # again)
    res << XOR3_T[s0.sign][s1.sign][c]
    return BitString.new(res.reverse)
end
bitwise_add0(s0,s1) click to toggle source

Bitwise addition without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 471
def self.bitwise_add0(s0,s1)
    return BitString.new("x"*(s0.width+1))
end
bitwise_and(s0,s1) click to toggle source

Bitwise and

# File lib/HDLRuby/hruby_bstr.rb, line 536
def self.bitwise_and(s0,s1)
    res = s0.each.zip(s1.each).map { |b0,b1| AND_T[b0][b1] }.join
    # puts "s0=#{s0}, s1=#{s1}, res=#{res}"
    return BitString.new(res.reverse)
end
bitwise_cp(s0,s1) click to toggle source

Bitwise cp.

# File lib/HDLRuby/hruby_bstr.rb, line 744
def self.bitwise_cp(s0,s1)
    # Compare the signs.
    if s0.sign == "0" and s1.sign == "1" then
        return ONE
    elsif s0.sign == 0 and s1.sign == "1" then
        return MINUS_ONE
    end
    # Compare the other bits.
    sub = self.bitwise_sub(s0,s1)
    if sub.negative? then
        return MINUS_ONE
    elsif sub.zero? then
        return ZERO
    elsif sub.positive? then
        return ONE
    else
        return UNKNOWN
    end
end
bitwise_cp0(s0,s1) click to toggle source

Bitwise cp without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 739
def self.bitwise_cp0(s0,s1)
    return UNKNOWN
end
bitwise_div(s0,s1) click to toggle source

Bitwise div.

# File lib/HDLRuby/hruby_bstr.rb, line 805
def self.bitwise_div(s0,s1)
    width = s0.width
    # The zero cases.
    if s0.zero? then
        return res
    elsif s1.maybe_zero? then
        return UNKNOWN.extend(width)
    end
    # Handle the sign: the division is only performed on positive
    # numbers.
    # NOTE: we are sure that s0 and s1 are not zero since these
    # cases have been handled before.
    sign = nil
    if s0.sign == "0" then
        if s1.sign == "0" then
            sign = "0"
        elsif s1.sign == "1" then
            sign = "1"
            s1 = -s1
        else
            # Unknown sign, unkown result.
            return UNKNOWN.extend(width)
        end
    elsif s0.sign == "1" then
        s0 = -s0
        if s1.sign == "0" then
            sign = "1"
        elsif s1.sign == "1" then
            sign = "0"
            s1 = -s1
        else
            # Unknwown sign, unknown result.
            return UNKNOWN.extend(width)
        end
    else
        # Unknown sign, unknown result.
        return UNKNOWN.extend(width)
    end
    # Convert s0 and s1 to list of bits of widths of s0 and s1 -1
    # (the largest possible value).
    # s0 will serve as current remainder.
    s0 = BitString.new(s0) if s0.is_a?(Numeric)
    s1 = BitString.new(s1) if s1.is_a?(Numeric)
    s0 = s0.extend(s0.width+s1.width-1)
    s1 = s1.extend(s0.width)
    s0 = s0.to_list
    s1 = s1.to_list
    puts "first s1=#{s1}"
    # Adujst s1 to the end of s0 and the corresponding 0s in front of q
    msb = s0.reverse.index {|b| b != 0}
    steps = s0.size-msb
    self.list_shl!(s1,steps-1)
    q = [ 0 ] * (width-steps)
    # Apply the non-restoring division algorithm.
    sub = true
    puts "steps= #{steps} s0=#{s0} s1=#{s1} q=#{q}"
    (steps).times do |i|
        if sub then
            self.list_sub!(s0,s1)
        else
            self.list_add!(s0,s1)
        end
        puts "s0=#{s0}"
        # Is the result positive?
        if s0[-1] == 0 then
            # Yes, the next step is a subtraction and the current
            # result bit is one.
            sub = true
            q.unshift(1)
        elsif s0[-1] == 1 then
            # No, it is negative the next step is an addition and the
            # current result bit is zero.
            sub = false
            q.unshift(0)
        else
            # Unknown sign, the remaining of q is unknown.
            (steps-i).times { q.unshift(self.new_unknown) }
            # Still, can add the positive sign bit.
            q.push(0)
            break
        end
        self.list_shr_1!(s1)
    end
    # Generate the resulting bit string.
    puts "q=#{q}"
    q = self.list_to_bstr(q)
    puts "q=#{q}"
    # Set the sign.
    if sign == "1" then
        q = (-q).trunc(width)
    elsif q.zero? then
        q = 0
    else
        q = q.extend(width)
    end
    # Return the result.
    return q
end
bitwise_div0(s0,s1) click to toggle source

Bitwise div without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 800
def self.bitwise_div0(s0,s1)
    return BitString.new("x"*(s0.width))
end
bitwise_eq(s0,s1) click to toggle source

Bitwise eq.

# File lib/HDLRuby/hruby_bstr.rb, line 594
def self.bitwise_eq(s0,s1)
    return UNKNOWN unless (s0.specified? and s1.specified?)
    return s0.str == s1.str ? TRUE : FALSE
end
bitwise_eq0(s0,s1) click to toggle source

Bitwise eq without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 589
def self.bitwise_eq0(s0,s1)
    return UNKNOWN
end
bitwise_ge(s0,s1) click to toggle source

Bitwise ge.

# File lib/HDLRuby/hruby_bstr.rb, line 726
def self.bitwise_ge(s0,s1)
    lt = self.bitwise_lt(s0,s1)
    if lt.eql?(TRUE) then
        return FALSE
    elsif lt.eql?(FALSE) then
        return TRUE
    else
        return UNKNOWN
    end
end
bitwise_ge0(s0,s1) click to toggle source

Bitwise ge without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 721
def self.bitwise_ge0(s0,s1)
    return UNKNOWN
end
bitwise_gt(s0,s1) click to toggle source

Bitwise gt.

# File lib/HDLRuby/hruby_bstr.rb, line 697
def self.bitwise_gt(s0,s1)
    return self.bitwise_lt(s1,s0)
end
bitwise_gt0(s0,s1) click to toggle source

Bitwise gt without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 692
def self.bitwise_gt0(s0,s1)
    return UNKNOWN
end
bitwise_le(s0,s1) click to toggle source

Bitwise le.

# File lib/HDLRuby/hruby_bstr.rb, line 708
def self.bitwise_le(s0,s1)
    gt = self.bitwise_gt(s0,s1)
    if gt.eql?(TRUE) then
        return FALSE
    elsif gt.eql?(FALSE) then
        return TRUE
    else
        return UNKNOWN
    end
end
bitwise_le0(s0,s1) click to toggle source

Bitwise le without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 703
def self.bitwise_le0(s0,s1)
    return UNKNOWN
end
bitwise_lt(s0,s1) click to toggle source

Bitwise lt.

# File lib/HDLRuby/hruby_bstr.rb, line 606
def self.bitwise_lt(s0,s1)
    # # Handle the zero cases.
    # if s0.zero? then
    #     return TRUE if s1.positive?
    #     return FALSE if s1.negative? or s1.zero?
    #     return UNKNOWN
    # elsif s1.zero? then
    #     return TRUE if s0.negative?
    #     return FALSE if s0.positive? or s0.zero?
    #     return UNKNOWN
    # end
    # # Handle the unspecified sign cases.
    # unless s0.sign? then
    #     # Check both sign cases.
    #     lt_pos = self.bitwise_lt(s0[-1] = "1",s1)
    #     lt_neg = self.bitwise_lt(s0[-1] = "0",s1)
    #     # At least one of the results is unspecified.
    #     return UNKNOWN unless (lt_pos.specified? and lt_neg.specified?)
    #     # Both results are specified and identical.
    #     return lt_pos if lt_pos == lt_neg
    #     # Results are different.
    #     return UNKNOWN
    # end
    # unless s1.sign? then
    #     # Check both sign cases.
    #     lt_pos = self.bitwise_lt(s0,s1[-1] = "1")
    #     lt_neg = self.bitwise_lt(s0,s1[-1] = "0")
    #     # At least one of the results is unspecified.
    #     return UNKNOWN unless (lt_pos.specified? and lt_neg.specified?)
    #     # Both results are specified and identical.
    #     return lt_pos if lt_pos == lt_neg
    #     # Results are different.
    #     return UNKNOWN
    # end
    # # Signs are specificied.
    # # Depending on the signs
    # if s0.positive? then
    #     if s1.positive? then
    #         # s0 and s1 are positive, need to compare each bit.
    #         s0.reverse_each.zip(s1.reverse_each) do |b0,b1|
    #             # puts "b0=#{b0} b1=#{b1}, LT_T[b0][b1]=#{LT_T[b0][b1]}"
    #             case LT_T[b0][b1]
    #             when "x" then return UNKNOWN
    #             when "1" then return TRUE
    #             when "0" then
    #                 return FALSE if GT_T[b0][b1] == "1"
    #             end
    #         end
    #     elsif s1.negative? then
    #         # s0 is positive and s1 is negative.
    #         return FALSE
    #     else
    #         # The sign of s1 is undefined, comparison is undefined too.
    #         return UNKNOWN
    #     end
    # elsif s0.negative? then
    #     if s1.positive? then
    #         # s0 is negative and s1 is positive
    #         return TRUE
    #     elsif s1.negative? then
    #         # s0 and s1 are negative, need to compare each bit.
    #         s0.reverse_each.zip(s1.reverse_each) do |b0,b1|
    #             case GT_T[b0][b1]
    #             when "x" then return UNKNOWN
    #             when "1" then return FALSE
    #             when "0" then
    #                 return TRUE if LT_T[b0][b1] == "1"
    #             end
    #         end
    #     end
    # else
    #     # The sign of s0 is undefined, comparison is undefined too.
    #     return UNKNOWN
    # end

    # Check the sign of the subtraction between s0 and s1.
    case (s0-s1).sign
    when "0" then return FALSE
    when "1" then return TRUE
    else 
        return UNKNOWN
    end
end
bitwise_lt0(s0,s1) click to toggle source

Bitwise lt without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 601
def self.bitwise_lt0(s0,s1)
    return UNKNOWN
end
bitwise_mod0(s0,s1) click to toggle source

Bitwise mod without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 906
def self.bitwise_mod0(s0,s1)
    return BitString.new("x"*(s1.width))
end
bitwise_mul(s0,s1) click to toggle source

Bitwise mul.

# File lib/HDLRuby/hruby_bstr.rb, line 770
def self.bitwise_mul(s0,s1)
    # Initialize the result to ZERO of combined s0 and s1 widths
    res = ZERO.extend(s0.width + s1.width)
    # The zero cases.
    if s0.zero? or s1.zero? then
        return res
    end
    # Convert s1 and res to lists of bits which support computation
    # between unknown bits of same values.
    s1 = s1.extend(res.width).to_list
    res = res.to_list
    # The other cases: perform a multiplication with shifts and adds.
    s0.each.lazy.take(s0.width).each do |b|
        case b
        when "1" then self.list_add!(res,s1)
        when "x","z" then self.list_add!(res,self.list_and_unknown(s1))
        end
        # puts "res=#{res} s1=#{s1}"
        self.list_shl_1!(s1)
    end
    # Add the sign row.
    case s0.sign
    when "1" then self.list_sub!(res,s1)
    when "x","z" then self.list_sub!(res,list_and_unknown(s1))
    end
    # Return the result.
    return self.list_to_bstr(res)
end
bitwise_mul0(s0,s1) click to toggle source

Bitwise mul without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 765
def self.bitwise_mul0(s0,s1)
    return BitString.new("x"*(s0.width+s1.width))
end
bitwise_neg(s) click to toggle source

Bitwise negation

# File lib/HDLRuby/hruby_bstr.rb, line 526
def self.bitwise_neg(s)
    # -s = ~s + 1
    # # Not s.
    # s = BitString.bitwise_not(s)
    # # Add 1.
    # return BitString.bitwise_add(s,ONE.extend(s.width))
    return ~s + 1
end
bitwise_neg0(s) click to toggle source

Bitwise negation without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 521
def self.bitwise_neg0(s)
    return BitString.new("x"*(s.width+1))
end
bitwise_not(s) click to toggle source

Bitwise not

# File lib/HDLRuby/hruby_bstr.rb, line 555
def self.bitwise_not(s)
    return BitString.new(s.each.map { |b| NOT_T[b] }.join.reverse)
end
bitwise_or(s0,s1) click to toggle source

Bitwise or

# File lib/HDLRuby/hruby_bstr.rb, line 543
def self.bitwise_or(s0,s1)
    res = s0.each.zip(s1.each). map { |b0,b1| OR_T[b0][b1] }.join
    return BitString.new(res.reverse)
end
bitwise_pos(s) click to toggle source

Bitwise positive sign: does nothing.

# File lib/HDLRuby/hruby_bstr.rb, line 516
def self.bitwise_pos(s)
    return s
end
bitwise_shl(s0,s1) click to toggle source

Bitwise shift left.

# File lib/HDLRuby/hruby_bstr.rb, line 560
def self.bitwise_shl(s0,s1)
    # puts "s0=#{s0} s1=#{s1}"
    return BitString.new("x" * s0.width) unless s1.specified?
    s1 = s1.to_numeric
    if s1 >= 0 then
        return BitString.new(s0.str + "0" * s1)
    elsif -s1 > s0.width then
        return ZERO
    else
        return s0.trim(s0.width+s1)
    end
end
bitwise_shr(s0,s1) click to toggle source

Bitwise shift right.

# File lib/HDLRuby/hruby_bstr.rb, line 574
def self.bitwise_shr(s0,s1)
    # puts "s0=#{s0} s1=#{s1}"
    return BitString.new("x" * s0.width) unless s1.specified?
    s1 = s1.to_numeric
    if s1 <= 0 then
        return BitString.new(s0.str + "0" * -s1)
    elsif s1 > s0.width then
        return ZERO
    else
        return s0.trim(s0.width-s1)
    end
end
bitwise_sub(s0,s1) click to toggle source

Bitwise subtraction

# File lib/HDLRuby/hruby_bstr.rb, line 495
def self.bitwise_sub(s0,s1)
    # # Negate s1.
    # s1 = BitString.bitwise_neg(s1).trunc(s0.width)
    # # puts "s1.width = #{s1.width} s0.width = #{s0.width}"
    # # Add it to s0: but no need to add a bit since neg already added
    # # one.
    # return BitString.bitwise_add(s0,s1)
    # Perform the computation is a way to limit the propagation of
    # unspecified bits.
    # Is s1 specified?
    if s1.specified? then
        # Yes, perform -s1+s0
        return (-s1 + s0)
    else
        # No, perform s0+1+NOT(s1).
        # puts "s0=#{s0} s0+1=#{s0+1} not s1=#{bitwise_not(s1)}"
        return (s0 + 1 + bitwise_not(s1)).trunc(s0.width+1)
    end
end
bitwise_sub0(s0,s1) click to toggle source

Bitwise subtraction without processing of the x and z states.

# File lib/HDLRuby/hruby_bstr.rb, line 490
def self.bitwise_sub0(s0,s1)
    return BitString.new("x"*(s0.width+1))
end
bitwise_xor(s0,s1) click to toggle source

Bitwise xor

# File lib/HDLRuby/hruby_bstr.rb, line 549
def self.bitwise_xor(s0,s1)
    res = s0.each.zip(s1.each). map { |b0,b1| XOR_T[b0][b1] }.join
    return BitString.new(res.reverse)
end
list_add!(l0,l1) click to toggle source

Adds l1 to l0.

NOTE:

  • l0 is contains the result.

  • The result has the same size as l0 (no sign extension).

  • Assumes l0 and l1 have the same size.

# File lib/HDLRuby/hruby_bstr.rb, line 978
def self.list_add!(l0,l1)
    # puts "add l0=#{l0} l1=#{l1}"
    c = 0 # Current carry.
    l0.each_with_index do |b0,i|
        b1 = l1[i]
        # puts "i=#{i} b0=#{b0} b1=#{b1} c=#{c}"
        if b0 == b1 then
            # The sum is c.
            l0[i] = c
            # The carry is b0.
            c = b0
        elsif b0 == c then
            # The sum is b1.
            l0[i] = b1
            # The carry is b0.
            c = b0
        elsif b1 == c then
            # The sum is b0.
            l0[i] = b0
            # The carry is b1.
            c = b1
        else
            l0[i] = self.new_unknown
            c = self.new_unknown
        end
    end
    return l0
end
list_add_1!(l0) click to toggle source

Adds 1 to l0.

NOTE:

  • l0 is contains the result.

  • The result has the same size as l0 (no sign extension).

# File lib/HDLRuby/hruby_bstr.rb, line 1012
def self.list_add_1!(l0)
    c = 1 # Current carry.
    l0.each_with_index do |b0,i|
        if c == 0 then
            # The sum is b0.
            l0[i] = b0
            # The carry is unchanged.
        elsif b0 == 0 then
            # The sum is c.
            l0[i] = c
            # The carry is 0.
            c = 0
        elsif b0 == c then
            # The sum is 0.
            l0[i] = 0
            # The carry is b0.
            c = b0
        else
            # Both sum and carry are unknown
            l0[i] = BitString.new_unknown
            c = BitString.new_unknown
        end
    end
    return l0
end
list_and_unknown(l) click to toggle source

Compute the and between l and an unknown value.

# File lib/HDLRuby/hruby_bstr.rb, line 954
def self.list_and_unknown(l)
    return l.map do |b|
        b == 0 ? 0 : BitString.new_unknown
    end
end
list_not(l) click to toggle source

Compute the not of l

# File lib/HDLRuby/hruby_bstr.rb, line 961
def self.list_not(l)
    return l.map do |b|
        case b
        when 0 then 1
        when 1 then 0
        else
            BitString.new_unknown
        end
    end
end
list_shl!(l,x) click to toggle source

Left shifts l x times.

NOTE:

  • l contains the result.

  • The result has the same size as l (no sign extension).

# File lib/HDLRuby/hruby_bstr.rb, line 1083
def self.list_shl!(l,x)
    l.pop(x)
    l.unshift(*([0]*x))
end
list_shl_1!(l) click to toggle source

Left shifts l once.

NOTE:

  • l contains the result.

  • The result has the same size as l (no sign extension).

# File lib/HDLRuby/hruby_bstr.rb, line 1060
def self.list_shl_1!(l)
    l.pop
    l.unshift(0)
    return l
end
list_shr_1!(l) click to toggle source

Right shifts l once.

NOTE:

  • l contains the result.

  • The result has the same size as l (no sign extension).

# File lib/HDLRuby/hruby_bstr.rb, line 1071
def self.list_shr_1!(l)
    l.shift
    l.push(0)
    return l
end
list_sub!(l0,l1) click to toggle source

Subtracts l1 from l0.

NOTE:

  • l0 is contains the result.

  • The result has the same size as l0 (no sign extension).

  • Assumes l0 and l1 have the same size.

# File lib/HDLRuby/hruby_bstr.rb, line 1044
def self.list_sub!(l0,l1)
    # Adds 1 to l0.
    BitString.list_add_1!(l0)
    # Adds ~l1 to l0.
    # puts "l0=#{l0} l1=#{l1} ~l1=#{self.list_not(l1)}}"
    self.list_add!(l0,self.list_not(l1))
    # puts "l0=#{l0}"
    # puts "now l0=#{l0}"
    return l0
end
list_to_bstr(l) click to toggle source

Converts list of bits l to a bit string.

# File lib/HDLRuby/hruby_bstr.rb, line 948
def self.list_to_bstr(l)
    str = l.reverse_each.map { |b| b > 1 ? "x" : b }.join
    return BitString.new(str)
end
new(str,sign = nil) click to toggle source

Creates a new bit string from str with sign.

NOTE:

  • sign can be “0”, “1”, “z” and “x”, is positive when “0” and negative when “1”.

  • when not present it is assumed to be within str.

# File lib/HDLRuby/hruby_bstr.rb, line 34
def initialize(str,sign = nil)
    # puts "str=#{str}"
    # Maybe str is an numeric.
    if str.is_a?(Numeric) then
        # Yes, convert it to a binary string.
        num = str
        str = num.to_s(2)
        # And fix the sign.
        if str[0] == "-" then
            # str = str[1..-1]
            str = (2**str.size+num).to_s(2)
            puts "str=#{str}"
            sign = "-"
        else
            sign = "+"
        end
        # puts "str=#{str} sign=#{sign}"
    end
    # Process the sign
    sign = sign.to_s unless sign.is_a?(Integer)
    case sign
    when 0, "0","+" then @str = "0"
    when 1, "1","-" then @str = "1"
    when 2, "z","Z" then @str = "z"
    when 3, "x","X" then @str = "x"
    when nil, ""    then @str = "" # The sign is in str
    else
        raise "Invalid bit string sign: #{sign}"
    end
    # Check and set the value of the bit string.
    if str.respond_to?(:to_a) then
        # Str is a bit list: convert it to a string.
        str = str.to_a.map do |e|
            case e
            when 0 then "0"
            when 1 then "1"
            when 2 then "z"
            when 3 then "x"
            else
                e
            end
        end.reverse.join
    end
    @str += str.to_s.downcase
    # puts "@str=#{@str}"
    unless @str.match(/^[0-1zx]+$/) then
        raise "Invalid value for creating a bit string: #{str}"
    end
end
new_unknown() click to toggle source

Creates a new uniq unknown bit.

# File lib/HDLRuby/hruby_bstr.rb, line 924
def self.new_unknown
    @@unknown += 1
    return @@unknown
end

Public Instance Methods

[](index) click to toggle source

Gets a bit by index.

NOTE: If the index is larger than the bit string width, returns the

bit sign.
# File lib/HDLRuby/hruby_bstr.rb, line 132
def [](index)
    # Handle the negative index case.
    if index < 0 then
        return self[self.width+index]
    end
    # Process the index.
    index = index > @str.size ? @str.size : index
    # Get the corresponding bit.
    return @str[-index-1]
end
[]=(index,value) click to toggle source

Sets the bit at index to value.

NOTE: when index is larger than the bit width, the bit string is sign extended accordingly.

# File lib/HDLRuby/hruby_bstr.rb, line 147
def []=(index,value)
    # Handle the negative index case.
    if index < 0 then
        return self[self.width+index] = value
    end
    # Duplicate the bit string content to ensure immutability.
    str = @str.clone
    # Process the index.
    if index >= str.size then
        # Overflow, sign extend the bit string.
        str += str[-1] * (index-str.size+1)
    end
    # Checks and convert the value
    value = make_bit(value)
    # Sets the value to a copy of the bit string.
    str[-index-1] = value
    # Return the result as a new bit string.
    return BitString.new(str)
end
coerce(other) click to toggle source

Coerces.

# File lib/HDLRuby/hruby_bstr.rb, line 252
def coerce(other)
    return [BitString.new(other),self]
end
each(&ruby_block) click to toggle source

Iterates over the bits.

NOTE: the sign bit in comprised.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_bstr.rb, line 204
def each(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each) unless ruby_block
    # A block? Apply it on each bit.
    @str.each_char.reverse_each(&ruby_block)
end
extend(width) click to toggle source

Extend to width.

NOTE:

  • if the width is already larger than width, do nothing.

  • preserves the sign.

# File lib/HDLRuby/hruby_bstr.rb, line 194
def extend(width)
   return self if width <= @str.size - 1
   return BitString.new(@str[0] * (width-@str.size+1) + @str)
end
maybe_zero?() click to toggle source

Tells if the bit string could be zero.

# File lib/HDLRuby/hruby_bstr.rb, line 118
def maybe_zero?
    return ! self.nonzero?
end
negative?() click to toggle source

Tells if the bit string is strictly negative.

NOTE: return false if the sign is undefined

# File lib/HDLRuby/hruby_bstr.rb, line 101
def negative?
    return @str[0] == "1"
end
nonzero?() click to toggle source

Tells if the bit string is not zero.

# File lib/HDLRuby/hruby_bstr.rb, line 113
def nonzero?
    return @str.each_char.any? {|b| b == "1" }
end
positive?() click to toggle source

Tells if the bit string is strictly.

NOTE: return false if the sign is undefined of if it is unknown

if the result is zero or not.
# File lib/HDLRuby/hruby_bstr.rb, line 94
def positive?
    return (@str[0] == "0" and self.nonzero?)
end
reverse_each(&ruby_block) click to toggle source

Reverse iterates over the bits.

NOTE: the sign bit in comprised.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_bstr.rb, line 216
def reverse_each(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:reverse_each) unless ruby_block
    # A block? Apply it on each bit.
    @str.each_char(&ruby_block)
end
sign() click to toggle source

Gets the sign of the bit string.

# File lib/HDLRuby/hruby_bstr.rb, line 224
def sign
    return @str[0]
end
sign?() click to toggle source

Tell if the sign is specified.

# File lib/HDLRuby/hruby_bstr.rb, line 229
def sign?
    return (@str[0] == "0" or @str[0] == "1")
end
size()
Alias for: width
specified?() click to toggle source

Tell if the bit string is fully specified

# File lib/HDLRuby/hruby_bstr.rb, line 247
def specified?
    return ! @str.match(/[xz]/)
end
str()
Alias for: to_s
to_list() click to toggle source

Converts to a list of bits where unknown or high z bits are differentiate from each other.

NOTE:

  • the sign bit is also added to the list.

  • the distinction between z and x is lost.

# File lib/HDLRuby/hruby_bstr.rb, line 935
def to_list
    return @str.each_char.reverse_each.map.with_index do |b,i|
        case b
        when "0"     then 0
        when "1"     then 1
        when "z","x" then BitString.new_unknown
        else
            raise "Internal error: invalid bit in bitstring: #{b}"
        end
    end
end
to_numeric() click to toggle source

Convert the bit string to a Ruby Numeric.

NOTE: the result will be wrong is the bit string is unspecified.

# File lib/HDLRuby/hruby_bstr.rb, line 236
def to_numeric
    res = 0
    # Process the bits.
    @str[1..-1].each_char { |b| res = res << 1 | b.to_i }
    # Process the sign.
    res = res - (2**(@str.size-1)) if @str[0] == "1"
    # Return the result.
    return res
end
to_s() click to toggle source

Converts to a string (sign bit is comprised).

# File lib/HDLRuby/hruby_bstr.rb, line 123
def to_s
    return @str.clone
end
Also aliased as: str
to_verilog() click to toggle source

Converts the system to Verilog code.

# File lib/HDLRuby/hruby_verilog.rb, line 1442
def to_verilog
    return "#{self.to_s}"
end
trim(width) click to toggle source

Trims to width.

NOTE:

  • trim remove the begining of the bit string.

  • if the width is already smaller than width, do nothing.

  • do not preserve the sign, but keep the last bit as sign bit.

# File lib/HDLRuby/hruby_bstr.rb, line 184
def trim(width)
    return self if width >= @str.size-1
    return BitString.new(@str[0..width])
end
trunc(width) click to toggle source

Truncs to width.

NOTE:

  • trunc remove the end of the bit string.

  • if the width is already smaller than width, do nothing.

  • do not preserve the sign, but keep the last bit as sign bit.

# File lib/HDLRuby/hruby_bstr.rb, line 173
def trunc(width)
    return self if width >= @str.size-1
    return BitString.new(@str[(@str.size-width-1)..-1])
end
width() click to toggle source

Gets the bitwidth.

# File lib/HDLRuby/hruby_bstr.rb, line 85
def width
    return @str.size
end
Also aliased as: size
zero?() click to toggle source

Tells if the bit string is zero.

NOTE: return false if the bit string is undefined.

# File lib/HDLRuby/hruby_bstr.rb, line 108
def zero?
    return ! @str.each_char.any? {|b| b != "0" }
end