数字逻辑基本概念和术语



一、数字逻辑通信基础

数字逻辑通信研究超大规模集成电路内部,诸多逻辑单元/IP信息交换。为支持大量复杂高速集成电路内部的通信,需要定制某些规则,以满足以下目的:

  1. 保证信息交换的可靠性。
  2. 在信息可靠的前提下追求最高的传输速率。
  3. 支持和保证所有参与传输的单元,具有对传输加以控制的权利和义务(不对等)。

1.1数字逻辑通信的概念和术语

1.1.1 单向传输(Uindirectional Transfer)

数据仅仅在一个方向流动,称为单向传输。

handshake
data
handshake
a
b

1.1.2 双向传输(Bidirectional Transfer)

数据仅在两个模块之间往返流动,称为双向传输。

handshake
rdata
wdata
handshake
a
b

1.1.3 存储器映射传输(Memory-Mapped Transfer)

伴随有地址信息和控制信息,访问存储器类设备的传输,称为存储器映射传输。

handshake
rdata
wdata
controller
addr
handshake
a
b

1.1.4 流传输(Streaming Transfer)

无伴随地址信息的单向或双向传输,称为流传输。

handshake
rdata
wdata
wcontroller
rcontroller
handshake
a
b

流传输定义可以是单向或双向,但大部分的电路中,流传输以单向传输(AXI的流单向化基础)

handshake
data
controller
handshake
a
b

1.1.5 无反制单向传输(Transfer Without BackPressure)

在两个模块之间发生的传输中,仅仅上游模块具传输控制权利,下游模块仅仅有被控制义务,这种权利义务不对等的形式,称为无反制流传输。

handshake
controller
a
b

1.1.6 源宿传输(Source-Sink Transfer)

单向流传输中,将上游模块接口称为源接口(Source Interface),将下游模块接口称为宿接口(Sink Interface),据此构成的通信称为源宿通信。

handshake
data
controller
handshake
source
sink
SOURCE
SINK

1.1.7 主从传输(Master-Slave Transfer)

存储器映射传输中,将发出地址和主控信息的电路逻辑,称为主机接口(Master Interface),响应地址信息和主控信息的电路逻辑,称为从机接口(Slave Interface),据此构成的通信称为主从通信。

handshake
wdata
addr
rdata
controller
handshake
master
slave
MASTER
SLAVE

1.1.8 随机传输(Random Transfer)

主从传输中,每一个数据信息都伴随以后对应的地址信息,称为随机传输。
ZX-李老师

1.1.9 突发传输(Burst Transfer)

主从传输或者流传输中,一次握手成功,传输若干个信号的传输(信号要大于一),称为突发传输。
ZX-李老师

二、无反制流传输ST

无反制流传输是一种权力义务不对等的传输,源接口具有控制权,而宿接口没有。

2.1 传输模型

data
valid
st_source
st_sink
SOURCE
SINK

st_source:源接口
st_sink:宿接口
data:信息
valid:握手信息

2.2 传输规则

源接口:

  • 源模块需要发送信息,则将信息送往data,并且将握手信息valid设置为真。
  • 源模块需要停止发送,则将握手信息valid设置为假。(data不影响信息传送的停止)

宿接口:

  • 宿接口需时刻准备着接受主机发送的握手信号valid。
  • 宿主接口接收到握手信号valid时,需立刻响应。

总结:源接口具有对传输的控制权(断言,反断言),宿接口仅仅有响应的义务。(响应源接口的命令)

2.3 传输例子

ZX-李老师

2.4 典型解决方案

上游源接口获得全部控制权,故可以直接用FSM(有限状态机)来解决。这里我用两个案例来说明。

  • 宿接口架构:
    ZX李老师

  • 宿接口状态机(SINK_FSM)状态转移图:
    ZX李老师

2.5 无反制传输设计例子一

下图所示,宿接口接收上游的8位无反制传输数据,传递给其下游的七段数码管显示电路。
任务目标:
为其设计,建模和ABV验证(基于断言的验证)
ZX-李老师

2.5.1 架构

引用典型解决方案,得到架构:
ZX李老师

2.5.2 状态转移图

引用典型解决方案的STG:
ZX李老师

2.5.3 验证架构

ABV验证架构:
ZX李老师

2.5.4 设计代码

设计模块:

