본문 바로가기

Verilog 공부

HDLBits (Circuits - Sequential Circuits - Latches and FF) - Verilog 문제 풀이 2-2-1

문제 : D-FF

  • Blocking VS NON-Blocking
    • Blocking : 순차적 할당
    • Non-Blocking : 동시 할당
//Blocking!!
begin 
    x=0;
    y=x;
end
//result : x=0, y=0

//NonBlocking
begin
    x<=0;
    y<=x;
end
//result : x=0, y=x (x의 값이 보장되지 않는다.)
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-FF 8Bit

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

문제 : D-FF with Reset

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

문제 : DFF with reset value

module top_module (
    input clk,
    input reset,
    input [7:0] d,
    output [7:0] q
);

    always @ (negedge clk)
        if(reset) q<=8'h34;
        else q<=d;

endmodule

문제 : DFF with asynchronous reset

  • 비동기식 reset -> reset도 clk처럼 써보자
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 <= 0;
        else              // 입력값 d를 q에 저장
            q <= d;
    end
endmodule

문제 : DFF with byte Enable

  • resetn : synchronous active low reset
    • clk 내부에서 if로 처리
    • 보통 뒤에 n이 붙어 있으면 0일때 reset함
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==0)       
            q[7:0] <= 0;
        else if(byteena[0] == 1)
            q[7:0] <= d[7:0];
    end

    always @ (posedge clk) begin
        if (resetn==0)       
            q[15:8] <= 0;
        else if(byteena[1] == 1)
            q[15:8] <= d[15:8];
    end
endmodule

문제 : D Latch

  • D Latch는 Ena signal이 1일때 값으로 바꾸는 것
module top_module (
    input d, 
    input ena,
    output q);

    always @ (*) begin
        if (ena)       
            q <= d;
    end

endmodule

문제 : DFF with asynchronous reset

  • always 안에 ar과 같이 다른 변수의 경우도 posedge와 같이 정해줘야함
  • posedge ar 이란 뜻은 "ar =1이 될때 동작해"라는 것
  • 비동기식 reset이기 때문에 ar=1일때도 동작하게 되는 것
module top_module (
    input clk,
    input d, 
    input ar,   // asynchronous reset
    output q);

    always @ (posedge clk or posedge ar) begin
        if (ar==1)       
            q <= 0;
        else 
            q <= d;
    end

endmodule

문제 : DFF with synchronous reset

  • 동기식 reset이기 때문에 clk에 맞춰 reset의 값을 확인해주면 됨
module top_module (
    input clk,
    input d, 
    input r,   // synchronous reset
    output q);

    always @ (posedge clk) begin
        if (r==1)       
            q <= 0;
        else 
            q <= d;
    end

endmodule

문제 : DFF with Gate

  • reg 선언 필요
module top_module (
    input clk,
    input in, 
    output reg out);

    always @ (posedge clk) begin
        out <= in ^ out; 
    end

endmodule

문제 : MUX and DFF 1

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

module top_module (
    input clk,
    input w, R, E, L,
    output Q
);
    always @ (posedge clk) begin
        Q <= L ? R : (E ? w : Q); 
    end

endmodule

문제 : DFFs and Gates

module top_module (
    input clk,
    input x,
    output reg z
); 
    reg q1, q2, q3; 

    always @ (posedge clk) begin
        q1 <= q1 ^ x;       
        q2 <= ~q2 & x;       
        q3 <= ~q3 | x; 
        //기존 틀린 풀이는 
        //z <=  ~(q1 | q2 | q3); z는 conbinational logic임
        //따라서 외부 할당 해야함     
    end

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

endmodule

문제 : Create Circuit from truth table

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

    always @ (posedge clk) begin
        Q <= j ? (k? ~Q : 1) : (k? 0 : Q);
    end

endmodule

문제 : Detect an edge

module top_module (
    input clk,
    input [7:0] in,
    output reg [7:0] pedge
);

    reg [7:0] r;  // 이전 클럭 주기의 입력 값을 저장할 레지스터

    always @ (posedge clk) begin
        r <= in;  
        pedge <= (in & ~r);  
    end

endmodule
  • 처음 푼 방법

module top_module (
    input clk,
    input reg [7:0] in,
    output reg [7:0] pedge
);

    always @ (posedge clk) begin
        pedge[0] <= pedge[0] ^ in[0];
        pedge[1] <= pedge[1] ^ in[1];
        pedge[2] <= pedge[2] ^ in[2];
        pedge[3] <= pedge[3] ^ in[3];
        pedge[4] <= pedge[4] ^ in[4];
        pedge[5] <= pedge[5] ^ in[5];
        pedge[6] <= pedge[6] ^ in[6];
        pedge[7] <= pedge[7] ^ in[7];
    end
endmodule
  • 같은 값이 여러 사이클 걸쳐 나오면 틀리게 됨 - reg를 두고 풀어야함