860 likes | 1.87k Views
순차회로 모델링. Sun, Hye-Seung. 순차회로 모델링. 순차회로 현재의 입력 , 과거의 입력 , 회로에 기억된 상태값에 의해 출력이 결정 과거의 입력 , 현재의 상태값을 저장하는 기억소자 ( 래치 또는 플립플롭 ) 와 조합논리회로로 구성 데이터 레지스터 , 시프트 레지스터 , 계수기 (counter), 직렬 / 병렬 변환기 , 유한상태머신 (Finite State Machine; FSM), 주파수 분주기 , 펄스 발생기 등 클록신호에 의해 동작되는 래치 또는 플립플롭을 포함
E N D
순차회로 모델링 Sun, Hye-Seung
순차회로 모델링 • 순차회로 • 현재의 입력, 과거의 입력, 회로에 기억된 상태값에 의해 출력이 결정 • 과거의 입력, 현재의 상태값을 저장하는 기억소자(래치 또는 플립플롭)와 조합논리회로로 구성 • 데이터 레지스터, 시프트 레지스터, 계수기(counter), 직렬/병렬 변환기, 유한상태머신(Finite State Machine; FSM), 주파수 분주기, 펄스 발생기 등 • 클록신호에 의해 동작되는 래치 또는 플립플롭을 포함 • 래치와 플립플롭 • 래치 : 클록신호의 레벨(즉, 0 또는 1)에 따라 동작하는 저장소자 • 플립플롭 : 클록신호의 상승 또는 하강에지에 동기되어 동작하는 저장소자 • always 구문 내부에 if 조건문을 이용하여 모델링 • 순차회로의 모델링 • always 블록을 이용한 행위수준 모델링, 게이트 프리미티브 및 하위모듈 인스턴스, 연속 할당문 등 다양한 Verilog 구문들이 사용됨 • 할당문의 형태 (nonblocking 또는 blocking) 에 따라 회로의 동작과 구조가 달라짐
d D q Q clock clock G d q 11.1.1래치(Latch) • Positive level-sensitive D latch module dlatch(clock, d, q); input clock, d; output q; reg q; always @(clock or d) begin if(clock) q = d; end endmodule Positive level-sensitive D latch 코드 11.1
11.1.1래치(Latch) module tb_dlatch ; reg clk, d; dlatch U0(clk, d, q); initial begin clk = 1'b0; forever #10 clk = ~clk; end initial begin d = 1'b0; forever begin #15 d = 1'b1; #20 d = 1'b0; #10 d = 1'b1; #10 d = 1'b0; #10 d = 1'b1; #15 d = 1'b0; end end endmodule Testbench for D latch 코드 11.2
11.1.1래치(Latch) • Negative level-sensitive 방식으로 동작하는 8비트 D 래치 회로를 설계하고, 테스트벤치를 작성하여 기능을 검증한다. 코드 11.1의 시뮬레이션 결과
11.1.1래치(Latch) • Active-low 리셋을 갖는 positive level-sensitive D latch module dlatch_rst(rst, clock, d, q); input rst, clock, d; output q; reg q; always @(clock or rst or d) begin if(!rst) q = 1'b0; else if(clock) q = d; end endmodule 코드 11.3
11.1.1래치(Latch) • Active-low 셋과 리셋을 갖는 negative level-sensitive 8비트 D 래치 회로를 설계하고, 테스트벤치를 작성하여 기능을 검증한다. 코드 11.3의 시뮬레이션 결과
합성 결과 Latch 11.1.1래치(Latch) • Latch가 포함된 회로에 blocking 할당문이 사용된 경우 module latch_blk(en, a, b, c, y); input en, a, b, c; output y; reg m, y; always @(en or a or b or c) begin if(en) begin m = ~(a | b); y = ~(m & c); end end endmodule 코드 11.4
합성 결과 Latch Latch 11.1.1래치(Latch) • Latch가 포함된 회로에 nonblocking 할당문이 사용된 경우 module latch_nonblk(en, a, b, c, y); input en, a, b, c; output y; reg m, y; always @(en or a or b or c) begin if(en) begin m <= ~(a | b); y <= ~(m & c); end end endmodule 코드 11.5
11.1.1래치(Latch) • 코드 11.6은 코드 11.4에서 blocking 할당문의 순서를 바꾼 경우이다. 코드 11.4와 동일한 회로인지, 만약 다른 회로라면 어떤 회로가 되는지 시뮬레이션과 합성을 통해 확인하고, 그 이유를 생각해 본다. module latch_blk2(en, a, b, c, y); input en, a, b, c; output y; reg m, y; always @(en or a or b or c) begin if(en) begin y = ~(m & c); m = ~(a | b); end end endmodule 코드 11.6
11.1.1래치(Latch) • 코드 11.7은 코드 11.5에서 nonblocking 할당문의 순서를 바꾼 경우이다. 코드 11.5와 동일한 회로인지, 만약 다른 회로라면 어떤 회로가 되는지 시뮬레이션과 합성을 통해 확인하고, 그 이유를 생각해 본다. module latch_nonblk2(en, a, b, c, y); input en, a, b, c; output y; reg m, y; always @(en or a or b or c) begin if(en) begin y <= ~(m & c); m <= ~(a | b); end end endmodule 코드 11.7
clk d D d q Q q clock 11.1.2플립플롭(Flip flop) • Positive edge-triggered D Flip-flop module dff(clk, d, q); input d ,clk; output q; reg q; always @(posedge clk) q <= d; endmodule Positive edge-triggered D Flip-flop 코드 11.8
11.1.2플립플롭(Flip flop) 코드 11.8의 시뮬레이션 결과
11.1.2플립플롭(Flip flop) • Edge-triggered D Flip-flop with q and qb outputs module dff_bad1(clk, d, q, q_bar); input d, clk; output q, q_bar; reg q, q_bar; always @(posedge clk) begin // nonblocking assignments q <= d; q_bar <= ~d; end endmodule 코드 11.9(a) Not Recommended module dff_bad2(clk, d, q, q_bar); input d, clk; output q, q_bar; reg q, q_bar; always @(posedge clk) begin // blocking assignments q = d; q_bar = ~d; end endmodule 코드 11.9(b)
11.1.2플립플롭(Flip flop) • Edge-triggered D Flip-flop with q and qb outputs Recommended module dff_good(clk, d, q, q_bar); input d, clk; output q, q_bar; reg q; // using assign statement for q_bar assign q_bar = ~q; always @(posedge clk) q <= d; endmodule 코드 11.9(c)
Flip flop Flip flop Flip flop 11.1.2플립플롭(Flip flop) • Edge-triggered D Flip-flop with q and qb outputs 코드 11.9 (a), (b)의 합성 결과 코드 11.9 (c)의 합성 결과
11.1.2플립플롭(Flip flop) • q와 q_bar 출력을 갖는 D 플립플롭을 코드 11.10과 같이 모델링하면, 단순 D 플립플롭이 아닌 다른 회로가 된다. 시뮬레이션과 합성을 통해 코드 11.10의 모델링이 어떤 회로로 동작하는 지 확인하고, 그 이유를 생각해 본다. module dff_bad3(clk, d, q, q_bar); input d, clk; output q, q_bar; reg q, q_bar; always @(posedge clk) begin q <= d; q_bar <= ~q; end endmodule 코드 11.10
11.1.2플립플롭(Flip flop) • Edge-triggered D Flip-flop with synchronous active-low reset module dff_sync_rst(clk, d, rst_n, q, qb); input clk, d, rst_n; output q, qb; reg q; assign qb = ~q; always @(posedge clk) // include only clk begin if(!rst_n) // active-low reset q <= 1'b0; else q <= d; end endmodule 코드 11.11
11.1.2플립플롭(Flip flop) • Edge-triggered D Flip-flop with synchronous active-low reset 코드 11.11의 시뮬레이션 결과
11.1.2플립플롭(Flip flop) • Edge-triggered D Flip-flop with asynchronous active-low reset module dff_async_rst(clk, d, rst_n, q, qb); input clk, d, rst_n; output q, qb; reg q; assign qb = ~q; always @(posedge clk or negedge rst_n) // both clk and rst_n begin if(!rst_n) // active-low reset q <= 1'b0; else q <= d; end endmodule 코드 11.12
11.1.2플립플롭(Flip flop) • Edge-triggered D Flip-flop with asynchronous active-low reset 코드 11.12의 시뮬레이션 결과
11.1.2플립플롭(Flip flop) • 다음의 D 플립플롭을 Verilog HDL로 모델링하고, 시뮬레이션을 통해 동작을 확인한다. ① 동기식 active-high 리셋을 갖는 D 플립플롭 ② 동기식 active-high 셋을 갖는 D 플립플롭 ③ 동기식 active-low 셋과 리셋을 갖는 D 플립플롭 ④ 비동기식 active-high 리셋을 갖는 D 플립플롭 ⑤ 비동기식 active-high 셋을 갖는 D 플립플롭 ⑥ 비동기식 active-low 셋과 리셋을 갖는 D 플립플롭
합성 결과 Flip Flop 11.1.2플립플롭(Flip flop) • 플립플롭이 포함된 회로에 blocking 할당문이 사용된 경우 module seq_blk(clk, a, b, c, d, e, y); input clk, a, b, c, d, e; output y; reg m, n, y; always @(posedge clk) begin m = ~(a & b); n = c | d; y = ~(m | n | e); end endmodule 코드 11.13
합성 결과 Flip Flop Flip Flop Flip Flop 11.1.2플립플롭(Flip flop) • 플립플롭이 포함된 회로에 nonblocking 할당문이 사용된 경우 module seq_nonblk(clk, a, b, c, d, e, y); input clk, a, b, c, d, e; output y; reg m, n, y; always @(posedge clk) begin m <= ~(a & b); n <= c | d; y <= ~(m | n | e); end endmodule 코드 11.14
11.1.2플립플롭(Flip flop) • 코드 11.15는 코드 11.13에서 blocking 할당문의 순서를 바꾼 경우이다. 코드 11.13과 동일한 회로인지, 만약 다른 회로라면 어떤 회로가 되는지 시뮬레이션과 합성을 통해 확인하고, 그 이유를 생각해 본다. 코드 11.15 module seq_blk2(clk, a, b, c, d, e, y); input clk, a, b, c, d, e; output y; reg m, n, y; always @(posedge clk) begin y = ~(m | n | e); m = ~(a & b); n = c | d; end endmodule
Flip Flop Shift register Flip Flop Flip Flop Flip Flop Flip Flop 11.2 Blocking과 Nonblocking 할당문 • 순차회로에서 blocking할당문 순서의 영향 module blk1(clk, d, q3); input clk; output q3; input d; reg q3, q2, q1, q0; always @(posedge clk) begin q0 = d; q1 = q0; q2 = q1; q3 = q2; end endmodule module blk2(clk, d, q3); input clk; output q3; input d; reg q3, q2, q1, q0; always @(posedge clk) begin q3 = q2; q2 = q1; q1 = q0; q0 = d; end endmodule 코드 11.16(a) 코드 11.16(b)
Flip Flop Flip Flop Flip Flop Flip Flop 11.2 Blocking과 Nonblocking 할당문 • 순차회로에서 nonblocking할당문 순서의 영향 module non_blk1(clk, d, q3); input clk; output q3; input d; reg q3, q2, q1, q0; always @(posedge clk) begin q0 <= d; q1 <= q0; q2 <= q1; q3 <= q2; end endmodule module non_blk2(clk, d, q3); input clk; output q3; input d; reg q3, q2, q1, q0; always @(posedge clk) begin q3 <= q2; q2 <= q1; q1 <= q0; q0 <= d; end endmodule 코드 11.17(a) 코드 11.17(b)
11.2 Blocking과 Nonblocking 할당문 • 코딩 가이드라인 • 가이드라인-1:순차회로 또는 래치를 모델링하는 always 블록에서는 nonblocking할당문을 사용한다. • 가이드라인-2:조합논리회로를 모델링하는 always 블록에서는 blocking할당문을 사용한다.
11.2 Blocking과 Nonblocking 할당문 • 가이드라인-3:동일한 always 블록에서 순차회로와 조합논리회로를 함께 표현하는 경우에는 nonblocking 할당문을 사용한다.
11.2 Blocking과 Nonblocking 할당문 • 가이드라인-4:동일한 always 블록 내에서 blocking할당문과 nonblocking할당문을 혼합해서 사용하지 않는다. module ba_nba1(q, a, b, clk, rst_n); output q; input a, b, rst_n, clk; reg q, tmp; always @(posedge clk or negedge rst_n) if(!rst_n) q <= 1'b0; else begin tmp = a & b; q <= tmp; end endmodule 코드 11.18(a) Bad Coding module ba_nba2(q, a, b, clk, rst_n); output q; input a, b, rst_n, clk; reg q, tmp; always @(posedge clk or negedge rst_n) if(!rst_n) q = 1'b0; //blocking else begin tmp = a & b; q <= tmp; //nonblocking end endmodule 코드 11.18(b)
11.2 Blocking과 Nonblocking 할당문 module ba_nba3(q, a, b, clk, rst_n); output q; input a, b, rst_n, clk; reg q; always @(posedge clk or negedge rst_n) if(!rst_n) q <= 1'b0; else q <= a & b; endmodule Good Coding 코드 11.18(c) module ba_nba4(q, a, b, clk, rst_n); output q; input a, b, rst_n, clk; reg q; wire tmp; assign tmp = a & b; always @(posedge clk or negedge rst_n) if(!rst_n) q <= 1'b0; else q <= tmp; endmodule 코드 11.18(d)
11.2 Blocking과 Nonblocking 할당문 • 가이드라인-5:다수의 always 블록에서 동일한 reg 변수에 값을 할당하지 않는다. module badcode1(q, d1, d2, clk, rst_n); output q; input d1, d2, clk, rst_n; reg q; always @(posedge clk or negedge rst_n) if(!rst_n) q <= 1'b0; else q <= d1; always @(posedge clk or negedge rst_n) if(!rst_n) q <= 1'b0; else q <= d2; endmodule 코드 11.19 Multiple source driving이 발생하는 코딩
11.2 Blocking과 Nonblocking 할당문 • 코드 11.20 (a), (b)의 출력 y1, y2를 확인하고, 그 이유를 생각해 본다. • 코드 11.20 (a), (b)의 합성 결과, 동일한 회로가 되는지, 아니면 서로 다른 회로가 되는 지 확인한다. module fbosc_blk(y1, y2, clk, rst); output y1, y2; input clk, rst; reg y1, y2; always @(posedge clk or posedge rst) if(rst) y1 = 0; // reset else y1 = y2; always @(posedge clk or posedge rst) if(rst) y2 = 1; // set else y2 = y1; endmodule Blocking 할당문 사용 코드 11.20(a)
11.2 Blocking과 Nonblocking 할당문 module fbosc_nonblk(y1, y2, clk, rst); output y1, y2; input clk, rst; reg y1, y2; always @(posedge clk or posedge rst) if(rst) y1 <= 0; // reset else y1 <= y2; always @(posedge clk or posedge rst) if(rst) y2 <= 1; // set else y2 <= y1; endmodule Nonblocking 할당문 사용 코드 11.20(b)
11.3시프트 레지스터 • 시프트 레지스터 • 클록신호가 인가될 때마다 데이터가 왼쪽 또는 오른쪽으로 이동되는 회로 • 여러 개의 플립플롭이 직렬로 연결된 구조 • 형태 • 직렬입력-직렬출력(Serial-In, Serial-Out) • 직렬입력-병렬출력(Serial-In, Parallel-Out) • 병렬입력-직렬출력(Parallel-In, Serial-Out) • 병렬입력-병렬출력(Parallel-In, Parallel-Out) • 왼쪽 시프트, 오른쪽 시프트, 양방향 시프트 • nonblocking 할당문, 시프트 연산자, 결합 연산자, 반복문 등 다양한 구문으로 모델링
q[7] q[2] q[1] q[0] DFF DFF DFF DFF Q D Q D Q D D sin Q sout clk rst 11.3.1직렬입력-직렬출력 시프트 레지스터 그림 11.17 직렬입력-직렬출력 시프트 레지스터 module shift_reg_nblk1(clk, rst, sin, sout); input clk, rst, sin; output sout; reg [7:0] q; assign sout = q[7]; always @(posedge clk) begin if(!rst) q <= 8'b0; else begin q[0] <= sin; q[1] <= q[0]; q[2] <= q[1]; q[3] <= q[2]; q[4] <= q[3]; q[5] <= q[4]; q[6] <= q[5]; q[7] <= q[6]; end end endmodule 코드 11.21
11.3.1직렬입력-직렬출력 시프트 레지스터 module shift_reg_nblk2(clk, rst, sin, sout); input clk, rst, sin; output sout; reg [7:0] q; assign sout = q[7]; always @(posedge clk) begin if(!rst) q <= 0; else begin q[0] <= sin; q[7:1] <= q[6:0]; end end endmodule 벡터 할당문을 사용한 경우 코드 11.22
11.3.1직렬입력-직렬출력 시프트 레지스터 • 그림 11.17의 시프트 레지스터를 다음의 방법으로 모델링하고, 시뮬레이션한다. ① 결합 연산자를 사용하는 방법 ② 시프트 연산자를 사용하는 방법 ③ for 반복문을 사용하는 방법 코드 11.22의 시뮬레이션 결과
din[0] pout[8] din[8] pout[2] din[2] pout[1] din[1] pout[0] load load load MUX MUX MUX DFF DFF DFF DFF Q Q Q D D D D Q clk rst 11.3.2병렬입력-병렬출력 시프트 레지스터 • 병렬입력-병렬출력 시프트 레지스터 그림 11.19 병렬입력-직렬출력 시프트 레지스터
11.3.2병렬입력-병렬출력 시프트 레지스터 module pld_shift_reg(clk, rst, load, din, pout); input clk, rst, load; input [7:0] din; output [7:0] pout; reg [7:0] data_reg; assign pout = data_reg; always @(posedge clk) begin if(!rst) data_reg <= 0; else if(load) data_reg <= din; else data_reg <= data_reg << 1; end endmodule 코드 11.23
11.3.2병렬입력-병렬출력 시프트 레지스터 • 직렬입력-병렬출력 8비트 시프트 레지스터를 모델링하고, 시뮬레이션을 통해 동작을 확인한다. 코드 11.23의 시뮬레이션 결과
11.3.2병렬입력-병렬출력 시프트 레지스터 • 양방향 병렬포트를 갖는 시프트 레지스터 • 데이터의 병렬로드(wr=0)와 시프팅 동작(en=0)이 동시에 일어나지 않으며, • data_io 포트가 inout 이므로 rd 신호와 wr 신호가 동시에 0이 되지 않는다. 표 11.1 양방향 병렬포트를 갖는 시프트 레지스터의 신호 정의
11.3.2병렬입력-병렬출력 시프트 레지스터 • 양방향 병렬포트를 갖는 시프트 레지스터 module shifter(clk, rst, en, wr, rd, si, so, data_io); parameter Len = 8; input clk, rst, en, wr, rd, si; output so; inout [Len-1:0] data_io; reg [Len-1:0] shift_reg; assign data_io = !rd ? shift_reg : {Len{1'bz}}; assign so = shift_reg[7]; always @(posedge clk) begin if(!rst) shift_reg <= {Len{1'b0}}; else begin if(!en) begin shift_reg <= shift_reg << 1; shift_reg[0] <= si; end else if(!wr) shift_reg <= data_io; end end endmodule 코드 11.24
11.3.2병렬입력-병렬출력 시프트 레지스터 • 양방향 병렬포트를 갖는 시프트 레지스터 코드 11.24의 시뮬레이션 결과 (직렬입력 데이터의 시프팅 동작)
11.3.2병렬입력-병렬출력 시프트 레지스터 • 양방향 병렬포트를 갖는 시프트 레지스터 코드 11.24의 시뮬레이션 결과 (병렬입력 데이터의 시프팅 동작)
11.3.2병렬입력-병렬출력 시프트 레지스터 • 코드 11.24의 시프트 레지스터에 좌/우 시프팅 기능을 추가하여 설계 하고, 시뮬레이션을 통해 동작을 확인한다. 신호의 정의는 다음과 같다.
DFF DFF DFF DFF DFF DFF DFF DFF sout q q q q q q q q d d d d d d d d clk rst 11.3.3선형 귀환 시프트 레지스터 • 선형 귀환 시프트 레지스터(Linear Feedback Shift Register; LFSR) • 선형 귀환을 통해 2진 비트열을 생성 • N-비트 시프트 레지스터에 의해, 최대 2N개의 의사 난수 시퀀스 생성 • 계수기, 의사 난수(pseudo-random sequence) 발생, 데이터 암호/복호, 데이터 압축, 데이터 무결성 검사합(data integrity checksum) 등 디지털 시스템에서 매우 다양한 목적으로 사용 • 시스템 IC의 내장형 자기 진단(Built-In Self-Test; BIST) 회로에 사용되어 테스트 벡터 생성 및 테스트 응답 분석에도 사용 그림 11.23 LFSR 회로
11.3.3선형 귀환 시프트 레지스터 • 선형 귀환 시프트 레지스터(Linear Feedback Shift Register; LFSR) • 시프트 레지스터의 초기화 • XOR게이트가 사용되는 LFSR : 레지스터를 0으로 초기화시키지 않는다. • 0이 계속 시프팅되므로, LFSR로 동작할 수 없다. • XNOR게이트가 사용되는 LFSR : 레지스터를 1로 초기화시키지 않는다. • 1이 계속 시프팅되므로, LFSR로 동작할 수 없다. • 3비트 LFSR
11.3.3선형 귀환 시프트 레지스터 • 3비트 LFSR module lfsr_Bad1(q3, clk, pre_n); output q3; input clk, pre_n; reg q3, q2, q1; assign n1 = q1 ^ q3; // Blocking 할당문을 사용한 경우 always @(posedge clk or negedge pre_n) if(!pre_n) begin q3 = 1'b1; q2 = 1'b1; q1 = 1'b1; end else begin q3 = q2; q2 = n1; q1 = q3; end endmodule Bad Code 코드 11.25(a)
11.3.3선형 귀환 시프트 레지스터 • 3비트 LFSR module lfsr_Good1(q3, clk, pre_n); output q3; input clk, pre_n; reg q3, q2, q1; // Nonblocking 할당문을 사용한 경우 always @(posedge clk or negedge pre_n) if(!pre_n) begin q3 <= 1'b1; q2 <= 1'b1; q1 <= 1'b1; end else begin q3 <= q2; q2 <= q1 ^ q3; q1 <= q3; end endmodule Good Code 코드 11.25(b)