the freethinker
the freethinker

Reputation: 41

Issue in writing a RTL logic

Lets suppose that I have a bus B. I want to create a new bus C whose signals are delayed by a magnitude proportional to their index if the corresponding index of B is 1. Let me explain this with an example lets say my original bus B (of width 5) is having a value 10111 and B stays at this value forever. Now I want C to be like this:

clk 0: 00001
clk 1: 00011
clk 2: 00111
clk 3: 10111

(Note that 3rd bit is a 0 in bus B, hence after bit position 2 its the MSB of C (bit position 4) that should be high in the very next clock).

Below shown is the corresponding waveform.


B[0] ,,,|'''''''''''''''''''''''''''''''''
B[1] ,,,|'''''''''''''''''''''''''''''''''
B[2] ,,,|'''''''''''''''''''''''''''''''''
B[3] ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
B[4] ,,,|'''''''''''''''''''''''''''''''''

clk   ,,|''|,,|''|,,|''|,,|''|,,|''|,,|''|

C[0] ,,,|'''''''''''''''''''''''''''''''''
C[1] ,,,,,,,,,|'''''''''''''''''''''''''''
C[2] ,,,,,,,,,,,,,,,|'''''''''''''''''''''
C[3] ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
C[4] ,,,,,,,,,,,,,,,,,,,,,,|''''''''''''''

How can I model this in synthesizable RTL logic using systemverilog and always block.I am looking for something similar to this(This is just a pseuocode):

Logic[width-1:0][width-1:0] temp;
logic hit_zero; //This is a variable seen and modified by all the generated always blocks(I am not sure if that's allowed)
generate
   for (genvar i = 0; i < width; i++) begin
        always @(posedge clk) begin
              if (B[i] == 1) begin
                 temp[i] <= temp[i] << i;
                 if (hit_zero) begin
                   temp[i] <= temp[i] << (pos+1);
                   hit_zero <= 0;
                 end
                 pos <= i;
              end else begin
                 temp[i] <= temp[i] << i;
                 hit_zero <= 1;  
              end
              temp[i][0] <= B[i];
        end
   end
  endgenerate
  generate 
   for (genvar i = 0; i < width; i++) begin 
    assign C[i] = temp[i][i];
   end
  endgenerate

Upvotes: 0

Views: 146

Answers (1)

Serge
Serge

Reputation: 12344

I have come up with an example of a single always block which seems to do the part which you want, at least in simulation. It should be synthesizable, though i did not try it. It expects a reset signal to set up initial values. So, you can try to use it as a base for your exploration.

It needs pos to point to the current bit position, which gets incremented based on the bit state of the B (incr).

done is needed to make the loop synthesizable.

  logic clk, reset;
  logic [4:0] B,C;

  reg[4:0]creg;
  int pos;
  int incr;
  bit done;

  always @(posedge clk) begin
    if (reset) begin
      pos <= 0;
      creg <= 0;
    end
    else begin
      incr = 0;
      done = 0;
      for (int i = 0; i < 5; i++) begin
        if (!done && i >= pos) begin
          incr++;
          creg[i] <= B[i];
          if (B[i])
            done = 1;
        end
      end
      pos <= pos + incr;
    end
  end

  assign C = creg;

Upvotes: 2

Related Questions