模块实例化异常:无法读取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
相关产品推荐
相关产品推荐

