2

I am trying to implement butterfly FFT algorithm in verilog. DIT Butterfly Network

I create K(Here 4) butterfly modules . I create modules like this.

localparam K = 4;
genvar     i;
generate 
for(i=0;i<N/2;i=i+1)
begin:BN
    butterfly #(
    .M_WDTH   (3 + 2*1),
    .X_WDTH   (4)
    )
    bf (
    .clk(clk), 
    .rst_n(rst_n), 
    .m_in(min), 
    .w(w[i]), 
    .xa(IN[i]), 
    .xb(IN[i+2]), 
    .x_nd(x_ndd), 
    .m_out(mout[i]), 
    .ya(OUT[i]),
    .yb(OUT[i+2]),
    .y_nd(y_nddd[i])
);
end

Each level I have to change input Xa and Xb for each Module (Here Number of level 3).

So I try to initialize reg type "IN"array and assign the array to input Xa and Xb. When I initialize "IN" array manually, it works perfectly.

The problem I face now, I couldn't assign Main module input X to register type "IN" array. Main module input X ,

input wire signed [N*2*X_WDTH-1:0] X,

I have to assign this X into array "IN",

reg signed  [2*X_WDTH-1:0] IN [0:N-1];

I assigned like this,

initial
begin

IN[0]= X[2*X_WDTH-1:0];
IN[1]=X[4*X_WDTH-1:2*X_WDTH];
IN[2]=X[6*X_WDTH-1:4*X_WDTH];
IN[3]= X[8*X_WDTH-1:6*X_WDTH];
IN[4]= X[10*X_WDTH-1:8*X_WDTH];
IN[5]=X[12*X_WDTH-1:10*X_WDTH];
IN[6]=X[14*X_WDTH-12*X_WDTH];
IN[7]= X[16*X_WDTH-1:14*X_WDTH];

end

I have gone through many tutorials and forums. No luck.

Can't we assign wire type to reg type array? If so how I can solve this problem.

Here is the Main module where I initialize Butterfly modules,

module Network
#(
// N
parameter N = 8,
// K.
parameter K = 3,
 parameter M_WDTH=5,
 parameter X_WDTH=4
 
)
(
input wire                        clk,
input wire                        rst_n,

// X
input wire signed [N*2*X_WDTH-1:0] X,
//Y
output wire signed  [N*2*X_WDTH-1:0] Y,

output wire signed [K-1:0] y_ndd
);


wire   y_nddd    [K-1:0];
assign y_ndd ={y_nddd[1],y_nddd[0]};


reg [4:0] min=5'sb11111;
wire [4:0] mout [0:K-1];


reg   x_ndd;
reg [2:0] count=3'b100;

reg   [2*X_WDTH-1:0] w [K-1:0];
reg [2*X_WDTH-1:0] IN [0:N-1];
wire [2*X_WDTH-1:0] OUT [0:N-1];

assign Y = {OUT[3],OUT[2],OUT[1],OUT[0]};

reg [3:0] a;

initial
begin

//TODO : Here is the problem. Assigning Wire to reg array. Synthesize ok. In Simulate "red" output.
IN[0]= X[2*X_WDTH-1:0];
IN[1]=X[4*X_WDTH-1:2*X_WDTH];
IN[2]=X[6*X_WDTH-1:4*X_WDTH];
IN[3]= X[8*X_WDTH-1:6*X_WDTH];
IN[4]= X[10*X_WDTH-1:8*X_WDTH];
IN[5]=X[12*X_WDTH-1:10*X_WDTH];
IN[6]=X[14*X_WDTH-12*X_WDTH];
IN[7]= X[16*X_WDTH-1:14*X_WDTH];

//TODO :This is only a random values
w[0]=8'sb01000100;
w[1]=8'sb01000100;
w[2]=8'sb01000100;
w[3]=8'sb01000100;

end


/* levels */
genvar i;

generate 
for(i=0;i<N/2;i=i+1)
begin:BN
    butterfly #(
    .M_WDTH   (3 + 2*1),
    .X_WDTH   (4)
    )
    bf (
    .clk(clk), 
    .rst_n(rst_n), 
    .m_in(min), 
    .w(w[i]), 
    .xa(IN[i]), 
    .xb(IN[i+N/2]), 
    .x_nd(x_ndd), 
    .m_out(mout[i]), 
    .ya(OUT[2*i]),
    .yb(OUT[2*i+1]),
    .y_nd(y_nddd[i])
);
end

