为什么在模拟过程中所有变量都是'x'

时间:2014-11-02 19:30:31

标签: verilog

我正在尝试模拟这个模块,但在模拟过程中所有变量都是x。为什么? 变量定义和使用有什么问题吗? 我是verilog的新手,我不确定我对变量的用法是否正确.. 这是模块和测试平台:

module viterbi_decoder(
        clock , // Clock input of the design
        reset , // active high, synchronous Reset input
        in_vector ,
        out_vector
        );
        //inputs 
        input clock;
        input reset;
        input [7:0]in_vector;
        //outputs 
        output [7:0] out_vector;
        reg [7:0] out_vector;
        //local variables
        integer index;
        integer row00[4:0];
        integer row01[4:0];
        integer row10[4:0];
        integer row11[4:0];

        integer prev_row00[4:0];
        integer prev_row01[4:0];
        integer prev_row10[4:0];
        integer prev_row11[4:0];

        integer who;
        integer from;
        integer mini;
        integer ham_dist_1;
        integer ham_dist_2;


        reg in[1:0];
        always @ (posedge clock)
        begin 
            if (reset)
            begin
            //reset device
                row00[0] <= 3;
                row01[0] <= 3;
                row10[0] <= 3;
                row11[0] <= 3;
            end
            else
            begin
                row00[0] <= 3;
                row01[0] <= 3;
                row10[0] <= 3;
                row11[0] <= 3;

                for (index=0; index < 8; index = index + 2)
                    //mini([n-1,0],[n-1,1])
                    ham_dist_1 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 0 + row00[(index / 2)];
                    ham_dist_2 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 1 + row01[(index / 2)];
                    if (ham_dist_1 > ham_dist_2 )
                    begin
                        row00[index / 2 + 1] <= ham_dist_1;
                        prev_row00[index / 2 + 1] <= 0;
                    end
                    else
                    begin
                        row00[index / 2 + 1] <= ham_dist_2;
                        prev_row00[index / 2 + 1] <= 1;
                    end
                    ham_dist_1 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 0 + row10[(index / 2)];
                    ham_dist_2 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 1 + row11[(index / 2)];
                    if (ham_dist_1 > ham_dist_2 )
                    begin
                        row01[index / 2 + 1] <= ham_dist_1;
                        prev_row01[index / 2 + 1] <= 2;
                    end
                    else
                    begin
                        row01[index / 2 + 1] <= ham_dist_2;
                        prev_row01[index / 2 + 1] <= 3;
                    end
                    ham_dist_1 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 0 + row00[(index / 2)];
                    ham_dist_2 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 1 + row01[(index / 2)];
                    if (ham_dist_1 > ham_dist_2 )
                    begin
                        row10[index / 2 + 1] <= ham_dist_1;
                        prev_row10[index / 2 + 1] <= 0;
                    end
                    else
                    begin
                        row10[index / 2 + 1] <= ham_dist_2;
                        prev_row10[index / 2 + 1] <= 1;
                    end

                    ham_dist_1 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 1 + row10[(index / 2)];
                    ham_dist_2 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 0 + row11[(index / 2)];
                    if (ham_dist_1 > ham_dist_2 )
                    begin
                        row11[index / 2 + 1] <= ham_dist_1;
                        prev_row11[index / 2 + 1] <= 2;
                    end
                    else
                    begin
                        row11[index / 2 + 1] <= ham_dist_2;
                        prev_row11[index / 2 + 1] <= 3;
                    end
                //trace back algorithm
                who <= 00;
                from <= prev_row00[4];
                mini <= row00[4];
                if (row01[4] < mini)
                begin
                    who <= 01;
                    from <= prev_row01[4];
                    mini <= row01[4];
                end
                if (row10[4] < mini)
                begin
                    who <= 10;
                    from <= prev_row10[4];
                    mini <= row10[4];
                end
                if (row11[4] < mini)
                begin
                    who <= 11;
                    from <= prev_row11[4];
                    mini <= row11[4];
                end
                for (index=3; index > 0; index = index - 1 )
                begin
                    if (who == 00 && from == 00)
                    begin
                        out_vector[(index + 1) * 2] <= 0;
                        out_vector[((index + 1) * 2 )- 1] <= 0;
                        who <= 00;
                        from <= prev_row00[index -1];
                    end
                    else if (who == 00 && from == 01)
                    begin
                        out_vector[(index + 1) * 2] <= 1;
                        out_vector[((index + 1) * 2 )- 1] <= 1;
                        who <= 01;
                        from <= prev_row01[index -1];
                    end 
                    else if (who == 01 && from == 10)
                    begin
                        out_vector[(index + 1) * 2] <= 1;
                        out_vector[((index + 1) * 2 )- 1] <= 0;
                        who <= 10;
                        from <= prev_row10[index -1];
                    end
                    else if (who == 01 && from == 11)
                    begin
                        out_vector[(index + 1) * 2] <= 0;
                        out_vector[((index + 1) * 2 )- 1] <= 1;
                        who <= 11;
                        from <= prev_row11[index -1];
                    end
                    else if (who == 10 && from == 00)
                    begin
                        out_vector[(index + 1) * 2] <= 1;
                        out_vector[((index + 1) * 2 )- 1] <= 1;
                        who <= 00;
                        from <= prev_row00[index -1];
                    end
                    else if (who == 10 && from == 01)
                    begin
                        out_vector[(index + 1) * 2] <= 0;
                        out_vector[((index + 1) * 2 )- 1] <= 0;
                        who <= 01;
                        from <= prev_row01[index -1];
                    end
                    else if (who == 11 && from == 10)
                    begin
                        out_vector[(index + 1) * 2] <= 0;
                        out_vector[((index + 1) * 2 )- 1] <= 1;
                        who <= 10;
                        from <= prev_row10[index -1];
                    end
                    else if (who == 11 && from == 11)
                    begin
                        out_vector[(index + 1) * 2] <= 1;
                        out_vector[((index + 1) * 2 )- 1] <= 0;
                        who <= 11;
                        from <= prev_row11[index -1];
                    end
                end
            end
        end