`timescale 1ns / 1ps
module st_exampel1(clk, rst_n, valid, data, q, write);

    input clk, rst_n;
    input valid;
    input [7:0] data;
    output reg [7:0] q;
    output reg write;

    always @ (posedge clk)
    begin : FSM
        if (!rst_n)
            begin
                q <= 0;
                write <= 0;
            end
        else if (valid)
            begin
                q <= data;
                write <= 1;
            end
        else
            write <= 0;
    end

endmodule

仿真模块:

`timescale 1ns / 1ps
module st_exampel1_tb;

   logic clk, rst_n;
   logic [7:0] data, q;
   logic valid, write;
   
    stimulate STIM(
        .clk(clk), 
        .rst_n(rst_n), 
        .data(data), 
        .valid(valid)
    );
    
    st_exampel1 DUT(
        .clk(clk), 
        .rst_n(rst_n), 
        .valid(valid), 
        .data(data), 
        .q(q), 
        .write(write)
    );
    
    scoreboard SC(
        .clk(clk), 
        .rst_n(rst_n), 
        .data(data), 
        .valid(valid), 
        .q(q), 
        .write(write)
    );

endmodule

stimulate模块:

`timescale 1ns / 1ps
module stimulate(clk, rst_n, data, valid);

    output reg clk, rst_n;
    output reg [7:0] data;
    output reg valid;
    
    initial begin
        clk <= 1;
        rst_n <= 0;
        data <= 0;
        valid <= 0;
        
        #200ns
        @ (posedge clk)
        rst_n <= 1;
        
        #200ns
        forever begin
            @ (posedge clk)
            if (({$random} % 16)>=4)
                begin
                    data <= {$random}%256;
                    valid <= 1;
                end
            else
                begin
                    data <= 0;
                    valid <= 0;
                end
        end
    end

    always #10ns clk <= ~clk;
    
    initial #2us $stop;

endmodule

记分牌模块:

`timescale 1ns / 1ps
module scoreboard(clk, rst_n, data, valid, q, write);

    input clk, rst_n;
    input [7:0] data, q;
    input valid, write;
    
    //因为data和valid要和q和write做对比,所以要晚一拍,所以设置了data1,valid1。
    reg [7:0] data1;
    reg valid1;
    
    //产生均衡寄存器,用来对齐data和q。
    always @ (posedge clk)
    begin
        data1 <= data;
        valid1 <= valid;
    end
    
    //断言判断
    always @ (posedge clk)
    begin
        if (write) begin
            assert (q == data1)//这里if换成了断言assert,优点是断言可以做覆盖,做基于断言的验证ABV。
                $display("OK: data=%0d q=%0d",data1,q);
            else
                $error("ERROR: data=%0d q=%0d",data1,q);
        end
    end

endmodule

2.5.5 验证

功能仿真截图:
是三金呐
断言报告:
是三金呐

2.6 无反制传输例子二

下图所示的无反制流节点SE2,接收上游的8位无反制传输数据,传递给其下游的七段数码管显示电路。
ZX李老师

任务目标:

  1. 若检测到data为奇数,并且小于250,则将data+1送下游q;
  2. 若检测到data为奇数,并且大于等于250,则将data直接送下游q;
  3. 若检测到data为偶数,则将0写入下游q;
  4. 为其设计,建模和ABV验证(基于断言的验证)

2.6.1 架构

引用典型方案,得到架构:
ZX李老师

2.6.2 状态转移图

ZX李老师

2.6.3 验证架构

基于断言的验证架构:
ZX李老师

2.6.4 设计代码

设计模块:

`timescale 1ns / 1ps
module st_exampel2(clk, rst_n, valid, data, q, write);

    input clk, rst_n;
    input valid;
    input [7:0] data;
    output reg [7:0] q;
    output reg write;

    always @ (posedge clk)
    begin : FSM
        if (!rst_n)
            begin
                q <= 0;
                write <= 0;
            end
        else if (valid && data <250 && data[0])
            begin
                q <= data + 1;
                write <= 1;
            end
        else if (valid && data >= 250 && data[0])
            begin
                q <= data;
                write <= 1;
            end
        else if (valid && ~data[0])
            begin
                q <= 0;
                write <= 1;
            end
        else
            write <= 0;
    end

endmodule

验证模块:

`timescale 1ns / 1ps
module st_exampel2_tb;

    logic clk, rst_n;
    logic valid;
    logic [7:0] data;
    logic [7:0] q;
    logic write;

    stimulate STIM(
        .clk(clk), 
        .rst_n(rst_n), 
        .valid(valid), 
        .data(data)
    );

    st_exampel2 DUT(
        .clk(clk), 
        .rst_n(rst_n), 
        .valid(valid), 
        .data(data), 
        .q(q), 
        .write(write)
    );
    
    scoreboard SC(
        .clk(clk), 
        .rst_n(rst_n), 
        .valid(valid), 
        .data(data), 
        .q(q), 
        .write(write)
    );

