Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    promach
    @promach
    @jbush001 By the way, is it true that "always@(posedge clk, posedge reset)" could only do asynchronous reset assertion, but not synchronous reset release ?
    promach
    @promach
    promach
    @promach
    @jbush001 should not have removed read_reset_synchronizer and write_reset_synchronizer
    promach
    @promach
    I think I have formally verified your afifo module. I will publish the code later for you
    @jbush001 by the way, will asynchronous reset assertion give rise to metastability ?
    promach
    @promach
    @jbush001 See https://verificationacademy.com/forums/systemverilog/cover-failed-asynchronous-fifo Your afifo module had passed bmc and induction verification, but failed cover(). Do you have any idea about this ?
    Jeff Bush
    @jbush001
    I don't know enough about what you're doing to say.
    promach
    @promach
    @jbush001 I got your afifo (even with clock gating feature) passing formal verification using SymbiYosys formal tool
    by the way, I am working on your round-robin arbiter. I do not quite understand what the purpose of update_lru signal. The code comment is not very clear to me. https://github.com/jbush001/NyuziProcessor/blob/master/hardware/core/rr_arbiter.sv#L33
    promach
    @promach
    Could I say that the output signal 'grant_oh' is to be used to drive https://i.imgur.com/3b3QqGJ.png ? But then, this does not look right to me either. Do you have any comment with regards to this imgur pic link ?
    Jeff Bush
    @jbush001
    The update_lru signal causes the priority to update. When it is low, grant_oh will remain the same, rather than jumping to the next ready unit. It's used when the resource cannot be used right away. For example, if the unit that the arbiter is controlling access to is not ready.
    I don't think this diagram is exactly it. It's missing the request logic, so it's a bit hard to compare.
    Jeff Bush
    @jbush001
    Notice the subtraction here. The borrow logic causes it to search to find the next set bit. One way of thinking of rr_arbiter is that it's a simplified ripple-borrow circuit that wraps around.
    I don't know if that helps.
    Jeff Bush
    @jbush001
    Nice job getting the afifo formally verified
    promach
    @promach

    @jbush001 Thanks for the verilog link.

    'base' is a one hot signal indicating the first request that should be considered for a grant.

    Huh ? And why ~(double_req-base) ?

    https://github.com/thomasrussellmurphy/stx_cookbook/blob/master/arbitration/arbiter.v#L41-L42

    The borrow logic causes it to search to find the next set bit. ??
    Jeff Bush
    @jbush001
    Yes, essentially
    It's a bit hard to visualize, so it can help to work through a few examples on paper
    promach
    @promach
    Why Bits counting algorithm ?
    Jeff Bush
    @jbush001
    the (n & (n - 1)) in the loop may look familiar
    promach
    @promach
    We are having ~(double_req-base) in the verilog code though
    Jeff Bush
    @jbush001
    Right. The double is used to make it wrap around.
    In kernigan's loop, it is clearing the lowest set bit from the result. In this case, we want to have only the lowest set bit in the result, which is the reason for the inversion.
    promach
    @promach
    The double is used to make it wrap around. <-- I am a bit confused
    promach
    @promach
    @jbush001 but this does not really make the inversion operation necessary. I can't see why we need to do the inversion
    Jeff Bush
    @jbush001
    On the double bit: consider the case where the requested bit is 0, but the base is 1. Without the doubling, this wouldn't grant any bits. But with the doubling, bit[WIDTH] will be granted. When the OR at the bottom of the module happens, this becomes bit 0. So it can "wrap" around to the low bits.
    Jeff Bush
    @jbush001
    On the inversion: it's a bit hard to explain clearly, I would suggest working a few examples manually. For me, there was a moment where it kind of clicked. The borrow ripple propagates through the zeroes, but stops when it hits the first 1. So only that first 1 will be flipped to a zero. When you take the inverse, it will become a 1, then you and them together and it stays 1 in the result. However, all of the other 1s in front of it will become zeros when you take the inverse. 0 & 1 = 0, so they will stay zeroes. The end result is that you have exactly one bit set.
    For example (in binary): 1100000 - 1 = 1011111
    ~1011111 = 0100000.
    1100000 & 0100000 = 0100000.
    it's kinda magical :)
    promach
    @promach
    @jbush001 input [WIDTH-1:0] base; seems redundant. We already had input [WIDTH-1:0] req;
    promach
    @promach
    @jbush001 Given that request = 3; in edaplayground simulation , base=2; or base=1; do not really affect the grant signal result. Why ?
    promach
    @promach
    In other words, why do we need base ?
    promach
    @promach

    @jbush001 Having read the section on arbiter with fairness in the Altera cookbook, I am a bit confused if arbiter.v is really a round-robin arbiter by itself alone.

    The index must be delivered in one-hot format for this implementation.
    To accomplish this, generate it from a round-robin shift register.
    If this is not possible, it needs a one-hot decoder.

    promach
    @promach

    @jbush001 Someone told me the following explanation :

    The base is an indication of where you want your priority to start from. In a round robin arbiter, you want to keep your base the previous winner left shifted by one.

    a & ~(a - b) gives you a one hot vector - that marks the position in which the first time you hit a 1 in a if you start walking left from the position where b is set.

    Here is an example. For simplicity let's consider WIDTH = 4. Let's say base = 'b0010. Let's say req = 'b1001. You would expect a round robin arbiter to output 'b1000. Now let's see how that works.

    double_req = 'b10011001.
    double_req & ~(double_req - base) =
    'b10011001 & ~('b10011001 - 'b0010) =
    'b10011001 & ~('b10010111) = 
    'b10011001 & 'b01101000 = 'b1000.

    Why do double_req ? Try working this out with req= 'b0001 and base = 'b0100. double_req just helps you with the wrap around.

    Other corner cases:

    req = 'b0010, base = 'b0010, you'd get 'b0010.
    req = 'b0011, base = 'b0010, you should get 'b0010 again. 
    req = 'b0110, base = 'b0010, you should get 'b0010.
    req = 'b0101, base = 'b0010, you get 'b0100.
    promach
    @promach
    @jbush001 must we have virtual channels at both input and output ports of each node within the Networks-on-Chip ?
    Jeff Bush
    @jbush001
    I'm not sure
    promach
    @promach
    @jbush001 For https://github.com/jbush001/NyuziProcessor/blob/master/hardware/core/oh_to_idx.sv#L40 , why use OR operation to avoid synthesizing priority encoder ? I have sent you an email asking about this just now.
        always_comb
        begin : convert
            index = 0;
            for (int oh_index = 0; oh_index < NUM_SIGNALS; oh_index++)
            begin
                if (one_hot[oh_index])
                begin
                    if (DIRECTION == "LSB0")
                        index |= oh_index[INDEX_WIDTH - 1:0];    // Use 'or' to avoid synthesizing priority encoder
                    else
                        index |= ~oh_index[INDEX_WIDTH - 1:0];
                end
            end
        end
    promach
    @promach
    @jbush001 this code will not work when it is not LSB0 and NUM_SIGNALS being not of power of two. Try to use NUM_SIGNALS = 5
    INDEX_WIDTH = $clog2(5) = 3
     if (one_hot[oh_index])  // one_hot[0] == 1
         index |= ~oh_index[INDEX_WIDTH - 1:0]; // ~000 == 111
    So, if we have input one_hot = 5'b00001, then we will arrive at output index = 3'b111 which is not the correct output