我的MSB下采样模块的Verilog测试平台设计

时间:2014-04-23 15:41:39

标签: simulation verilog hdl

几天前我问了一个我想要实现的模块(here),它接收输入样本的MSB,累加它们(通过移位)并在32位输出位时将它们组合成输出样本被“填满”。

感谢那里的帮助,我得到了这个实现,它不会产生任何编译错误,并且对Xilinx 12.1似乎很好:

module my_rx_dsp0
#(
    //frontend bus width
    parameter WIDTH = 24
)
(
    //control signals
    input clock, //dsp clock
    input reset, //active high synchronous reset
    input clear, //active high on packet control init
    input enable, //active high when streaming enabled

    //user settings bus, controlled through user setting regs API
    input set_stb, input [7:0] set_addr, input [31:0] set_data,

    //full rate inputs directly from the RX frontend
    input [WIDTH-1:0] frontend_i,
    input [WIDTH-1:0] frontend_q,

    //full rate outputs directly to the DDC chain
    output [WIDTH-1:0] ddc_in_i,
    output [WIDTH-1:0] ddc_in_q,

    //strobed samples {I16,Q16} from the RX DDC chain
    input [31:0] ddc_out_sample,
    input ddc_out_strobe, //high on valid sample
    output ddc_out_enable, //enables DDC module

    //strobbed baseband samples {I16,Q16} from this module
    output reg [31:0] bb_sample,
    output reg bb_strobe //high on valid sample
);

    reg [3:0] i_msb;
    reg [3:0] q_msb;

    reg [31:0] temp_buff = 0;
    reg [1:0] count = 0;

    always @(posedge clock) begin 
        if(ddc_out_strobe) begin
            // bit shifter for MSB
            temp_buff <= {i_msb,q_msb,temp_buff[31:8]};
            // to avoid if-else condition
            count <= (count==2'd3) ? 2'd0 : (count+1);
        end
    end

    always @(*) begin
        i_msb = ddc_out_sample[31:28];
        q_msb = ddc_out_sample[15:12];
        // to avoid if-else condition   
        bb_strobe = (count==2'd3);
        bb_sample = bb_strobe ? temp_buff : 32'd0;  
    end

    assign ddc_in_i = frontend_i;
    assign ddc_in_q = frontend_q;
    assign ddc_out_enable = enable; 

endmodule //my_rx_dsp0_custom

现在我想用一些例子来实现一个测试my_rx_dsp0.v的测试平台。 我实现了my_rx_dsp0_tb_2.v,它从名为my_input.dat的文件中读取32位样本,以input s ddc_out_sample的形式提供给模块。 然后将它们与my_output.dat中存储的正确值进行比较。

注意:我自己没有编写这个测试平台,我是从开源项目的另一个测试平台改编而来的。

以下是实施:

module my_rx_dsp0_tb ( );

reg clk;
reg reset;
reg enable;
reg ddc_out_strobe; //high on valid sample
reg [31:0] ddc_out_sample;
wire [31:0] bb_sample = 32'd0;
wire bb_strobe;
wire ddc_out_enable = 1'b1; //enables DDC module

parameter WIDTH = 24;
parameter clocks = 2; // number of clocks per input

reg endofsim = 0;
integer number_of_errors;
initial number_of_errors = 0;

wire set_stb = 1;
wire [7:0] set_addr;
wire [31:0] set_data;
wire [WIDTH-1:0] frontend_i;
wire [WIDTH-1:0] frontend_q;
wire [WIDTH-1:0] ddc_in_i;
wire [WIDTH-1:0] ddc_in_q;

reg signed [31:0] compare_out;

// Setup the clock
initial clk = 1'b0;
always #5 clk <= ~clk ;

// Come out of reset after a while
initial reset = 1'b1 ;
initial #1000 reset = 1'b0 ;

// Enable the entire system
initial enable = 1'b1 ;

// Instantiate UUT
my_rx_dsp0 #(.WIDTH(WIDTH)) UUT_rx_dsp0
    (   .clock(clk), .reset(reset), .clear(clear), .enable(enable),
        .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
        .frontend_i(frontend_i), .frontend_q(frontend_q),
        .ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q),
        .ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), .ddc_out_enable(ddc_out_enable),
        .bb_sample(bb_sample), .bb_strobe(bb_strobe) );

