verilog7

2023. 3. 14. 11:24Verilog

조합회로 설계 실습

module mux4x1_error (
    input [1:0] sel,
    input d0, d1, d2, d3,
    output m1,
    output reg m2
);

assign m1 = sel[1] ? (sel[0] ? d3 : d2) : (sel[0] ? d1 : d0);

always @(*) begin
    if (sel == 2'b11) m2 = d3;
    else if (sel == 2'b10) m2 = d2;
    else if (sel == 2'b01) m2 = d1;
    else if (sel == 2'b00) m2 = d0;
end
endmodule

이렇게 구현하면 Latch가 발생하게 된다. 

RTL 분석 결과
합성 결과

하지만 합성 과정에서 Latch가 없어진것을 볼 수 있다. 이러면 시뮬레이션과 실제 보드에서 동작이 다를 수 있다. 이는 툴의차이이다. 따라서 합성하고 시뮬레이션을 돌리는 것도 중요하다. 

 

else를 하나 추가해주면 모두 MUX로 합성된다. 

module mux4x1_error (
    input [1:0] sel,
    input d0, d1, d2, d3,
    output m1,
    output reg m2,
    output reg m3
);

assign m1 = sel[1] ? (sel[0] ? d3 : d2) : (sel[0] ? d1 : d0);

always @(*) begin
    if (sel == 2'b11) m2 = d3;
    else if (sel == 2'b10) m2 = d2;
    else if (sel == 2'b01) m2 = d1;
    else if (sel == 2'b00) m2 = d0;
    else m2 = 0;
end

else를 추가해 Latch 제거

`timescale 1ns / 1ps


module Mux_4X1(
        input [1:0] sel,
        input d0, d1, d2, d3,
        output m1,
        output reg m2
    );

assign m1 = sel[1] ? (sel[0] ? d3 : d2) :(sel[0] ? d1 : d0);

always @(*) begin
    case(sel)
        2'b00 : m2 = d0;
        2'b01 : m2 = d1;
        2'b10 : m2 = d2;
        2'b11 : m2 = d3;
        default : m2 = 0;
    endcase
end
endmodule

case를 사용해 MUX생성

비교기

 

 

`timescale 1ns/1ps

module comp_Large #(
    parameter WD = 4
) (
    input [WD - 1 : 0] a, b,
    output reg a_Larger_Then_b
    );
    
always @(*) begin
    a_Larger_Then_b = 0;
    if(a[3] > b[3]) a_Larger_Then_b = 1'b1;
    else if (a[2] > b[2]) a_Larger_Then_b = 1'b1;
    else if (a[1] > b[1]) a_Larger_Then_b = 1'b1;
    else if (a[0] > b[0]) a_Larger_Then_b = 1'b1;
end
endmodule

위 코드는 논리적인 오류가 있는 코드이다. 

`timescale 1ns/1ps

module comp_Large #(
    parameter WD = 4
) (
    input [WD - 1 : 0] a, b,
    output reg a_Larger_Then_b
    );
    
always @(*) begin
    a_Larger_Then_b = 0;
    if(a[3] > b[3]) a_Larger_Then_b = 1'b1;
    else if ((a[3] == b[3]) && (a[2] > b[2])) a_Larger_Then_b = 1'b1;
    else if ((a[3:2] == b[3:2]) && (a[1] > b[1])) a_Larger_Then_b = 1'b1;
    else if ((a[3:1] == b[3:1]) && (a[0] > b[0])) a_Larger_Then_b = 1'b1;
    else a_Larger_Then_b = 0;
end
endmodule
`timescale 1ns / 1ps

module test_compare;
parameter WD = 4;

reg [WD - 1 : 0] a, b;
wire a_Larger_Then_b;

comp_Large U1 (.a(a), .b(b), .a_Larger_Then_b(a_Larger_Then_b));

initial begin
    a = 4'b0;  b = 4'b0;
   #10 a = 4'h1; b = 4'h2;
   #10 a = 4'h2; b = 4'h1;
   #10 a = 4'h8; b = 4'ha;
   #10 a = 4'hb; b = 4'h3;
   #10 a= 4'h3;  b = 4'h3;
   $finish;

end
endmodule

잘 작동된다. 

 

'Verilog' 카테고리의 다른 글

verilog 10 FSM/ASM  (0) 2023.03.17
verilog 9 카운터 실습  (0) 2023.03.15
verilog 5  (0) 2023.03.13
verilog 3  (0) 2023.03.10
Verilog-2  (0) 2023.03.09