【问题标题】:FFT implemetation in Verilog: Assigning Wire input to Register type arrayVerilog 中的 FFT 实现:将 Wire 输入分配给寄存器类型数组
【发布时间】:2014-05-20 07:34:01
【问题描述】:

我正在尝试在 verilog 中实现蝶式 FFT 算法。

我创建了 K(Here 4) 蝴蝶模块。我创建这样的模块。

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

每个级别我都必须更改每个模块的输入 Xa 和 Xb(这里是级别 3 的数量)。

所以我尝试初始化 reg 类型“IN”数组并将数组分配给输入 Xa 和 Xb。当我手动初始化“IN”数组时,它工作得很好。

我现在面临的问题,我无法将主模块输入 X 分配给注册类型“IN”数组。 主模块输入 X ,

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

我必须将此 X 分配到数组“IN”中,

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

我是这样分配的,

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

我浏览过很多教程和论坛。没有运气。

我们不能将线类型分配给 reg 类型数组吗?如果是这样,我该如何解决这个问题。

这是我初始化蝴蝶模块的主模块

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

感谢任何帮助。 提前致谢。

【问题讨论】:

  • 我不明白错误“我无法将主模块输入 X 分配给寄存器类型“IN”数组”,您能否扩展问题并包含您遇到的错误。
  • 是的。我宣布 i 为 genvar。初始化模块完美运行。我面临将输入 X 分配给 reg 类型数组的问题。
  • 我合成的时候没有错误。但是当我模拟输出时是红色的。我认为这意味着无法将线类型分配给 reg 类型。还是有其他问题
  • 但是当我手动分配 IN 值时,模拟也能正常工作。
  • 所以我确定问题在于将输入 X(线型)分配给 IN 数组。但我找不到解决方案。

标签: fft verilog


【解决方案1】:

“输出为红色”,这可能意味着它是x 这可能是由于多个驱动程序或未初始化的值。如果它是非驱动的,它将是z

我认为主要问题是您这样做:

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

重要的部分是initial 这仅在时间 0 评估一次。通常在时间零时一切都是 x。为了使它与 assign IN[0] = ... 等效,请使用 always @* begin 这是一个组合块,当 X 发生变化时,它将更新 IN 的值。

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

我不知道您为什么不直接将您的 X 连接到您的蝴蝶 .xa.xb 端口?

其他指针
X 是一个错误的变量名 verilog,因为 wire 或 reg 可以保存四个值 1、0、x 或 z。

always @(posedge clk) 中,您应该使用非阻塞 (&lt;=) 分配来正确模拟触发器的行为。

y_ndd 是 k 位宽,但只分配了前 2 位。

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

分配应根据其参数宽度/大小。例如,INN 条目,但目前正好分配了 8 个条目。 N!=8时会有问题。查看Indexing vectors and arrays with +:。示例:

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

【讨论】:

  • 创建INOUT并将其映射到XY可以更容易地在波形中进行调试。 OP 确实需要根据其参数进行所有分配。例如INN 条目,但恰好分配了8 个条目,所以N!=8 时会出现问题。应该试试indexing with +:。例如always @* begin for(i=0;i&lt;N;i=i+1) IN[i] = X[ i*2*X_WDTH +: 2*X_WDTH]; end
  • 我在一些地方发现了这一点,假设工作正在进行中。就我个人而言,在像这样进行参数化之前,我会得到一个简单的版本。格雷格,如果您想在“其他指针”部分上方添加它作为可扩展性的建议,那就太好了。
  • 非常感谢摩根和格雷格。正如摩根所说,它正在进行中。感谢您提供通用版本的指南。
  • 正如摩根所说,我删除了初始块并初始化为始终块。现在可以了。非常感谢。
  • @“我不知道您为什么不直接将您的 X 连接到您的蝴蝶 .xa 和 .xb 端口?”。如果我们这样做,它只会给出第一步输出。但是对于下一个级别,我们必须使用第一阶段的输出作为输入。这就是我这样计划的原因。有没有比我的想法更有效的方法?如果有请建议我。谢谢。
猜你喜欢
  • 2013-05-21
  • 1970-01-01
  • 1970-01-01
  • 2015-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多