Skip to content

Commit

Permalink
AXI4-Stream
Browse files Browse the repository at this point in the history
  • Loading branch information
shili2017 committed Jun 8, 2022
1 parent 385cf90 commit 816bc83
Show file tree
Hide file tree
Showing 8 changed files with 1,041 additions and 1 deletion.
38 changes: 38 additions & 0 deletions Prims/AXI4Interface.sv
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,41 @@ interface axi_interface;
);

endinterface

interface axi_stream_interface;

axi_data_t tdata;
axi_strb_t tstrb;
axi_keep_t tkeep;
logic tlast;
axi_id_t tid;
axi_dest_t tdest;
axi_user_t tuser;
logic tvalid;
logic tready;

modport master (
output tdata,
output tstrb,
output tkeep,
output tlast,
output tid,
output tdest,
output tuser,
output tvalid,
input tready
);

modport slave (
input tdata,
input tstrb,
input tkeep,
input tlast,
input tid,
input tdest,
input tuser,
input tvalid,
output tready
);

endinterface
5 changes: 5 additions & 0 deletions Prims/AXI4Package.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ parameter DATA_WIDTH = 64;
parameter STRB_WIDTH = DATA_WIDTH / 8;
parameter ID_WIDTH = 8;
parameter USER_WIDTH = 8;
parameter KEEP_WIDTH = DATA_WIDTH / 8; // AXI4-Stream
parameter DEST_WIDTH = 4; // AXI4-Stream

parameter AXSIZE_1 = 3'b000;
parameter AXSIZE_2 = 3'b001;
Expand Down Expand Up @@ -38,6 +40,9 @@ typedef logic [3 : 0] axi_qos_t;
typedef logic [3 : 0] axi_region_t;
typedef logic [USER_WIDTH - 1 : 0] axi_user_t;

typedef logic [KEEP_WIDTH - 1 : 0] axi_keep_t; // AXI4-Stream
typedef logic [DEST_WIDTH - 1 : 0] axi_dest_t; // AXI4-Stream

parameter CHANNEL_AW = 3'b001;
parameter CHANNEL_W = 3'b011;
parameter CHANNEL_B = 3'b101;
Expand Down
161 changes: 161 additions & 0 deletions Prims/AXI4StreamBridge.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
`include "connect_parameters.v"

import axi4_pkg::*;

module AXI4StreamMasterBridge (
input CLK,
input RST_N,

// AXI4-Stream interface
axi_stream_interface.slave axis,

// InPortSimple send port
output [`FLIT_WIDTH - 1 : 0] put_flit,
output put_flit_valid,
input put_flit_ready
);

// State definitions
typedef enum logic [1 : 0] {IDLE, TDATA} state_t;
state_t state, next_state;

always_ff @(posedge CLK) begin
if (!RST_N)
state <= IDLE;
else
state <= next_state;
end

// Fire signals
wire t_fire = axis.tvalid && axis.tready;

assign axis.tready = put_flit_ready;

// FSM to handle AXI4-Stream master device request
always_comb begin
case (state)
IDLE: next_state = t_fire ? TDATA : IDLE;
TDATA: next_state = (t_fire && axis.tlast) ? IDLE : TDATA;
default: next_state = state;
endcase
end

// put_flit
logic [`FLIT_DATA_WIDTH - 1 : 0] put_flit_data;
logic [1 : 0] put_flit_dst;
logic put_flit_tail;

// InPortSimple output signal, use VC 0
assign put_flit = {put_flit_valid, put_flit_tail, put_flit_dst, 1'b1, put_flit_data};
assign put_flit_data = {axis.tuser, axis.tdest, axis.tid, axis.tlast, axis.tkeep, axis.tstrb, axis.tdata};
assign put_flit_dst = axis.tdest[1 : 0];
assign put_flit_tail = t_fire && axis.tlast;
assign put_flit_valid = t_fire;

// Debug
axi_data_t axis_tdata;
assign axis_tdata = axis.tdata;
axi_strb_t axis_tstrb;
assign axis_tstrb = axis.tstrb;
axi_keep_t axis_tkeep;
assign axis_tkeep = axis.tkeep;
logic axis_tlast;
assign axis_tlast = axis.tlast;
axi_id_t axis_tid;
assign axis_tid = axis.tid;
axi_dest_t axis_tdest;
assign axis_tdest = axis.tdest;
axi_user_t axis_tuser;
assign axis_tuser = axis.tuser;
logic axis_tvalid;
assign axis_tvalid = axis.tvalid;
logic axis_tready;
assign axis_tready = axis.tready;

endmodule

module AXI4StreamSlaveBridge (
input CLK,
input RST_N,

// AXI4 interface
axi_stream_interface.master axis,

// OutPortSimple recv port
input [`FLIT_WIDTH - 1 : 0] get_flit,
input get_flit_valid,
output get_flit_ready
);