endmodule

`timescale 1ns /1ps
module Testbench;


   reg clock_t;
   reg reset_t;
   reg [7:0] in_vector_t;

   wire [7:0] out_vector_t;

   viterbi_decoder viterbi_1(.clock(clock_t), .reset(reset_t), .in_vector(in_vector_t), .out_vector(out_vector_t));




      initial begin 
      clock_t = 0;
       reset_t = 0;


      end

always #10000 clock_t = ~clock_t; 

always@(posedge clock_t) 
begin

     //case 0
      in_vector_t <= 00110101; // <= 1; reset_t <= 0;
      #5 $display("Result_t = %b", out_vector_t);

      //case 1
      in_vector_t <= 00001111; //clock_t <= 1; reset_t <= 0;
      #5 $display("Result_t = %b", out_vector_t);

      //case 2
      in_vector_t <= 00010101; //clock_t <= 1; reset_t <= 0;
      #5 $display("Result_t = %b", out_vector_t);

      //case 3
      in_vector_t <= 00101100; //clock_t <= 1; reset_t <= 0;
      #5 $display("Result_t = %b", out_vector_t);

      //case 4
      in_vector_t <= 00000000; //clock_t <= 1; reset_t <= 0;
      #5 $display("Result_t = %b", out_vector_t);

   end
endmodule

1 个答案:

答案 0 :(得分:1)

首先,您的测试台需要改进。时钟非常慢,dut只会在任何时钟边沿看到in_vector_t <= 00000000;。我建议您更改与时钟边缘相关的in_vector_t。此外,由于您有一个自由运行的时钟,您需要使用$finish结束模拟。例如:

always #5 clock_t = ~clock_t;

initial begin
  $monitor("Result_t = %b", out_vector_t);
  @(posedge clock_t) in_vector_t <= 8'b00110101; //case 0
  @(posedge clock_t) in_vector_t <= 8'b00001111; //case 1
  @(posedge clock_t) in_vector_t <= 8'b00010101; //case 2
  @(posedge clock_t) in_vector_t <= 8'b00101100; //case 3
  @(posedge clock_t) in_vector_t <= 8'b00000000; //case 4
  @(posedge clock_t);
  #5 $finish; // end simulation
end

在您的设计中,您可能会将两位值设置/比较为1011。这些值在十进制十和十一。您需要指定宽度和基本类型,I.E。 2'b102'b11。您的测试台也是如此; 00001111是十进制一千一百一十一,8'b00001111是十进制十五。

您在时钟始终块内使用非阻塞(<=)。这是对的。问题是您的代码似乎取决于最近更新的值。通过非阻塞分配,寄存器在时间步结束之前不会获得新值。采样/比较该值的任何内容都将在此之前看到旧值。在这种情况下,您需要将块拆分为两个始终块:一个使用非阻塞(<=)同步,一个使用阻塞(=)。不知道你的完整预期逻辑我会给你一个入门的模板:

always @* begin : comb_logic__calc_next
   // defaults (constants or flops)
   next_example1 = 8'h00; // constant
   next_example2 = example2;// flop

   /* algorithms for here
    .... made-up example * /
   for (index = 0; index<8; index=index+1) begin
     if (input_bus[index]==1'b1) next_example1[index] = 1'b1;
     else  next_example2[index] = ~next_example2[index];
     if (next_example1[index]==example[7-index]) begin
       next_example2 = {next_example2[6:0],next_example2[7]};
     end
   end
end
always @(posedge clock) begin : synchronous_logic__assign_flops
  if (reset) begin
    // constants only
    example1 <= 8'h00;
    example2 <= 8'h00;
  end
  else begin
    // assign flops to next value
    example1 <= next_example1;
    example2 <= next_example2;
  end
end

除此之外,您还需要使用波形转储运行模拟。