组合逻辑与时序逻辑

1.概述

组合逻辑:输出只是当前输入逻辑电平的函数(有延时),与电路的原始状态无关。当前电路输入信号任何一个发生改变,输出都将发生改变。

时序逻辑:输出不仅是当前输入电平的函数,还与目前电路的状态有关。

数据通道开关逻辑电路

组合逻辑与时序逻辑_第1张图片

assign out = (controlswitch)?in:8'b0;

若controlswitch为1,则输出in信号,否则输出0。

三态数据通路控制器

组合逻辑与时序逻辑_第2张图片

inout[7:0] bus;//定义总线wire

assign bus = Linkbusswitch?outbuf:8'bz;

always@(posedge clk)

begin

if(!Linkbusswitch)

begin

        inbuf <= bus;

end

end

后者与前者的区别在于,前者控制信号切断时,输出为0,而后者控制信号切断时,输出为高阻,与总线脱离连接,此时如果总线的另一端有驱动源,总线可以作为模块的输入信号线。

2.同步时序和异步时序

同步时序:表示状态的寄存器组只能在唯一确定的触发条件发生时刻改变。

异步时序:表示触发条件由多个控制因素组成,如一个触发器的输出连接到另一个触发器的时钟就是异步时序逻辑。

在verilog HDL设计可综合模块时,要避免异步时序,一方面许多综合器不支持异步时序,另外异步时序很难控制由组合逻辑产生的竞争冒险。

同步时序在第一个时钟的正跳沿为输入做准备,在第一个时钟正跳沿和下一个时钟正跳沿之间有足够的时间使输入稳定,在第二个时钟正跳沿,可以产生稳定的输出。同步时序有个前提:确定下一状态所使用的组合电路的延迟与时钟到各触发器的差值必须小于一个周期。这就要求:全局时钟布线时尽量使各分支时钟一致,并且采用平衡树结构,在每一级加入缓冲器,使到各个触发器时钟同步。

数据接口的同步

数据接口的同步是数字系统设计常见问题。比如前级输出延时是随机的,如何在后级完成数据同步?级联的两个模块的基本时钟是异步时钟域,如何把前级输出的数据准确传送到下一级模块?

答:双口RAM或者FIFO,在输入端口使用前级时钟写数据,在输出端口使用本级时钟读数据,并有缓冲器空和满控制信号管理数据的读写。

3.同步状态机(重点)

Mealy状态机:时序逻辑的输出不但取决于状态还取决于输入。

Moore状态机:时序逻辑的输出仅取决于状态。

三段式状态机:

组合逻辑与时序逻辑_第3张图片

状态转移图:

组合逻辑与时序逻辑_第4张图片

三段式:

时序逻辑(状态寄存器):state<=nextstate;//nextstate为激励信号,state为当前状态。

组合逻辑:

module test(
    clk,
    reset,
    A,
    k1,
    k2
    );
    input clk,reset,A;
    output reg k1,k2;
    reg[3:0] state,nextstate;//define state and next state
    
    parameter idle = 4'b0001;
    parameter start = 4'b0010;
    parameter stop = 4'b0100;
    parameter clear = 4'b1000;
    
    //state register
    always@(posedge clk or negedge reset)
    begin
        if(!reset)
            state <= idle;
        else
            state <= nextstate;
    end
    
    //generate next state 
    always@(state or A)
    begin
        case(state)
        idle:
            if(A)
                nextstate = start;
            else
                nextstate = idle;
        state:
            if(!A)
                nextstate = stop;
            else
                nextstate = start;
        stop:
            if(A)
                nextstate = clear;
            else
                nextstate = stop;
        clear:
            if(!A)
                nextstate = idle;
            else
                nextstate = clear;
        default:
            nextstate = idle;
        endcase
    end
    
    //generate output
    always@(state or A or reset)
    begin
        if(!reset)
            k1 = 0;
        else if(!A&&state == clear)
            k1 = 1;
        else
            k1 = 0;     
    end
    
    always@(state or A or reset)
    begin
        if(!reset)
            k2 = 0;
        else if(A&&state == stop)
            k2 = 1;
        else
            k2 = 0;
    end
endmodule

testbench

module testbench(

    );
    reg clk,reset,A;
    wire k1,k2;
    initial
    begin
        clk = 0;
        A = 0;
    end
    //clock
    always #50 clk = ~clk;
    //reset
    initial
    begin
        reset = 1;
        #22 reset = 0;
        #133 reset = 1;
    end
    //
    always@(posedge clk)
    begin
        #30 A = {$random}%2;
        #(3*50+12);
    end
    
    test my_test(.clk(clk),.reset(reset),.A(A),.k1(k1),.k2(k2));
endmodule

 

你可能感兴趣的:(FPGA逻辑)