Master AXI Stream Specification:
Verilog Design Module: AXI Master (.v file)
----------------------------------------------------
module axi_stream_master(input areset_neg, aclk, send,
input [31:0] data, input tready, output reg tvalid, output tlast, output reg [31:0] tdata, output reg finish
//AXI Stream interface
);
reg [31:0] data_buf;
always@(posedge send or negedge areset_neg)
if (~areset_neg)
data_buf <= 0;
else
data_buf <= data; //when send goes HIGH, we
//send the data info into the data buffer
//we don't want our data to be changed that's why
//we keep it in data buffer (data_buf)
reg send_pulse_1d, send_pulse_2d; //delay the send signal
always@(posedge aclk)
if (~areset_neg)
{send_pulse_1d, send_pulse_2d} <= 2'b00;
else
{send_pulse_1d, send_pulse_2d} <= {send, send_pulse_1d};
//handshake happened b/w master and slave
wire handshake;
assign handshake = tvalid & tready; //handshake happens only when tvalid and tready - both are HIGH
//tdata
always @(posedge aclk)
if (~areset_neg)
tdata <= 1'b0;
else
if (handshake) //when handshake is happening >> tdata is sent
//no need to keep tdata anymore so "tdata <= 0"
tdata <= 0;
else if (send_pulse_1d)
tdata <= data_buf;
else
tdata <= tdata;
//tvalid (equals 0 when handshake is happening)
//as soon as the fifo becomes no empty the tvalid goes high
always @(posedge aclk)
if (~areset_neg)
tvalid <= 1'b0;
else
if (handshake)
tvalid <= 1'b0;
else
if (send_pulse_1d)
tvalid <= 1'b1;
else
tvalid <= tvalid;
//tlast
//same behavioral as tvalid
assign tlast = tvalid;
//finish
always @(posedge aclk)
if (~areset_neg)
finish <= 1'b0;
else
if (send_pulse_1d)
finish <= 1'b0;
else
if (handshake)
finish <= 1'b1;
else
finish <= 1'b0;
endmodule
------------------------------------------------------
SystemVerilog Testbench Module: Warning - The testbench below does not tests the full functionality of AXI Master and will not generate the complete functional waveform. It will only generate partial output (.sv file) -- ignore 'tdata'.
`timescale 1ns / 1psmodule
axi_stream_master_tb();
default clocking cb@(posedge aclk);
endclocking
bit aclk, areset_neg, send;
logic finish;
logic tready;
logic tvalid, tlast;
logic [31:0] tdata;
logic [31:0] data;
axi_stream_master inst_axi_stream_master (.areset_neg(areset_neg),
.aclk(aclk),
.send(send),
.tready(tready),
.tvalid(tvalid),
.tlast(tlast),
.tdata(tdata),
.finish(finish)
);
//////////Verification IP name highlighted////////////
/*wire [31:0] pc_status;
axi_stream_protocol_checker_0 inst_axiCheck(
.aclk(aclk), //input wire aclk
.aresetn(~areset_neg), //input wire aresetn
.pc_axis_tvalid(tvalid), //input wire pc_axis_tvalid
.pc_axis_tready(tready), //input wire pc_axis_tready
.pc_axis_tdata((5'd0,tdata)), // input wire [7:0] pc_axis_tdata
.pc_asserted(pc_asserted), //output wire pc_asserted
.pc_status(pc_status) //output wire [31:0] pc_status
);
*/
initial
forever #2 aclk++;
initial
begin
areset_neg <= 0;
##4 areset_neg <= 1; //##4 means FOUR CLOCK CYCLES
end
initial
begin
##6 send = 1;
##1 send = 0;
##12 send = 1;
##1 send =0;
end
initial
begin
tready = 0;
##5 tready = 1;
##1 tready = 0;
##8 tready = 1;
##1 tready = 0;
end
initial
begin
data <= 32'haaaa_bbbb;
##15
data <= 32'hcccc_dddd;
end
initial
##40 $finish;
endmodule
FIG: AXI Stream Master RTL Schematic. |
- Send user-provided data by AXI-Stream Protocol.
- User provides needed data to send to data input.
- When user activates send, the module should send user-provided data by AXI-Stream. Send is async signal.
- After finish sending should activate finish output for 1 cycle.
----------------------------------------------------
input [31:0] data, input tready, output reg tvalid, output tlast, output reg [31:0] tdata, output reg finish
//AXI Stream interface
);
reg [31:0] data_buf;
always@(posedge send or negedge areset_neg)
if (~areset_neg)
data_buf <= 0;
else
data_buf <= data; //when send goes HIGH, we
//send the data info into the data buffer
//we don't want our data to be changed that's why
//we keep it in data buffer (data_buf)
reg send_pulse_1d, send_pulse_2d; //delay the send signal
always@(posedge aclk)
if (~areset_neg)
{send_pulse_1d, send_pulse_2d} <= 2'b00;
else
{send_pulse_1d, send_pulse_2d} <= {send, send_pulse_1d};
//handshake happened b/w master and slave
wire handshake;
assign handshake = tvalid & tready; //handshake happens only when tvalid and tready - both are HIGH
//tdata
always @(posedge aclk)
if (~areset_neg)
tdata <= 1'b0;
else
if (handshake) //when handshake is happening >> tdata is sent
//no need to keep tdata anymore so "tdata <= 0"
tdata <= 0;
else if (send_pulse_1d)
tdata <= data_buf;
else
tdata <= tdata;
//tvalid (equals 0 when handshake is happening)
//as soon as the fifo becomes no empty the tvalid goes high
always @(posedge aclk)
if (~areset_neg)
tvalid <= 1'b0;
else
if (handshake)
tvalid <= 1'b0;
else
if (send_pulse_1d)
tvalid <= 1'b1;
else
tvalid <= tvalid;
//tlast
//same behavioral as tvalid
assign tlast = tvalid;
//finish
always @(posedge aclk)
if (~areset_neg)
finish <= 1'b0;
else
if (send_pulse_1d)
finish <= 1'b0;
else
if (handshake)
finish <= 1'b1;
else
finish <= 1'b0;
endmodule
------------------------------------------------------
SystemVerilog Testbench Module: Warning - The testbench below does not tests the full functionality of AXI Master and will not generate the complete functional waveform. It will only generate partial output (.sv file) -- ignore 'tdata'.
`timescale 1ns / 1psmodule
axi_stream_master_tb();
default clocking cb@(posedge aclk);
endclocking
bit aclk, areset_neg, send;
logic finish;
logic tready;
logic tvalid, tlast;
logic [31:0] tdata;
logic [31:0] data;
axi_stream_master inst_axi_stream_master (.areset_neg(areset_neg),
.aclk(aclk),
.send(send),
.tready(tready),
.tvalid(tvalid),
.tlast(tlast),
.tdata(tdata),
.finish(finish)
);
//////////Verification IP name highlighted////////////
/*wire [31:0] pc_status;
axi_stream_protocol_checker_0 inst_axiCheck(
.aclk(aclk), //input wire aclk
.aresetn(~areset_neg), //input wire aresetn
.pc_axis_tvalid(tvalid), //input wire pc_axis_tvalid
.pc_axis_tready(tready), //input wire pc_axis_tready
.pc_axis_tdata((5'd0,tdata)), // input wire [7:0] pc_axis_tdata
.pc_asserted(pc_asserted), //output wire pc_asserted
.pc_status(pc_status) //output wire [31:0] pc_status
);
*/
initial
forever #2 aclk++;
initial
begin
areset_neg <= 0;
##4 areset_neg <= 1; //##4 means FOUR CLOCK CYCLES
end
initial
begin
##6 send = 1;
##1 send = 0;
##12 send = 1;
##1 send =0;
end
initial
begin
tready = 0;
##5 tready = 1;
##1 tready = 0;
##8 tready = 1;
##1 tready = 0;
end
initial
begin
data <= 32'haaaa_bbbb;
##15
data <= 32'hcccc_dddd;
end
initial
##40 $finish;
endmodule
Output Simulation Waveform:
Comments
Post a Comment