2021年5月28日 星期五

Verilog Circuits Sequential Logic Latches and Flip-Flops

Verilog Circuits Sequential Logic Latches and Flip-Flops

Sequential Logic

Latches and Flip-Flops

·        D flip-flop

·        D flip-flops

·        DFF with reset

·        DFF with reset value

·        DFF with asynchronous reset

·        DFF with byte enable

·        D Latch

·        DFF

·        DFF

·        DFF+gate

·        Mux and DFF

·        Mux and DFF

·        DFFs and gates

·        Create circuit from truth table

·        Detect an edge

·        Detect both edges

·        Edge capture register

·        Dual-edge triggered flip-flop

Dff

A D flip-flop is a circuit that stores a bit and is updated periodically, at the (usually) positive edge of a clock signal.



D flip-flops are created by the logic synthesizer when a clocked always block is used (See alwaysblock2). A D flip-flop is the simplest form of "blob of combinational logic followed by a flip-flop" where the combinational logic portion is just a wire.

Create a single D flip-flop.

·

·      Blocking & Non Blocking

Blocking & Non Blocking
1. Blocking的語法 =  //循序式的方式執行程式
Exp :
        always@(posedge clock)
        begin
                Data = A&B;                   // blocking會先執行第一行程式
                OUT = A+B;                   // 緊接著再執行第二行程式
        end
注意 : 電路都使用blocking的方式設計會造成電路串連的太長,導致延遲太多時間。
2. Non blocking的語法 <=  //平行式的方式執行程式
Exp :
        always@(posedge clock)
        begin
                Data <= A&B;         // non blocking會同時執行
                OUT <= A+B;                 //
        end
 
注意 : 電路都使用non blocking的方式設計會造成電路面積加大(成本提高),因為並行處理的輸出都要額外給予一個暫存器來儲存。
  對於新手而言,該如何準確的判斷哪些時候該選用blocking,哪些時候又該選用non blocking來做處理,有相當程度的困難。因此通常會給予新手一些建議,避免設計電路上的錯誤。
 
1. 組合邏輯assign電路採用blocking,且必須搭配wire
2. 循序邏輯always電路採用non blocking,且必須搭配reg
組合邏輯à與時間無關,大多作為運算用。(如加、減法器)
循序邏輯à與時間有關,大多作為記憶資料,但不能運算。(如正反器)

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) begin

         q<=d;  //循序邏輯always電路採用non blocking,且必須搭配reg

    end

 

endmodule

Dff8


 







Create 8 D flip-flops. All DFFs should be triggered by the positive edge of clk.

module top_module(

        input clk,

        input [7:0] d,

        output reg [7:0] q);

       

        // Because q is a vector, this creates multiple DFFs.

        always @(posedge clk)

                q <= d;

       

endmodule

Dff8r


Create 8 D flip-flops with active high synchronous reset. All DFFs should be triggered by the positive edge of clk.

 






module top_module (

    input clk,

    input reset,            // Synchronous reset

    input [7:0] d,

    output [7:0] q

);

    always @(posedge clk) begin

        if (reset)

            q<=0;

        else

                 q <= d;

    end

endmodule

 

Dff8p

Create 8 D flip-flops with active high synchronous reset. The flip-flops must be reset to 0x34 rather than zero. All DFFs should be triggered by the negative edge of clk.

module top_module (

    input clk,

    input reset,

    input [7:0] d,

    output [7:0] q

);

    always @(negedge clk) begin

        if (reset)

            q<=8'h34;

        else

                        q <= d;

    end

endmodule

 

Dff8ar

