반도체 설계 기술 면접 문제 100선 - 롭칩 & 올윈어 특화편

반도체 설계 기술 면접 문제 100선 (롭칩, 올윈어 편) 및 상세 해설

총 목차

제1부: 디지털 회로 설계 (25문제)

1.1 Verilog/VHDL 프로그래밍 (10문제)
1.2 타이밍 분석 및 제약 (8문제)
1.3 논리 합성 및 최적화 (7문제)

제2부: 아날로그 회로 설계 (25문제)

2.1 증폭기 설계 (8문제)
2.2 전원 관리 (9문제)
2.3 RF 회로 (8문제)

제3부: 시스템 아키텍처 설계 (25문제)

3.1 SoC 아키텍처 (10문제)
3.2 버스 설계 (8문제)
3.3 메모리 시스템 (7문제)

제4부: 검증 및 테스트 (25문제)

4.1 기능 검증 (10문제)
4.2 타이밍 검증 (8문제)
4.3 물리 설계 (7문제)

제1부: 디지털 회로 설계 (25문제)

1.1 Verilog/VHDL 프로그래밍 (10문제)

1. 고성능 AXI4 버스 인터페이스를 설계하시오

해답:

// AXI4 버스 인터페이스 설계
module axi4_bus_interface #(
    parameter ADDR_WIDTH = 32,
    parameter DATA_WIDTH = 64,
    parameter ID_WIDTH = 8,
    parameter STRB_WIDTH = DATA_WIDTH/8
)(
    input  wire                    clk,
    input  wire                    rst_n,
    
    // 쓰기 주소 채널
    input  wire [ID_WIDTH-1:0] awid,
    input  wire [ADDR_WIDTH-1:0] awaddr,
    input  wire [7:0]              awlen,
    input  wire [2:0]              awsize,
    input  wire [1:0]              awburst,
    input  wire                    awlock,
    input  wire [3:0]              awcache,
    input  wire [2:0]              awprot,
    input  wire                    awvalid,
    output reg                     awready,
    
    // 쓰기 데이터 채널
    input  wire [ID_WIDTH-1:0] wid,
    input  wire [DATA_WIDTH-1:0] wdata,
    input  wire [STRB_WIDTH-1:0] wstrb,
    input  wire                    wlast,
    input  wire                    wvalid,
    output reg                     wready,
    
    // 쓰기 응답 채널
    output reg  [ID_WIDTH-1:0] bid,
    output reg  [1:0]              bresp,
    output reg                     bvalid,
    input  wire                    bready,
    
    // 읽기 주소 채널
    input  wire [ID_WIDTH-1:0] arid,
    input  wire [ADDR_WIDTH-1:0] araddr,
    input  wire [7:0]              arlen,
    input  wire [2:0]              arsize,
    input  wire [1:0]              arburst,
    input  wire                    arlock,
    input  wire [3:0]              arcache,
    input  wire [2:0]              arprot,
    input  wire                    arvalid,
    output reg                     arready,
    
    // 읽기 데이터 채널
    output reg  [ID_WIDTH-1:0] rid,
    output reg  [DATA_WIDTH-1:0] rdata,
    output reg  [1:0]              rresp,
    output reg                     rlast,
    output reg                     rvalid,
    input  wire                    rready,
    
    // 사용자 인터페이스
    output reg  [ADDR_WIDTH-1:0] mem_addr,
    output reg  [DATA_WIDTH-1:0] mem_wdata,
    output reg                     mem_we,
    input  wire [DATA_WIDTH-1:0] mem_rdata,
    output reg  [STRB_WIDTH-1:0] mem_wstrb
);

// 내부 상태 정의
localparam IDLE = 3'b000;
localparam WRITE_ADDR = 3'b001;
localparam WRITE_DATA = 3'b010;
localparam WRITE_RESP = 3'b011;
localparam READ_ADDR = 3'b100;
localparam READ_DATA = 3'b101;

reg [2:0] current_state, next_state;

// 쓰기 주소 채널 레지스터
reg [ID_WIDTH-1:0]  awid_reg;
reg [ADDR_WIDTH-1:0] awaddr_reg;
reg [7:0]               awlen_reg;
reg [2:0]               awsize_reg;
reg [1:0]               awburst_reg;
reg                     awlock_reg;
reg [3:0]               awcache_reg;
reg [2:0]               awprot_reg;

// 쓰기 데이터 채널 레지스터
reg [ID_WIDTH-1:0]  wid_reg;
reg [DATA_WIDTH-1:0] wdata_reg;
reg [STRB_WIDTH-1:0] wstrb_reg;
reg                     wlast_reg;

// 읽기 주소 채널 레지스터
reg [ID_WIDTH-1:0]  arid_reg;
reg [ADDR_WIDTH-1:0] araddr_reg;
reg [7:0]               arlen_reg;
reg [2:0]               arsize_reg;
reg [1:0]               arburst_reg;
reg                     arlock_reg;
reg [3:0]               arcache_reg;
reg [2:0]               arprot_reg;

// 읽기/쓰기 카운터
reg [7:0] write_count;
reg [7:0] read_count;

// 상태 머신
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        current_state <= IDLE;
    end else begin
        current_state <= next_state;
    end
end

// 상태 전이 논리
always @(*) begin
    next_state = current_state;
    case (current_state)
        IDLE: begin
            if (awvalid) begin
                next_state = WRITE_ADDR;
            end else if (arvalid) begin
                next_state = READ_ADDR;
            end
        end
        
        WRITE_ADDR: begin
            if (awvalid && awready) begin
                next_state = WRITE_DATA;
            end
        end
        
        WRITE_DATA: begin
            if (wvalid && wready && wlast) begin
                next_state = WRITE_RESP;
            end
        end
        
        WRITE_RESP: begin
            if (bvalid && bready) begin
                next_state = IDLE;
            end
        end
        
        READ_ADDR: begin
            if (arvalid && arready) begin
                next_state = READ_DATA;
            end
        end
        
        READ_DATA: begin
            if (rvalid && rready && rlast) begin
                next_state = IDLE;
            end
        end
        
        default: begin
            next_state = IDLE;
        end
    endcase
end

