可综合的 Verilog 模块化移位寄存器
Synthesizable Verilog modular shift register
我正在使用不同宽度的信号进行 LOTTT 流水线操作,并且想要一个 SYNTHESIZEABLE 模块,其中我可以传递 2 个参数:1) 管道数量 (L) 和 2) 信号宽度 (W)。
这样我只需要实例化模块并传递 2 个值,这比通过虚拟寄存器输入负载和信号传播负载要简单和强大得多......容易出错等等。
我已经写了一半的verilog代码,如果我错了,请您指正。
I AM FACING COMPILE ERROR ... SEE COMMENTS
*****************************************************************
PARTIAL VERILOG CODE FOR SERIAL IN SERIAL OUT SHIFT REGISTER WITH
1) Varying number of shifts / stages : L
2) Varying number of signal / register width : W
*****************************************************************
module SISO (clk, rst, Serial_in, Serial_out); // sIn -> [0|1|2|3|...|L-1] -> sOut
parameter L = 60; // Number of stages
parameter W = 60; // Width of Serial_in / Serial_out
input clk,rst;
input reg Serial_in;
output reg Serial_out;
// reg [L-1:0][W-1:0] R;
reg [L-1:0] R; // Declare a register which is L bit long
always @(posedge clk or posedge rst)
begin
if (rst) // Reset = active high
//**********************
begin
R[0] <= 'b0; // Exceptional case : feeding input to pipe
Serial_out <= 'b0; // Exceptional case : vomiting output from pipe
genvar j;
for(j = 1; j<= L; j=j+1) // Ensuring ALL registers are reset when rst = 1
begin : rst_regs // Block name = reset_the_registers
R[L] <= 'b0; // Verilog automatically assumes destination width @ just using 'b0
end
end
else
//**********************
begin
generate
genvar i;
for(i = 1; i< L; i=i+1)
begin : declare_reg
R[0] <= Serial_in; // <---- COMPILE ERROR POINTED HERE
R[L] <= R[L-1];
Serial_out <= R[L-1];
end
endgenerate;
end
//**********************
endmodule
//**********************
为什么这么复杂?下面的代码会更简单易懂:
module SISO #(
parameter L = 60, // Number of stages (1 = this is a simple FF)
parameter W = 60 // Width of Serial_in / Serial_out
) (
input clk, rst,
input [W-1:0] Serial_in,
output [W-1:0] Serial_out
);
reg [L*W-1:0] shreg;
always @(posedge clk) begin
if (rst)
shreg <= 0;
else
shreg <= {shreg, Serial_in};
end
assign Serial_out = shreg[L*W-1:(L-1)*W];
endmodule
但是,查看您的代码存在以下问题:
您将 Serial_in
声明为 input reg
。这是不可能的,input
不能是 reg
.
您正在 always 块中使用 generate..endgenerate
。 generate 块是一个模块项,不能在 always 块中使用。只需删除 generate
和 endgenerate
语句并将 i
声明为 integer
.
显然 Serial_in
和 Serial_out
必须声明为大小为 [W-1:0]
的向量。
您正在使用R
作为记忆。声明如下:reg [W-1:0] R [0:L-1]
.
你没有在 for 循环中使用 i
。显然,您打算将 R 的所有元素链接在一起,但您只是访问第 0 个、第 (L-1) 个和第 L 个元素。 (显然第 L 个元素不存在,这个数组将从 0 到 L-1。
我现在停止编写此列表,因为,对不起,我认为改进您发布的代码确实没有太多好处..
我正在使用不同宽度的信号进行 LOTTT 流水线操作,并且想要一个 SYNTHESIZEABLE 模块,其中我可以传递 2 个参数:1) 管道数量 (L) 和 2) 信号宽度 (W)。
这样我只需要实例化模块并传递 2 个值,这比通过虚拟寄存器输入负载和信号传播负载要简单和强大得多......容易出错等等。
我已经写了一半的verilog代码,如果我错了,请您指正。
I AM FACING COMPILE ERROR ... SEE COMMENTS
*****************************************************************
PARTIAL VERILOG CODE FOR SERIAL IN SERIAL OUT SHIFT REGISTER WITH
1) Varying number of shifts / stages : L
2) Varying number of signal / register width : W
*****************************************************************
module SISO (clk, rst, Serial_in, Serial_out); // sIn -> [0|1|2|3|...|L-1] -> sOut
parameter L = 60; // Number of stages
parameter W = 60; // Width of Serial_in / Serial_out
input clk,rst;
input reg Serial_in;
output reg Serial_out;
// reg [L-1:0][W-1:0] R;
reg [L-1:0] R; // Declare a register which is L bit long
always @(posedge clk or posedge rst)
begin
if (rst) // Reset = active high
//**********************
begin
R[0] <= 'b0; // Exceptional case : feeding input to pipe
Serial_out <= 'b0; // Exceptional case : vomiting output from pipe
genvar j;
for(j = 1; j<= L; j=j+1) // Ensuring ALL registers are reset when rst = 1
begin : rst_regs // Block name = reset_the_registers
R[L] <= 'b0; // Verilog automatically assumes destination width @ just using 'b0
end
end
else
//**********************
begin
generate
genvar i;
for(i = 1; i< L; i=i+1)
begin : declare_reg
R[0] <= Serial_in; // <---- COMPILE ERROR POINTED HERE
R[L] <= R[L-1];
Serial_out <= R[L-1];
end
endgenerate;
end
//**********************
endmodule
//**********************
为什么这么复杂?下面的代码会更简单易懂:
module SISO #(
parameter L = 60, // Number of stages (1 = this is a simple FF)
parameter W = 60 // Width of Serial_in / Serial_out
) (
input clk, rst,
input [W-1:0] Serial_in,
output [W-1:0] Serial_out
);
reg [L*W-1:0] shreg;
always @(posedge clk) begin
if (rst)
shreg <= 0;
else
shreg <= {shreg, Serial_in};
end
assign Serial_out = shreg[L*W-1:(L-1)*W];
endmodule
但是,查看您的代码存在以下问题:
您将
Serial_in
声明为input reg
。这是不可能的,input
不能是reg
.您正在 always 块中使用
generate..endgenerate
。 generate 块是一个模块项,不能在 always 块中使用。只需删除generate
和endgenerate
语句并将i
声明为integer
.显然
Serial_in
和Serial_out
必须声明为大小为[W-1:0]
的向量。您正在使用
R
作为记忆。声明如下:reg [W-1:0] R [0:L-1]
.你没有在 for 循环中使用
i
。显然,您打算将 R 的所有元素链接在一起,但您只是访问第 0 个、第 (L-1) 个和第 L 个元素。 (显然第 L 个元素不存在,这个数组将从 0 到 L-1。
我现在停止编写此列表,因为,对不起,我认为改进您发布的代码确实没有太多好处..