endgenerate


always @ (posedge clk)
begin
    if (count==3'b100)
    begin
        count=3'b001;
        x_ndd=1;
    end
    
    else
    begin
        count=count+1;
        x_ndd=0;
    end     
end



always@ (posedge y_ndd[0])
begin
    //TODO 
    //Here I have to swap OUT-->IN
end



endmodule

Any help is appreciated. Thanks in advance.

8
  • I do not understand the error "I couldn't assign Main module input X to register type "IN" array", could you expand the problem and include the errors you are getting. Commented May 20, 2014 at 7:46
  • Yes. I declared i as genvar. Initializing module works perfectly. I face problem to assign Input X to a reg type array. Commented May 20, 2014 at 7:49
  • There is no error when I synthesized. But when I simulate output is in red. I think that means wire type couldn't be assigned to reg type. or is there any other problem Commented May 20, 2014 at 7:54
  • But when I assign IN values manually, Simulation also works well. Commented May 20, 2014 at 7:55
  • So I'm sure problem is in assigning input X(wire type) to IN arrays. But I couldn't find out the solution. Commented May 20, 2014 at 7:57

1 Answer 1

4

"Output is red", this likely means it is x this could be due to multiple drivers or an uninitialized value. If it was un-driven it would be z.

The main Issue I believe is that you do this :

initial begin
  IN[0] = X[2*X_WDTH-1:0];
  IN[1] = X[4*X_WDTH-1:2*X_WDTH];
  ...

The important part is the initial This is only evaluated once, at time 0. Generally everything is x at time zero. To make this an equivalent of the assign IN[0] = ... for a wire use always @* begin this is a combinatorial block which will update the values for IN when ever X changes.

always @* begin
  IN[0] = X[2*X_WDTH-1:0];
  IN[1] = X[4*X_WDTH-1:2*X_WDTH];
  ...

I am not sure why you do not just connect your X to your butterfly .xa and .xb ports directly though?

Other pointers
X is a bad variable name verilog as a wire or reg can hold four values 1,0,x or z.

In always @(posedge clk) you should be using non-blocking (<=) assignments to correctly model the behaviour of a flip-flop.

y_ndd is k bits wide but only the first 2 bits are assigned.

output signed [K-1:0]          y_ndd
assign y_ndd = {y_nddd[1],y_nddd[0]};

Assignments should be in terms of their parameter width/size. For example IN has N entries but currently exactly 8 entries are assigned. There will been an issue when N!=8. Look into Indexing vectors and arrays with +:. Example:

integer idx;
always @* begin
  for (idx=0; idx<N; idx=idx+1)
    IN[idx] = X[ idx*2*X_WDTH +: 2*X_WDTH];
end
genvar gidx;
generate
  for(gidx=0; gidx<N; gidx=gidx+1) begin
    assign Y[ gidx*2*X_WDTH +: 2*X_WDTH] = OUT[gidx];
  end
endgenerate
Sign up to request clarification or add additional context in comments.

5 Comments

Creating IN and OUT and mapping it to X and Y make it easier to debug in waveform. The OP does need to make all of assignments in terms of its parameters. For example IN has N entries but exactly 8 entries are assigned so there will been an issue when N!=8. Should try indexing with +:. Ex always @* begin for(i=0;i<N;i=i+1) IN[i] = X[ i*2*X_WDTH +: 2*X_WDTH]; end
I had spotted that in a few places assuming a work in progress. Personally I would get a simple version working before parameterising like this. Greg if you want to add that as a suggestion for scalability above the 'other pointers' section that would be great.
Thanks a lot Morgan and Greg. As Morgan said it's in progress. Thanks for the guidelines for a general version.
As Morgan said I deleted initial block and initialized into always block. It works now. Thanks a lot.
@ "I am not sure why you do not just connect your X to your butterfly .xa and .xb ports directly though?". If we do so, it only will give first step output. But for next level we have to use output of first stage as input. That's why I planned like this. Is there any efficient way rather than my idea? If any please suggest me. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.