Skip to content

时序电路

约 648 个字 95 行代码 4 张图片 预计阅读时间 3 分钟

  1. D触发器:

功能介绍:

D 触发器是一个电路,存储 1bit 数据,并定期地根据触发器的输入(d)更新这 1 bit 数据,更新通常发生在时钟上升沿(clk)。存储的数据会通过输出管脚(q)输出。

t1时刻: d -> 0 t2时刻: clk->1 上升沿到来,触发器存储的数据变成 0,输出 q 保持为存储的值:0,直到下一个时钟上升沿到来。 t3时刻: d -> 1(d:我变了),q 仍保持 0 不动摇(时钟沿还没来呢) t4时刻: clk->1 上升沿到来,q->1(q:时钟沿来了,我该变身了) 绝大多数时候,我们不会在 Verilog 代码中显示例化一个触发器(作者没这么做过,但应该是可以做的),我们在时钟敏感的 always 块中的语句一般都会被综合工具转换为相应的触发器。 D 触发器可以认为是一个触发器和一段最简单的组合逻辑块(blob :想表达逻辑块的时候用我,别用 block)的组合。其中组合逻辑块仅仅是一段 wire。(q 直接输出了触发器的存储值)

  • clk=0,读取d
  • clk=1,写入d

注意时序的一些语法:

  1. always:
    always @(*) // 在任何情况下都执⾏always块,常⽤于书写组合逻辑 
    always @(a) // 当a的值发⽣改变的时候,执⾏ 
    always @(a or b) // 当a或b的值发⽣改变的时候,执⾏ 
    always @(posedge a or negedge b) // 当遇到a的正边沿或b的负边沿时,执⾏ always // 不带@,执⾏完⼀次块内内容后,就再执⾏⼀次,常⽤于tesebench的clk信号改变
    

其中: - 正边沿:信号从low到high - 负边沿:信号从high到low

  1. 阻塞性赋值和非阻塞性赋值

在Verilog中有以下三种赋值方法:

连续赋值(assign x=y;):不能在过程块内使用;
过程阻塞性赋值(x=y;):只能在过程块中使用;
过程非阻塞性复制(x<=y):只能在过程块内使用。
  • 在组合always块中,使用阻塞性赋值。在时序always块中,使用非阻塞性赋值。

8位触发器的实现:

module top_module (
    input clk,
    input [7:0] d,
    output [7:0] q
);
    always @(posedge clk)
        q<=d;
endmodule

给触发器配上同步复位端口(同步复位:当时钟上升沿到来时,如果同步复位端有效(本题中复位高电平有效,即 reset),那么任凭你触发器此前输出或者输入的是 0,是 1,输出一律变为 0):

module top_module (
    input clk,
    input reset,            // Synchronous reset
    input [7:0] d,
    output [7:0] q
);
    always@(posedge clk)begin
        if(reset)
            q <= 8'b0;
        else
            q <= d;
    end
endmodule

引入异步复位

  • 对于同步复位系统来说,当同步复位事件发生时,等到下一个时钟上升沿才会得到响应,响应的速度比较慢。
  • 与之相对的异步复位的响应就很快,因为在异步复位有效的时刻,复位响应就会发生,好像戳破气球一般。

简而言之:就是让areset的变化早于下一个clk上升沿被发现!

我写了一个同步复位,和异步进行了对比:

代码:(抄的ww)

module top_module (
    input clk,
    input areset,   // active high asynchronous reset
    input [7:0] d,
    output [7:0] q
);
    always @(posedge clk or posedge areset)begin
        if(areset)
            q<=8'b0;
        else
            q<=d;
    end
endmodule

锁存器:D-latches:

module top_module (
    input d,
    input ena,
    output q);
    always @(*)begin
        if(ena)
            q<=d;
    end
endmodule

其中,ena是使能端

触发器和门电路的综合:

module top_module (
    input clk,
    input x,
    output z
); 

    reg q1 = 0;
    reg q2 = 0;
    reg q3 = 0;

    always @ (posedge clk)
        begin
            q1 <= x ^ q1; 
        end

    always @ (posedge clk)
        begin
            q2 <= x & (~q2);
        end

    always @ (posedge clk)
        begin
            q3 <= x | (~q3);
        end

    assign z = ~(q1 | q2 | q3); 

endmodule

多变量,用case的巧妙写法:

module top_module (
    input clk,
    input j,
    input k,
    output Q); 

    always @ (posedge clk)
        begin
            case ({j, k})
                2'b00: Q <= Q;
                2'b01: Q <= 1'b0;
                2'b10: Q <= 1'b1;
                2'b11: Q <= ~Q;
            endcase
        end

endmodule

Comments