endmodule

stimulate模块:

`timescale 1ns / 1ps
module stimulate(clk, rst_n, valid, data);

    output reg clk, rst_n;
    output reg valid;
    output reg [7:0] data;

    initial begin
        clk <= 1;
        rst_n <= 0;
        data <= 0;
        valid <= 0;
        
        #200ns
        @ (posedge clk)
        rst_n <= 1;
        
        #200ns
        forever begin
            @ (posedge clk)
            if (({$random} % 16) >= 4)
                begin
                    data <= {$random} % 256;
                    valid <= 1;
                end
            else
                begin
                    data <= 0;
                    valid <= 0;
                end
        end
    end
    
    always #10ns clk <= ~clk;
    
    initial #2us $stop;

endmodule

记分牌模块:

`timescale 1ns / 1ps
module scoreboard(clk, rst_n, valid, data, q, write);

    input clk, rst_n;
    input valid, write;
    input [7:0] data, q;

    reg [7:0] data1;
    reg valid1;
    
    always @ (posedge clk)
    begin
        data1 <= data;
        valid1 <= valid;
    end

    always @ (posedge clk)
    begin
        if (write)
            begin
                if (data1 < 250 && data1[0])
                    begin
                        assert (q == data1 + 1)
                            $display("OK1: data=%0d q=%0d", data1, q);
                        else
                            $error("ERROR1: data=%0d q=%0d", data1, q);
                    end
                else if (data1 >= 250 && data1[0])
                    begin
                        assert (q == data1)
                            $display("OK2: data=%0d q=%0d", data1, q);
                        else
                            $error("ERROR2: data=%0d q=%0d", data1, q);
                    end
                else if (~data1[0])
                    begin
                        assert (q == 0)
                            $display("OK3: data=%0d q=%0d", data1, q);
                        else
                            $error("ERROR3: data=%0d q=%0d", data1, q);
                    end
            end
    end
    
endmodule

2.6.5 验证

功能仿真截图:
是三金呐
断言报告:
是三金呐

三 、流传输

流传输是所有复杂传输的基础。或者说,任何一种复杂数字逻辑通信,都可能被化简为流传输的组合。基于此,ARM的AMBR总线协议(AXI)提出:
1.将所有的复杂的通信形式,都进行流的单向化处理。
2.使得支持流单向化的AXI协议满足所有的通信协议。

3.1 流传输模型

data
valid
ready
st_source
st_sink
SOURCE
SINK

ready:流传输的握手信息,下游的权力信号,由宿模块发出。其余均和2.1一样。

3.2 不对等规则

3.2.1 下游主动反制规则

下游主动反制规则是下游权重规则中的一种,称为SAB(Sink-Active Backpressure mode),在SAB中下游ready有最高优先级,全程主动,上游配合下游,获得条件主动。

3.2.2 下游快速反制规则

下游快速反制规则也是下游权重规则中的一种,称为SFB(Sink-Fast Backpressure),在SFB中仍然是下游的ready优先,但是与SAB不同的是,SFB中上游模块在没有下游信号时获得条件主动,当上游信号出现变化时,信号将被动保持,必须等待下游信号来,然后重新获得条件主动。

3.2.3 下游被动反制规则

下游被动反制规则其实是上游权重规则的一种,称为SPB(Sink-Passivity Backpressure),下游根据上游的valid决定是否ready。

3.3 就绪潜伏期和请求潜伏期

从下游宿接口发出就绪信号ready,至上游源接口发出数据,其时钟延迟称为就绪潜伏期ReadyLatency;
从上游源接口发出valid和data,至下游宿接口响应就绪ready,其时钟延迟称为请求潜伏期ValidLatency;
这里下游宿主接口发出ready到宿主接口接收到数据或者上游源接口发出valid到上游源接口得到响应的ready,其至少两拍的时钟延迟称为访问潜伏期AccessLatency。(这里特别强调访问潜伏期不一定等于就绪潜伏期加上请求潜伏期)

3.4 对称潜伏期

数字逻辑通信中,为保证最高传输效率,其架构模型要求对称潜伏期。从输入激励有效到输出响应有效的时钟延迟,称为进入潜伏期EntryLatency;从输入激励无效至输出响应无效的时钟延迟,称为退出潜伏期ExitLatency。数字逻辑通信的流节点架构要求:Entry Latency=Exit Latency
ZX-李老师

