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.

Community
  • 1
  • 1
Jey
  • 79
  • 1
  • 9
  • 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. – Morgan May 20 '14 at 07:46
  • Yes. I declared i as genvar. Initializing module works perfectly. I face problem to assign Input X to a reg type array. – Jey May 20 '14 at 07: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 – Jey May 20 '14 at 07:54
  • But when I assign IN values manually, Simulation also works well. – Jey May 20 '14 at 07:55
  • So I'm sure problem is in assigning input X(wire type) to IN arrays. But I couldn't find out the solution. – Jey May 20 '14 at 07:57
  • For Information, I initialize butterfly modules inside Main module. – Jey May 20 '14 at 07:59
  • I have edited with Main module. Can you please check that. – Jey May 20 '14 at 09:06
  • Morgan, Could you please tell me where I'm doing fault in assigning X to IN arrays. – Jey May 20 '14 at 11:07

1 Answers1

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
Community
  • 1
  • 1
Morgan
  • 19,934
  • 8
  • 58
  • 84
  • 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 +:](http://www.stackoverflow.com/questions/18067571/indexing-vectors-and-arrays-with). Ex `always @* begin for(i=0;i – Greg May 20 '14 at 16:32
  • 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. – Morgan May 20 '14 at 16:46
  • Thanks a lot Morgan and Greg. As Morgan said it's in progress. Thanks for the guidelines for a general version. – Jey May 20 '14 at 17:40
  • As Morgan said I deleted initial block and initialized into always block. It works now. Thanks a lot. – Jey May 20 '14 at 17:42
  • @ **"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. – Jey May 20 '14 at 17:47