Verilog에서 발생하는 "ERROR:Xst:528 - Multi-source in Unit" 에러의 원인과 해결 방법을 상세하게 설명합니다.
문제상황
아래와 같이 공통된 출력 포트를 사용하는 두 개의 always 블록이 있는 Verilog 코드를 컴파일했습니다.
module multi_source_error (
input wire clk,
input wire rst,
input wire [3:0] a,
input wire [3:0] b,
output reg [7:0] y
);
always @(posedge clk or posedge rst) begin
if (rst) begin
y <= 8'b0;
end else begin
y <= a + b;
end
end
always @(posedge clk or posedge rst) begin
if (rst) begin
y <= 8'b0;
end else begin
y <= a - b;
end
end
endmodule
이 코드는 두 개의 입력 a와 b에 대한 덧셈과 뺄셈 연산을 수행하고 결과를 출력 포트 y에 저장하는 Verilog 모듈입니다. 이 코드에는 두 개의 always 블록이 있으며, 각 블록에서 출력 포트 y에 값을 할당하고 있습니다.
에러로그 내용:
ERROR:Xst:528 - Multi-source in Unit <multi_source_error> on signal <y>; this signal is connected to multiple drivers.
원인분석
에러 발생 원인: 이 에러는 하나의 신호가 여러 드라이버에 연결되어 있을 때 발생합니다. 위 코드의 경우, 출력 포트 y가 두 개의 always 블록에서 동시에 할당되고 있습니다.
이해에 필요한 개념: Verilog에서 하나의 신호는 하나의 드라이버만 가질 수 있습니다. 그렇지 않으면 컴파일러는 어떤 드라이버의 값을 사용해야 할지 결정할 수 없기 때문입니다. 이 문제를 해결하려면 출력 포트 y에 값이 할당되는 방식을 변경해야 합니다.
에러 발생 원리:
- 두 개의 always 블록이 공통된 출력 포트 y에 값을 할당하려고 시도합니다.
- 하나의 신호는 하나의 드라이버만 가질 수 있기 때문에 컴파일러는 에러를 발생시킵니다.
해결방법-1 (합친 always 블록 사용)
module multi_source_error_fixed1 (
input wire clk,
input wire rst,
input wire [3:0] a,
input wire [3:0] b,
input wire add_sub,
output reg [7:0] y
);
always @(posedge clk or posedge rst) begin
if (rst) begin
y <= 8'b0;
end else begin
if (add_sub) begin
y <= a + b;
end else begin
y <= a - b;
end
end
end
endmodule
수정된 코드 설명: 이 코드에서는 두 개의 always 블록을 하나로 합쳤습니다. 새로운 입력 포트 add_sub
를 추가하여 덧셈과 뺄셈 연산을 선택할 수 있습니다. add_sub
가 1일 때 덧셈을 수행하고, 0일 때 뺄셈을 수행합니다. 이렇게 하면 하나의 always 블록에서 출력 포트 y
에 값을 할당하므로 에러가 해결됩니다.
해결된 코드의 작동원리:
- 클럭의 상승 에지에서 레지스터
y
에 값을 할당합니다. add_sub
입력에 따라 덧셈 또는 뺄셈 연산을 수행하여 결과를y
에 저장합니다.
해결방법-2 (Mux 사용)
module multi_source_error_fixed2 (
input wire clk,
input wire rst,
input wire [3:0] a,
input wire [3:0] b,
input wire add_sub,
output reg [7:0] y
);
wire [7:0] add_result;
wire [7:0] sub_result;
assign add_result = a + b;
assign sub_result = a - b;
always @(posedge clk or posedge rst) begin
if (rst) begin
y <= 8'b0;
end else begin
if (add_sub) begin
y <= add_result;
end else begin
y <= sub_result;
end
end
end
endmodule
수정된 코드 설명: 이 코드에서는 두 개의 중간 결과 add_result와 sub_result를 생성하고, 이들 중 하나를 y에 할당하는 방식으로 에러를 해결했습니다. 이렇게 하면 출력 포트 y에 값이 할당되는 방식을 변경하여 하나의 드라이버만 사용하게 됩니다.
해결된 코드의 작동원리:
- 덧셈과 뺄셈 연산의 결과를 각각 add_result와 sub_result에 저장합니다.
- 클럭의 상승 에지에서 add_sub 입력에 따라 add_result 또는 sub_result를 레지스터 y에 할당합니다.