3.5 流域Streaming和流节点

数据信息在集成电路内部,从源头经过多个节点的加工处理后,到达最下游。这样的传输路径,称为流域Streaming。其中的节点称为流节点(StreamNode)。
为了保证最高效率和正确性。可以证明,流域中若所有节点遵循唯一规则,称为单规则流域。否则为多规则流域。
对于单规则流域:

  1. 对于下游主动反制SAB或者下游快速反制SFB单规则流域,流域中的所有流节点,必须具有唯一而且相同的就绪潜伏期ReadyLatency。
  2. 对于下游被动反制SPB的单规则流域,所有流节点,必须具有唯一而且相同的请求潜伏期ValidLatency。

四、下游主动反制SAB

4.1 传输模型

data
valid
ready
sab_source
sab_sink
SOURCE
SINK

sab_source:SAB中的流传输源接口
sab_sink:SAB中的流传输宿接口
data:流传输的数据信息,单向,并且是从源流向宿
valid:流传输的握手信息,源权力信号
ready:流传输的握手信号,宿权力信号

4.2 传输规则

源接口传输规则:

  1. 源接口全程必须监听宿接口发出的就绪信号(ready)。
  2. 若源接口监听到ready为真,此时源接口进入条件主动。
  3. 源接口进入条件主动后,可以选择走,发出valid为真,并加载数据;也可以选择停,发出valid为假。
  4. 若源接口监听到ready为假,此时源接口进入被动等待。

宿接口传输规则:

  • 下游宿接口全程主动,随时根据自身需要,发出走或者停。
  • 若下游宿接口能够接收数据,则随时将ready设置为真;若不能够接收数据,则随时将ready设置为假。
  • 若下游设置为真,则后续周期必须监听valid信号,若valid为真,则必须立即捕获data数据。否则停止捕获。

4.3 传输例子时序

ZX李老师
当valid为真时传输数据,当valid为假时不用管

4.4 典型解决方案一(发散不参与源控)

下游主动反制SAB流节点的典型方案,采用流节点不参与反制。对上游的控制,称为源控(反制),对下游的控制,称为宿控。该典型解决方案一则是SAB的流节点,无源控,仅仅保留宿控。

  • 架构

ZX李老师

  • 下游就绪潜伏期发散
    证明:
    DownReadyLatency = UpReadyLatency + LogicLatency
    ZX李老师
    可以证明,在SAB的上述典型方案一中,下游就绪潜伏期满足:
    DownReadyLatency = UpReadyLatency + LogicLatency

这里:
DownReadyLatency:下游就绪潜伏期
UpReadyLatency:上游就绪潜伏期
LogicLatency:本地流节点逻辑潜伏期

4.5 下游主动反制方案设计例子一

任务目标:
下图所示的两级异或电路,SAB设计方案一,建模和ABV验证;

4.5.1 架构

ZX李老师
其ABV验证平台:

4.5.2 验证架构

ZX李老师

4.5.3 设计代码

设计模块:

`timescale 1ns / 1ps
module sab_example1(clk, rst_n, up_data, up_valid, up_ready, down_data, down_valid, down_ready);

    input clk, rst_n;
    input [7:0] up_data;
    input up_valid;
    output up_ready;
    output [7:0] down_data;
    output down_valid;
    input down_ready;

    wire [7:0] sr0_data;
    wire sr0_valid;
    
    se1_reg SR0(
        .clk(clk), 
        .rst_n(rst_n), 
        .data_in(up_data), 
        .valid_in(up_valid), 
        .data_out(sr0_data), 
        .valid_out(sr0_valid)
    );
    
    se1_reg SR1(
        .clk(clk), 
        .rst_n(rst_n), 
        .data_in(sr0_data), 
        .valid_in(sr0_valid), 
        .data_out(down_data), 
        .valid_out(down_valid)
    );

    assign up_ready = down_ready; 
    
    
endmodule

reg模块:

`timescale 1ns / 1ps
module se1_reg(clk, rst_n, data_in, valid_in, data_out, valid_out);

    parameter KEY = 8'h55;      //因为需要用异或所以定义parameter

    input clk, rst_n;
    input [7:0] data_in;
    input valid_in;
    output reg [7:0] data_out;
    output reg valid_out;

    always @ (posedge clk)
    begin
        if (!rst_n)
            begin
                data_out <= 0;
                valid_out <= 0;
            end
        else
            begin
                data_out <= data_in ^ KEY; //同一个值异或两次还原;
                valid_out <= valid_in;      //上游为真(假),下游为真(假);
            end
    end

