Reputation: 41
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
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