Home CONNECT Note (3) - AXI4 Interface
Post
Cancel

CONNECT Note (3) - AXI4 Interface

Source code: link.

AXI Requests & Responses In Flits

Signals in 5 channels are encapsulated in flit data, with following parameters.

1
2
3
4
5
parameter ADDR_WIDTH   = 32;
parameter DATA_WIDTH   = 64;
parameter STRB_WIDTH   = DATA_WIDTH / 8;
parameter ID_WIDTH     = 8;
parameter USER_WIDTH   = 8;

LSBs of AxID indicates the sender. LSBs of AxADDR indicates the target receiver.

connect_parameters.v is modified according to the given configurations.

1
2
3
4
5
`define NUM_USER_SEND_PORTS 4
`define NUM_USER_RECV_PORTS 4
`define NUM_VCS 2
`define FLIT_DATA_WIDTH 92
`define FLIT_WIDTH (`FLIT_DATA_WIDTH + 5)

AW/AR Channel

1
2
3
4
5
6
7
8
9
10
11
12
13
channel   - [91 : 89]  # aw = 3'b001, ar = 3'b010
axuser    - [88 : 81]
axid      - [80 : 73]
------ padding ------
axlen     - [60 : 53]
axsize    - [52 : 50]
axburst   - [49 : 48]
axlock    - [47 : 47]
axcache   - [46 : 43]
axprot    - [42 : 40]
axqos     - [39 : 36]
axregion  - [35 : 32]
axaddr    - [31 :  0]

Updated on 06/10, we need to unify AXI4-Stream and AXI4 id/user field.

1
2
3
4
5
6
7
8
9
10
11
12
13
channel   - [91 : 89]  # r = 3'b110
------ padding ------
axlen     - [76 : 69]
axsize    - [68 : 66]
axburst   - [65 : 64]
axlock    - [63 : 63]
axcache   - [62 : 59]
axprot    - [58 : 56]
axqos     - [55 : 52]
axregion  - [51 : 48]
axaddr    - [47 : 16]
axuser    - [15 :  8]
axid      - [ 7 :  0]

W Channel

1
2
3
4
5
6
channel   - [91 : 89]  # w = 3'b011
wuser     - [88 : 81]
wid       - [80 : 73]
wlast     - [72 : 72]
wstrb     - [71 : 64]
wdata     - [63 :  0]

Updated on 06/10, we need to unify AXI4-Stream and AXI4 id/user field.

1
2
3
4
5
6
channel   - [91 : 89]  # r = 3'b110
wlast     - [88 : 88]
wstrb     - [87 : 80]
wdata     - [79 : 16]
wuser     - [15 :  8]
wid       - [ 7 :  0]

B Channel

1
2
3
4
5
6
channel   - [91 : 89]  # b = 3'b101
buser     - [88 : 81]
bid       - [80 : 73]
------ padding ------
bresp     - [65 : 64]
------ padding ------

Updated on 06/10, we need to unify AXI4-Stream and AXI4 id/user field.

1
2
3
4
5
6
channel   - [91 : 89]  # r = 3'b110
------ padding ------
bresp     - [81 : 80]
------ padding ------
buser     - [15 :  8]
bid       - [ 7 :  0]

R Channel

1
2
3
4
5
6
7
channel   - [91 : 89]  # r = 3'b110
ruser     - [88 : 81]
rid       - [80 : 73]
rlast     - [72 : 72]
------ padding ------
rresp     - [65 : 64]
rdata     - [63 :  0]

Updated on 06/10, we need to unify AXI4-Stream and AXI4 id/user field.

1
2
3
4
5
6
7
channel   - [91 : 89]  # r = 3'b110
rlast     - [88 : 88]
------ padding ------
rresp     - [81 : 80]
rdata     - [79 : 16]
ruser     - [15 :  8]
rid       - [ 7 :  0]

Bridge Design

A bridge is used to convert a pair of send & recv port to a standard AXI protocol interface, either as a master device or a slave device. For example, for a network with 4 endpoints, we can have 2 master devices and 2 slave devices.

Peek flow control is used in current version.

FSM of Master Bridge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
always_comb begin
  case (state)
    IDLE: begin
      if (aw_fire)
        next_state = WDATA;
      else if (ar_fire)
        next_state = RDATA1;
      else
        next_state = state;
    end
    WDATA: begin
      if (w_fire && axi.wlast)
        next_state = WRESP1;
      else
        next_state = state;
    end
    WRESP1: begin
      if (get_flit[`FLIT_WIDTH - 1]) // flit is valid
        next_state = WRESP2;
      else
        next_state = state;
    end
    WRESP2: begin
      if (b_fire)
        next_state = IDLE;
      else
        next_state = state;
    end
    RDATA1: begin
      if (get_flit[`FLIT_WIDTH - 1]) // flit is valid
        next_state = RDATA2;
      else
        next_state = state;
    end
    RDATA2: begin
      if (r_fire) begin
        if (axi.rlast)
          next_state = IDLE;
        else
          next_state = RDATA1;
      end else
        next_state = state;
    end
    default: next_state = state;
  endcase
end

