组合逻辑与$display

这次发现的问题其实还是很有代表性的 是关于系统函数与组合逻辑的时刻取指问题

问题发现的缘由是 本来想写一个纯组合逻辑运算的电路 用display的方式把每次的结果显示出来 于是便有了下文

首先先看一下代码

 1 ////////////////////////////////////////////////////////////////////////////////
 2 //          MODULE NAME     :   gray_code                                     //
 3 //          DATE            :   Thu Aug 23 11:05:54 CST 2012                  //
 4 //          DESCRIPTION     :   gray_code template test for dual n-bit Gray   //
 5 //                              code counter encoder/decoder                  //
 6 //          VERSION         :   1.0                                           //
 7 ////////////////////////////////////////////////////////////////////////////////
 8 module gray_code #(parameter    WIDTH=4)(
 9     input   wire    [WIDTH-1:0]     bin_in
10 ,   output  wire    [WIDTH-1:0]     gray_enc
11 ,   output  wire    [WIDTH-2:0]     gray_enc_minus
12 ,   output  reg     [WIDTH-1:0]     bin_dec
13 );
14 ////////////////////////////////////////////////////////////////////////////////
15 ////////////////////////////////////////////////////////////////////////////////
16 assign  gray_enc        =   {bin_in[WIDTH-1], bin_in[WIDTH-1:1] ^ bin_in[WIDTH-2:0]}    ;
17 assign  gray_enc_minus  =   {gray_enc[WIDTH-1] ^ gray_enc[WIDTH-2], gray_enc[WIDTH-3:0]};
18 always @(*) begin: proc_gray_dec
19     integer m;
20     bin_dec =   'b0;
21     bin_dec[WIDTH-1]    =   gray_enc[WIDTH-1];
22     for(m=WIDTH-1;m>0;m=m-1)
23         bin_dec[m-1]    =   bin_dec[m] ^ gray_enc[m-1];
24 end
25 ////////////////////////////////////////////////////////////////////////////////
26 
27 endmodule   //          CREATED BY poiu_elab@1207
28 
29 ////////////////////////////////////////////////////////////////////////////////

这里的代码是个纯组合逻辑运算gray码与解gray码的电路 没啥新鲜的 再看看testbench

 1 ////////////////////////////////////////////////////////////////////////////////
 2 //  DATE    :   Thu Aug 23 11:37:04 CST 2012
 3 ////////////////////////////////////////////////////////////////////////////////
 4 `timescale 1ns/100ps
 5 `define     CLK_OSC     20
 6 `define     CLK_CYCLE   (1000.0/2.0/`CLK_OSC)
 7 `define     WIDTH       4
 8 `define     FOR_SESSION_RIGHT
 9 //`define     FOR_SESSION_WRONG
10 //`define     REPEAT_SESSION
11 
12 module tb();
13 ////////////////////////////////////////////////////////////////////////////////
14 reg     [`WIDTH-1:0]    bin_in          ;
15 wire    [`WIDTH-1:0]    gray_enc        ;
16 wire    [`WIDTH-2:0]    gray_enc_minus  ;
17 wire    [`WIDTH-1:0]    bin_dec         ;
18 
19 reg     [`WIDTH:0]      k               ;
20 ////////////////////////////////////////////////////////////////////////////////
21 // stimulation generation
22 initial begin: proc_sti_gen
23 bin_in  =   'bx ;
24 k=0;
25 //------------------------------------------------------------------------------
26 `ifdef  FOR_SESSION_RIGHT
27     $display("\tk\t\tbin_in\t\tgray_en\t\tgray_enc_minus\tbin_dec\n");
28     for(k=0;k<(1<<`WIDTH);k=k+1) begin
29         bin_in   =  k   ;
30         #(`CLK_CYCLE);
31         //$monitor("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
32         $display("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
33     end
34 //------------------------------------------------------------------------------
35 `elsif  FOR_SESSION_WRONG
36     $display("\tk\t\tbin_in\t\tgray_en\t\tgray_enc_minus\tbin_dec\n");
37     for(k=0;k<(1<<`WIDTH);k=k+1) begin
38         #(`CLK_CYCLE)   bin_in   =  k   ;
39         //$monitor("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
40         //$strobe("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
41         $display("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
42     end
43 //------------------------------------------------------------------------------
44 `elsif  REPEAT_SESSION
45     $display("\tk\t\tbin_in\t\tgray_en\t\tgray_enc_minus\tbin_dec\n");
46     repeat(1<<`WIDTH) begin
47         bin_in = k;
48         #(`CLK_CYCLE)
49         $display("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
50         k=k+1;
51     end
52 `endif
53 //------------------------------------------------------------------------------
54 #(50*`CLK_CYCLE);
55 $stop;
56 end
57 ////////////////////////////////////////////////////////////////////////////////
58 gray_code #(`WIDTH)u_gray_code(
59     .   bin_in          (   bin_in          )
60 ,   .   gray_enc        (   gray_enc        )
61 ,   .   gray_enc_minus  (   gray_enc_minus  )
62 ,   .   bin_dec         (   bin_dec         )
63 );
64 ////////////////////////////////////////////////////////////////////////////////
65 
66 endmodule   //          CREATED BY poiu_elab@1207
67 
68 ////////////////////////////////////////////////////////////////////////////////

