조합논리회로 모델링 Sun, Hye-Seung
조합논리회로의 형태와 설계에 사용되는 Verilog 구문 논리합성이 지원되지 않는 Verilog 구문 조합논리회로 모델링 조합논리회로의 형태와 설계에 사용되는 Verilog 구문 조합논리회로의 형태 ∙논리 게이트 ∙Multiplexer ∙Encoder ∙Decoder ∙Random Logic ∙Adder ∙Subtractor ∙ALU ∙Lookup Table ∙Comparator 조합논리회로 설계에 사용되는 Verilog 구문 ∙게이트 프리미티브 ∙연속 할당문 (assign 문) ∙행위수준 모델링 (if 문, case 문, for 문) ∙함수 및 task (시간 또는 event 제어를 갖지 못한다) ∙모듈 인스턴스 논리합성이 지원되지 않는 Verilog 구문 ∙initial 문 ∙스위치 프리미티브 (cmos, nmos, tran 등) ∙forever, while, repeat 등의 반복문 ∙wait, event, 지연 등 타이밍 제어 구문 ∙force-release, fork-join ∙시스템 task ($finish, $time 등)
조합논리회로 모델링 조합논리회로 모델링 시 유의사항 always 구문 if 조건문과 case 문 감지신호 목록 (sensitivity list)에 회로 (즉, always 블록으로 모델링되는 회로)의 입력신호들이 빠짐없이 모두 포함되어야 함 그렇지 않은 경우 ; 합성 전과 합성 후의 시뮬레이션 결과가 다를 수 있음 if 조건문과 case 문 모든 입력 조건들에 대한 출력값이 명시적으로 지정되어야 함 그렇지 않은 경우 ; 래치가 생성되어 순차논리회로가 될 수 있음 논리 최적화가 용이한 구조와 표현을 사용 최소의 게이트 수와 최소 지연경로를 갖는 회로가 합성되도록 해야 함 소스코드가 간결해지도록 모델링 소스코드의 가독성 (readability)을 좋게 하여 오류 발생 가능성을 줄여 주고, 디버깅을 용이하게 하여 설계 생산성을 높여 줌
10.1.1 기본 논리게이트 모델링 4입력 NAND 게이트 비트 연산자, 축약연산자, 게이트 프리미티브 y 비트 연산자, 축약연산자, 게이트 프리미티브 module nand4_op1(a, y); input [3:0] a; output y; assign y = ~(a[0] & a[1] & a[2] & a[3]); // 비트 연산자 // assign y = ~&a; // 축약 연산자 // nand U0(y, a[0], a[1], a[2], a[3]); // 게이트 프리미티브 endmodule 코드 10.1 ~ 10.3
10.1.1 기본 논리게이트 모델링 4입력 NAND 게이트 if 조건문 module nand4_if(a, y); input [3:0] a; output y; reg y; always @(a) begin if(a == 4'b1111) y = 1'b0; else y = 1'b1; end endmodule 코드 10.4
10.1.1 기본 논리게이트 모델링 4입력 NAND 게이트 (테스트벤치) module tb_nand4; reg [3:0] a; wire y; integer i; nand4_op1 U0(a, y); // nand4_op2 U0(a, y); // nand4_gate U0(a, y); // nand4_if U0(a, y); initial begin a = 0; for(i=1; i < 32; i=i+1) #20 a = i; end endmodule 코드 10.5
10.1.1 기본 논리게이트 모델링 4입력 NAND 게이트의 시뮬레이션 결과
10.1.1 기본 논리게이트 모델링 3입력 NOR 게이트를 아래의 방식으로 모델링하고, 테스트벤치를 작성하여 기능을 검증 비트단위 연산자를 사용하는 방법 축약 연산자를 사용하는 방법 게이트 프리미티브를 사용하는 방법 if 조건문을 사용하는 방법
10.1.2 멀티비트 논리연산의 모델링 4비트 2입력 NOR 게이트 비트 연산자 a[3:0] b[3:0] y[3] y[2] module nor_op(a, b, y); input [3:0] a, b; output [3:0] y; assign y = ~(a | b); // assign y[0] = ~(a[0] | b[0]); // assign y[1] = ~(a[1] | b[1]); // assign y[2] = ~(a[2] | b[2]); // assign y[3] = ~(a[3] | b[3]); endmodule 코드 10.6
10.1.2 멀티비트 논리연산의 모델링 4비트 2입력 NOR 게이트 for 반복문 게이트 프리미티브 배열 module nor_for(a, b, y); input [3:0] a, b; output [3:0] y; reg [3:0] y; integer i; always @(a or b) begin for(i=0; i < 4; i=i+1) y[i] = ~(a[i] | b[i]); end endmodule 게이트 프리미티브 배열 module nor_gate(a, b, y); input [3:0] a, b; output [3:0] y; nor U0 [3:0](y, a, b); endmodule 코드 10.7 코드 10.8
10.1.2 멀티비트 논리연산의 모델링 4비트 2입력 XOR게이트를 아래의 방식으로 모델링하고, 테스트벤치를 작성하여 기능을 검증 비트단위 연산자를 사용하는 방법 게이트 프리미티브를 사용하는 방법 for 반복문을 사용하는 방법
10.1.3 부울함수의 모델링 부울함수의 모델링 비트 연산자 module comb_gate(a, b, c, d, e, y); input a, b, c, d, e; output y; assign y = ~((a | b) &(c | d) & e); endmodule 코드 10.10
10.1.4 진리표의 모델링 진리표의 모델링 case 문 표 10.2 Booth 인코딩 진리표 module booth_enc(xin, y, y2, neg); input [2:0] xin; output y, y2, neg; reg [2:0] tmp; assign y = tmp[2]; assign y2 = tmp[1]; assign neg = tmp[0]; always @(xin) begin case(xin) 0 : tmp = 3'b000; 1,2 : tmp = 3'b100; 3 : tmp = 3'b010; 4 : tmp = 3'b011; 5,6 : tmp = 3'b101; 7 : tmp = 3'b001; endcase end endmodule 표 10.2 Booth 인코딩 진리표 xin[2:0] y y2 neg 000 001 1 010 011 100 101 110 111 코드 10.11
10.1.4 진리표의 모델링 진리표의 모델링 테스트벤치 module tb_booth_enc; reg [2:0] xin; wire y, y2, neg; integer i; booth_enc U0(xin, y, y2, neg); initial begin xin = 0; for(i=1; i < 16; i=i+1) #20 xin = i; end endmodule 코드 10.12
10.1.4 진리표의 모델링 시뮬레이션 결과 그림 10.6 코드 10.11의 합성 결과
10.1.4 진리표의 모델링 아래의 진리표를 Verilog HDL로 모델링하고, 테스트벤치를 작성하여 기능을 검증 표 10.3 Booth 인코딩 진리표(2) xin[2:0] yz y2 neg add 000 1 001 010 011 100 101 110 111
10.1.5 Lookup Table의 모델링 Lookup Table 회로 동작에 필요한 많은 양의 고정된 데이터 값을 저장하기 위해 사용되는 조합논리회로 블록 함수를 이용하여 독립된 파일로 모델링되고, 소스코드에서 lookup 테이블 함수를 호출하여 저장된 데이터를 읽어내는 방법을 사용 저장될 데이터들을 case 문으로 표현 lookup 테이블의 주소가 case 문의 조건으로 사용 n-비트의 주소를 갖는 lookup 테이블은 최대 개의 데이터를 저장
10.1.5 Lookup Table의 모델링 Lookup Table의 모델링 (함수 이용) function [7:0] data_line1; input [3:0] addr_in; begin case(addr_in) 0 : data_line1 = 8'b0010_0000; 1 : data_line1 = 8'b0100_0100; 2 : data_line1 = 8'b0110_1001; 3 : data_line1 = 8'b0110_0111; . . . . . . 14 : data_line1 = 8'b0110_1110; 15 : data_line1 = 8'b0010_0000; default : data_line1 = 8'b0000_0000; endcase end endfunction 코드 10.13
10.2 멀티플렉서 4비트 4:1 멀티플렉서 4개의 4비트 입력 중에서 하나를 선택하여 출력 if 조건문, case 문, 조건연산자 등을 이용하여 모델링 module mux41_if(sel, a, b, c, d, y); input [1:0] sel; input [3:0] a, b, c, d; output [3:0] y; reg [3:0] y; always @(sel or a or b or c or d) begin if (sel == 2'b00) y = a; else if(sel == 2'b01) y = b; else if(sel == 2'b10) y = c; else if(sel == 2'b11) y = d; else y = 4'bx; end endmodule if 조건문 코드 10.14
10.2 멀티플렉서 모델링 4비트 4:1 멀티플렉서 case 문 module mux41_case(sel, a, b, c, d, y); input [1:0] sel; input [3:0] a, b, c, d; output [3:0] y; reg [3:0] y; always @(sel or a or b or c or d) begin case(sel) 0 : y = a; 1 : y = b; 2 : y = c; 3 : y = d; default : y = 4'bx; endcase end endmodule case 문 코드 10.15
10.2 멀티플렉서 모델링 4비트 4:1 멀티플렉서 조건 연산자 module mux41_conop(sel, a, b, c, d, y); input [1:0] sel; input [3:0] a, b, c, d; output [3:0] y; assign y =(sel == 0) ? a : (sel == 1) ? b : (sel == 2) ? c : (sel == 3) ? d : 4'bx; endmodule 조건 연산자 코드 10.16
10.2 멀티플렉서 모델링 4비트 4:1 멀티플렉서 테스트벤치 module tb_mux41; reg [3:0] a, b, c, d; reg [1:0] sel; wire [3:0] y; mux41_if U0(sel, a, b, c, d, y); // mux41_case U0(sel, a, b, c, d, y); // mux41_conop U0(sel, a, b, c, d, y); initial begin a = 4'b0001; b = 4'b0010; c = 4'b0100; d = 4'b1000; #80 a = 4'b1100; b = 4'b0011; c = 4'b0110; d = 4'b1001; end initial sel = 2'b00; always #20 sel = sel + 1; endmodule 테스트벤치 코드 10.17
10.2 멀티플렉서 모델링 4비트 4:1 멀티플렉서 시뮬레이션 결과
10.2 멀티플렉서 모델링 4비트 4:1 멀티플렉서 그림 10.8 코드 10.14 ~ 10.16의 합성 결과
10.2 멀티플렉서 모델링 8비트 8:1 멀티플렉서 case 문 module mux81_case(sel, in_word, out_bit); input [2:0] sel; input [7:0] in_word; output out_bit; reg out_bit; always @(sel or in_word) begin case(sel) endcase end endmodule 코드 10.18 case 문 코드를 완성한다.
10.3.1 2진 인코더 n:m 2진 인코더 n-비트의 입력을 m-비트의 출력으로 변환(단, n=2m) if 조건문, case 문, for 반복문 등 여러 가지 방법으로 모델링 반복문 ; 입력의 비트 수가 큰 경우 또는 입/력 비트 수를 파라미터화하여 모델링하는 경우에 유용 진리표에 나열된 입력조건 이외의 경우에는 출력에 don’t care 값을 할당하여 최소화된 회로가 합성되도록 함 표 10.4 4:2 2진 인코더의 진리표 입력 a[3:0] 출력 y[1:0] 0001 00 0010 01 0100 10 1000 11
10.3.1 2진 인코더 4:2 2진 인코더 case 문 if 조건문 module enc_4to2_case(a, y); input [3:0] a; output [1:0] y; reg [1:0] y; always @(a) begin casex(a) 4'b0001 : y = 0; 4'b0010 : y = 1; 4'b0100 : y = 2; 4'b1000 : y = 3; default : y = 2'bx; endcase end endmodule module enc_4to2_if(a, y); input [3:0] a; output [1:0] y; reg [1:0] y; always @(a) begin if (a == 4'b0001) y = 0; else if(a == 4'b0010) y = 1; else if(a == 4'b0100) y = 2; else if(a == 4'b1000) y = 3; else y = 2'bx; end endmodule if 조건문 코드 10.19 코드 10.20
10.3.1 2진 인코더 4:2 2진 인코더 for 반복문 module enc_4to2_for(a, y); input [3:0] a; output [1:0] y; reg [1:0] y; reg [3:0] temp; integer n; always @(a) begin temp = 4'b0001; y = 2'bx; for(n = 0; n < 4; n = n + 1) begin if(a == temp) y = n; temp = temp << 1; end endmodule for 반복문 코드 10.21
10.3.1 2진 인코더 4:2 2진 인코더 테스트벤치 module tb_enc_4to2; reg [3:0] a; wire [1:0] y; enc_4to2_case U0(a, y); // enc_4to2_if U0(a, y); // enc_4to2_for U0(a, y); always begin a = 4'b0001; #20 a = 4'b0010; #20 a = 4'b0100; #20 a = 4'b1000; #20; end endmodule 테스트벤치 코드 10.22
10.3.1 2진 인코더 코드 10.19의 합성결과 코드 10.20, 코드 10.21의 합성결과
10.3.1 2진 인코더 enable 신호를 갖는 4:2 이진 인코더를 다음의 방법으로 모델링하고, 시뮬레이션을 통해 검증 case 문을 사용하는 방법 if 조건문을 사용하는 방법 for 반복문을 사용하는 방법
10.3.2 우선순위 인코더 4:2 우선순위 인코더 표 10.5 4:2 우선순위 인코더의 진리표 입력 출력 a[3:0] y[1:0] valid 1xxx 11 1 01xx 10 001x 01 0001 00 0000 xx
10.3.2 우선순위 인코더 4:2 우선순위 인코더 if 조건문 사용 module pri_enc_4to2_if(a, valid, y); input [3:0] a; output valid; output [1:0] y; reg valid; reg [1:0] y; always @(a) begin valid = 1; if (a[3]) y = 3; else if(a[2]) y = 2; else if(a[1]) y = 1; else if(a[0]) y = 0; else begin valid = 0; y = 2'bx; end endmodule if 조건문 사용 코드 10.23
10.3.2 우선순위 인코더 4:2 우선순위 인코더 casex 문 사용 코드 10.24 module pri_enc_4to2_case(a, valid, y); input [3:0] a; output valid; output [1:0] y; reg valid; reg [1:0] y; always @(a) begin valid = 1; casex(a) 4'b1xxx : y = 3; 4'b01xx : y = 2; 4'b001x : y = 1; 4'b0001 : y = 0; default : begin valid = 0; y = 2'bx; end endcase endmodule casex 문 사용 코드 10.24
10.3.2 우선순위 인코더 4:2 우선순위 인코더 for 문 사용 module pri_enc_4to2_for(a, valid, y); input [3:0] a; output valid; output [1:0] y; reg valid; reg [1:0] y; integer n; always @(a) begin valid = 0; y = 2'bx; for(n = 0; n < 4; n = n+1) if(a[n]) begin valid = 1; y = n; end endmodule for 문 사용 코드 10.25
10.3.2 우선순위 인코더 4:2 우선순위 인코더 테스트벤치 module tb_pri_enc; reg [3:0] a; wire valid; wire [1:0] y; pri_enc_4to2_case U0(a, valid, y); // pri_enc_4to2_if U0(a, valid, y); // pri_enc_4to2_for U0(a, valid, y); always begin a = 4'b0001; #20 a = 4'b0010; #20 a = 4'b0100; #20 a = 4'b1000; #20; end endmodule 테스트벤치 코드 10.26
10.3.2 우선순위 인코더 4:2 우선순위 인코더 시뮬레이션 결과
10.3.2 우선순위 인코더 4:2 우선순위 인코더 그림 10.12 코드 10.23 ~ 10.25의 합성 결과
10.3.2 우선순위 인코더 enable 신호를 갖는 4:2 우선순위 인코더를 다음의 방법으로 모델링하고, 시뮬레이션을 통해 검증 case 문을 사용하는 방법 if 조건문을 사용하는 방법 for 반복문을 사용하는 방법
10.3.3 디코더 m:n 2진 디코더 m-비트의 입력을 n-비트의 출력으로 변환(단, n=2m) if 조건문, case 문, for 반복문 등 여러 가지 방법으로 모델링 반복문 ; 입력의 비트 수가 큰 경우 또는 입/력 비트 수를 파라미터화하여 모델링하는 경우에 유용 표 10.6 2:4 2진 디코더의 진리표 입력 a[1:0] 출력 y[3:0] 00 0001 01 0010 10 0100 11 1000
10.3.3 디코더 2:4 이진 디코더 if 조건문 사용 module dec_2to4_if(a, y); input [1:0] a; output [3:0] y; reg [3:0] y; always @(a) begin if(a == 0) y = 4'b0001; else if(a ==1) y = 4'b0010; else if(a ==2) y = 4'b0100; else y = 4'b1000; end endmodule if 조건문 사용 코드 10.27
10.3.3 디코더 2:4 이진 디코더 case 문 사용 module dec_2to4_case(a, y); input [1:0] a; output [3:0] y; reg [3:0] y; always @(a) begin case(a) 0 : y = 4'b0001; 1 : y = 4'b0010; 2 : y = 4'b0100; 3 : y = 4'b1000; default: y = 4'bx; endcase end endmodule case 문 사용 코드 10.28
10.3.3 디코더 2:4 이진 디코더 for 문 사용 module dec_2to4_for(a, y); input [1:0] a; output [3:0] y; reg [3:0] y; integer n; always @(a) begin for(n = 0; n <= 3; n = n + 1) if(a == n) y[n] = 1'b1; else y[n] = 1'b0; end endmodule for 문 사용 코드 10.29
10.3.3 디코더 2:4 이진 디코더 테스트벤치 module tb_dec_2to4; reg [1:0] a; wire [3:0] y; dec_2to4_case U0(a, y); // dec_2to4_if U0(a, y); // dec_2to4_for U0(a, y); always begin a = 4'b00; #20 a = 4'b01; #20 a = 4'b10; #20 a = 4'b11; #20; end endmodule 테스트벤치 코드 10.30
10.3.3 디코더 2:4 이진 디코더 시뮬레이션 결과
10.3.3 디코더 2:4 이진 디코더 그림 10.14 코드 10.27 ~ 10.29의 합성 결과
10.3.3 디코더 Active-high enable 신호를 갖는 3:6 디코더 (표 10.7)를 다음의 방법으로 모델링하고, 시뮬레이션을 통해 검증 if 조건문을 사용하는 방법 enable 신호와 입력 a를 결합 연산자 { }로 묶어 case 문의 조건으로 사용하는 방법 enable 입력 a[2:0] 출력 y[5:0] xxx 000000 1 000 000001 001 000010 010 000100 011 001000 100 010000 101 100000 110 111 표 10.7
10.3.3 디코더 파라미터화된 디코더 코드 10.31 module dec_param(en, a, y); parameter in_width = 3, out_width = 8; input en; input [in_width-1:0] a; output [out_width-1:0] y; reg [out_width-1:0] y; integer n; always @(en or a) begin if(!en) y = 0; else if(a > out_width-1) for(n = 0; n <= out_width-1; n = n+1) y[n] = 1'bx; if(a == n) y[n] = 1'b1; y[n] = 1'b0; end endmodule 코드 10.31
10.3.3 디코더 모듈 dec_param을 이용한 3:6 디코더 module dec_param_inst(en, addr, dec_addr); input en; input [2:0] addr; output [5:0] dec_addr; // 3:6 디코더 구현 dec_param #(3, 6) decoder_3to6(en, addr, dec_addr); endmodule 코드 10.32
10.4 비교기 비교기 4비트 비교기 두 입력의 상대적인 크기를 비교 관계연산자, if 조건문, for 반복문 등 여러 가지 방법으로 모델링 4비트 비교기 module comp_assign(a, b, agtb, altb, aeqb); input [3:0] a, b; output altb, agtb, aeqb; assign altb =(a < b); assign agtb =(a > b); assign aeqb =(a == b); endmodule 관계연산자 사용 코드 10.33
10.4 비교기 4비트 비교기 if 조건문 사용 module comp_if(a, b, agtb, altb, aeqb); input [3:0] a, b; output altb, agtb, aeqb; reg altb, agtb, aeqb; always @(a or b) begin altb = 1'b0; agtb = 1'b0; aeqb = 1'b0; if(a == b) aeqb = 1'b1; else if(a > b) agtb = 1'b1; else altb = 1'b1; end endmodule if 조건문 사용 코드 10.34
10.4 비교기 4비트 비교기 module comp_for(a, b, agtb, altb, aeqb); parameter size=4; input [size-1:0] a, b; output altb, agtb, aeqb; reg altb, agtb, aeqb; integer i; always @(a or b) begin altb = 1'b0; agtb = 1'b0; aeqb = 1'b1; for(i = size-1; i > = 0; i=i-1) begin : comp_loop if(a[i] != b[i]) begin agtb = a[i]; altb = ~a[i]; aeqb = 0; disable comp_loop; end endmodule for 문 사용 코드 10.35
10.4 비교기 4비트 비교기 테스트벤치 코드 10.36 module tb_comp; reg [3:0] a, b; wire agtb, altb, aeqb; // comp_assign Uo(a, b, agtb, altb, aeqb); // comp_if Uo(a, b, agtb, altb, aeqb); comp_for Uo(a, b, agtb, altb, aeqb); always begin a = 4'b0001; b = 4'b1001; #20 a = 4'b0010; b = 4'b0000; #20 a = 4'b1100; b = 4'b1101; #20 a = 4'b1001; b = 4'b1001; #20 a = 4'b0111; b = 4'b0100; #20 a = 4'b1111; b = 4'b1111; #20 a = 4'b1101; b = 4'b1001; #20 a = 4'b0000; b = 4'b0000; #20 a = 4'b1010; b = 4'b1010; #20 a = 4'b0001; b = 4'b1011; #20; end endmodule 테스트벤치 코드 10.36
10.4 비교기 4비트 비교기 시뮬레이션 결과
10.4 비교기 4비트 비교기 코드 10.33의 합성 결과
10.4 비교기 4비트 비교기 코드 10.34의 합성 결과
10.4 비교기 4비트 비교기 코드 10.35의 합성 결과
10.5 Tri-state 버스 3상태 버스 드라이버 회로의 여러 부분에서 생성된 신호들을 공통 버스를 통해 회로의 다른 부분으로 전송하기 위해 사용 제어신호는 데이터를 버스에 보내거나 또는 데이터 소스를 버스로부터 격리시켜 high impedance 상태로 만듬 조건 연산자 또는 게이트 프리미티브를 사용하여 모델링 Circuit Block-B enable_b bus_data Block-A enable_a data_b data_a
10.5 Tri-state 버스 3상태 버스 드라이버 조건연산자 사용 게이트 프리미티브 사용 module tristate_conop(in, oe, out); input in, oe; output out; assign out =(oe) ? in : 1'bz; endmodule 조건연산자 사용 코드 10.37 module tristate_gate(in, oe, out); input in, oe; output out; bufif1 b1(out, in, oe); // Active-high oe endmodule 게이트 프리미티브 사용 코드 10.38
10.5 Tri-state 버스 3상태 버스 드라이버 테스트벤치 코드 10.39 `define PERIOD 20 module tb_tristate; reg in, oe; // tristate_gate U0_tristate_1(in, oe, out); tristate_conop U0_tristate_2(in, oe, out); initial begin #0 oe = 1'b0; in = 1'b1; #(`PERIOD) in = 1'b0; #(`PERIOD) in = 1'b1; oe = 1'b1; #(`PERIOD*2) in = 1'b1; #(`PERIOD*3) in = 1'b0; #(`PERIOD) oe = 1'b0; #(`PERIOD) in = 1'b1; #(`PERIOD*15) $stop; end endmodule 테스트벤치 코드 10.39
10.5 Tri-state 버스 3상태 버스 드라이버 시뮬레이션 결과
10.5 Tri-state 버스 양방향 버스 드라이버 보내기와 받기를 동시에 처리 Circuit Block rcv send bus_data rcv received_data send_data
10.5 Tri-state 버스 양방향 버스 드라이버 module bidir_bus(send, send_data, rcv, received_data, bus_data); input send, rcv; input [7:0] send_data; inout [7:0] bus_data; output [7:0] received_data; assign received_data =(rcv) ? bus_data : 8'bz; assign bus_data =(send) ? send_data : bus_data; endmodule 코드 10.40
10.5 Tri-state 버스 양방향 버스 드라이버 테스트벤치 코드 10.41 ‘define PERIOD 20 module tb_bidir_bus; reg send, rcv; reg [7:0] send_data; wire [7:0] received_data, bus_data; bidir_bus U0(send, send_data, rcv, received_data, bus_data); initial begin #0 send = 1'b0; rcv = 1'b0; send_data = 8'h00; #(‘PERIOD) send_data = 8'h07; #(‘PERIOD) send_data = 8'h15; send = 1'b1; #(‘PERIOD) send_data = 8'hAB; #(‘PERIOD) send_data = 8'h34; #(‘PERIOD) send_data = 8'h11; send = 1'b0; rcv = 1'b1; #(‘PERIOD*2) send_data = 8'h21; #(‘PERIOD) send_data = 8'h77; #(‘PERIOD*2) send_data = 8'h66; send = 1'b1; rcv = 1'b1; #(‘PERIOD) send_data = 8'h12; #(‘PERIOD) send_data = 8'hCF; send = 1'b0; rcv = 1'b0; #(‘PERIOD) send_data = 8'h89; #(‘PERIOD) send_data = 8'h65; #(‘PERIOD*15) $stop; end endmodule 테스트벤치 코드 10.41
10.5 Tri-state 버스 양방향 버스 드라이버 시뮬레이션 결과
10.5 Tri-state 버스 그림 10.21의 버스 드라이버를 조건 연산자를 사용하여 모델링하고, 시뮬레이션을 통해 검증 (단, 데이터는 8비트로 설계) Circuit Block-B enable_a bus_data Block-A data_b data_a MUX enable_b 그림 10.21
10.6 원하지 않는 래치의 합성 원하지 않는 래치의 합성 순수한 조합논리회로의 합성 case 문에 모든 가능한 case 항목들이 포함되지 않는 경우 if 조건문에서 else 블록이 생략되는 경우 순수한 조합논리회로의 합성 모든 가능한 입력 조건들에 대해 출력값을 명시적으로 지정 default 값을 지정
10.6 원하지 않는 래치의 합성 래치로 합성되는 case 문의 예 module case_latch(sel, in1, in2, y_out); input [1:0] sel; input [3:0] in1, in2; output [3:0] y_out; reg [3:0] y_out; always @(sel or in1 or in2) begin case(sel) 2'b10 : y_out = in1; 2'b01 : y_out = in2; endcase end endmodule 코드 10.42
10.6 원하지 않는 래치의 합성 래치로 합성되는 case 문의 예 코드 10.42의 시뮬레이션 결과
10.6 원하지 않는 래치의 합성 래치로 합성되는 case 문의 예 코드 10.42의 합성 결과 래치
10.6 원하지 않는 래치의 합성 래치로 합성되는 if 문의 예 module if_latch(a, b, y_out); input a, b; output [3:0] y_out; reg [3:0] y_out; always @(a or b) begin if (({a, b}) == 2'b11) y_out = 5; else if(({a, b}) == 2'b10) y_out = 2; else if(({a, b}) == 2'b01) y_out = 3; // No else block end endmodule 코드 10.43
10.6 원하지 않는 래치의 합성 래치로 합성되는 if 문의 예 코드 10.43의 합성 결과 래치
10.6 원하지 않는 래치의 합성 case 문에 default 문이 포함된 경우 래치가 합성되지 않음 module case_no_latch1(sel, in1, in2, y_out); input [1:0] sel, in1, in2; output [1:0] y_out; reg [1:0] y_out; always @(sel or in1 or in2) begin case(sel) 2'b10 : y_out = in1; 2'b01 : y_out = in2; default : y_out = 2'bx; endcase end endmodule 코드 10.44
10.6 원하지 않는 래치의 합성 case 문에 default 문이 포함된 경우 코드 10.44의 합성 결과
10.6 원하지 않는 래치의 합성 case 문이 초기값을 갖는 경우 래치가 합성되지 않음 module case_no_latch2(memce0, memce1, cs, en, addr); output memce0, memce1, cs; input en; input [31:30] addr; reg memce0, memce1, cs; always @(addr or en) begin {memce0, memce1, cs} = 3'b0; // 초기값을 할당 casez({addr, en}) 3'b101: memce0 = 1'b1; 3'b111: memce1 = 1'b1; 3'b0?1: cs = 1'b1; endcase end endmodule 코드 10.45
10.6 원하지 않는 래치의 합성 case 문이 초기값을 갖는 경우 코드 10.45의 합성 결과