FSM of Slave Bridge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
always_comb begin
  case (state)
    IDLE: begin
      if (get_flit[`FLIT_WIDTH - 1]) begin // flit is valid
        if (get_flit[`FLIT_DATA_WIDTH - 1 : `FLIT_DATA_WIDTH - 3] == CHANNEL_AW)
          next_state = WADDR;
        else if (get_flit[`FLIT_DATA_WIDTH - 1 : `FLIT_DATA_WIDTH - 3] == CHANNEL_AR)
          next_state = RADDR;
        else
          next_state = state;
      end else
        next_state = state;
    end
    WADDR: begin
      if (aw_fire)
        next_state = WDATA1;
      else
        next_state = state;
    end
    WDATA1: begin
      if (get_flit[`FLIT_WIDTH - 1]) // flit is valid
        next_state = WDATA2;
      else
        next_state = state;
    end
    WDATA2: begin
      if (w_fire) begin
        if (axi.wlast)
          next_state = WRESP;
        else
          next_state = WDATA1;
      end else
        next_state = state;
    end
    WRESP: begin
      if (b_fire)
        next_state = IDLE;
      else
        next_state = state;
    end
    RADDR: begin
      if (ar_fire)
        next_state = RDATA;
      else
        next_state = state;
    end
    RDATA: begin
      if (r_fire) begin
        if (axi.rlast)
          next_state = IDLE;
        else
          next_state = RDATA;
      end else
        next_state = state;
    end
    default: next_state = state;
  endcase
end

Test

We create a master device and a slave device to send or receive data. See AXI4Device.sv for example device modules and testbench_sample_peek_axi4.sv for test bench.

Results

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# ---- Performing Reset ----
#     9: Port 0 send flit 1c2000000006d000000000002
#     9: [m0-aw] addr=00000002
#    10: Port 0 send flit 1c60000ffdeadbeefdeadbeef
#    10: Port 1 send flit 1e4000200006d000000000003
#    10: [m0- w] data=deadbeefdeadbeef
#    10: [m1-ar] addr=00000003
#    11: Port 0 send flit 1c60000ffdeadbeefdeadbef0
#    11: [m0- w] data=deadbeefdeadbef0
#    12: Port 0 send flit 1c60000ffdeadbeefdeadbef1
#    12: Port 2 recv flit 1c2000000006d000000000002
#    12: [m0- w] data=deadbeefdeadbef1
#    13: Port 0 send flit 1c60000ffdeadbeefdeadbef2
#    13: [m0- w] data=deadbeefdeadbef2
#    14: Port 0 send flit 1c60001ffdeadbeefdeadbef3
#    14: Port 3 recv flit 1e4000200006d000000000003
#    14: [m0- w] data=deadbeefdeadbef3
#    14: [s0-aw] addr=00000002
#    15: Port 2 recv flit 1c60000ffdeadbeefdeadbeef
#    16: [s0- w] data=deadbeefdeadbeef
#    16: [s1-ar] addr=00000003
#    17: Port 3 send flit 1ac000000deadbeefdeadbeef
#    17: Port 2 recv flit 1c60000ffdeadbeefdeadbef0
#    17: [s1- r] data=deadbeefdeadbeef
#    18: Port 3 send flit 1ac000000deadbeefdeadbef0
#    18: [s0- w] data=deadbeefdeadbef0
#    18: [s1- r] data=deadbeefdeadbef0
#    19: Port 3 send flit 1ac000000deadbeefdeadbef1
#    19: Port 2 recv flit 1c60000ffdeadbeefdeadbef1
#    19: [s1- r] data=deadbeefdeadbef1
#    20: Port 3 send flit 1ac000100deadbeefdeadbef2
#    20: Port 1 recv flit 1ac000000deadbeefdeadbeef
#    20: [s0- w] data=deadbeefdeadbef1
#    20: [s1- r] data=deadbeefdeadbef2
#    21: Port 2 recv flit 1c60000ffdeadbeefdeadbef2
#    21: [m1- r] data=deadbeefdeadbeef
#    22: Port 1 recv flit 1ac000000deadbeefdeadbef0
#    22: [s0- w] data=deadbeefdeadbef2
#    23: Port 2 recv flit 1c60001ffdeadbeefdeadbef3
#    23: [m1- r] data=deadbeefdeadbef0
#    24: Port 1 recv flit 1ac000000deadbeefdeadbef1
#    24: [s0- w] data=deadbeefdeadbef3
#    25: Port 2 send flit 18a0000000000000000000000
#    25: [m1- r] data=deadbeefdeadbef1
#    25: [s0- b]
#    26: Port 1 recv flit 1ac000100deadbeefdeadbef2
#    27: [m1- r] data=deadbeefdeadbef2
#    28: Port 0 recv flit 18a0000000000000000000000
#    29: [m0- b]
# actual:deadbeefdeadbeef expected:deadbeefdeadbeef
# 
# actual:deadbeefdeadbef0 expected:deadbeefdeadbef0
# 
# actual:deadbeefdeadbef1 expected:deadbeefdeadbef1
# 
# actual:deadbeefdeadbef2 expected:deadbeefdeadbef2
# 
# Pass
# actual:deadbeefdeadbeef expected:deadbeefdeadbeef
# 
# actual:deadbeefdeadbef0 expected:deadbeefdeadbef0
# 
# actual:deadbeefdeadbef1 expected:deadbeefdeadbef1
# 
# actual:deadbeefdeadbef2 expected:deadbeefdeadbef2
# 
# Pass
This post is licensed under CC BY 4.0 by the author.