460 likes | 882 Vues
디지털 시스템 설계 (3). Module. Verilog HDL 프로그램의 기본 구조 대소문자 구별 Statement terminator로 semicolon을 사용 Timing specification은 시뮬레이션을 위해서 사용. Module 의 구성요소. Port 선언. 포트 리스트 모듈에 사용되는 포트 이름의 list 예 : module mux_latch(y_out, sel_a, sel_b, data_a, data_b); 포트 타입 input : 입력 포트 output : 출력 포트
E N D
Module • Verilog HDL 프로그램의 기본 구조 • 대소문자 구별 • Statement terminator로 semicolon을 사용 • Timing specification은 시뮬레이션을 위해서 사용
Port 선언 • 포트 리스트 • 모듈에 사용되는 포트 이름의 list • 예 : module mux_latch(y_out, sel_a, sel_b, data_a, data_b); • 포트 타입 • input : 입력 포트 • output : 출력 포트 • inout : 입•출력 포트 • 포트 선언 • 포트 리스트에 나열된 포트명의 타입을 결정하는 과정을 의미 • <port type> <port_name>; • 예 • input sel_a, sel_b, data_a, data_b; • output y_out; • input [3:0] a; • output [3:0] a, b;
Port 선언 • 포트선언시의 일반적 표현방법 • i_[port_name] • “i_”현재 포트의 이름이 입력 포트임을 의미 • RHS(Right-Hand Side argument)로 사용 • o_[port_name] • “o_”현재 포트의 이름이 출력 포트임을 의미 • LHS(Left-Hand Side argument)로 사용 • LHS, RHS의 규칙을 따르지 않을경우 합성 이후 네트(net)가 연결되어 있지 않는 플로팅(floating) 상태가 되고, 레이아웃(Layout)시 GND(Ground, 접지 전압, 0V 또는 VDD(동작 전압)로 강제로 할당되므로 주의 • b_[port_name] • “b_”현재 포트의 이름이 입출력 양방향(bi-directional) 포트임을 의미 • RHS, LHS에 사용가능 • 버스의 선언은 down-ward로 기술 • 예 : [BIT_WIDTH-1:0]
데이터 형태 • 물리적 데이터 형태 • 논리값의 종류 • 추상적 데이터 형태 • Integer, real, time 등
데이터 형태 • 변수선언(데이터 형태 선언) • 종류 • reg : register (latch 또는 flip-flop) • 일시적으로 데이터를 저장하는 변수를 의미 • 하드웨어 레지스터를 의미하지는 않는다 • always, initial 문 등에서 사용 • 예 : reg alu_reg; reg [7:0] alu_reg; • wire : net (배선) • 값 저장 불가능 • assign 문에서 사용 • 예 : wire adder_out; wire [15:0] adder_out, mult_out; • constant • 파라미터를 이용하여 변수 값을 사용할 때
데이터 형 • 수 표현 • Sized 또는 unsized 형식의 수 표현 가능 • Sized 형식의 수 표현 • 형식 : <size>’<base format><number> • 예 : 3’b010 //3의 prefix는 수의 size를 의미 • Unsized 형식의 수 표현 • Base format이 없는 경우는 default로 decimal을 의미 • Size가 없는 경우는 default로 32-bit의 수를 의미 • 예 : 321 //32-bit을 갖는 decimal number 321을 의미 • Base format • Decimal : ‘d 또는 ‘D • Hexadecimal : ‘h 또는 ‘H • Binary : ‘b 또는 ‘B • Octal : ‘o 또는 ‘O
데이터 형 • 수 표현 • 음수의 표현 • <size> 앞에 –부호를 위치하여 표현 • 예 : -8’d3 //3의 2의 보수 형태로 저장된 8bit의 음수 • 틀린 예 : 4’d-2 • 수의 확장 법칙 • MSB가 0, X, 또는 Z 인 경우 • 각 각 MSB가 0, X, Z가 되도록 확장 • 예 : 3’b01 = 3’b001, 3’bx1 = 3’bxx1 , 3’bz = 3’bzzz • MSB가 1인 경우 • MSB를 0으로 채우는 방향으로 확장 • 예 : 3’b1 = 3’b001
데이터 형 • 수 표현
(예) A = 4’b0011, B = 4’b0100, D = 6, E =4 일때 A * B = 4’b1100 D / E = 1 //Truncates any fractional part A + B = 4’b0111 B – A = 4’b0001 13 % 3 = 1 연산자 • Binary 연산자의 종류 (예) 어떤 operand bit이 x값을 가지면 전체 연산 결과는 x 이다. in1 = 4’b101x, in2 = 4’b1010 일 때 Sum = in1 + in 2; //sum은 4’bx -7 % 2 = -1 //첫 번째 operand의 부호 7 % -2 = 1 //첫 번째 operand의 부호
(예) ain = 3’b010, bin = 3’b100, cin = 3’b111, din = 3’b01z, ein = 3’b01x일 때 ain > bin 은 false(1’b0) 의 결과 ain < bin 은 ture(1’b1)의 결과 ain >= bin 은 unknown(1’bx)의 결과 ain <= ein은 unknown(1’bx)의 결과 연산자 • 관계 연산자
(예) A = 3 ; B = 0; A && B //Evaluates to 0. Equivalent to (logical 1 && logical 0) A || B //Evaluates to 1. Equivalent to (logical 1 && logical 0) !A //Evaluates to 0. Equivalent to not(logical 1) !B //Evaluates to 1. Equivalent to not(logical 0) A = 2’b0x ; B = 2’b10; A && B //Evaluates to x. Equivalent to (x && logical 1) (a == 2) && (b == 3) //Evaluates to 1 if both a == 2 and b==3 are true 연산자 • 논리 연산자
만일 두 operand의 길이가 다르면 짧은 길이의 operand가 0으로 left-extend (예) X = 4’b1010, Y = 4’b1101, Z = 4’b10x1일 때 ~X //Result is 4’b0101 X & Y //Result is 4’b1000 X | Y //Result is 4’b1111 X ^ Y //Result is 4’b0111 X ^~ Y //Result is 4’b1000 X & Z //Result is 4’b10x0 연산자 • Bitwise 연산자
vector를 하나의 bit로 줄이는 연산을 수행한다. X 또는 Z는 연산자에 따라서 unknown일 수도 있고 known일 수도 있다. (예) ain = 5’b10101, bin = 4’b0011, cin = 3’bz00, din = 3’bx011일 때 &ain //Result is 1’b0 ~&ain //Result is 1’b1 |cin //Result is 1’bx &din //Result is 1’b0 연산자 • Unary Reduction 연산자
case equality와 case inequality를 제외하고 operand에 X 나 Z를 포함하면 결과는 unknown (예) A = 4, B = 3, X = 4’b1010, Y = 4’b1101, Z = 4’b1xxz, M = 4’b1xxz, N = 4’b1xxx일 때 A == B //Result is logical 0 X != Y //Result is logical 1 X == Z //Result is x Z == M //Result is logical 1(all bits match, including x and z) Z == N //Result is logical 0(least significant bit does not match) M != N //Result is logical 1 연산자 • Equality 연산자
연산자 • 기타 연산자
Multi Bit 선언 • 신호 선언 [MSB:LSB] • Input [7:0] abus; reg [15:8] add; • 한 비트의 선택 • assign abc = abus[5] ; assign abus[5] = abc ; • 여러 신호를 하나의 신호로 할당 • assign abcd[15:0] = {abus[7:0],add[15:8]} ;
Array • Register 형은 array로 선언 가능 • Reg [15:0] mem [0:255]; • mem은 16bit * 256word, 512 byte의 메모리 • resister 배열은 bit 선택과 부분 선택 불가 • 반드시 word 단위의 액세스 • Bit 선택이나 부분 선택 • 일시적인 net 신호를 이용 • Ex) wire [15:0] temp; • assign temp = mem [100];
기술방법(Description) • 구조적 기술방법(Structural description) • Explicit structural description • Primitive 또는 라이브러리 셀의 instance 및 연결을 통한 기술 • Implicit structural description • Continuous assignment를 통한 기술 • 동작 기술 방법(Behavioral description) • 회로의 동작을 기술함으로 설계하는 방법 • 대표적으로 initial, always behavior를 사용 • Procedural block 과 procedural statement로 구성
기술방법 • Explicit description • Implicit description module 8bit_or_gate(y, a, b); input [7:0]a, b; output y; or G1(y, a, b); endmodule module 8bit_or_gate(y, a, b); input [7:0]a, b; output y; or8bit(y, a, b); endmodule Primitive를 이용한 기술 라이브러리를 이용한 기술 module 8bit_or_gate(y, a, b); input [7:0]a, b; output y; assign y = a | b; endmodule
Primitives • Predetermined Primitives
Module Instantiation • Port connection의 2가지 방법 • Connecting by ordered list • Connecting ports by name • Connecting by ordered list
Module Instantiation • Connecting ports by name
Assign • Assign • Wire에 값을 가하고 update 하기 위해 사용 • LHS (Left Hand Side)의 데이터 타입은 항상 net data type이여야 한다 • Always active • RHS (Right Hand Side)의 어느 한 operand라도 변화하면, expression은 실행되고 LHS 값은 즉시 update 된다 • RHS의 데이터 타입은 net, register, function call등 어떤 것이어도 상관 없다
Procedural Blocks • Procedure의 정의 • sequential 하게 동작하는 코드 부분을 의미 • procedural statement • procedure안에 존재하는 statement • 예를 들어, 2-to-1 MUX의 경우
Initial Block • 시뮬레이션을 위한 초기화, 모니터링, waveform의 기술시에 주로 사용된다 • 시뮬레이션 타임 0에서 시작하여 오직 1번만 실행된다 • 하나의 initial block이 여러 개의 behavioral statement를 가질 경우 begin ~ end로 group 되어야 한다 • 독립적인 initial block은 서로 concurrent 하다 • Initial block 내부의 statement들은 sequential 하게 동작한다 • initial block은 중첩될 수 없다 • synthesis 되지 않는다
Initial Block module TestBench; reg a, b, c, d Initial a = 1’b0; Initial Begin b = 1’b1; #5 c = 1’b0; #10 d = 1’b0; End Initial #20 $finish; endmodule
always @([Senstitivity_list]) begin . . . end Always Block(Level-Senssitive Circuit) • 논리조합회로(Level-Sensitive Circuit)와 논리순차회로(Edge Sensitive Circuit) 에서 사용가능 • 논리조합회로에는 Blocking Assignment(=)만을 사용
always @ ( Edge condition [signal] or Edge condition [signal] or…) begin ... end Always Block(Edge-Senssitive Circuit) • 논리순차회로에는 non-Blocking Assignment(<=)만을 사용 • Edge Contition • posedge • negedge • Edge Condition 은 최소 1개 최대 3개까지 기술
Blocking vs. Non-Blocking • Blocking • Non-Blocking
Blocking vs. Non-Blocking • Blocking • Non-Blocking
if(<condition1>) sequence of statement(s) else if(<condition2>) sequence of statement(s) …… else sequence of statements(s) Procedural Statement • if-else statement • 어떤 조건을 근거로 하여 statement를 실행 할 것인지를 결정하 는데 사용 • TOP에서 BOTTOM으로 조건 평가 실시 • 모든 조건이 false이면 else에 관계되는 statement를 실행 E.g. 4-to-1 mux module mux4_1(out, in, sel); output out; input [3:0] in; input [1:0] sel; reg out; wire [3:0] in; wire [1:0] sel; always @(in or sel) if (sel == 0) out = in[0]; else if (sel == 1) out = in[1]; else if (sel == 2) out = in[2]; else out = in[3]; endmodule
case (expression) <condition1>: sequence of statement(s) <condition2>: sequence of statement(s) … default : sequence of statement(s) endcase Procedural Statement • case statement • if else와 같이 조건 평가에 의한 statement의 실행 • 모든 가능한 조건이 고려되어야 함 • default : 기술되지 않은 모든 가능한 조건에 해당 • 중첩 될 수 있다 • expression의 결과와 condition의 bit 수가 같지 않을 때는 MSB부터 0 fill 한다 E.g. 4-to-1 mux module mux4_1(out, in, sel); output out; input [3:0] in; input [1:0] sel; reg out; wire [3:0] in; wire [1:0] sel; always @(in or sel) case (sel) 0: out = in[0]; 1: out = in[1]; 2: out = in[2]; 3: out = in[3]; endcase endmodule
module count(Y, start); output [3:0] Y; input start; reg [3:0] Y; wire start; integer i; initial Y = 0; always @(posedge start) for (i = 0; i < 3; i = i + 1) #10 Y = Y + 1; endmodule Procedural Statement • For • loop의 시작에서 일단 한번 statement를 실행하고 expression이 참일때만 계속 loop를 실행
Module Add_half_1(sum, c_out, a, b); input a, b; output sum, c_out; wire c_out_bar; xor(sum, a, b); nand(c_out_bar, a, b); not(c_out, c_out_bar); endmodule Verilog HDL • Module 구조 예 모듈 선언 포트 선언 데이터 타입 선언 회로 동작기술 Predefined primitive 를 사용하여 instantiation
Module Add_half_2(sum, c_out, a, b); input a, b; output sum, c_out; wire c_out_bar; assign {c_out, sum} = a + b; endmodule Verilog HDL 회로 동작기술 Continuous assignment 구문사용
Module Add_full(sum, c_out, a, b); input a, b, c_in; output sum, c_out; wire w1, w2, w3; add_half_1 M1 (w1, s2, a, b); add_half_2 M2 (sum, w3, s1, c_in); or(c_out, w2, s3); endmodule Verilog HDL 기존에 설계한 half_adder를 이용한 Structural description module instantiation 사용 (parent module / child module) module instantiation시 반드시 module instance name이 들어가야 함 (primitive instantiation시는 optional)
Module full_adder(sum, carry_out, in1, in2, carry_in); input in1, in2, carry_in; output sum, carry_out; reg sum, carryout; always @(in1 or in2)begin {carry_out, sum} = in1+in2+carryin; end endmodule Verilog HDL sumHA = a ^ b c_outHA = ab sumFA = (a + b) ^ c_in c_outFA = (a + b) c_in + abc_in Half_adder의 결과를 sum을 연산자 +, c_out를 연산자 &로 치환하면 sumFA = (a + b) + c_in c_outFA = a&b | a&b&c_in