日常记录(75)FiFo与基础内容

异步FIFO

https://gitee.com/bai-mengwei/asyn_fifo/tree/master/dut
最重要的是同步时钟域和亚稳态,是使用非阻塞赋值(两级D触发器实现的)
功能点分为:

存储体本身

    always @(posedge rclk) begin
        if (rclk_en) begin
            rdata <= MEM[raddr];
        end
    end

    always @(posedge wclk) begin
        if (wclk_en) begin
            MEM[waddr] <= wdata;
        end
    end

空状态判断

读格雷码指针和从读时钟域获取到的写指针相同,则为空。

    always @(posedge rclk or negedge rrst_n) begin
        if (!rrst_n) begin
            rempty <= 1;
        end else begin
            rempty <= (rgnext==rwptr2);
        end
    end

满状态判断

三个条件:首位不同,前两位异或值相同,除前两位相同。

    assign w_2ndmsb = wgnext[ADDRSIZE] ^ wgnext[ADDRSIZE-1];
    assign wr_2ndmsb = wrptr2[ADDRSIZE] ^ wrptr2[ADDRSIZE-1];

    always @(posedge wclk or negedge wrst_n) begin
        if (!wrst_n) begin
            wfull <= 0;
        end else begin
            wfull <= (wgnext[ADDRSIZE] !== wrptr2[ADDRSIZE]) && (w_2ndmsb==wr_2ndmsb) 
                     && (wgnext[ADDRSIZE-2:0] == wrptr2[ADDRSIZE-2:0]);
        end
    end

读时钟域同步

D触发器获得写指针。(从读时钟域)

    always @(posedge rclk or negedge rrst_n) begin
        if (!rrst_n) begin
            {rwptr2, rwptr1} <= 0;
        end else begin
            {rwptr2, rwptr1} <= {rwptr1, wptr};
        end
    end

写时钟域同步

同理在写时钟域获得读指针。

    always @(posedge wclk or negedge wrst_n) begin
        if (!wrst_n) begin
            {wrptr2, wrptr1} <= 0;
        end else begin
            {wrptr2, wrptr1} <= {wrptr1, rptr};
        end
    end

顶层集成

    sync_r2w sync_r2w(.wrptr2(wrptr2), .rptr(rptr), .wclk(wclk), .wrst_n(wrst_n));
    sync_w2r sync_w2r(.rwptr2(rwptr2), .wptr(wptr), .rclk(rclk), .rrst_n(rrst_n));

    fifomem fifomem(.wdata(wdata), .rdata(rdata), .raddr(raddr), .waddr(waddr),
        .rclk(rclk), .wclk(wclk), .rclk_en(rinc), .wclk_en(winc));

    rptr_empty rptr_empty(.rempty(rempty), .raddr(raddr), .rptr(rptr), .rwptr2(rwptr2), 
        .rinc(rinc), .rclk(rclk), .rrst_n(rrst_n));

    wptr_full wptr_full(.wfull(wfull), .waddr(waddr), .wptr(wptr), .wrptr2(wrptr2), 
        .winc(winc), .wclk(wclk), .wrst_n(wrst_n));

数组操作

$time的数据类型

time类型,64位无符号,4状态的变量。

$isunknown函数

需要和if、== 1配合使用,否则可能失败。用于检测变量是z或者x。
而直接检测变量是z或者x的===号,需要声明出对应为位数,即1'bx等。

数组元素的操作

  • 值全为1的方式可以使用default,但是需要单独使用。我这里。
  • 值全为1的方式也可以使用'{n{number}}的方式,但是要确定n的个数是数组元素的个数。
  • 合并数组的单个索引,可以使用单个赋值操作。但是连续赋值操作失效。
  • 确定数组中的元素可以使用$size
  • 队列$insert可以在索引前插入数字,但是不能使用default赋值。
  • 求和,积等内部的方法的,配合with语句使用。
  • find、sort、shuffer方法等可以使用。
  • 流操作符号<<和>>符号的使用。

代码