// State definitions
typedef enum logic [1 : 0] {IDLE, TDATA} state_t;
state_t state, next_state;

always @(posedge CLK) begin
if (!RST_N)
state <= IDLE;
else
state <= next_state;
end

// Fire signals
wire t_fire = axis.tvalid && axis.tready;

// Flit register
reg [`FLIT_WIDTH - 1 : 0] get_flit_reg;
wire get_flit_reg_valid = get_flit_reg[`FLIT_WIDTH - 1];
wire get_flit_reg_is_tail = get_flit_reg[`FLIT_WIDTH - 2];
wire [1 : 0] get_flit_reg_dst = get_flit_reg[`FLIT_WIDTH - 3 : `FLIT_WIDTH - 4];
wire get_flit_reg_vc = get_flit_reg[`FLIT_WIDTH - 5];
wire [`FLIT_DATA_WIDTH - 1 : 0] get_flit_reg_data = get_flit_reg[`FLIT_DATA_WIDTH - 1 : 0];

always @(posedge CLK) begin
if (!RST_N) begin
get_flit_reg <= 0;
end else if (get_flit_ready) begin
get_flit_reg <= get_flit;
end
end

// FSM to handle AXI4-Stream slave device status
always_comb begin
case (state)
IDLE: next_state = get_flit_valid ? TDATA : IDLE;
TDATA: next_state = t_fire ? IDLE : TDATA;
default: next_state = state;
endcase
end

assign axis.tuser = get_flit_reg_data[100 : 93];
assign axis.tdest = get_flit_reg_data[92 : 89];
assign axis.tid = get_flit_reg_data[88 : 81];
assign axis.tlast = get_flit_reg_data[80];
assign axis.tkeep = get_flit_reg_data[79 : 72];
assign axis.tstrb = get_flit_reg_data[71 : 64];
assign axis.tdata = get_flit_reg_data[63 : 0];
assign axis.tvalid = (state == TDATA);

// OutPortSimple output signal
assign get_flit_ready = (state == IDLE);

// Debug
axi_data_t axis_tdata;
assign axis_tdata = axis.tdata;
axi_strb_t axis_tstrb;
assign axis_tstrb = axis.tstrb;
axi_keep_t axis_tkeep;
assign axis_tkeep = axis.tkeep;
logic axis_tlast;
assign axis_tlast = axis.tlast;
axi_id_t axis_tid;
assign axis_tid = axis.tid;
axi_dest_t axis_tdest;
assign axis_tdest = axis.tdest;
axi_user_t axis_tuser;
assign axis_tuser = axis.tuser;
logic axis_tvalid;
assign axis_tvalid = axis.tvalid;
logic axis_tready;
assign axis_tready = axis.tready;

endmodule
150 changes: 150 additions & 0 deletions Prims/AXI4StreamDevice.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import axi4_pkg::*;

module AXI4StreamMasterDevice #(parameter ID = 0) (
input CLK,
input RST_N,
axi_stream_interface.master axis,
input logic start,
input axi_dest_t dest
);

typedef enum logic [1 : 0] {IDLE, TDATA} state_type;
state_type state, next_state;

localparam LEN = 24;

axi_data_t data = 64'hdeadbeef00000000;
axi_len_t len_cnt;
logic start_delay;

