跳轉到

Latches and Flip-Flops

D flip-flop

原題:D flip-flop

練習如何用sequential block建立DFF,注意要用non-blocking assignment。

Verilog
module top_module (
    input clk,    // Clocks are used in sequential circuits
    input d,
    output reg q );//

    // Use a clocked always block
    //   copy d to q at every positive edge of clk
    //   Clocked always blocks should use non-blocking assignments
    always@(posedge clk)
        q <= d;
endmodule

D flip-flops

原題:D flip-flops

練習如何用sequential block建立8-bit input DFF。

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

DFF with reset

原題:DFF with reset

練習如何用sequential block建立8-bit input with DFF synchronous reset。

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

DFF with reset value

原題:DFF with reset value

練習負緣更新,然後題目所說在reset時要更新成0x34,0x的意思是16進位制。

Verilog
module top_module (
    input clk,
    input reset,
    input [7:0] d,
    output reg [7:0] q
);
    always@(negedge clk)begin
        if(reset) q <= 8'h34;
        else q <= d;
    end
endmodule

DFF with asynchronous reset

原題:DFF with asynchronous reset

需要做異步復位的DFF。

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

DFF with byte enable

原題:DFF with byte enable

重點是DFF加上enable。

Verilog
module top_module (
    input clk,
    input resetn,
    input [1:0] byteena,
    input [15:0] d,
    output reg[15:0] q
);
    always@(posedge clk)begin
        if(~resetn) q <= 16'h0000;
        else begin
            q[15:8] <= byteena[1] ? d[15:8]: q[15:8];
            q[7:0] <= byteena[0] ? d[7:0]: q[7:0];
        end
    end
endmodule

D Latch

原題:D Latch

練習寫d latch,因為d latch是level-sensitive,所以要用always@(*),而因為是sequential logic,所以要用non-blocking assignment。

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

DFF(1)

原題:DFF(1)

練習寫DFF with asynchronous reset。

Verilog
module top_module (
    input clk,
    input d, 
    input ar,   // asynchronous reset
    output reg q);
    always@(posedge clk,posedge ar)begin
        if(ar) q <= 1'b0;
        else q <= d;
    end
endmodule

DFF(2)

原題:DFF(2)

練習寫DFF with synchronous reset,和前一題不同的是,不用考慮reset的正緣觸發。

Verilog
module top_module (
    input clk,
    input d, 
    input r,   // synchronous reset
    output reg q);
    always@(posedge clk)begin
        if(r) q <= 1'b0;
        else q <= d;
    end
endmodule

DFF+gate

原題:DFF+gate

練習寫DFF加上gate的填寫。

Verilog
module top_module (
    input clk,
    input in, 
    output reg out);
    always@(posedge clk)begin
        out <= out ^ in;
    end
endmodule

Mux and DFF(1)

原題:Mux and DFF(1)

練習一個DFF加上一個mux。

Verilog
module top_module (
    input clk,
    input L,
    input r_in,
    input q_in,
    output reg Q);
    always@(posedge clk)begin
        Q <= L ? r_in : q_in;
    end
endmodule

Mux and DFF(2)

原題:Mux and DFF(2)

練習一個DFF加上超過1個gate,此時就可以考慮將combinational logic另外在sequential block外assign好。

Verilog
module top_module (
    input clk,
    input w, R, E, L,
    output reg Q
);  
    wire q_in;
    assign q_in = L ? R : (E ? w : Q);
    always@(posedge clk)begin
        Q <= q_in;
    end
endmodule

DFFs and gates

原題:DFFs and gates

只是寫3個DFF。

Verilog
module top_module (
    input clk,
    input x,
    output z
); 
    reg q1,q2,q3;
    assign z = ~(q1 | q2 | q3);
    always@(posedge clk)begin
        q1 <= q1 ^ x;
        q2 <= ~q2 & x;
        q3 <= ~q3 | x;
    end
endmodule

Create circuit from truth table

原題:Create circuit from truth table

練習寫JK-FF。

Verilog
module top_module (
    input clk,
    input j,
    input k,
    output reg 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

Detect an edge

原題:Detect an edge

練習寫edge detection,為了比較上個clk的輸入,要多開一個dff存。

Verilog
module top_module (
    input clk,
    input [7:0] in,
    output reg [7:0] pedge
);
    reg [7:0] in_prev;
    always@(posedge clk)begin
        in_prev <= in;
        pedge <= ~in_prev & in;
    end
endmodule

Detect both edges

原題:Detect both edges

練習寫edge detection,和前一題不同的是,要同時判斷0變1和1變0。

Verilog
module top_module (
    input clk,
    input [7:0] in,
    output reg [7:0] anyedge
);
    reg [7:0] in_prev;
    always@(posedge clk)begin
        in_prev <= in;
        anyedge <= in ^ in_prev;
    end
endmodule

Edge capture register

原題:Edge capture register

最難的地方就是將edge detection變成edge capture,最簡單的做法就是多or上回合的output。

Verilog
module top_module (
    input clk,
    input reset,
    input [31:0] in,
    output reg [31:0] out
);
    reg [31:0] in_prev;
    always@(posedge clk)begin
        in_prev <= in;
        if(reset)
            out <= 32'h0000_0000;
        else begin
            out <= ~in & in_prev | out;
        end
    end
endmodule

Dual-edge triggered flip-flop

原題:Dual-edge triggered flip-flop

可參考標準解法理解電路結構,重點在觀察輸出回授如何形成下一拍狀態。

Verilog
module top_module (
    input clk,
    input d,
    output q
);
    // Why does this work? 
    // After posedge clk, p changes to d^n. Thus q = (p^n) = (d^n^n) = d.
    // After negedge clk, n changes to p^n. Thus q = (p^n) = (p^d^p) = d.
    reg r1, r2;
    assign q = r1 ^ r2;
    always@(posedge clk) r1 <= r2 ^ d;
    always@(negedge clk) r2 <= r1 ^ d;
endmodule