module taa ();
    initial begin
        $display("time: %t", $time);
    end

    initial begin
        reg a = 'bx;
        if($isunknown(a)==1) begin
            $display("is un know n x");
        end
        $display("value x is %d", a);
        if (a === 1'bx) begin
            $display("is un know n x equal");
        end
        a = 'bz;
        if ($isunknown(a) == 1) begin
            $display("is un know n z");
        end
        if (a === 1'bz) begin
            $display("is un know n z equal");
        end
    end

    initial begin
        int a[10] = '{10{12}};

        a[3:7] = '{default:2};

        a[0:1] = '{32, 33};
        /* a[5:8] =  {default:1}; */
        $display("value a %p", a);

    end

    initial begin
        bit [3:0][7:0] a;
        a[0] = 8'b1011_0011;
        a[1] = 123;
        a[3][3] = 1;
        $display("pack array a is %h", a);
    end

    initial begin
        bit [3:0] a[5] = '{default:7};
        int b[$:5]='{5{1}};
        $display("count of a is %0d, %p", $size(a), a);
        $display("before: queue of b is %0d, %p", $size(b), b);
        b.insert(2, 3);
        $display("after: queue of b is %0d, %p", $size(b), b);

        $display("type of a is %s", $typename(a));
        $display("sum value of a is %d", a.sum() with (item+32'h0));
        $display("unique of a is %p", a.unique());
        $display("size of a %0d, %p", $size(a), a);
    end

    initial begin
        int a[5] = '{1, 2, 3 ,4, 5};
        int ans[$];
        a.shuffle();
        $display("a is %p", a);
        ans = a.find(x) with (x>3);
        $display("value ans %p", ans);
        ans = a.find_index with(item<3);
        $display("value ans %p", ans);
        a.sort();
        $display("sort a is %p", a);
    end

    initial begin
        bit [15:0] a = 16'ha1a1;
        byte b ,c;
        a = {<<{a}};
        $display("value a is %h", a);
        a = {<<byte{a}};
        $display("value a is %h", a);
        {<<{b, c}} = a;
        $display("b, c %h, %h", b , c);
    end


endmodule

结果

time:                    0
is un know n x
value x is x
is un know n x equal
is un know n z
is un know n z equal
value a '{32, 33, 12, 2, 2, 2, 2, 2, 12, 12} 
pack array a is 08007bb3
count of a is 5, '{'h7, 'h7, 'h7, 'h7, 'h7} 
before: queue of b is 5, '{1, 1, 1, 1, 1} 
after: queue of b is 6, '{1, 1, 3, 1, 1, 1} 
type of a is bit[3:0]$[0:4]
sum value of a is         35
unique of a is '{'h7} 
size of a 5, '{'h7, 'h7, 'h7, 'h7, 'h7} 
a is '{5, 3, 4, 2, 1} 
value ans '{5, 4} 
value ans '{3, 4} 
sort a is '{1, 2, 3, 4, 5} 
value a is 8585
value a is 8585
b, c a1, a1

ref和output

由于inout、input、output在赋值过程中如果数据过大,造成堆栈空间的数据复制压力。
sv引入的ref,允许使用引用变量。

笔试错误

PCIe

一种串行接口。

queue的size函数和mailbox的num函数

queue有size函数,没有num函数。mailbox有num函数,没有size函数。

foreach的二维遍历

直接遍历。在取值的时候需要正常调用。

module tbb ();
    initial begin
        mailbox mbx;
        mbx = new();
        mbx.put(1);
        mbx.put(3);
        $display(mbx.num());
    end

    initial begin
        int que[$];
        $display("-----------------------------------");
        que.push_back(2);
        que.push_back(3);
        $display(que.size());
    end

    initial begin
        int a[3][4];
        $display("-----------------------------------");
        a[0] = '{4{2}};
        a[1] = '{4{3}};
        a[2] = '{4{4}};
        foreach (a[, j]) begin
            $display(a[2][j]);
        end
    end
endmodule

输出结果:

          2
-----------------------------------
          2
-----------------------------------
          4
          4
          4
          4
posted @ 2022-03-12 18:30  大浪淘沙、  阅读(130)  评论(0)    收藏  举报