오직 현재의 입력에 의해서 출력이 결정되는 논리
wire 자료형에 값을 연속적으로 할당하는 키워드
연속 할당 이므로 우변이 바뀌면 좌변도 자동으로 바뀐다.
wire a, b;
wire y;
assign y = a & b; // a 또는 b가 바뀌면 y도 즉시 갱신
assign문은 주로 조합 회로를 구성할 떄 사용된다.
module gates (
input wire a, b, c,
output wire y1, y2, y3, y4
);
// 기본 게이트
assign y1 = a & b; // AND
assign y2 = a | b; // OR
assign y3 = ~a; // NOT
assign y4 = (a & b) | c; // 복합 논리
endmodule
아래와 같이 MUX를 만들때 사용되기도한다.
module mux2to1 (
input wire sel,
input wire [7:0] a, b,
output wire [7:0] y
);
// sel=0이면 a, sel=1이면 b
assign y = sel ? b : a;
endmodule
sensitivity list가 *이므로 입력이 하나라도 바뀌면 실행되는 조합 회로 블록이다.
reg y; // always 블록 안에서는 reg 사용!
always @(*) begin
if (sel)
y = b;
else
y = a;
end
reg라고해서 꼭 플립플롭인 것은 아니다.
위와 같이 조합논리 회로를 구성하는데 사용할수도있다.
대표적인 예시는 아래와 같은 4:1 MUX 이다.
// 4:1 멀티플렉서
module mux4to1 (
input wire [1:0] sel,
input wire [7:0] a, b, c, d,
output reg [7:0] y // always 블록이므로 reg
);
always @(*) begin
case (sel)
2'b00: y = a;
2'b01: y = b;
2'b10: y = c;
2'b11: y = d;
endcase
end
endmodule
래치란, 의도치 않게 생긴 메모리 소자를 의미한다.
아래의 예시를 살펴보자.
always @(*) begin
if (sel)
y = a;
// else가 없음! sel=0일 때 y는 어떤 값?
// → 이전 값 유지 → 래치 생성!
end
작성자는 조합 논리를 작성하려했다. 그런데 만약 sel이 0일 경우, y값을 조작하는 코드가 없다.
그래서 y는 이전 값을 그대로 유지하는 메모리적인 특성을 나타내게 된다.
(위의 경우에 y가 의도치 않은 래치이다)
조합회로에는 메모리 특성을 가지지 않으므로 이는 잘못되었다.
이를 방지하기위해
(1) if, else, else if 등으로 모든 경우를 기술
(2) 디폴트 값을 먼저 할당하고 if 블록에 진입
(3) case문 내부에서 default문 사용
등의 방법을 사용할 수 있다.