I'm doing a LOTTT of pipelining with varying width signals and wanted a SYNTHESIZEABLE module wherein i could pass 2 parameters : 1) number of pipes (L) and 2) width of signal (W).
That way i just have to instantiate the module and pass 2 values which is so much simple and robust than typing loads and loads of signal propagation via dummy registers...prone to errors and et all.
I have HALF written the verilog code , kindly request you to correct me if i am wrong.
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
//**********************
Why so complicated? The following code would be much simpler and easier to understand:
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
However, looking at your code there are the following problems:
You declare Serial_in
as input reg
. This is not possible, an input
cannot be a reg
.
You are using generate..endgenerate
within an always block. A generate block is a module item and cannot be used in an always block. Simply remove the generate
and endgenerate
statements and declare i
as integer
.
Obviously Serial_in
and Serial_out
must be declared as vectors of size [W-1:0]
.
You are using R
as a memory. Declare it as such: reg [W-1:0] R [0:L-1]
.
You are not using i
in you for loop. Obviously you meant to chain all the elements of R together, but you are just accessing the 0th, (L-1)th and Lth element. (Obviously the Lth element is nonexisting, this array would be going from 0 to L-1.
I'm now stopping writing this list because, I'm sorry, I think there really is not much to gain by improving the code you have posted..