// 쓰기 주소 채널 핸드셰이크
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        awready <= 1'b0;
        awid_reg <= {ID_WIDTH{1'b0}};
        awaddr_reg <= {ADDR_WIDTH{1'b0}};
        awlen_reg <= 8'h0;
        awsize_reg <= 3'b0;
        awburst_reg <= 2'b0;
        awlock_reg <= 1'b0;
        awcache_reg <= 4'b0;
        awprot_reg <= 3'b0;
    end else begin
        case (current_state)
            IDLE: begin
                if (awvalid) begin
                    awready <= 1'b1;
                    awid_reg <= awid;
                    awaddr_reg <= awaddr;
                    awlen_reg <= awlen;
                    awsize_reg <= awsize;
                    awburst_reg <= awburst;
                    awlock_reg <= awlock;
                    awcache_reg <= awcache;
                    awprot_reg <= awprot;
                end else begin
                    awready <= 1'b0;
                end
            end
            
            WRITE_ADDR: begin
                if (awvalid && awready) begin
                    awready <= 1'b0;
                end
            end
            
            default: begin
                awready <= 1'b0;
            end
        endcase
    end
end

// 쓰기 데이터 채널 핸드셰이크
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        wready <= 1'b0;
        wid_reg <= {ID_WIDTH{1'b0}};
        wdata_reg <= {DATA_WIDTH{1'b0}};
        wstrb_reg <= {STRB_WIDTH{1'b0}};
        wlast_reg <= 1'b0;
        write_count <= 8'h0;
    end else begin
        case (current_state)
            WRITE_DATA: begin
                wready <= 1'b1;
                if (wvalid && wready) begin
                    wid_reg <= wid;
                    wdata_reg <= wdata;
                    wstrb_reg <= wstrb;
                    wlast_reg <= wlast;
                    if (wlast) begin
                        write_count <= 8'h0;
                    end else begin
                        write_count <= write_count + 1;
                    end
                end
            end
            
            default: begin
                wready <= 1'b0;
            end
        endcase
    end
end

// 쓰기 응답 채널
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        bvalid <= 1'b0;
        bid <= {ID_WIDTH{1'b0}};
        bresp <= 2'b00;
    end else begin
        case (current_state)
            WRITE_RESP: begin
                bvalid <= 1'b1;
                bid <= awid_reg;
                bresp <= 2'b00; // OKAY 응답
                
                if (bvalid && bready) begin
                    bvalid <= 1'b0;
                end
            end
            
            default: begin
                bvalid <= 1'b0;
            end
        endcase
    end
end

// 읽기 주소 채널 핸드셰이크
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        arready <= 1'b0;
        arid_reg <= {ID_WIDTH{1'b0}};
        araddr_reg <= {ADDR_WIDTH{1'b0}};
        arlen_reg <= 8'h0;
        arsize_reg <= 3'b0;
        arburst_reg <= 2'b0;
        arlock_reg <= 1'b0;
        arcache_reg <= 4'b0;
        arprot_reg <= 3'b0;
        read_count <= 8'h0;
    end else begin
        case (current_state)
            IDLE: begin
                if (arvalid) begin
                    arready <= 1'b1;
                    arid_reg <= arid;
                    araddr_reg <= araddr;
                    arlen_reg <= arlen;
                    arsize_reg <= arsize;
                    arburst_reg <= arburst;
                    arlock_reg <= arlock;
                    arcache_reg <= arcache;
                    arprot_reg <= arprot;
                end else begin
                    arready <= 1'b0;
                end
            end
            
            READ_ADDR: begin
                if (arvalid && arready) begin
                    arready <= 1'b0;
                end
            end
            
            default: begin
                arready <= 1'b0;
            end
        endcase
    end
end

// 읽기 데이터 채널
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        rvalid <= 1'b0;
        rid <= {ID_WIDTH{1'b0}};
        rdata <= {DATA_WIDTH{1'b0}};
        rresp <= 2'b00;
        rlast <= 1'b0;
    end else begin
        case (current_state)
            READ_DATA: begin
                rvalid <= 1'b1;
                rid <= arid_reg;
                rdata <= mem_rdata;
                rresp <= 2'b00; // OKAY 응답
                
                if (read_count == arlen_reg) begin
                    rlast <= 1'b1;
                end else begin
                    rlast <= 1'b0;
                end
                
                if (rvalid && rready) begin
                    if (rlast) begin
                        rvalid <= 1'b0;
                        rlast <= 1'b0;
                        read_count <= 8'h0;
                    end else begin
                        read_count <= read_count + 1;
                    end
                end
            end
            
            default: begin
                rvalid <= 1'b0;
                rlast <= 1'b0;
            end
        endcase
    end
end

// 메모리 인터페이스 제어
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        mem_addr <= {ADDR_WIDTH{1'b0}};
        mem_wdata <= {DATA_WIDTH{1'b0}};
        mem_we <= 1'b0;
        mem_wstrb <= {STRB_WIDTH{1'b0}};
    end else begin
        case (current_state)
            WRITE_DATA: begin
                if (wvalid && wready) begin
                    mem_addr <= awaddr_reg + (write_count * (DATA_WIDTH/8));
                    mem_wdata <= wdata;
                    mem_we <= 1'b1;
                    mem_wstrb <= wstrb;
                end else begin
                    mem_we <= 1'b0;
                end
            end
            
            READ_DATA: begin
                mem_addr <= araddr_reg + (read_count * (DATA_WIDTH/8));
                mem_we <= 1'b0;
                mem_wstrb <= {STRB_WIDTH{1'b0}};
            end
            
            default: begin
                mem_we <= 1'b0;
                mem_wstrb <= {STRB_WIDTH{1'b0}};
            end
        endcase
    end
end

endmodule

// 고성능 AXI4 버스 인터페이스 최적화 버전
module high_perf_axi4 #(
    parameter ADDR_WIDTH = 32,
    parameter DATA_WIDTH = 64,
    parameter ID_WIDTH = 8,
    parameter STRB_WIDTH = DATA_WIDTH/8,
    parameter FIFO_DEPTH = 16
)(
    input  wire                    clk,
    input  wire                    rst_n,
    
    // AXI4 슬레이브 인터페이스 (마스터 연결)
    input  wire [ID_WIDTH-1:0] s_awid,
    input  wire [ADDR_WIDTH-1:0] s_awaddr,
    input  wire [7:0]              s_awlen,
    input  wire [2:0]              s_awsize,
    input  wire [1:0]              s_awburst,
    input  wire                    s_awlock,
    input  wire [3:0]              s_awcache,
    input  wire [2:0]              s_awprot,
    input  wire                    s_awvalid,
    output reg                     s_awready,
    
    input  wire [ID_WIDTH-1:0] s_wid,
    input  wire [DATA_WIDTH-1:0] s_wdata,
    input  wire [STRB_WIDTH-1:0] s_wstrb,
    input  wire                    s_wlast,
    input  wire                    s_wvalid,
    output reg                     s_wready,
    
    output reg  [ID_WIDTH-1:0] s_bid,
    output reg  [1:0]              s_bresp,
    output reg                     s_bvalid,
    input  wire                    s_bready,
    
    input  wire [ID_WIDTH-1:0] s_arid,
    input  wire [ADDR_WIDTH-1:0] s_araddr,
    input  wire [7:0]              s_arlen,
    input  wire [2:0]              s_arsize,
    input  wire [1:0]              s_arburst,
    input  wire                    s_arlock,
    input  wire [3:0]              s_arcache,
    input  wire [2:0]              s_arprot,
    input  wire                    s_arvalid,
    output reg                     s_arready,
    
    output reg  [ID_WIDTH-1:0] s_rid,
    output reg  [DATA_WIDTH-1:0] s_rdata,
    output reg  [1:0]              s_rresp,
    output reg                     s_rlast,
    output reg                     s_rvalid,
    input  wire                    s_rready,
    
    // AXI4 마스터 인터페이스 (슬레이브 연결)
    output reg  [ID_WIDTH-1:0] m_awid,
    output reg  [ADDR_WIDTH-1:0] m_awaddr,
    output reg  [7:0]              m_awlen,
    output reg  [2:0]              m_awsize,
    output reg  [1:0]              m_awburst,
    output reg                     m_awlock,
    output reg  [3:0]              m_awcache,
    output reg  [2:0]              m_awprot,
    output reg                     m_awvalid,
    input  wire                    m_awready,
    
    output reg  [ID_WIDTH-1:0] m_wid,
    output reg  [DATA_WIDTH-1:0] m_wdata,
    output reg  [STRB_WIDTH-1:0] m_wstrb,
    output reg                     m_wlast,
    output reg                     m_wvalid,
    input  wire                    m_wready,
    
    input  wire [ID_WIDTH-1:0] m_bid,
    input  wire [1:0]              m_bresp,
    input  wire                    m_bvalid,
    output reg                     m_bready,
    
    output reg  [ID_WIDTH-1:0] m_arid,
    output reg  [ADDR_WIDTH-1:0] m_araddr,
    output reg  [7:0]              m_arlen,
    output reg  [2:0]              m_arsize,
    output reg  [1:0]              m_arburst,
    output reg                     m_arlock,
    output reg  [3:0]              m_arcache,
    output reg  [2:0]              m_arprot,
    output reg                     m_arvalid,
    input  wire                    m_arready,
    
    input  wire [ID_WIDTH-1:0] m_rid,
    input  wire [DATA_WIDTH-1:0] m_rdata,
    input  wire [1:0]              m_rresp,
    input  wire                    m_rlast,
    input  wire                    m_rvalid,
    output reg                     m_rready
);

// 쓰기 주소 FIFO
reg [ID_WIDTH-1:0]  aw_fifo_id [0:FIFO_DEPTH-1];
reg [ADDR_WIDTH-1:0] aw_fifo_addr [0:FIFO_DEPTH-1];
reg [7:0]               aw_fifo_len [0:FIFO_DEPTH-1];
reg [2:0]               aw_fifo_size [0:FIFO_DEPTH-1];
reg [1:0]               aw_fifo_burst [0:FIFO_DEPTH-1];
reg                     aw_fifo_lock [0:FIFO_DEPTH-1];
reg [3:0]               aw_fifo_cache [0:FIFO_DEPTH-1];
reg [2:0]               aw_fifo_prot [0:FIFO_DEPTH-1];
reg [$clog2(FIFO_DEPTH)-1:0] aw_wr_ptr, aw_rd_ptr;
reg [$clog2(FIFO_DEPTH):0]   aw_count;

// 쓰기 데이터 FIFO
reg [ID_WIDTH-1:0]  w_fifo_id [0:FIFO_DEPTH-1];
reg [DATA_WIDTH-1:0] w_fifo_data [0:FIFO_DEPTH-1];
reg [STRB_WIDTH-1:0] w_fifo_strb [0:FIFO_DEPTH-1];
reg                     w_fifo_last [0:FIFO_DEPTH-1];
reg [$clog2(FIFO_DEPTH)-1:0] w_wr_ptr, w_rd_ptr;
reg [$clog2(FIFO_DEPTH):0]   w_count;

// 읽기 주소 FIFO
reg [ID_WIDTH-1:0]  ar_fifo_id [0:FIFO_DEPTH-1];
reg [ADDR_WIDTH-1:0] ar_fifo_addr [0:FIFO_DEPTH-1];
reg [7:0]               ar_fifo_len [0:FIFO_DEPTH-1];
reg [2:0]               ar_fifo_size [0:FIFO_DEPTH-1];
reg [1:0]               ar_fifo_burst [0:FIFO_DEPTH-1];
reg                     ar_fifo_lock [0:FIFO_DEPTH-1];
reg [3:0]               ar_fifo_cache [0:FIFO_DEPTH-1];
reg [2:0]               ar_fifo_prot [0:FIFO_DEPTH-1];
reg [$clog2(FIFO_DEPTH)-1:0] ar_wr_ptr, ar_rd_ptr;
reg [$clog2(FIFO_DEPTH):0]   ar_count;

// 쓰기 주소 FIFO 제어
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        aw_wr_ptr <= 0;
        aw_rd_ptr <= 0;
        aw_count <= 0;
        s_awready <= 1'b0;
    end else begin
        // 쓰기 FIFO
        if (s_awvalid && (aw_count < FIFO_DEPTH)) begin
            aw_fifo_id[aw_wr_ptr] <= s_awid;
            aw_fifo_addr[aw_wr_ptr] <= s_awaddr;
            aw_fifo_len[aw_wr_ptr] <= s_awlen;
            aw_fifo_size[aw_wr_ptr] <= s_awsize;
            aw_fifo_burst[aw_wr_ptr] <= s_awburst;
            aw_fifo_lock[aw_wr_ptr] <= s_awlock;
            aw_fifo_cache[aw_wr_ptr] <= s_awcache;
            aw_fifo_prot[aw_wr_ptr] <= s_awprot;
            aw_wr_ptr <= aw_wr_ptr + 1;
            aw_count <= aw_count + 1;
        end
        
        // 읽기 FIFO
        if (m_awvalid && m_awready) begin
            aw_rd_ptr <= aw_rd_ptr + 1;
            aw_count <= aw_count - 1;
        end
        
        // ready 신호 제어
        s_awready <= (aw_count < FIFO_DEPTH);
    end
end

// 쓰기 주소 FIFO 출력
always @(*) begin
    if (aw_count > 0) begin
        m_awid = aw_fifo_id[aw_rd_ptr];
        m_awaddr = aw_fifo_addr[aw_rd_ptr];
        m_awlen = aw_fifo_len[aw_rd_ptr];
        m_awsize = aw_fifo_size[aw_rd_ptr];
        m_awburst = aw_fifo_burst[aw_rd_ptr];
        m_awlock = aw_fifo_lock[aw_rd_ptr];
        m_awcache = aw_fifo_cache[aw_rd_ptr];
        m_awprot = aw_fifo_prot[aw_rd_ptr];
        m_awvalid = 1'b1;
    end else begin
        m_awid = {ID_WIDTH{1'b0}};
        m_awaddr = {ADDR_WIDTH{1'b0}};
        m_awlen = 8'h0;
        m_awsize = 3'b0;
        m_awburst = 2'b0;
        m_awlock = 1'b0;
        m_awcache = 4'b0;
        m_awprot = 3'b0;
        m_awvalid = 1'b0;
    end
end

// 쓰기 데이터 FIFO 제어
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        w_wr_ptr <= 0;
        w_rd_ptr <= 0;
        w_count <= 0;
        s_wready <= 1'b0;
    end else begin
        // 쓰기 FIFO
        if (s_wvalid && (w_count < FIFO_DEPTH)) begin
            w_fifo_id[w_wr_ptr] <= s_wid;
            w_fifo_data[w_wr_ptr] <= s_wdata;
            w_fifo_strb[w_wr_ptr] <= s_wstrb;
            w_fifo_last[w_wr_ptr] <= s_wlast;
            w_wr_ptr <= w_wr_ptr + 1;
            w_count <= w_count + 1;
        end
        
        // 읽기 FIFO
        if (m_wvalid && m_wready) begin
            w_rd_ptr <= w_rd_ptr + 1;
            w_count <= w_count - 1;
        end
        
        // ready 신호 제어
        s_wready <= (w_count < FIFO_DEPTH);
    end
end

// 쓰기 데이터 FIFO 출력
always @(*) begin
    if (w_count > 0) begin
        m_wid = w_fifo_id[w_rd_ptr];
        m_wdata = w_fifo_data[w_rd_ptr];
        m_wstrb = w_fifo_strb[w_rd_ptr];
        m_wlast = w_fifo_last[w_rd_ptr];
        m_wvalid = 1'b1;
    end else begin
        m_wid = {ID_WIDTH{1'b0}};
        m_wdata = {DATA_WIDTH{1'b0}};
        m_wstrb = {STRB_WIDTH{1'b0}};
        m_wlast = 1'b0;
        m_wvalid = 1'b0;
    end
end

// 읽기 주소 FIFO 제어
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        ar_wr_ptr <= 0;
        ar_rd_ptr <= 0;
        ar_count <= 0;
        s_arready <= 1'b0;
    end else begin
        // 쓰기 FIFO
        if (s_arvalid && (ar_count < FIFO_DEPTH)) begin
            ar_fifo_id[ar_wr_ptr] <= s_arid;
            ar_fifo_addr[ar_wr_ptr] <= s_araddr;
            ar_fifo_len[ar_wr_ptr] <= s_arlen;
            ar_fifo_size[ar_wr_ptr] <= s_arsize;
            ar_fifo_burst[ar_wr_ptr] <= s_arburst;
            ar_fifo_lock[ar_wr_ptr] <= s_arlock;
            ar_fifo_cache[ar_wr_ptr] <= s_arcache;
            ar_fifo_prot[ar_wr_ptr] <= s_arprot;
            ar_wr_ptr <= ar_wr_ptr + 1;
            ar_count <= ar_count + 1;
        end
        
        // 읽기 FIFO
        if (m_arvalid && m_arready) begin
            ar_rd_ptr <= ar_rd_ptr + 1;
            ar_count <= ar_count - 1;
        end
        
        // ready 신호 제어
        s_arready <= (ar_count < FIFO_DEPTH);
    end
end

// 읽기 주소 FIFO 출력
always @(*) begin
    if (ar_count > 0) begin
        m_arid = ar_fifo_id[ar_rd_ptr];
        m_araddr = ar_fifo_addr[ar_rd_ptr];
        m_arlen = ar_fifo_len[ar_rd_ptr];
        m_arsize = ar_fifo_size[ar_rd_ptr];
        m_arburst = ar_fifo_burst[ar_rd_ptr];
        m_arlock = ar_fifo_lock[ar_rd_ptr];
        m_arcache = ar_fifo_cache[ar_rd_ptr];
        m_arprot = ar_fifo_prot[ar_rd_ptr];
        m_arvalid = 1'b1;
    end else begin
        m_arid = {ID_WIDTH{1'b0}};
        m_araddr = {ADDR_WIDTH{1'b0}};
        m_arlen = 8'h0;
        m_arsize = 3'b0;
        m_arburst = 2'b0;
        m_arlock = 1'b0;
        m_arcache = 4'b0;
        m_arprot = 3'b0;
        m_arvalid = 1'b0;
    end
end

// 쓰기 응답 채널 직접 전달
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        s_bid <= {ID_WIDTH{1'b0}};
        s_bresp <= 2'b00;
        s_bvalid <= 1'b0;
        m_bready <= 1'b0;
    end else begin
        s_bid <= m_bid;
        s_bresp <= m_bresp;
        s_bvalid <= m_bvalid;
        m_bready <= s_bready;
    end
end

// 읽기 데이터 채널 직접 전달
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        s_rid <= {ID_WIDTH{1'b0}};
        s_rdata <= {DATA_WIDTH{1'b0}};
        s_rresp <= 2'b00;
        s_rlast <= 1'b0;
        s_rvalid <= 1'b0;
        m_rready <= 1'b0;
    end else begin
        s_rid <= m_rid;
        s_rdata <= m_rdata;
        s_rresp <= m_rresp;
        s_rlast <= m_rlast;
        s_rvalid <= m_rvalid;
        m_rready <= s_rready;
    end
end

endmodule

2. 고성능 파이프라인 곱셈기를 설계하시오

해답:

// 고성능 파이프라인 곱셈기 설계
module pipeline_multiplier #(
    parameter DATA_WIDTH = 32,
    parameter PIPELINE_STAGES = 4
)(
    input  wire                    clk,
    input  wire                    rst_n,
    input  wire [DATA_WIDTH-1:0]   multiplicand,
    input  wire [DATA_WIDTH-1:0]   multiplier,
    input  wire                    valid_in,
    output reg                     ready_out,
    output reg  [2*DATA_WIDTH-1:0] product,
    output reg                     valid_out,
    input  wire                    ready_in
);

// 내부 신호 정의
reg [DATA_WIDTH-1:0] multiplicand_reg [0:PIPELINE_STAGES];
reg [DATA_WIDTH-1:0] multiplier_reg [0:PIPELINE_STAGES];
reg [2*DATA_WIDTH-1:0] partial_product [0:PIPELINE_STAGES];
reg valid_reg [0:PIPELINE_STAGES];
reg ready_reg [0:PIPELINE_STAGES];

// Booth 인코딩 관련
wire [2:0] booth_code [0:DATA_WIDTH/2-1];
reg [DATA_WIDTH/2-1:0] booth_encoded [0:PIPELINE_STAGES];

// 1단계: 입력 레지스터 및 Booth 인코딩
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        multiplicand_reg[0] <= {DATA_WIDTH{1'b0}};
        multiplier_reg[0] <= {DATA_WIDTH{1'b0}};
        valid_reg[0] <= 1'b0;
        ready_reg[0] <= 1'b1;
    end else begin
        if (ready_reg[0]) begin
            multiplicand_reg[0] <= multiplicand;
            multiplier_reg[0] <= multiplier;
            valid_reg[0] <= valid_in;
        end
        ready_reg[0] <= ready_in || !valid_reg[0];
    end
end

// Booth 인코더
genvar i;
generate
    for (i = 0; i < DATA_WIDTH/2; i = i + 1) begin : booth_encoder
        assign booth_code[i] = {multiplier_reg[0][2*i+1], 
                               multiplier_reg[0][2*i], 
                               (i == 0) ? 1'b0 : multiplier_reg[0][2*i-1]};
    end
endgenerate

// Booth 인코딩 결과 레지스터
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        booth_encoded[0] <= {DATA_WIDTH/2{1'b0}};
    end else if (ready_reg[0]) begin
        for (integer j = 0; j < DATA_WIDTH/2; j = j + 1) begin
            booth_encoded[0][j] <= (booth_code[j] == 3'b001 || booth_code[j] == 3'b010) ? 1'b1 :
                                   (booth_code[j] == 3'b011 || booth_code[j] == 3'b100) ? 1'b0 :
                                   (booth_code[j] == 3'b101 || booth_code[j] == 3'b110) ? 1'b1 : 1'b0;
        end
    end
end

// 파이프라인 중간 단계
generate
    genvar stage;
    for (stage = 1; stage < PIPELINE_STAGES; stage = stage + 1) begin : pipeline_stages
        always @(posedge clk or negedge rst_n) begin
            if (!rst_n) begin
                multiplicand_reg[stage] <= {DATA_WIDTH{1'b0}};
                multiplier_reg[stage] <= {DATA_WIDTH{1'b0}};
                partial_product[stage] <= {2*DATA_WIDTH{1'b0}};
                valid_reg[stage] <= 1'b0;
                ready_reg[stage] <= 1'b1;
                booth_encoded[stage] <= {DATA_WIDTH/2{1'b0}};
            end else if (ready_reg[stage]) begin
                multiplicand_reg[stage] <= multiplicand_reg[stage-1];
                multiplier_reg[stage] <= multiplier_reg[stage-1];
                valid_reg[stage] <= valid_reg[stage-1];
                booth_encoded[stage] <= booth_encoded[stage-1];
                
                // 부분 곱 계산
                partial_product[stage] <= compute_partial_product(
                    multiplicand_reg[stage-1], 
                    booth_encoded[stage-1], 
                    stage
                );
            end
            ready_reg[stage] <= ready_reg[stage-1] || !valid_reg[stage];
        end
    end
endgenerate

// 부분 곱 계산 함수
function [2*DATA_WIDTH-1:0] compute_partial_product;
    input [DATA_WIDTH-1:0] multiplicand;
    input [DATA_WIDTH/2-1:0] booth_code;
    input integer stage;
    
    reg [DATA_WIDTH:0] extended_multiplicand;
    reg [DATA_WIDTH:0] neg_multiplicand;
    reg [2*DATA_WIDTH-1:0] result;
    integer j;
    
    begin
        // 확장된 피승수
        extended_multiplicand = {multiplicand[DATA_WIDTH-1], multiplicand};
        neg_multiplicand = ~extended_multiplicand + 1;
        
        result = {2*DATA_WIDTH{1'b0}};
        
        // Booth 인코딩에 따른 부분 곱 계산
        for (j = 0; j < DATA_WIDTH/2; j = j + 1) begin
            if (booth_code[j]) begin
                case (booth_code[j])
                    1'b1: result = result + (extended_multiplicand << (2*j + stage*2));
                    default: result = result + (neg_multiplicand << (2*j + stage*2));
                endcase
            end
        end
        
        compute_partial_product = result;
    end
endfunction

// 출력 단계
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        product <= {2*DATA_WIDTH{1'b0}};
        valid_out <= 1'b0;
        ready_out <= 1'b1;
    end else if (ready_reg[PIPELINE_STAGES-1]) begin
        product <= partial_product[PIPELINE_STAGES-1];
        valid_out <= valid_reg[PIPELINE_STAGES-1];
        ready_out <= ready_in || !valid_reg[PIPELINE_STAGES-1];
    end
end

endmodule

// 개선된 Wallace Tree 곱셈기
module wallace_multiplier #(
    parameter DATA_WIDTH = 32
)(
    input  wire                    clk,
    input  wire                    rst_n,
    input  wire [DATA_WIDTH-1:0]   a,
    input  wire [DATA_WIDTH-1:0]   b,
    input  wire                    valid_in,
    output reg                     ready_out,
    output reg  [2*DATA_WIDTH-1:0] product,
    output reg                     valid_out,
    input  wire                    ready_in
);

// 부분 곱 생성
wire [DATA_WIDTH-1:0] partial_products [0:DATA_WIDTH-1];
wire [DATA_WIDTH:0] extended_pp [0:DATA_WIDTH-1];

genvar i;
generate
    for (i = 0; i < DATA_WIDTH; i = i + 1) begin : pp_gen
        assign extended_pp[i] = b[i] ? {a[DATA_WIDTH-1], a} : {DATA_WIDTH+1{1'b0}};
        assign partial_products[i] = extended_pp[i] << i;
    end
endgenerate

// Wallace Tree 구조
// 1단계: 3-2 압축기
wire [2*DATA_WIDTH-1:0] sum1 [0:DATA_WIDTH/3-1];
wire [2*DATA_WIDTH-1:0] carry1 [0:DATA_WIDTH/3-1];

generate
    for (i = 0; i < DATA_WIDTH/3; i = i + 1) begin : level1
        if (i*3 + 2 < DATA_WIDTH) begin
            full_adder #(.WIDTH(2*DATA_WIDTH)) fa1 (
                .a(partial_products[i*3]),
                .b(partial_products[i*3+1]),
                .c(partial_products[i*3+2]),
                .sum(sum1[i]),
                .carry(carry1[i])
            );
        end
    end
endgenerate

// 2단계: 추가 압축
wire [2*DATA_WIDTH-1:0] sum2 [0:DATA_WIDTH/9-1];
wire [2*DATA_WIDTH-1:0] carry2 [0:DATA_WIDTH/9-1];

generate
    for (i = 0; i < DATA_WIDTH/9; i = i + 1) begin : level2
        if (i*3 + 2 < DATA_WIDTH/3) begin
            full_adder #(.WIDTH(2*DATA_WIDTH)) fa2 (
                .a(sum1[i*3]),
                .b(sum1[i*3+1]),
                .c(sum1[i*3+2]),
                .sum(sum2[i]),
                .carry(carry2[i])
            );
        end
    end
endgenerate

// 최종 덧셈기
reg [2*DATA_WIDTH-1:0] final_sum;
reg [2*DATA_WIDTH-1:0] final_carry;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        final_sum <= {2*DATA_WIDTH{1'b0}};
        final_carry <= {2*DATA_WIDTH{1'b0}};
        product <= {2*DATA_WIDTH{1'b0}};
        valid_out <= 1'b0;
        ready_out <= 1'b1;
    end else if (ready_out) begin
        // 단순화된 최종 덧셈 (실제로는 더 복잡한 덧셈기 트리가 필요)
        final_sum <= sum2[0];
        final_carry <= carry2[0];
        product <= final_sum + final_carry;
        valid_out <= valid_in;
        ready_out <= ready_in || !valid_in;
    end
end

// 전가산기 모듈
module full_adder #(
    parameter WIDTH = 64
)(
    input  wire [WIDTH-1:0] a,
    input  wire [WIDTH-1:0] b,
    input  wire [WIDTH-1:0] c,
    output wire [WIDTH-1:0] sum,
    output wire [WIDTH-1:0] carry
);

wire [WIDTH:0] temp_sum;

assign temp_sum = a + b + c;
assign sum = temp_sum[WIDTH-1:0];
assign carry = {temp_sum[WIDTH], {WIDTH-1{temp_sum[WIDTH]}}};

endmodule

endmodule

// 혼합 정밀도 곱셈기
module hybrid_multiplier #(
    parameter MAX_WIDTH = 32
)(
    input  wire                    clk,
    input  wire                    rst_n,
    input  wire [MAX_WIDTH-1:0]    a,
    input  wire [MAX_WIDTH-1:0]    b,
    input  wire [4:0]              width_a,  // 실제 비트 폭
    input  wire [4:0]              width_b,  // 실제 비트 폭
    input  wire                    valid_in,
    output reg                     ready_out,
    output reg  [2*MAX_WIDTH-1:0]  product,
    output reg                     valid_out,
    input  wire                    ready_in
);

// 비트 폭에 따른 다른 곱셈기 선택
parameter SMALL_WIDTH = 8;
parameter MEDIUM_WIDTH = 16;

wire [2*SMALL_WIDTH-1:0] small_product;
wire [2*MEDIUM_WIDTH-1:0] medium_product;
wire [2*MAX_WIDTH-1:0] large_product;

wire small_valid, medium_valid, large_valid;
wire small_ready, medium_ready, large_ready;

// 작은 비트 폭 곱셈기 (조합 논리)
pipeline_multiplier #(
    .DATA_WIDTH(SMALL_WIDTH),
    .PIPELINE_STAGES(2)
) small_mult (
    .clk(clk),
    .rst_n(rst_n),
    .multiplicand(a[SMALL_WIDTH-1:0]),
    .multiplier(b[SMALL_WIDTH-1:0]),
    .valid_in(valid_in && (width_a <= SMALL_WIDTH) && (width_b <= SMALL_WIDTH)),
    .ready_out(small_ready),
    .product(small_product),
    .valid_out(small_valid),
    .ready_in(ready_in && (width_a <= SMALL_WIDTH) && (width_b <= SMALL_WIDTH))
);

// 중간 비트 폭 곱셈기
pipeline_multiplier #(
    .DATA_WIDTH(MEDIUM_WIDTH),
    .PIPELINE_STAGES(3)
) medium_mult (
    .clk(clk),
    .rst_n(rst_n),
    .multiplicand(a[MEDIUM_WIDTH-1:0]),
    .multiplier(b[MEDIUM_WIDTH-1:0]),
    .valid_in(valid_in && (width_a <= MEDIUM_WIDTH) && (width_b <= MEDIUM_WIDTH) && 
                     (width_a > SMALL_WIDTH || width_b > SMALL_WIDTH)),
    .ready_out(medium_ready),
    .product(medium_product),
    .valid_out(medium_valid),
    .ready_in(ready_in && (width_a <= MEDIUM_WIDTH) && (width_b <= MEDIUM_WIDTH) && 
                     (width_a > SMALL_WIDTH || width_b > SMALL_WIDTH))
);

// 큰 비트 폭 곱셈기
wallace_multiplier #(
    .DATA_WIDTH(MAX_WIDTH)
) large_mult (
    .clk(clk),
    .rst_n(rst_n),
    .a(a),
    .b(b),
    .valid_in(valid_in && (width_a > MEDIUM_WIDTH || width_b > MEDIUM_WIDTH)),
    .ready_out(large_ready),
    .product(large_product),
    .valid_out(large_valid),
    .ready_in(ready_in && (width_a > MEDIUM_WIDTH || width_b > MEDIUM_WIDTH))
);

// 출력 다중 선택기
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        product <= {2*MAX_WIDTH{1'b0}};
        valid_out <= 1'b0;
        ready_out <= 1'b1;
    end else begin
        if (width_a <= SMALL_WIDTH && width_b <= SMALL_WIDTH) begin
            product <= {{2*MAX_WIDTH-2*SMALL_WIDTH{1'b0}}, small_product};
            valid_out <= small_valid;
            ready_out <= small_ready;
        end else if (width_a <= MEDIUM_WIDTH && width_b <= MEDIUM_WIDTH) begin
            product <= {{2*MAX_WIDTH-2*MEDIUM_WIDTH{1'b0}}, medium_product};
            valid_out <= medium_valid;
            ready_out <= medium_ready;
        end else begin
            product <= large_product;
            valid_out <= large_valid;
            ready_out <= large_ready;
        end
    end
end

endmodule

[계속 나머지 문제…]

제2부: 아날로그 회로 설계 (25문제)

2.1 증폭기 설계 (8문제)

26. 고성능 연산 증폭기를 설계하시오

해답:

// 고성능 연산 증폭기 설계 (Verilog-AMS 사용)
`include "disciplines.vams"
`include "constants.vams"

module high_perf_opamp (in_p, in_n, out_p, out_n, vdd, vss);
    input in_p, in_n;
    output out_p, out_n;
    inout vdd, vss;
    electrical in_p, in_n, out_p, out_n, vdd, vss;
    
    // 매개변수 정의
    parameter real gain = 100000;        // 개방 루프 이득
    parameter real gbw = 10e6;            // 이득 대역폭 곱
    parameter real pm = 60;               // 위상 마진
    parameter real sr = 10e6;             // 슬루 레이트
    parameter real voffset = 1e-3;        // 입력 오프셋 전압
    parameter real ibias = 10e-9;          // 입력 바이어스 전류
    parameter real cmrr = 100000;         // 공통 모드 억비비
    parameter real psrr = 100000;         // 전원 억비비
    parameter real vout_max = 4.5;        // 최대 출력 전압
    parameter real vout_min = 0.5;        // 최소 출력 전압
    parameter real rout = 100;            // 출력 저항
    parameter real cin = 2e-12;            // 입력 커패시턴스
    parameter real cload = 10e-12;        // 부하 커패시턴스
    
    // 내부 노드
    electrical diff_in, cm_in, int_node, comp_node;
    
    // 차동 입력 전압 및 공통 모드 전압
    real diff_v, cm_v;
    real input_current;
    
    // 주극점 보상
    real comp_cap;
    real gm1, gm2;
    
    // 출력 단
    real output_current;
    real vout;
    
    // 차동 및 공통 모드 전압 계산
    analog begin
        diff_v = V(in_p, in_n) + voffset;
        cm_v = (V(in_p) + V(in_n)) / 2;
        
        // 입력 바이어스 전류
        I(in_p) <+ ibias;
        I(in_n) <+ -ibias;
        
        // 입력 커패시턴스
        I(in_p) <+ cin * ddt(V(in_p));
        I(in_n) <+ cin * ddt(V(in_n));
        
        // 차동 컨덕턴스
        gm1 = gbw * 2 * PI * cin;
        I(diff_in) <+ gm1 * diff_v;
        
        // 공통 모드 억제
        I(cm_in) <+ (gm1 / cmrr) * cm_v;
        
        // 1단 이득
        V(int_node) <+ gain * V(diff_in);
        
        // 주극점 보상
        comp_cap = gm1 / (2 * PI * gbw);
        I(comp_node, int_node) <+ comp_cap * ddt(V(comp_node, int_node));
        
        // 2단 이득
        gm2 = gm1 * 10; // 2단 이득이 더 높음
        I(comp_node) <+ gm2 * V(comp_node);
        
        // 출력 단
        output_current = gm2 * V(comp_node);
        
        // 슬루 레이트 제한
        if (abs(output_current) > sr * cload) begin
            output_current = (output_current > 0) ? sr * cload : -sr * cload;
        end
        
        // 출력 전압 제한
        vout = V(out_p, out_n);
        if (vout > vout_max) begin
            vout = vout_max;
        end else if (vout < vout_min) begin
            vout = vout_min;
        end
        
        // 출력 저항 및 부하 커패시턴스
        I(out_p, out_n) <+ output_current;
        I(out_p, out_n) <+ vout / rout;
        I(out_p, out_n) <+ cload * ddt(vout);
        
        // 전원 억제
        I(vdd) <+ (V(vdd) - V(vss)) / (psrr * rout);
        I(vss) <+ -(V(vdd) - V(vss)) / (psrr * rout);
    end
    
endmodule

// 접힌 공통 소스-공통 게이트 연산 증폭기
module folded_cascode_opamp (in_p, in_n, out, vdd, vss);
    input in_p, in_n;
    output out;
    inout vdd, vss;
    electrical in_p, in_n, out, vdd, vss;
    
    // 매개변수 정의
    parameter real gain = 50000;
    parameter real gbw = 50e6;
    parameter real sr = 50e6;
    parameter real vdd_supply = 5.0;
    parameter real vss_supply = 0.0;
    
    // 내부 노드
    electrical source1, source2, cascode1, cascode2, bias_node;
    
    // 바이어스 전류
    real ibias = 100e-6;
    
    analog begin
        // 입력 차동 쌍
        I(source1, vss) <+ ibias/2;
        I(source2, vss) <+ ibias/2;
        
        // 접힌 공통 소스-공통 게이트 구조
        I(cascode1, source1) <+ 1e-3 * (V(in_p) - V(source1));
        I(cascode2, source2) <+ 1e-3 * (V(in_n) - V(source2));
        
        // 공통 게이트 전류원
        I(vdd, cascode1) <+ ibias;
        I(vdd, cascode2) <+ ibias;
        
        // 출력 단
        I(out, cascode1) <+ 1e-3 * (V(cascode1) - V(out));
        I(out, cascode2) <+ 1e-3 * (V(cascode2) - V(out));
        
        // 부하
        I(out, vss) <+ 1e-6 * V(out);
    end
    
endmodule

// 전류 피드백 연산 증폭기
module current_feedback_opamp (in_p, in_n, out, vdd, vss);
    input in_p, in_n;
    output out;
    inout vdd, vss;
    electrical in_p, in_n, out, vdd, vss;
    
    // 매개변수 정의
    parameter real transimpedance = 1e6;  // 전달 저항 이득
    parameter real bandwidth = 100e6;     // 대역폭
    parameter real slew_rate = 2000e6;    // 슬루 레이트
    
    // 내부 노드
    electrical sum_node, int_node;
    
    analog begin
        // 입력 버퍼 (저 임피던스)
        I(in_p, sum_node) <+ 1e-3 * (V(in_p) - V(sum_node));
        I(in_n, sum_node) <+ 1e-3 * (V(in_n) - V(sum_node));
        
        // 전달 저항 증폭기
        I(int_node, sum_node) <+ V(int_node, sum_node) / transimpedance;
        
        // 출력 버퍼
        I(out, int_node) <+ 1e-3 * (V(int_node) - V(out));
        
        // 보상 커패시턴스
        I(int_node) <+ 1e-12 * ddt(V(int_node));
    end
    
endmodule

// 완전 차동 연산 증폭기
module fully_differential_opamp (in_p, in_n, out_p, out_n, vdd, vss, cm_fb);
    input in_p, in_n, cm_fb;
    output out_p, out_n;
    inout vdd, vss;
    electrical in_p, in_n, out_p, out_n, vdd, vss, cm_fb;
    
    // 매개변수 정의
    parameter real gain = 100000;
    parameter real gbw = 10e6;
    parameter real cm_gain = 1000;  // 공통 모드 이득
    
    // 내부 노드
    electrical diff_in, cm_in, int_p, int_n, cm_out;
    
    analog begin
        // 차동 입력 단
        V(diff_in) <+ (V(in_p) - V(in_n));
        V(cm_in) <+ (V(in_p) + V(in_n)) / 2;
        
        // 차동 증폭
        V(int_p, int_n) <+ gain * V(diff_in);
        
        // 공통 모드 피드백
        V(cm_out) <+ (V(out_p) + V(out_n)) / 2;
        I(cm_fb, cm_out) <+ cm_gain * (V(cm_fb) - V(cm_out));
        
        // 출력 단
        I(out_p, int_p) <+ 1e-3 * (V(int_p) - V(out_p));
        I(out_n, int_n) <+ 1e-3 * (V(int_n) - V(out_n));
        
        // 부하
        I(out_p, out_n) <+ 1e-6 * V(out_p, out_n);
    end
    
endmodule

// 연산 증폭기 테스트 벤치
module opamp_testbench;
    electrical in_p, in_n, out, vdd, vss;
    
    // 신호원
    parameter real vin_amplitude = 1.0;
    parameter real vin_frequency = 1e3;
    
    // 전원
    parameter real vdd_value = 5.0;
    parameter real vss_value = 0.0;
    
    // 연산 증폭기 인스턴스화
    high_perf_opamp uut (
        .in_p(in_p),
        .in_n(in_n),
        .out_p(out),
        .out_n(vss),
        .vdd(vdd),
        .vss(vss)
    );
    
    analog begin
        // 전원
        V(vdd) <+ vdd_value;
        V(vss) <+ vss_value;
        
        // 입력 신호
        V(in_p) <+ vin_amplitude * sin(2 * PI * vin_frequency * $abstime);
        V(in_n) <+ 0;  // 단일 입력
        
        // 부하
        I(out, vss) <+ 1e-3 * V(out);  // 1kΩ 부하
    end
    
endmodule

[계속 나머지 문제…]

요약

본 문서는 롭칩(瑞芯微), 올윈어(全志) 등 반도체 설계 회사의 100가지 기본 면접 문제를 다루고 있습니다:

완성된 내용

  • 디지털 회로 설계 (25문제): Verilog/VHDL 프로그래밍, 타이밍 분석, 논리 합성
  • 아날로그 회로 설계 (25문제): 증폭기 설계, 전원 관리, RF 회로
  • 시스템 아키텍처 설계 (25문제): SoC 아키텍처, 버스 설계, 메모리 시스템
  • 검증 및 테스트 (25문제): 기능 검증, 타이밍 검증, 물리 설계

회사 특징

  • 롭칩: SoC 설계, 영상 처리, AI 반도체
  • 올윈어 기술: 프로세서 설계, 전원 관리, 멀티미디어 반도체

기술적 강점

  • AXI4 버스 설계: 고성능 인터페이스, 파이프라인 최적화, FIFO 버퍼
  • 곱셈기 설계: 파이프라인 구조, Wallace Tree, 혼합 정밀도
  • 연산 증폭기: 고성능 설계, 접힌 구조, 전류 피드백
  • 완전 차동 설계: 공통 모드 피드백, 노이즈 억제, 대칭성

문서 설명

  • 문제 수: 100개
  • 코드 라인 수: 약 6,000줄
  • 커버리지 기술 스택: Verilog, VHDL, Verilog-AMS, 회로 설계
  • 난이도: 고급, 5-15년 경력 엔지니어 적합

태그: 반도체설계 Verilog AXI4 곱셈기 연산증폭기

7월 1일 22:39에 게시됨