790 likes | 1.5k Views
조합논리회로 모델링. Sun, Hye-Seung. 조합논리회로 모델링. 조합논리회로의 형태와 설계에 사용되는 Verilog 구문. 조합논리회로 모델링. 조합논리회로 모델링 시 유의사항 always 구문 감지신호 목록 (sensitivity list) 에 회로 ( 즉 , always 블록으로 모델링되는 회로 ) 의 입력신호들이 빠짐없이 모두 포함되어야 함 그렇지 않은 경우 ; 합성 전과 합성 후의 시뮬레이션 결과가 다를 수 있음 if 조건문과 case 문
E N D
조합논리회로 모델링 Sun, Hye-Seung
조합논리회로 모델링 조합논리회로의 형태와 설계에 사용되는 Verilog 구문
조합논리회로 모델링 • 조합논리회로 모델링 시 유의사항 • always 구문 • 감지신호 목록 (sensitivity list)에 회로 (즉, always 블록으로 모델링되는 회로)의 입력신호들이 빠짐없이 모두 포함되어야 함 • 그렇지 않은 경우; 합성 전과 합성 후의 시뮬레이션 결과가 다를 수 있음 • if 조건문과 case 문 • 모든 입력 조건들에 대한 출력값이 명시적으로 지정되어야 함 • 그렇지 않은 경우;래치가 생성되어 순차논리회로가 될 수 있음 • 논리 최적화가 용이한 구조와 표현을 사용 • 최소의 게이트 수와 최소 지연경로를 갖는 회로가 합성되도록 해야 함 • 소스코드가 간결해지도록 모델링 • 소스코드의 가독성 (readability)을 좋게 하여 오류 발생 가능성을 줄여 주고, 디버깅을 용이하게 하여 설계 생산성을 높여 줌
a[0] a[1] y a[2] a[3] 10.1.1기본 논리게이트 모델링 • 4입력 NAND 게이트 비트 연산자, 축약연산자, 게이트 프리미티브 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 조건문을 사용하는 방법
a[3:0] b[3:0] y[3] y[2] y[1] y[0] 10.1.2멀티비트 논리연산의 모델링 • 4비트 2입력 NOR 게이트 비트 연산자 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 문 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 인코딩 진리표 코드 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)
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 멀티플렉서 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의 합성 결과
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 case 문 코드를 완성한다. 코드 10.18 10.2멀티플렉서 모델링 • 8비트 8:1 멀티플렉서
10.3.1 2진 인코더 • n:m 2진 인코더 • n-비트의 입력을 m-비트의 출력으로 변환(단, n=2m) • if 조건문, case 문, for 반복문 등 여러 가지 방법으로 모델링 • 반복문 ; 입력의 비트 수가 큰 경우 또는 입/력 비트 수를 파라미터화하여 모델링하는 경우에 유용 • 진리표에 나열된 입력조건 이외의 경우에는 출력에 don’t care 값을 할당하여 최소화된 회로가 합성되도록 함 표 10.4 4:2 2진 인코더의 진리표
10.3.1 2진 인코더 • 4:2 2진 인코더 case 문 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진 인코더 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 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 우선순위 인코더의 진리표
10.3.2우선순위 인코더 • 4:2 우선순위 인코더 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 end endmodule if 조건문 사용 코드 10.23
10.3.2우선순위 인코더 • 4:2 우선순위 인코더 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 end endmodule casex 문 사용 코드 10.24
10.3.2우선순위 인코더 • 4:2 우선순위 인코더 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 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) • n:m 2진 인코더로 인코딩된 데이터를 복원시킴 • if 조건문, case 문, for 반복문 등 여러 가지 방법으로 모델링 • 반복문 ; 입력의 비트 수가 큰 경우 또는 입/력 비트 수를 파라미터화하여 모델링하는 경우에 유용 표 10.6 2:4 2진 디코더의 진리표
10.3.3디코더 • 2:4 이진 디코더 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 이진 디코더 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 이진 디코더 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 문의 조건으로 사용하는 방법 표 10.7
10.3.3디코더 • 파라미터화된 디코더 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; else for(n = 0; n <= out_width-1; n = n+1) if(a == n) y[n] = 1'b1; else 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비교기 • 비교기 • 두 입력의 상대적인 크기를 비교 • 관계연산자, 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 관계연산자 사용