assign axis.tdata = data + len_cnt;
assign axis.tstrb = 8'hff;
assign axis.tkeep = 8'hff;
assign axis.tlast = (state == TDATA && len_cnt == LEN - 1);
assign axis.tid = ID;
assign axis.tdest = dest;
assign axis.tuser = 0;
assign axis.tvalid = (state == TDATA);

always_ff @(posedge CLK) begin
if (~RST_N) begin
len_cnt <= 0;
end else begin
if (state == TDATA && axis.tvalid && axis.tready)
len_cnt <= len_cnt + 1;
end
end

always_ff @(posedge CLK) begin
if (~RST_N) begin
start_delay <= 0;
end else begin
start_delay <= start;
end
end

always_comb begin
case (state)
IDLE : next_state = (start_delay) ? TDATA : IDLE;
TDATA: next_state = (axis.tvalid && axis.tready && axis.tlast) ? IDLE : TDATA;
default: next_state = IDLE;
endcase
end

always_ff @(posedge CLK) begin
if (!RST_N) begin
state <= IDLE;
end else begin
state <= next_state;
end
end

// Debug
axi_data_t axis_tdata;
assign axis_tdata = axis.tdata;
axi_strb_t axis_tstrb;
assign axis_tstrb = axis.tstrb;
axi_keep_t axis_tkeep;
assign axis_tkeep = axis.tkeep;
logic axis_tlast;
assign axis_tlast = axis.tlast;
axi_id_t axis_tid;
assign axis_tid = axis.tid;
axi_dest_t axis_tdest;
assign axis_tdest = axis.tdest;
axi_user_t axis_tuser;
assign axis_tuser = axis.tuser;
logic axis_tvalid;
assign axis_tvalid = axis.tvalid;
logic axis_tready;
assign axis_tready = axis.tready;

endmodule

module AXI4StreamSlaveDevice (
input CLK,
input RST_N,
axi_stream_interface.slave axis
);

typedef enum logic [2 : 0] {IDLE, TDATA} state_type;
state_type state, next_state;

axi_dest_t dest;
axi_len_t len_cnt;

axi_data_t buffer[0 : 32];

assign axis.tready = 1;

always_ff @(posedge CLK) begin
if (!RST_N) begin
len_cnt <= 0;
for (int i = 0; i < 32; i++) begin
buffer[i] = 0;
end
end else begin
if (axis.tvalid && axis.tready) begin
len_cnt <= len_cnt + 1;
buffer[len_cnt] <= axis.tdata;
end
end
end

always_comb begin
case (state)
IDLE : next_state = (axis.tvalid) ? TDATA : IDLE;
TDATA: next_state = (axis.tvalid && axis.tready && axis.tlast) ? IDLE : TDATA;
default: next_state = IDLE;
endcase
end

always_ff @(posedge CLK) begin
if (!RST_N) begin
state <= IDLE;
end else begin
state <= next_state;
end
end

// Debug
axi_data_t axis_tdata;
assign axis_tdata = axis.tdata;
axi_strb_t axis_tstrb;
assign axis_tstrb = axis.tstrb;
axi_keep_t axis_tkeep;
assign axis_tkeep = axis.tkeep;
logic axis_tlast;
assign axis_tlast = axis.tlast;
axi_id_t axis_tid;
assign axis_tid = axis.tid;
axi_dest_t axis_tdest;
assign axis_tdest = axis.tdest;
axi_user_t axis_tuser;
assign axis_tuser = axis.tuser;
logic axis_tvalid;
assign axis_tvalid = axis.tvalid;
logic axis_tready;
assign axis_tready = axis.tready;

endmodule
2 changes: 1 addition & 1 deletion Prims/FlitFIFO.sv
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ module InPortFIFO (

assign deq_ready = (credit_counter != 0);
assign send_ports_putFlit_flit_in = {EN_send_ports_putFlit, deq_data[`FLIT_WIDTH - 2 : 0]};
assign EN_send_ports_putFlit = deq_valid;
assign EN_send_ports_putFlit = deq_valid && deq_ready;
assign EN_send_ports_getCredits = 1;

always_comb begin
Expand Down
Loading

0 comments on commit 816bc83

Please sign in to comment.