[AMBA] AXI Protocol 설계(Verilog) - ① Signal Descriptions
이번에는 Verilog로 AXI Protocol의 동작을 확인해보려고 합니다.
ARM사의 AMBA AXI datasheet를 참고했습니다.
AXI는 말 그대로 Interface이기 때문에 실체라고 할게 딱히 없습니다.
Master와 Slave를 연결하는 Bus의 규격을 ARM에서 정해놓은 것인데요,
저와 같은 학부생들은 Master와 Slave를 구하기 어렵습니다.
BFM(Bus Functional Model)을 짜서 Bus의 동작을 시뮬레이션해도 되지만
그건 조금 어려워서 아직 공부 중 입니다.
그래서 제멋대로 AXI Slave를 Verilog로 짜보겠습니다.
목적은 오로지 AMBA를 복습하고 기능을 직접 확인해보기 위함입니다!
오늘은 Master가 전송하는 신호를 Testbench에서 직접 넣어주도록 하겠습니다.
Slave는 임의로 delay를 주는 방식을 이용해 간단하게 만들어보겠습니다.
물론 합성은 불가능합니다.
I/O Signal이 담긴 Block Diagram 입니다.
Block Diagram
- Write Address Channel
- Write Data Channel
- Write Response Channel
- Read Address Channel
- Read Response Channel
AXI는 5개의 독립된 channel을 가지고 있습니다.
그래서 5개를 나눠서 표시하였습니다.
Slave 안에 memory를 할당해주어서 데이터를 읽고 쓰도록 설계할 예정입니다.
Verilog Code
Clock
input i_clk,
input i_resetn,
Write Address Channel
input [3:0] i_awid,
input [7:0] i_awaddr,
input [3:0] i_awlen,
input [2:0] i_awsize,
input [1:0] i_awburst,
input i_awvalid,
output reg o_awready,
Write Data Channel
input [3:0] i_wid,
input [15:0] i_wdata,
input i_wlast,
input i_wvalid,
output reg o_wready,
Write Response Channel
input i_bready,
output reg [3:0] o_bid,
output reg [1:0] o_bresp,
output reg o_bvalid,
Read Address Channel
input [3:0] i_arid,
input [7:0] i_araddr,
input [3:0] i_arlen,
input [2:0] i_arsize,
input [1:0] i_arburst,
input i_arvalid,
output reg o_arready,
Read Data Channel
input i_rready,
output reg [3:0] o_rid,
output reg [15:0] o_rdata,
output reg o_rlast,
output reg o_rvalid,
output reg [1:0] o_rresp,
Test용 Signal
input test_awready,
input test_wready,
input [1:0] test_bresp,
input test_arready
여기 신호들은 Slave의 동작을 위한 것 입니다.
임의로 만든 Slave는 별 다른 기능을 하지 않기 때문에 항상 ready 상태입니다.
handshake를 확인하기 위해 ready와 busy 상태를 번갈아가며 사용하였습니다.
Register
reg [7:0] r_waddr;
reg [3:0] r_wburstn;
reg [15:0] r_wdata;
reg r_wlast;
reg r_waddr_on;
reg r_wdata_on;
reg [4:0] awlen_cnt;
reg [15:0] mem [0:15];
여기 보이는 레지스터들은 handshake가 되었을 때,
Master에서 받은 신호를 저장할 곳 입니다.
지금은 하나씩만 만들었는데 FIFO 등을 이용해 여러 값을 보관할 수 있습니다.
메모리는 시뮬레이션을 편하게 보려고 작게 만들었습니다.
Wire
wire aw_handshake = i_awvalid && o_awready;
wire w_handshake = i_wvalid && o_wready;
wire b_handshake = i_bready && o_bvalid;
wire ar_handshake = i_arvalid && o_arready;
wire r_handshake = i_rready && o_rvalid;
wire로 handshake 구간을 표시해두면 waveform에서 더 빠르게 찾아 볼 수 있습니다.