Create 8 D flip-flops with active high asynchronous reset. All DFFs should be triggered by the positive edge of clk.

      // In Verilog, the sensitivity list looks strange. The FF's reset is sensitive to the

      // *level* of areset, so why does using "posedge areset" work?

      // To see why it works, consider the truth table for all events that change the input

      // signals, assuming clk and areset do not switch at precisely the same time:

     

      //  clk           areset       output

      //   x       0->1         q <= 0; (because areset = 1)

      //   x       1->0         no change (always block not triggered)

      //  0->1      0          q <= d; (not resetting)

      //  0->1      1          q <= 0; (still resetting, q was 0 before too)

      //  1->0      x          no change (always block not triggered)

 

 

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'h00;

        else

                        q <= d;

    end

endmodule

 

Dff16e

Create 16 D flip-flops. It's sometimes useful to only modify parts of a group of flip-flops. The byte-enable inputs control whether each byte of the 16 registers should be written to on that cycle. byteena[1] controls the upper byte d[15:8], while byteena[0] controls the lower byte d[7:0].

module top_module (

    input clk,

    input resetn,

    input [1:0] byteena,

    input [15:0] d,

    output [15:0] q);

    always@(posedge clk) begin

        if (resetn==1'b0)

            q<=16'h00;

         else begin

            case(byteena)

                2'b00: q <= q;

                2'b01: q <= {q[15:8], d[7:0]};

                2'b10: q <= {d[15:8], q[7:0]};

                2'b11: q <= d;

            endcase

            end

    end       

endmodule

Exams/m2014 q4a

Implement the following circuit:




Note that this is a latch, so a Quartus warning about having inferred a latch is expected.

module top_module (

    input d,

    input ena,

    output q);

    always@(*) begin

        if (ena)

            q=d;

    end

endmodule

Exams/m2014 q4b

Implement the following circuit:  input ar,   // asynchronous reset






//正確

// input ar,    asynchronous reset

module top_module (

    input clk,

    input d,

    input ar,   // asynchronous reset

    output q);

    always @(posedge clk, posedge ar)begin

        if (ar)

            q<=0;

        else

            q<=d;

    end

endmodule

 

//錯誤

module top_module (

    input clk,

    input d,

    input ar,   // asynchronous reset

    output q);

    always @(posedge clk)begin

        if (ar)

            q<=0;

        else

            q<=d;

    end

endmodule

Exams/m2014 q4c

Implement the following circuit: input r,   // synchronous reset






//同步式 D 正反器

 

module top_module (

    input clk,

    input d,

    input r,   // synchronous reset

    output q);

    always @(posedge clk)begin

        if (r)

            q<=0;

        else

            q<=d;

    end

 

endmodule

Exams/m2014 q4d

Implement the following circuit:








module top_module (

    input clk,

    input in,

    output out);

        wire d1;

    assign d1=out^in;

    d_ff u0(clk,d1,out);

endmodule

 

module d_ff (

    input clk,    // Clocks are used in sequential circuits

    input d,

    output reg q );//

    always@(posedge clk) begin

         q<=d;  //循序邏輯always電路採用non blocking,且必須搭配reg

    end

endmodule

 

Mt2015 muxdff

Taken from ECE253 2015 midterm question 5

Consider the sequential circuit below:







Assume that you want to implement hierarchical Verilog code for this circuit, using three instantiations of a submodule that has a flip-flop and multiplexer in it. Write a Verilog module (containing one flip-flop and multiplexer) named top_module for this submodule.

module top_module (

        input clk,

        input L,

        input r_in,

        input q_in,

        output reg Q);

   always@(posedge clk)begin

        if(L)begin

            Q <= r_in;

        end

        else begin

            Q <= q_in;

        end

    end

endmodule

 

module top_module (
    input clk,
    input L,
    input r_in,
    input q_in,
    output reg Q);
 
    wire temp;
    assign temp = L ? r_in : q_in;  //2 to 1 選擇器
    always @ (posedge clk ) //觸發器
        begin
           Q <= temp; 
        end
endmodule

 

Exams/2014 q4a

 

Consider the n-bit shift register circuit shown below:






Write a Verilog module named top_module for one stage of this circuit, including both the flip-flop and multiplexers.

module top_module (

    input clk,

    input w, R, E, L,

    output Q

);

    wire temp_d;

    assign temp_d= (L==1)? R : (E==1)?w:Q;

     always @ (posedge clk ) //觸發器

        begin

           Q <= temp_d;

        end

endmodule

Exams/ece241 2014 q4

Given the finite state machine circuit as shown, assume that the D flip-flops are initially reset to zero before the machine begins.

Build this circuit.




module top_module (

    input clk,

    input x,

    output z

);

        wire d1,d2,d3;

    wire q1,q2,q3;

    assign d1=x ^ q1;

    assign d2=x & (~q2);

    assign d3=x | (~q3);

    d_ff u0(clk,d1,q1);

    d_ff u1(clk,d2,q2);

    d_ff u2(clk,d3,q3);

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

endmodule

 

module d_ff (

    input clk,    // Clocks are used in sequential circuits

    input d,

    output reg q );//

    always@(posedge clk) begin

         q<=d;  //循序邏輯always電路採用non blocking,且必須搭配reg

    end

endmodule

Exams/ece241 2013 q7

A JK flip-flop has the below truth table. Implement a JK flip-flop with only a D-type flip-flop and gates. Note: Qold is the output of the D flip-flop before the positive clock edge.

J

K

Q

0

0

Qold

0

1

0

1

0

1

1

1

~Qold

 

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

Edgedetect

For each bit in an 8-bit vector, detect when the input signal changes from 0 in one clock cycle to 1 the next (similar to positive edge detection). The output bit should be set the cycle after a 0 to 1 transition occurs.

Here are some examples. For clarity, in[1] and pedge[1] are shown separately.

邊緣檢測的特性就是兩邊電平發生了變化,無非是01上升緣10下降緣

具體的設計可以採用一個暫存器Q來存儲上一個時鐘沿的輸入值D,當暫存器與輸入D的值分別為10時,則檢測到下降沿。

如圖:


信號前一狀態 in_last  0 低電平,當前狀態 in  1 高電平,即可檢測出該信號的上升。因此電路組成:保存信號前一狀態的D觸發器 + 輸出組合邏輯 out = ~in_last & in 。電路結構見下的電路圖。


????  out = ~in_last & in ????


 

module top_module (

    input clk,

    input [7:0] in,

    output [7:0] pedge

);

   reg[7:0] in_last;

    always@(posedge clk) begin

       in_last <= in;

       pedge <= ~in_last & in;

    end

endmodule

//錯誤

module top_module (

    input clk,

    input [7:0] in,

    output [7:0] pedge

);

   reg[7:0] in_last;

    always@(posedge clk) begin

        in_last <= in;

        pedge <= in_last & ~in;

     end 

endmodule

Edgedetect2

For each bit in an 8-bit vector, detect when the input signal changes from one clock cycle to the next (detect any edge). The output bit should be set the cycle after a 0 to 1 transition occurs.

Here are some examples. For clarity, in[1] and anyedge[1] are shown separately

1. 上升沿加下降沿檢測

上升沿核心檢測邏輯: ~in_last & in

降沿類似上升沿核心邏輯為: in_last & ~in

最後運用或邏輯組合起來即可。核心代碼:anyedge = (~in_last & in) | (in_last & ~in)

2. 互斥或邏輯檢測。邊沿檢測,從整體來看,即信號發生變化就進行檢測輸出。因此使用異或邏輯 。核心代碼: in^ in_last (in  xor in_last)




module top_module (

    input clk,

    input [7:0] in,

    output [7:0] anyedge

);

   reg[7:0] in_last;

    always @(posedge clk) begin

         //D flip-flop

       in_last <= in;

       // Method1: posedge +negedge

       //assign anyedge = (~in_last & in) | (in_last & ~in);

       // Method2: XOR

      anyedge <= in ^ in_last;

    end   

endmodule

Edgecapture

For each bit in a 32-bit vector, capture when the input signal changes from 1 in one clock cycle to 0 the next. "Capture" means that the output will remain 1 until the register is reset (synchronous reset).

Each output bit behaves like a SR flip-flop: The output bit should be set (to 1) the cycle after a 1 to 0 transition occurs. The output bit should be reset (to 0) at the positive clock edge when reset is high. If both of the above events occur at the same time, reset has precedence. In the last 4 cycles of the example waveform below, the 'reset' event occurs one cycle earlier than the 'set' event, so there is no conflict here.

In the example waveform below, reset, in[1] and out[1] are shown again separately for clarity.

對於32bits向量中的每一位元,當輸入信號由1變為0時進行檢測(即下降沿檢測)。其中檢測表示在重定信號(同步)到達前,輸出將保持1。 每一個輸出位就像一個RS觸發器,即當對應位出現1 to 0的變化時,輸出位將置1;而當reset信號為高電平,輸出位元將在下一個時鐘的上升沿被重定。如果信號的下降沿和reset事件在同一時刻發生,將優先執行復位操作。在下圖示例波形的最後4個時鐘週期中,reset事件比‘set’事件早一個週期出現,因此這裡沒有前述衝突。 為清楚起見,in[1]out[1]在波形中分別單獨顯示。

 

邊緣檢測輸出保持狀態1,直到reset信號到達



module top_module (

    input clk,

    input reset,

    input [31:0] in,

    output [31:0] out

);

   reg[31:0] in_last;//in's last state

   always@(posedge clk)//D Flip-Flop

       in_last <= in;

 

    always@(posedge clk)  begin

       if(reset)

          out <= 32'h0000_0000;

       else

          out <= out | in_last & ~in;

    end

endmodule

Dualedge

You're familiar with flip-flops that are triggered on the positive edge of the clock, or negative edge of the clock. A dual-edge triggered flip-flop is triggered on both edges of the clock. However, FPGAs don't have dual-edge triggered flip-flops, and always @(posedge clk or negedge clk) is not accepted as a legal sensitivity list.

Build a circuit that functionally behaves like a dual-edge triggered flip-flop:

一般的觸發器都是時鐘上升沿或下降沿觸發的。雙邊沿觸發器則是在時鐘的兩個邊沿都會引起觸發。然而,FPGA沒有雙邊沿觸發的觸發器,且always@(posedge clk, negedge clk)中的敏感事件清單不合乎語法。 設計一種電路,使其功能類似於雙邊沿觸發器。 Tips: 1)在FPGA中雖不能設計雙邊沿觸發器,但是能夠設計單獨的上升沿觸發器和下降沿觸發器。2)該問題屬於中等難度的電路設計問題,只需要對基本的Verilog語法有所掌握即可。

 

該問題有兩種解法,一種是Mux選擇輸出法,另一種是網站給出的XOR方法

Mux選擇輸出法



module top_module (

    input clk,

    input d,

    output q

);

        reg neg_q, pos_q;

        always@(negedge clk)//negedge triggered flip-flop

                neg_q <= d;

 

    always@(posedge clk)//posedge triggered flip-flop

                pos_q <= d; 

 

    assign q = clk ? pos_q : neg_q;      //a mux for out      

 

endmodule

XOR

module top_module (

    input clk,

    input d,

    output q

);

       reg p, n;

       

       always @(posedge clk)  // A positive-edge triggered flip-flop

                p <= d ^ n; 

 

    always @(negedge clk)  // A negative-edge triggered flip-flop

               n <= d ^ p;

 

    // 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 d^p. Thus q = (p^n) = (p^d^q) = d.

        // At each (positive or negative) clock edge, p and n FFs alternately

        // load a value that will cancel out the other and cause the new value of d to remain.

        assign q = p ^ n;

 

endmodule

 

 

 

沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...