MUX
4-to-1 MUX를 예시로 구현했다.
4-to-1 MUX는 2bit select 변수 값에 따라 in0, in1, in2, in3 중 하나를 선택하여 출력으로 내보내는 회로이다. 일반적으로 select의 2진수 값이 0, 1, 2, 3일 경우 각각 in0, in1, in2, in3를 선택하게 된다.
순서대로 case, if를 이용한 설계와 조건 연산자 ? : 를 이용한 설계 예시다.
module mux0(
input [1:0] in0, in1, in2, in3, // bit size can be changed
input [1:0] select,
output [1:0] out
);
reg [1:0] mux_out;
assign out = mux_out;
always @ (*) begin // always @ (select)
case (select)
2'b00: mux_out = in0;
2'b01: mux_out = in1;
2'b10: mux_out = in2;
2'b11: mux_out = in3;
default: mux_out = 2'b0;
endcase
end
endmodule
module mux1(
input [1:0] in0, in1, in2, in3, // bit size can be changed
input [1:0] select,
output [1:0] out
);
reg [1:0] mux_out;
assign out = mux_out;
always @ (*) begin
if (select == 2'b00) begin
mux_out = in0;
end
else if (select == 2'b01) begin
mux_out = in1;
end
else if (select == 2'b10) begin
mux_out = in2;
end
else if (select == 2'b11) begin
mux_out = in3;
end
else begin
mux_out = 2'b0;
end
end
endmodule
module mux2(
input [1:0] in0, in1, in2, in3, // bit size can be changed
input [1:0] select,
output [1:0] out
);
wire [1:0] tmp0, tmp1; // selection with select[0]
assign tmp0 = select[0] ? in1 : in0; // 1: 2'b01, 0: 2'b00
assign tmp1 = select[0] ? in3 : in2; // 3: 2'b11, 2: 2'b10
assign out = select[1] ? tmp1 : tmp0;
// tmp0: 2'b01 or 2'b00
// tmp1: 2'b11 or 2'b10
endmodule
mux0와 mux1은 always @ (*)을 이용했으며 mux2는 ? :를 이용하여 설계했다.
mux0와 mux1은 결과적으로 같은 설계인데, 주목해야할 점은 default와 else가 있다는 것이다. MUX를 앞선 두 가지 방법으로 설계할 경우 이 default와 else가 없으면 안 된다. 왜냐하면 always @ (*)은 예외 경우를 포함하지 않을 경우 합성 시 예상치 못한 latch가 생성될 수 있기 때문이다. 또한 nonblocking이 아니라 blocking assignment를 써야 한다.
mux2는 select[0], select[1]으로 나누어 선택을 하게 된다. 주석에도 적어뒀지만 0, 1, 2, 3이 각각 2'b00, 2'b01, 2'b10, 2'b11이고 이들의 LSB(Least Significant Bit)가 각각 0, 1, 0, 1이므로 select[0]가 0일 경우 각각 in0, in2를 선택하고 1일 경우 in1, in3를 선택하게 했다. 마찬가지로 select[1]도 MSB(Most Significant Bit)에 따라 선택하도록 구현했다.
데이터 in0, in1, in2, in3의 경우 예시에서는 2비트를 택했지만 원하는 비트 사이즈로 바꿔도 무방하다.
개인적으로 always @ (*)을 통한 구현은 설계 시에 사용하지 않는 것을 추천한다. 앞서 언급한 대로 합성 시에 예상치 못한 latch가 생성될 가능성이 있기 때문이다. 꼭 써야 한다면 반드시 예외 경우까지 포함하도록 설계해야 한다.