这里的3种显示方式 第1种是可以正常显示的for session,第2种是不能正常显示的for session,第3种是能正常显示的repeat session,正常显示的值是什么呢 是这样的

    k        bin_in      gray_en    gray_enc_minus     bin_dec

     0        0000        0000        000                0000

     1        0001        0001        001                0001

     2        0010        0011        011                0010

     3        0011        0010        010                0011

     4        0100        0110        110                0100

     5        0101        0111        111                0101

     6        0110        0101        101                0110

     7        0111        0100        100                0111

     8        1000        1100        000                1000

     9        1001        1101        001                1001

    10        1010        1111        011                1010

    11        1011        1110        010                1011

    12        1100        1010        110                1100

    13        1101        1011        111                1101

    14        1110        1001        101                1110

    15        1111        1000        100                1111

 

不正常的显示是什么样的呢

    k        bin_in      gray_en     gray_enc_minus    bin_dec

     0        0000        xxxx        xxx                xxxx

     1        0001        0000        000                0000

     2        0010        0001        001                0001

     3        0011        0011        011                0010

     4        0100        0010        010                0011

     5        0101        0110        110                0100

     6        0110        0111        111                0101

     7        0111        0101        101                0110

     8        1000        0100        100                0111

     9        1001        1100        000                1000

    10        1010        1101        001                1001

    11        1011        1111        011                1010

    12        1100        1110        010                1011

    13        1101        1010        110                1100

    14        1110        1011        111                1101

    15        1111        1001        101                1110

而正常的与不正常的差在了哪里呢 就是display的位置 其实错误的case也是我没太注意的地方写到的 按照的正常的写法

    for(k=0;k<(1<<`WIDTH);k=k+1) begin
        bin_in   =  k   ;
        #(`CLK_CYCLE);
        //$monitor("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
        $display("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
    end

首先先对bin_in赋值k,之后延迟一段时间 再用$display读出所有变量的值,而错误的呢

    for(k=0;k<(1<<`WIDTH);k=k+1) begin
        #(`CLK_CYCLE)   bin_in   =  k   ;
        //$monitor("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
        //$strobe("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
        $display("\t%d\t\t%b\t\t%b\t\t%b\t\t%b\n", k, bin_in, gray_enc, gray_enc_minus, bin_dec);
    end

是将bin_in赋值k,之后立刻就用系统函数$display读出所有变量的值,这里我理解可以把$display看成是一个阻塞赋值语句,进行到它的时候,虽然说硬件是并行的,但不是真正并行的,执行到display的时候就先把display需要的值给到display输出的变量里面,再接着把bin_in的值给到gray_code这个模块里面供各个wire进行组合逻辑运算。所以display就能在各个wire的组合逻辑运算之前拿到各个变量的值 从而出现如上所示的情况 所以这点还是要注意一下的

这次算是误打误撞碰到的这个现象在变化的沿处进行的操作就尤其要注意这种东西 至此 完结

posted @ 2012-08-24 14:24  poiu_elab  阅读(452)  评论(0编辑  收藏  举报