//-------Setup file IO-------//
//
integer i, r_in, r_out, infile, outfile;

initial begin
    infile = $fopen("my_input.dat","r");
    outfile = $fopen("my_output.dat","r");
    $timeformat(-9, 2, " ns", 10) ;
    // for n=9,p=2 digits after decimal pointer
    //min_field_width=10 number of character positions for %t
end      

//-------Get sim values and display errors-------//
//
initial begin
    // Initialize inputs
    ddc_out_strobe <= 1'd0;
    ddc_out_sample <= 32'd0;

    // Wait for reset to go away
    @(negedge reset) #0;

    while(!endofsim) begin
        // Write the input from the file or 0 if EndOfFile(EOF)
        @(posedge clk) begin
            #1
            ddc_out_strobe <= 1'b1;
            if(!$feof(infile))
                r_in = $fscanf(infile,"%b\n",ddc_out_sample);
            else
                ddc_out_sample <= 32'd0;
        end
        //
        // Clocked in; set the strobe to 0 if the # of clocks/sample
        // is greater than 1
        if( clocks > 1 ) begin
            @(posedge clk) begin
                ddc_out_strobe <= 1'b0  ;
            end

            // Wait for the specified # of cycles
            for( i = 0 ; i < (clocks-2) ; i = i + 1 ) begin
                @(posedge clk) #1 ;
            end
        end
        //

        //
        // Print out the number of errors that occured
        if(number_of_errors) begin
            $display("FAILED: %d errors during simulation",number_of_errors) ;
        end else begin
            $display("PASSED: Simulation successful") ;
        end 
        // 
    end 
end

//-------Comparison btwn simulated values vs known good values-------//
//
always @(posedge clk) begin
    if(reset)
        endofsim <= 1'b0 ;
    else begin
        if(!$feof(outfile)) begin
            if(bb_strobe) begin
                r_out = $fscanf(outfile,"%b\n",compare_out);
                if(compare_out != bb_sample) begin
                    $display("%t: %b != %b",$realtime,bb_sample,compare_out);
                    number_of_errors = number_of_errors + 1;
                end else begin
                    $display("%t: %b = %b",$realtime,bb_sample,compare_out);
                end
            end
        end else begin
            // Signal end of simulation when no more outputs
            endofsim <= 1'b1 ;
        end
    end
end 

endmodule // my_rx_dsp0_tb

使用Xilinx ISE Suite Edition 12.1中的ISim进行模拟时,我无法从模块中获得所需的功能。我担心输出包含多个x个状态(未知状态),而不是预期的10

问题这是由于:

1)使用$fscanf读取文件的方式?

2)初始化reg [31:0] temp_buff = 0

错了

3)或者有人知道出了什么问题吗?

来自测试平台的错误提示(作为示例):     xx000x00xxx00x0xx000x0x000000000 != 10000110111001011100010001101100

1 个答案:

答案 0 :(得分:0)

X来自bb_sampleddc_out_enable上有多个冲突的驱动程序。 wire类型合并驱动程序,相同强度的冲突位值解析为X.

UUT_rx_dsp0是潜水员。但是,您通过声明电线的方式添加了其他驱动程序。

...
wire [31:0] bb_sample = 32'd0; // "= 32'd0" is a continuous driver
wire bb_strobe;
wire ddc_out_enable = 1'b1; // "= 1'd1" is a continuous driver
...

你想要的是:

...
wire [31:0] bb_sample;
wire bb_strobe;
wire ddc_out_enable;
...

纠正上述问题将解决X问题。基于示例错误,它看起来像数据未命中匹配。根据提供的信息,很难说它是测试平台还是设计问题。可能只是时钟或传播偏斜。