endmodule

仿真模块:

`timescale 1ns / 1ps
module sab_example1_tb;

    logic clk, rst_n;
    logic [7:0] down_data, up_data;
    logic down_valid, up_valid, up_ready, down_ready;

    stimulate STIM(
        .clk(clk), 
        .rst_n(rst_n), 
        .up_data(up_data), 
        .up_valid(up_valid), 
        .up_ready(up_ready), 
        .down_ready(down_ready)
    );
    
    sab_example1 DUT(
        .clk(clk), 
        .rst_n(rst_n), 
        .up_data(up_data), 
        .up_valid(up_valid), 
        .up_ready(up_ready), 
        .down_data(down_data), 
        .down_valid(down_valid), 
        .down_ready(down_ready)
    );
    
    scoreboard SC(
        .clk(clk), 
        .rst_n(rst_n), 
        .down_data(down_data), 
        .down_valid(down_valid), 
        .up_data(up_data), 
        .up_valid(up_valid), 
        .up_ready(up_ready), 
        .down_ready(down_ready)
    );

endmodule

stimulate模块:

`timescale 1ns / 1ps
module stimulate(clk, rst_n, up_data, up_valid, up_ready, down_ready);

    output reg clk, rst_n;
    output reg [7:0] up_data;
    output reg up_valid, down_ready;
    input up_ready;     //握手

    //时钟复位;
    initial begin
        clk <= 1;
        rst_n <= 0;
        
        #200ns
        @ (posedge clk)
        rst_n <= 1;
        
        #20us $stop;
    end
    always #10ns clk <= ~clk;
    
    //SAB上游源接口;
    initial begin
        up_data <= 0;
        up_valid <= 0;
        
        #200ns
        forever begin
            @ (posedge clk)
            if (up_ready)   //上游获得条件主动的前提是up_ready为真;
                begin
                    if (({$random} % 16) > 4)   //上游四分之三几率条件主动走;
                        begin
                            up_data <= {$random} % 256;
                            up_valid <= 1;
                        end
                    else                        //上游四分之一几率条件主动停;
                        up_valid <= 0;
                end
            else            //上游被动停,必须停;
                begin
                    up_valid <= 0;
                end
        end
    end
    
    //下游宿接口;
    initial begin
        down_ready <= 0;
        
        #220ns
        forever begin
            @ (posedge clk)
            if (({$random} % 16) > 4)   //下游四分之三几率主动走;
                down_ready <= 1;
            else                        //下游四分之一几率主动停;
                down_ready <= 0;
        end
    end

endmodule

记分牌模块:

`timescale 1ns / 1ps
module scoreboard(clk, rst_n, down_data, down_valid, up_data, up_valid, up_ready, down_ready);

    input clk, rst_n;
    input [7:0] down_data, up_data;
    input down_valid, up_valid, up_ready, down_ready;

    reg [7:0] mem [65535:0];     //验证存储器;
    reg up_ready1;              //上游就绪潜伏期需要均衡出来和上游的valid对齐;
    reg down_ready1, down_ready2, down_ready3;  //同理;

    integer i,j;                //验证存储器的指针,i=写指针,j=读指针;
    
    //上游就绪潜伏期均衡;
    always @ (posedge clk) 
        up_ready1 <= up_ready;
    
    //下游就绪潜伏期均衡;
    always @ (posedge clk)
    begin 
        down_ready1 <= up_ready;
        down_ready2 <= down_ready1;
        down_ready3 <= down_ready2;
    end
    
    //上游数据捕获至存储器;
    initial begin
        i <= 0;
        
        #200ns
        forever begin
            @ (posedge clk)
            if (up_valid && up_ready1)
                begin
                    mem[i] <= up_data;
                    i <= i + 1;
                end
        end
    end
    
    //下游数据捕获并且与验证存储器数据断言比较;
    initial begin
        j <= 0;
        
        #220ns
        forever begin
            @ (posedge clk)
            if (down_valid && down_ready3)
                begin
                    assert (down_data == mem[j])
                        $display("OK: up_data=%0d down_data=%0d",mem[j],down_data);
                    else
                        $error("ERROR: up_data=%0d down_data=%0d",mem[j],down_data);
                        j <= j + 1;
                end
        end
    end

endmodule

4.5.4 验证

功能仿真截图:
是三金呐
断言报告:
是三金呐

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值