编写 RTL 逻辑的问题
Issue in writing a RTL logic
假设我有一个总线 B。我想创建一个新的总线 C,如果 B 的相应索引为 1,其信号延迟与其索引成比例的幅度。让我用一个例子来解释假设我原来的总线 B(宽度为 5)的值为 10111,并且 B 永远保持在该值。现在我想让 C 变成这样:
clk 0: 00001
clk 1: 00011
clk 2: 00111
clk 3: 10111
(请注意,总线 B 中的第 3 位是 0,因此在位位置 2 之后,C 的 MSB(位位置 4)在下一个时钟中应该为高)。
下图是对应的波形
B[0] ,,,|'''''''''''''''''''''''''''''''''
B[1] ,,,|'''''''''''''''''''''''''''''''''
B[2] ,,,|'''''''''''''''''''''''''''''''''
B[3] ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
B[4] ,,,|'''''''''''''''''''''''''''''''''
clk ,,|''|,,|''|,,|''|,,|''|,,|''|,,|''|
C[0] ,,,|'''''''''''''''''''''''''''''''''
C[1] ,,,,,,,,,|'''''''''''''''''''''''''''
C[2] ,,,,,,,,,,,,,,,|'''''''''''''''''''''
C[3] ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
C[4] ,,,,,,,,,,,,,,,,,,,,,,|''''''''''''''
我如何使用 systemverilog 在 synthesizable RTL 逻辑中对此进行建模并且总是 block.I 正在寻找与此类似的东西(这只是一个伪代码):
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
我提出了一个 always 块的示例,它似乎可以完成您想要的部分,至少在模拟中是这样。它应该是可合成的,虽然我没有尝试过。它需要一个复位信号来设置初始值。所以,你可以尝试把它作为你探索的基地。
需要pos
指向当前位位置,根据B
(incr
)的位状态递增。
需要 done
才能使循环可综合。
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;
假设我有一个总线 B。我想创建一个新的总线 C,如果 B 的相应索引为 1,其信号延迟与其索引成比例的幅度。让我用一个例子来解释假设我原来的总线 B(宽度为 5)的值为 10111,并且 B 永远保持在该值。现在我想让 C 变成这样:
clk 0: 00001
clk 1: 00011
clk 2: 00111
clk 3: 10111
(请注意,总线 B 中的第 3 位是 0,因此在位位置 2 之后,C 的 MSB(位位置 4)在下一个时钟中应该为高)。
下图是对应的波形
B[0] ,,,|'''''''''''''''''''''''''''''''''
B[1] ,,,|'''''''''''''''''''''''''''''''''
B[2] ,,,|'''''''''''''''''''''''''''''''''
B[3] ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
B[4] ,,,|'''''''''''''''''''''''''''''''''
clk ,,|''|,,|''|,,|''|,,|''|,,|''|,,|''|
C[0] ,,,|'''''''''''''''''''''''''''''''''
C[1] ,,,,,,,,,|'''''''''''''''''''''''''''
C[2] ,,,,,,,,,,,,,,,|'''''''''''''''''''''
C[3] ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
C[4] ,,,,,,,,,,,,,,,,,,,,,,|''''''''''''''
我如何使用 systemverilog 在 synthesizable RTL 逻辑中对此进行建模并且总是 block.I 正在寻找与此类似的东西(这只是一个伪代码):
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
我提出了一个 always 块的示例,它似乎可以完成您想要的部分,至少在模拟中是这样。它应该是可合成的,虽然我没有尝试过。它需要一个复位信号来设置初始值。所以,你可以尝试把它作为你探索的基地。
需要pos
指向当前位位置,根据B
(incr
)的位状态递增。
done
才能使循环可综合。
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;