본문 바로가기

주의!!! 코드는 아직 검증되기 전입니다. 전체적인 구조를 잡기 위해 올려두는 부분이니 그대로 활용이 불가합니다.

AXI 슬레이브 모듈을 설계할 때, 이 모듈은 마스터로부터의 쓰기 및 읽기 요청을 수용하고 처리할 수 있어야 합니다. 여기서는 쓰기 요청을 받아 메모리에 데이터를 저장하는 간단한 슬레이브 모듈을 구현해 보겠습니다. 슬레이브 모듈은 AXI 프로토콜의 응답 메커니즘을 활용하여 마스터에게 쓰기 완료 신호를 보내야 합니다.

다음은 SystemVerilog를 사용한 AXI 슬레이브 모듈의 기본 구현입니다:
슬레이브 모듈의 코드를 수정하여 리셋 시 모든 상태 및 신호를 초기화하고, 주요 동작 시점에서 $display 디버깅 메시지를 추가하겠습니다. 이는 동작을 명확히 추적하고 초기 상태에서 'X'값이 발생하지 않도록 보장합니다.

수정된 AXI 슬레이브 모듈 (axi_slave.sv)

module axi_slave #(
  parameter ADDR_WIDTH = 32,
  parameter DATA_WIDTH = 128,
  parameter MEM_DEPTH = 256  // 메모리 깊이
)(
  input wire aclk,
  input wire aresetn,
  interface axi_if
);

  // 메모리 배열
  reg [DATA_WIDTH-1:0] memory [0:MEM_DEPTH-1];

  // 쓰기 작업 처리를 위한 상태 머신
  typedef enum {IDLE, WRITE, WRITE_RESPONSE} slave_state_t;
  slave_state_t state = IDLE;

  // 상태 머신 및 신호 처리
  always @(posedge aclk) begin
    if (!aresetn) begin
      // 리셋 동작: 모든 제어 신호를 초기 상태로 설정
      state <= IDLE;
      axi_if.awready <= 1'b0;
      axi_if.wready <= 1'b0;
      axi_if.bvalid <= 1'b0;
      axi_if.bresp <= 2'b00; // 초기 응답 상태는 OKAY로 설정
      $display("AXI Slave: Reset state. All control signals are cleared.");
    end else begin
      case (state)
        IDLE: begin
          if (axi_if.awvalid && !axi_if.awready) begin
            axi_if.awready <= 1'b1; // 주소 수락
            $display("AXI Slave: Address accepted. Addr=%h", axi_if.awaddr);
            state <= WRITE;
          end
          if (axi_if.wvalid && !axi_if.wready) begin
            axi_if.wready <= 1'b1; // 데이터 수락 준비
          end
        end
        WRITE: begin
          if (axi_if.wvalid && axi_if.wready) begin
            memory[axi_if.awaddr >> 4] <= axi_if.wdata; // 메모리에 데이터 쓰기
            axi_if.wready <= 1'b0;
            axi_if.awready <= 1'b0;
            state <= WRITE_RESPONSE;
            $display("AXI Slave: Data written to memory at index %d. Data=%h", axi_if.awaddr >> 4, axi_if.wdata);
          end
        end
        WRITE_RESPONSE: begin
          axi_if.bresp <= 2'b00; // OKAY 응답
          axi_if.bvalid <= 1'b1;
          if (axi_if.bready && axi_if.bvalid) begin
            axi_if.bvalid <= 1'b0;
            state <= IDLE;
            $display("AXI Slave: Write response sent.");
          end
        end
        default: state <= IDLE;
      endcase
    end
  end
endmodule

위 코드는 다음과 같은 기능을 제공합니다:

설명

  1. 메모리 배열: 슬레이브는 내부적으로 데이터를 저장할 수 있는 메모리 배열을 가집니다. 메모리의 깊이는 파라미터를 통해 조정할 수 있습니다.
  2. 상태 머신: 슬레이브는 주소를 수신하고, 데이터를 받아 메모리에 저장한 후 응답을 반환하는 상태 머신을 갖고 있습니다.
  3. AXI 프로토콜 처리: 각 상태에 따라 AXI 인터페이스를 통해 신호를 받고 보내며, 모든 AXI 트랜잭션의 요구 사항을 충족시킵니다.
  • 리셋 동작: 모든 제어 신호를 안전한 초기값으로 설정하여 리셋 시 'X' 상태를 방지합니다.
  • 상태 머신: 슬레이브의 동작을 관리하기 위한 상태 머신을 통해 주소를 수신하고 데이터를 메모리에 기록한 다음, 응답을 보냅니다.
  • $display 문: 주요 동작 시점에서 디버깅 정보를 출력하여 시뮬레이션을 추적할 수 있습니다.

이러한 변경을 통해 슬레이브 모듈이 보다 안정적으로 동작하고, 시뮬레이션 중에 이벤트를 쉽게 추적할 수 있습니다.
이 모듈은 기본적인 쓰기 작업만을 처리하도록 설계되었으며, 필요에 따라 읽기 작업 및 추가 기능을 포함시킬 수 있습니다. 이 슬레이브 모듈은 마스터 모듈과 함께 사용하여 AXI 통신을 테스트하고 검증하는 데 사용할 수 있습니다.

B로그0간

개발 관련 글과 유용한 정보를 공유하는 공간입니다.