한국기술교육대학교 장영조
한국기술교육대학교전기전자통신공학부 2
1. 조합회로설계 2. 순차회로설계 3. FSM 회로설계 4. ASM 을사용한설계 한국기술교육대학교전기전자통신공학부 3
조합논리회로의형태와설계에사용되는 Verilog 구문 조합논리회로의형태 조합논리회로설계에사용되는 Verilog 구문 논리합성이지원되지않는 Verilog 구문 논리게이트 Multiplexer Encoder Decoder Random Logic Adder Subtractor ALU Lookup Table Comparator 게이트프리미티브 연속할당문 (assign 문 ) 행위수준모델링 (if 문, case 문, for 문 ) 함수및 task ( 시간또는 event 제어를갖지못한다 ) 모듈인스턴스 initial 문 스위치프리미티브 (cmos, nmos, tran 등 ) forever (while, repeat 는경우에따라 ) 의반복문 wait, event, 지연등타이밍제어구문 force-release, fork-join 시스템 task ($finish, $time 등 ) 한국기술교육대학교전기전자통신공학부 4
조합회로모델링시유의사항 always 구문 감지신호목록 (sensitivity list) 에회로 ( 즉, always 블록으로모델링되는회로 ) 의입력신호들이빠짐없이모두포함되어야함 그렇지않은경우 ; 합성전과합성후의시뮬레이션결과가다를수있음 if 조건문과 case 문 모든입력조건들에대한출력값이명시적으로지정되어야함 그렇지않은경우 ; 래치가생성되어순차논리회로가될수있음 unwanted latch 논리최적화가용이한구조와표현을사용 최소의게이트수와최소지연경로를갖는회로가합성되도록해야함 소스코드가간결해지도록모델링 소스코드의가독성 (readability) 을좋게하여오류발생가능성을줄여주고, 디버깅을용이하게하여설계생산성을높여줌 한국기술교육대학교전기전자통신공학부 5
3 상버퍼의다양한모델링비교 tri_s.v, 프리미티브게이트를 code 3.1.2-1 사용한 3상회로 module tri_s(a, b, c, d, e, f, g, h, w, x, y, z); input a, b, c, d, e, f, g, h; output w, x, y, z; bufif1 U0 (w, a, b); notif1 U1 (x, c, d); bufif0 U2 (y, e, f); notif0 U3 (z, g, h); code 3.1.2-2 tri_d.v, 조건연산자를사용한 3상회로 module tri_d(a, b, c, d, e, f, g, h, w, x, y, z); input a, b, c, d, e, f, g, h; output w, x, y, z; assign w = b? a : 1'bz; assign x = d?!c : 1'bz; assign y =!f? e : 1'bz; assign z =!h?!g : 1'bz; B A F E code 3.1.2-3 W bufif1 Y bufif0 tri_b.v, if~else 를사용한 3 상회로 module tri_b (a, b, c, d, e, f, g, h, w, x, y, z); input a, b, c, d, e, f, g, h; output w, x, y, z; reg w, x, y, z; always @ * begin if (b) w = a; else w = 1'bz; if (d) x = ~c; else x = 1'bz; if (!f) y = e; else y = 1'bz; if (!h) z = ~g; else z = 1'bz; end H D G C notif1 notif0 Z X 한국기술교육대학교전기전자통신공학부 6
가산기모델링의합성비교 RCA4.v, 4 비트가산기의구 code 3.1.4-3 조적설계 module RCA4 (A, B, Cin, S, Cout); input [3:0] A, B; input Cin; output [3:0] S; output Cout; wire [3:0] A, B, S; wire [3:1] Carry; FA U0 (A[0], B[0], Cin, S[0], Carry[1]); FA U1 (A[1], B[1], Carry[1], S[1], Carry[2]); FA U2 (A[2], B[2], Carry[2], S[2], Carry[3]); FA U3 (A[3], B[3], Carry[3], S[3], Cout); ADD4.v, 4 비트가산기의 code 3.1.4-4 데이터플로우설계 module ADD4 (A, B, Cin, S, Cout); input [3:0] A, B; input Cin; output [3:0] S; output Cout; wire [3:0] A, B; wire [3:0] S; assign { Cout, S} = A + B + Cin; ADD4 의합성회로 RCA4 의합성회로 한국기술교육대학교전기전자통신공학부 7
가감산기 code 3.1.4-5 ADSB4.v, 4 비트가감산기 module ADSB4 (x, y, s, sum, cout); input [3:0] x, y; input s; output [3:0] sum; output cout; wire [3:0] x, y, ty; wire [3:0] sum; assign ty = {4{s}} ^ y; RCA4 U0(.A(x),.B(ty),.Cin(s),.S(sum),.Cout(cout)); ADSB4 의합성회로 ADD_p.v, 파라미터를사용한 code 3.1.4-6 가산기 module ADD_p (A, B, Cin, S, Cout); parameter BW = 4; input [BW-1:0] A, B; input Cin; output [BW-1:0] S; output Cout; wire [BW-1:0] A, B; wire [BW-1:0] S; wire [BW:0] tc; genvar i; assign tc[0] = Cin; assign Cout = tc[bw]; generate for (i=0; i<bw; i=i+1) begin : add assign S[i] = A[i] ^ B[i] ^ tc[i]; assign tc[i+1]=(a[i]&b[i]) (A[i]&tc[i]) (B[i]&tc[i]); end endgenerate 한국기술교육대학교전기전자통신공학부 8
code 3.1.5-2 module enc4t2_ca ( input wire [3:0] a, output reg [1:0] y); always @ * case(a) 4'b1000 : y = 2'd3; 4'b0100 : y = 2'd2; 4'b0010 : y = 2'd1; 4'b0001 : y = 2'd0; default : y = 2'd0; endcase enc4t2_ca.v, 4-to-2 인코더, case 문사용 code 3.1.5-3 pri_enc8t3.v, 8-to-3 우선순위인코더 module pri_enc8t3 ( input wire [7:0] a, output reg [2:0] y, output reg v); always @ * casex (a) 8'b0??????? : {y, v} = 4'b111_1; 8'b10?????? : {y, v} = 4'b110_1; 8'b110????? : {y, v} = 4'b101_1; 8'b1110???? : {y, v} = 4'b100_1; 8'b11110??? : {y, v} = 4'b011_1; 8'b111110?? : {y, v} = 4'b010_1; 8'b1111110? : {y, v} = 4'b001_1; 8'b11111110 : {y, v} = 4'b000_1; default : {y, v} = 4'b000_0; endcase pri_enc8t3 시뮬레이션 한국기술교육대학교전기전자통신공학부 9
code 3.1.6-2 dec3to8.v, 3-to-8 디코더 module dec3to8 (input wire en, input wire [2:0] a, output reg [7:0] y ); always @ * casex ({en, a}) 4'b0??? : y = 8'b0000_0000; 4'b1000 : y = 8'b0000_0001; 4'b1001 : y = 8'b0000_0010; 4'b1010 : y = 8'b0000_0100; 4'b1011 : y = 8'b0000_1000; 4'b1100 : y = 8'b0001_0000; 4'b1101 : y = 8'b0010_0000; 4'b1110 : y = 8'b0100_0000; 4'b1111 : y = 8'b1000_0000; default : y = 8'b0000_0000; endcase code 3.1.6-4 decntom.v, 파라미터를사용한디코더 module decntom (en, a, d); parameter N=4, M=10; input en; input [N-1:0] a; output [M-1:0] d; reg [M-1:0] d; integer i; always @ (en or a) begin if (!en) d = {M{1'b1}}; else if ( a > M-1) for (i=0; i <=M-1; i=i+1) d[i] = 1'b1; else for (i=0; i <=M-1; i=i+1) if ( a == i) d[i] = 1'b0; end else d[i] = 1'b1; module dec4t12 (en, a, y); input en; input [3:0] a; output [11:0] y; decntom #(4,12) U1 (en, a, y); 한국기술교육대학교전기전자통신공학부 10
code 3.1.9-1 cmp1.v, 1 비트비교기 module cmp1 (input wire a, b, output wire eq, agb, alb ); assign eq = (a == b); assign agb = (a > b); assign alb = (a < b); code 3.1.9-2 cmp4.v, 4 비트비교기 module cmp4 (input wire[3:0] a, b, output wire eq, agb, alb ); assign agb = (a > b)? 1'b1 : 1'b0; assign alb = (a < b)? 1'b1 : 1'b0; assign eq = (a == b)? 1'b1 : 1'b0; cmp4 의합성회로 cmp1 의합성회로 cmp4 의 eq 하층회로 한국기술교육대학교전기전자통신공학부 11
7485 비교기진리표 code 3.1.9-3 t7485.v, 74LS85 비교기 module t7485 (input wire[3:0] a, b, input wire ieq, iagb, ialb, output reg oeq, oagb, oalb ); always @ * begin if (a > b) begin oagb = 1'b1; oalb=1'b0; oeq = 1'b0; end else if(a < b) begin oagb = 1'b0; oalb=1'b1; oeq = 1'b0; end else casex ({iagb, ialb, ieq}) // (a==b) 3'b100 : begin oagb = 1'b1; oalb=1'b0; oeq = 1'b0; end 3'b010 : begin oagb = 1'b0; oalb=1'b1; oeq = 1'b0; end 3'bxx1 : begin oagb = 1'b0; oalb=1'b0; oeq = 1'b1; end 3'b110 : begin oagb = 1'b0; oalb=1'b0; oeq = 1'b0; end default : begin oagb = 1'b1; oalb=1'b1; oeq = 1'b0; end endcase end 한국기술교육대학교전기전자통신공학부 12
순차회로 현재의입력, 회로에저장된과거의상태값에의해출력결정 상태값을저장하는기억소자 ( 래치또는플립플롭 ) 와조합논리회로로구성 데이터레지스터, 시프트레지스터, 카운터 (counter), 직렬 / 병렬변환기, 유한상태머신 (Finite State Machine; FSM), 주파수분주기, 펄스발생기등 클록신호에의해동작되는래치또는플립플롭을포함 래치와플립플롭 래치 : 클록신호의레벨 ( 즉, 0 또는 1) 에따라동작하는저장소자 플립플롭 : 클록신호의상승또는하강에지에동기되어동작하는저장소자 always 구문내부에 if 조건문을이용하여모델링 순차회로의모델링 always 블록을이용한행위수준모델링, 게이트프리미티브및하위모듈인스턴스, 연속할당문등다양한 Verilog 구문들이사용됨 할당문의형태 (nonblocking 또는 blocking) 에따라회로의동작과구조가달라짐 한국기술교육대학교전기전자통신공학부 13
R S Q Qb S R Q(t+1) 상태 0 0 0 1 1 0 1 1 Q(t) 0 1 - hold reset set forbidden rs_d.v, RS 래치, 데이터 code 3.2.1-1 플로우모델링 module rs_d ( r, s, q, qb); input r, s; output q, qb; wire tq, tqb; assign qb = tqb; assign q = tq; assign tq =!( r tqb ); assign tqb =!( s tq ); rs_d 의합성회로 한국기술교육대학교전기전자통신공학부 14
code 3.2.1-2 rs_b.v, RS 래치, 동작적모델링 module rs_b ( r, s, q, qb); input r, s; output q, qb; reg tq; assign qb = ~tq; assign q = tq; always @ (r or s or tq ) begin case ({r, s}) 2'b00 : tq <= tq; // hold 2'b01 : tq <= 1'b1; // set 2'b10 : tq <= 1'b0; // reset 2'b11 : tq <= 1'b0; // invalid default : tq <= tq; // default, hold endcase end rs_b 의합성회로 한국기술교육대학교전기전자통신공학부 15
D CP D1 D2 d_cpb 의합성회로 Q Qb D CP D Q Qb d_cpb.v, 클록입력을가진 code 3.2.1-5 D 래치 module d_cpb (cp, d, q, qb); input cp, d; output q, qb; reg tq; assign qb = ~tq; assign q = tq; always @ (cp or d ) begin if (cp) tq <= d; else tq <= tq; end 한국기술교육대학교전기전자통신공학부 16
D clk rst D Q Qb d clk pr D q d_ff_async.v, 비동기입력을 code 3.2.2-2 가진 D 플립플롭 module d_ff_async(clk, rst, d, q, qb); input clk, rst, d; output q, qb; reg q; assign qb = ~q; always @ (negedge rst or posedge clk) if (~rst) q <= 1'b0; else q <= d; code 3.2.2-3 d_ff_sync_pr.v, 동기프리셋을가진 D 플립플롭 module d_ff_sync_pr (clk, pr, d, q); input clk, pr, d; output q; reg q; always @ ( posedge clk) if (pr) q <= 1'b1; // 동기형프리셋 else q <= d; 한국기술교육대학교전기전자통신공학부 17
d en clk D q rst clk en q+ 동작 0 x x 1 1 1 0 1 0 x 0 d q q reset load hold hold rst code 3.2.2-4 d_ff_as.v, 다양한신호를가진 D 플립플롭 module d_ff_as(clk, rst, en, d, q); input clk, rst, en, d; output q; reg q; always @ (negedge rst or posedge clk) if (!rst) q <= 1'b0; else if (en) q <= d; 한국기술교육대학교전기전자통신공학부 18
J clk K rst JK q qb rst clk J K q(t+1) 동작 1 x x x 0 0 0 0 0 1 0 1 0 0 1 1 0 0 x x 0 q 0 1 qb q reset hold reset set toggle hold code 3.2.2-5 jk_ff.v, JK 플립플롭 module jk_ff (clk, rst, j, k, q, qb); input clk, rst, j, k; output q, qb; reg q; assign qb = ~q; always @ (posedge rst or posedge clk) if (rst) q <= 1'b0; else case( {j,k} ) 2'b01 : q <= 1'b0; // reset 2'b10 : q <= 1'b1; // set 2'b11 : q <= ~q; // toggle endcase default : q <= q; // hold 한국기술교육대학교전기전자통신공학부 19
클록신호가인가될때마다데이터가왼쪽또는오른쪽으로이동 여러개의플립플롭이직렬로연결된구조 형태 직렬입력-직렬출력 ( SISO, Serial-In, Serial-Out) 직렬입력-병렬출력 ( SIPO, Serial-In, Parallel-Out) 병렬입력-직렬출력 ( PISO, Parallel-In, Serial-Out) 병렬입력-병렬출력 ( PIPO, Parallel-In, Parallel-Out) 왼쪽시프트, 오른쪽시프트, 양방향시프트 nonblocking 할당문, 시프트연산자, 결합연산자, 반복문등다양한구문으로모델링 한국기술교육대학교전기전자통신공학부 20
code 3.2.3-1 reg8.v, 8 비트 PIPO 레지스터 module reg8 (clk, rst, ld, d, q); input clk, rst, ld; input [7:0] d; output [7:0] q; reg [7:0] q; always @ (posedge rst or posedge clk) if (rst) q <= 8'b0; // 비동기리셋 else if (ld) q <= d; // 병렬로드 code 3.2.3-3 sipo6.v, 6 비트 SIPO 레지스터 module sipo6 (clk, rst, d, q); input clk, rst; input d; // 직렬입력 output [5:0] q; // 병렬출력 reg [5:0] q; always @ (posedge rst or posedge clk) if (rst) q <= 0; else q <= {d, q[5:1]}; // shift right sipo6 시뮬레이션 한국기술교육대학교전기전자통신공학부 21
code 3.2.3-3 siso4.v, 4 비트 SISO 레지스터 code 3.2.3-4 piso4.v, 4 비트 PISO 레지스터 module siso4 (clk, rst, sh, d, q); input clk, rst, sh; input d; output q; reg [3:0] tq; assign q = tq[0]; // serial out always @ (posedge rst or posedge clk) if (rst) tq <= 0; // reset else if (sh==1) tq <= {d, tq[3:1]}; // shift right else tq <= tq; // hold module piso4 (clk, rst, sh_ldb, d, sout); input clk, rst, sh_ldb; input[3:0] d; output sout; reg [3:0] tq; assign sout = tq[0]; // serial out always @ (posedge rst or posedge clk) if (rst) tq <= 4'b0; // reset else if (sh_ldb) tq <= {1'b0, tq[3:1]}; // shift right else tq <= d; // load piso4 시뮬레이션 한국기술교육대학교전기전자통신공학부 22
code 3.2.3-5 module univ_sr # ( parameter N=8) ( input wire clk, rst, input wire [1:0] s, input wire [N-1:0] d, output wire [N-1:0] q ) ; reg [N-1:0] r_reg, r_next ; univ_sr.v, universal 레지스터 assign q = r_reg; always @ (posedge rst or posedge clk ) if ( rst) r_reg <= 0 ; else r_reg <= r_next ; univ_sr 시뮬레이션 always @ * case(s) 2'b00 : r_next = r_reg ; // hold 2'b01 : r_next = {d[n-1], r_reg[n-1:1]}; // shift right 2'b10 : r_next = {r_reg[n-2:0], d[0] } ; // shift left default : r_next = d ; endcase // load 한국기술교육대학교전기전자통신공학부 23
code 3.2.4-1 mod16.v, 4 비트 2 진카운터 module mod16 (rst, clk, q, tco); input rst, clk; output [3:0] q; output tco; reg [3:0] q; always @ (posedge rst or posedge clk) if (rst) q <= 4'b0000; else q <= q + 1'b1; assign tco = (q == 4'b1111)? 1'b0 : 1'b1; 비동기형 tco bcd 시뮬레이션 code 3.2.4-3 bcd.v, BCD 카운터 module bcd(rst, en, clk, q, tco); input rst, en, clk; output [3:0] q; output tco; reg [3:0] q; reg tco; always @ (posedge rst or posedge clk) if (rst) begin q <= 4'b0000; tco <= 1'b1; end else if (en) // 동기형 tco if (q == 4'd8) begin q <= q+1'b1; tco <= 1'b0; end else if (q == 4'd9) begin q <= 4'b0000; tco <= 1'b1; end else begin q <= q+1'b1; tco <= 1'b1; end 동기형 tco 한국기술교육대학교전기전자통신공학부 24
code 3.2.4-4 mod100.v, mod100 카운터 module mod100 (rst, en, clk, q, tco); input rst, en, clk; output [7:0] q; output tco; wire tco, tc1, tc2; bcd LB (rst, en, clk, q[3:0], tc1); bcd UB (rst, en, tc1, q[7:4], tc2); // upper digit, 비동기형확장 // bcd UB (rst,!tc1, clk, q[7:4], tc2); // upper digit, 동기형확장 assign tco = tc1 tc2; code 3.2.4-5 module modn_cnt (rst, clk, q, rco); parameter N=4, M=12; input clk, rst; output [N-1:0] q; output rco; reg rco; reg [N-1:0] r_reg; wire rco_n; wire [N-1:0] r_next ; modn_cnt.v, 파라미터를사용한카운터 assign q = r_reg; assign r_next = (r_reg==(m-1))? {N{1'b0}} : r_reg + 1'b1; assign rco_n = (r_reg==(m-2))? 1'b0 :1'b1; // 동기형 rco always @ ( posedge rst or posedge clk) if (rst) begin r_reg <= { N{1'b0}}; rco <= 1'b1; end else begin r_reg <= r_next; rco <= rco_n; end 카운터의설계에서고속카운터의동작을위해서는동기형확장이필요하다. 한국기술교육대학교전기전자통신공학부 25
rst load en up q* 동작 1 0 0 0 0-1 0 0 0 - - 1 1 0 - - 1 0 - all 0s d q+1 q-1 q 비동기리셋병렬 load 상승카운터하강카운터유지 code 3.2.4-6 univ_cnt.v, 만능 2진카운터 module univ_cnt # (parameter N=4) ( input wire clk, rst, input wire load, en, up, input wire [N-1:0] d, output reg tu, td, output wire [N-1:0] q ) ; reg [N-1:0] r_reg, r_next; assign q = r_reg; always @( posedge clk or posedge rst) // 순차회로 if (rst) r_reg <= { N{1'b0}}; else r_reg <= r_next; always @ * begin // 조합회로 tu = 1'b1; td = 1'b1; if (load) r_next = d ; // 병렬입력 load else if (en & up) begin // 상승카운터동작 r_next = r_reg + 1'b1; if (r_reg==2**n-1) tu = 1'b0; // 카운터최대값 end else if (en & ~up) begin // 하강카운터동작 r_next = r_reg - 1'b1; if (r_reg==0) td = 1'b0; // 카운터최소값 end else r_next = r_reg; // 유지 end 한국기술교육대학교전기전자통신공학부 26
code 3.2.4-7 ring.v, 링카운터 module ring (rst, clk, q); parameter N = 5, N1=N-1; input rst, clk; output [N1:0] q; reg [N1:0] q; always @ (posedge rst or posedge clk) if (rst) q <= { 1'b1, {N1{1'b0}} }; // preset 10..000 else q <= { q[0], q[n1:1]}; // rotate right code 3.2.4-8 johnson.v, 존슨카운터 module johnson (rst, clk, q); parameter N = 5; input rst, clk; output [N-1:0] q; reg [N-1:0] q; always @ (posedge rst or posedge clk) if (rst) q <= {N{1'b0}} ; // preset 00..000 else q <= { ~q[0], q[n-1:1]}; // reverse rotate right 한국기술교육대학교전기전자통신공학부 27