You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

模块实例化异常:无法读取wr_en与fifo_in数据的排查求助

模块实例化与测试台驱动问题

我的8转32位转换器工作正常,计划让FIFO仅在wr_en为高电平时读取输入数据,将wr_en连接到转换器的valid_q输出(valid_q=1表示转换完成),同时把fifo_in连接到转换器的data_out。我在FIFO模块第12行做了如下实例化:

converter_8_32 fifo_dut(.clk(clk),.rst(rst),.valid_q(wr_en),.data_out(fifo_in));

当前遇到两个问题:

  • 无法读取wr_en和fifo_in的数据
  • 疑问:既然valid_q和data_out已经由converter_8_32模块生成,测试台中是否还需要驱动wr_en_tb和fifo_in_tb?

相关代码如下:

// fifo to read 32 bit data if wr_en=1
module fifo(
    input clk,
    input rst,
    input wr_en,
    input [31:0] fifo_in,
    output [31:0] fifo_out);
 
reg [31:0] reg_fifo;
 
//fifo instantiation with converter module
converter_8_32 fifo_dut(.clk(clk),.rst(rst),.valid_q(wr_en),.data_out(fifo_in));
 
always @(*) begin
    if(!rst) begin
        reg_fifo<=0; end
        else if (wr_en==1'b1) begin
            reg_fifo<=fifo_in; end
        else reg_fifo<=0;    
end
assign fifo_out=reg_fifo;
endmodule
 
//converter block to convert 8 bit input to 32 bit output for every 4 clocks.
////output is valid if valid_q=1 where we receive 32 bit data out
 
module converter_8_32(
    input clk,
    input valid,
    input rst,
    output reg valid_q,
    input [7:0] data_in, //8 bit input
    output reg [31:0] data_out); //32 bit data out
 
reg [7:0] temp_reg [0:3];
 
integer N=4;
always @ (posedge clk or negedge rst) begin
    if (!rst) begin     
        data_out<=0;
        valid_q<=0;
            end
 
    else if (!valid) begin
            data_out<=0;
            valid_q<=0;
            N<=4;
                       end
               
    else begin            
        temp_reg[N-1]<=data_in;
        N=N-1;    
        if (N==0) 
        begin 
            valid_q<=1;
            N<=4;
            end
                else begin
                valid_q<=0;
                data_out<=data_in; end
            end
        end
                                             
 
always @ (posedge clk) begin
        if (N==0)
        // concatentaion operator to concatenate previous 3 data along
    // with preset data_in to generate 32 bit data
        data_out<={temp_reg[3],temp_reg[2],temp_reg[1],data_in};
            
end
 
endmodule


// **TEST BENCH**
`timescale 1ns/1ps
module fifo_tb();
reg clk_tb;
reg rst_tb;
reg valid_tb;
reg [7:0] data_in_tb;
wire valid_q_tb;
wire [31:0] data_out_tb;
 
reg wr_en_tb;
reg [31:0] fifo_in_tb;
wire [31:0] fifo_out_tb;
 
converter_8_32 dut_converter (.clk(clk_tb),.rst(rst_tb),.valid(valid_tb),.data_in(data_in_tb),.valid_q(valid_q_tb),.data_out(data_out_tb));
fifo dut_top (.clk(clk_tb),.rst(rst_tb),.wr_en(wr_en_tb),.fifo_in(fifo_in_tb),.fifo_out(fifo_out_tb));
 
always # 1 clk_tb=~clk_tb;
always #8 valid_tb=~valid_tb;
integer i;
 
initial begin
 clk_tb=0;
 rst_tb=0;
 valid_tb=1;
 data_in_tb=0;
 #2.5 rst_tb=1'b1; 
 //valid_tb=1'b1;
 #0.5;
 for (i=0;i<255;i=i+1) begin
     data_in_tb=i;
     #2;
 end
end
endmodule

问题分析与修复方案

1. FIFO模块核心错误

你在fifo模块内部实例化了converter_8_32,但同时将wr_en、fifo_in定义为模块的输入端口,这会触发多驱动冲突:

  • 硬件中不允许一个信号同时被外部测试台和内部模块驱动,这会导致信号状态不确定,无法读取有效数据。

正确逻辑是:fifo模块仅负责数据缓存,不需要内部实例化转换器,而是通过输入端口接收转换器的输出信号,在测试台中完成两者的连接。

2. 测试台错误

测试台中你同时实例了转换器和FIFO,但错误地将FIFO的wr_en、fifo_in连接到手动定义的reg信号,而非转换器的输出valid_q_tb、data_out_tb,导致FIFO完全没接收到转换器的有效数据。

修复后的代码

修正后的FIFO模块

// fifo to read 32 bit data if wr_en=1
module fifo(
    input clk,
    input rst,
    input wr_en,          // 由外部转换器提供有效信号
    input [31:0] fifo_in, // 由外部转换器提供32位数据
    output [31:0] fifo_out);
 
reg [31:0] reg_fifo;
 
always @(*) begin
    if(!rst) begin
        reg_fifo = 0; 
    end
    else if (wr_en == 1'b1) begin
        reg_fifo = fifo_in; 
    end
    else begin
        reg_fifo = 0;    
    end
end
assign fifo_out = reg_fifo;
endmodule

修正后的测试台

`timescale 1ns/1ps
module fifo_tb();
reg clk_tb;
reg rst_tb;
reg valid_tb;
reg [7:0] data_in_tb;
wire valid_q_tb;
wire [31:0] data_out_tb;
 
// 无需手动定义wr_en_tb和fifo_in_tb,直接复用转换器输出
wire [31:0] fifo_out_tb;
 
// 实例化转换器
converter_8_32 dut_converter (
    .clk(clk_tb),
    .rst(rst_tb),
    .valid(valid_tb),
    .data_in(data_in_tb),
    .valid_q(valid_q_tb),
    .data_out(data_out_tb)
);
// 实例化FIFO,直接连接转换器的输出信号
fifo dut_top (
    .clk(clk_tb),
    .rst(rst_tb),
    .wr_en(valid_q_tb),    // 连接转换器的转换完成信号
    .fifo_in(data_out_tb), // 连接转换器的32位输出数据
    .fifo_out(fifo_out_tb)
);
 
always #1 clk_tb = ~clk_tb;
always #8 valid_tb = ~valid_tb;
integer i;
 
initial begin
 clk_tb = 0;
 rst_tb = 0;
 valid_tb = 1;
 data_in_tb = 0;
 #2.5 rst_tb = 1'b1; 
 #0.5;
 for (i=0;i<255;i=i+1) begin
     data_in_tb = i;
     #2;
 end
end
endmodule

额外优化建议

  • 转换器模块中,复位分支缺少N <= 4;的初始化,建议添加,避免复位后计数状态异常。
  • FIFO的always @(*)组合逻辑块中,建议使用阻塞赋值=,更符合组合逻辑的硬件行为;若想实现时序缓存,可改为always @(posedge clk or negedge rst)的时序逻辑块。

内容的提问来源于stack exchange,提问作者ARUNA M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:42:04