Skip to content

Commit

Permalink
Added more of Eddie and Ruben's IP projects
Browse files Browse the repository at this point in the history
Additionally, added the initial bare metal software for transmitting
packets into and receiving packets from RANC on ZCU102

Partial progress on #9
  • Loading branch information
mackncheesiest committed Feb 10, 2022
1 parent 39545d2 commit 79aa3e3
Show file tree
Hide file tree
Showing 237 changed files with 5,751 additions and 0 deletions.
748 changes: 748 additions & 0 deletions hardware/BareMetalSoftware/StreamingSoftware/streamingrx.c

Large diffs are not rendered by default.

403 changes: 403 additions & 0 deletions hardware/BareMetalSoftware/StreamingSoftware/streamingtx.c

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions hardware/IP/AXI-StreamPacketBuffer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vivado_project/*
424 changes: 424 additions & 0 deletions hardware/IP/AXI-StreamPacketBuffer/AXI-StreamPacketBuffer.tcl

Large diffs are not rendered by default.

555 changes: 555 additions & 0 deletions hardware/IP/AXI-StreamPacketBuffer/component.xml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// AXI-StreamPacketBuffer.v
//
// Created for Dr. Akoglu's Reconfigurable Computing Lab
// at the University of Arizona
//
// Converts packets into an AXI-Stream.
//////////////////////////////////////////////////////////////////////////////////


module AXIStreamPacketBuffer #(
parameter PACKET_WIDTH = 30,
parameter MAX_NUM_PACKETS = 200,
// Parameters of Axi Master Bus Interface M00_AXIS
parameter integer C_M00_AXIS_TDATA_WIDTH = 32,
parameter integer C_M00_AXIS_START_COUNT = 32
)(
input clk,
input rst,
input tick,
input [PACKET_WIDTH-1:0] packet,
input packet_valid,
output buffer_overflow_error,
output buffer_to_stream_error,
// Ports of Axi Master Bus Interface M00_AXIS
input wire m00_axis_aclk,
input wire m00_axis_aresetn,
output wire m00_axis_tvalid,
output wire [C_M00_AXIS_TDATA_WIDTH-1 : 0] m00_axis_tdata,
output wire [(C_M00_AXIS_TDATA_WIDTH/8)-1 : 0] m00_axis_tstrb,
output wire m00_axis_tlast,
input wire m00_axis_tready
);

function integer clogb2 (input integer bit_depth);
begin
for(clogb2=0; bit_depth>0; clogb2=clogb2+1)
bit_depth = bit_depth >> 1;
end
endfunction

wire [clogb2(MAX_NUM_PACKETS)-1:0] read_addr;
wire [C_M00_AXIS_TDATA_WIDTH-1:0] buffer_out;
wire [clogb2(MAX_NUM_PACKETS)-1:0] num_packets;
wire read_en;
wire [C_M00_AXIS_TDATA_WIDTH-1:0] padded_packet;

localparam AXIS_PACKET_WIDTH_DIFFERENCE = C_M00_AXIS_TDATA_WIDTH - PACKET_WIDTH;
wire [AXIS_PACKET_WIDTH_DIFFERENCE-1:0] padding = {AXIS_PACKET_WIDTH_DIFFERENCE{1'b0}};

assign padded_packet = {padding, packet};

DoubleBuffer #(
.BUFFER_DEPTH(MAX_NUM_PACKETS),
.DATA_WIDTH(C_M00_AXIS_TDATA_WIDTH)
) DoubleBuffer_inst (
.clk(clk),
.rst(rst),
.tick(tick),
.din_valid(packet_valid),
.din(padded_packet),
.read_addr(read_addr),
.dout(buffer_out),
.num_packets(num_packets),
.read_en(read_en),
.buffer_overflow_error(buffer_overflow_error)
);

AXIStreamPacketBuffer_M00_AXIS #(
.MAX_STREAM_DEPTH(MAX_NUM_PACKETS),
.C_M_AXIS_TDATA_WIDTH(C_M00_AXIS_TDATA_WIDTH),
.C_M_START_COUNT(C_M00_AXIS_START_COUNT)
) AXIStreamPacketBuffer_M00_AXIS_inst (
.read_en(read_en),
.data(buffer_out),
.num_packets(num_packets),
.read_addr(read_addr),
.buffer_to_stream_error(buffer_to_stream_error),
.M_AXIS_ACLK(m00_axis_aclk),
.M_AXIS_ARESETN(m00_axis_aresetn),
.M_AXIS_TVALID(m00_axis_tvalid),
.M_AXIS_TDATA(m00_axis_tdata),
.M_AXIS_TSTRB(m00_axis_tstrb),
.M_AXIS_TLAST(m00_axis_tlast),
.M_AXIS_TREADY(m00_axis_tready)
);

endmodule
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@

`timescale 1 ns / 1 ps

module AXIStreamPacketBuffer_M00_AXIS #
(
// Users to add parameters here
parameter integer MAX_STREAM_DEPTH = 32,
// User parameters ends
// Do not modify the parameters beyond this line

// Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_M_AXIS_TDATA_WIDTH.
parameter integer C_M_AXIS_TDATA_WIDTH = 32,
// Start count is the number of clock cycles the master will wait before initiating/issuing any transaction.
parameter integer C_M_START_COUNT = 32
)
(
// Users to add ports here
input wire read_en,
input wire [C_M_AXIS_TDATA_WIDTH-1:0] data,
input wire [clogb2(MAX_STREAM_DEPTH)-1:0] num_packets,
output wire [clogb2(MAX_STREAM_DEPTH)-1:0] read_addr,
output reg buffer_to_stream_error,
// User ports ends
// Do not modify the ports beyond this line

// Global ports
input wire M_AXIS_ACLK,
//
input wire M_AXIS_ARESETN,
// Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted.
output wire M_AXIS_TVALID,
// TDATA is the primary payload that is used to provide the data that is passing across the interface from the master.
output wire [C_M_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA,
// TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte.
output wire [(C_M_AXIS_TDATA_WIDTH/8)-1 : 0] M_AXIS_TSTRB,
// TLAST indicates the boundary of a packet.
output wire M_AXIS_TLAST,
// TREADY indicates that the slave can accept a transfer in the current cycle.
input wire M_AXIS_TREADY
);
// Total number of output data
// localparam NUMBER_OF_OUTPUT_WORDS = STREAM_DEPTH;

function integer clogb2 (input integer bit_depth);
begin
for(clogb2=0; bit_depth>0; clogb2=clogb2+1)
bit_depth = bit_depth >> 1;
end
endfunction

// WAIT_COUNT_BITS is the width of the wait counter.
localparam integer WAIT_COUNT_BITS = clogb2(C_M_START_COUNT-1);

// bit_num gives the minimum number of bits needed to address 'depth' size of FIFO.
localparam bit_num = clogb2(MAX_STREAM_DEPTH);

// Define the states of state machine
// The control state machine oversees the writing of input streaming data to the FIFO,
// and outputs the streaming data from the FIFO
localparam [1:0] IDLE = 2'b00, // This is the initial/idle state

INIT_COUNTER = 2'b01, // This state initializes the counter, once
// the counter reaches C_M_START_COUNT count,
// the state machine changes state to SEND_STREAM
SEND_STREAM = 2'b10; // In this state the
// stream data is output through M_AXIS_TDATA
// State variable
reg [1:0] mst_exec_state;
// Example design FIFO read pointer
reg [bit_num-1:0] read_pointer;

// AXI Stream internal signals
//wait counter. The master waits for the user defined number of clock cycles before initiating a transfer.
reg [WAIT_COUNT_BITS-1 : 0] count;
//streaming data valid
wire axis_tvalid;
//streaming data valid delayed by one clock cycle
reg axis_tvalid_delay;
//Last of the streaming data
wire axis_tlast;
//Last of the streaming data delayed by one clock cycle
reg axis_tlast_delay;
//FIFO implementation signals
reg [C_M_AXIS_TDATA_WIDTH-1 : 0] stream_data_out;
wire tx_en;
//The master has issued all the streaming data stored in FIFO
reg tx_done;


// I/O Connections assignments

assign M_AXIS_TVALID = axis_tvalid_delay;
assign M_AXIS_TDATA = stream_data_out;
assign M_AXIS_TLAST = axis_tlast_delay;
assign M_AXIS_TSTRB = {(C_M_AXIS_TDATA_WIDTH/8){1'b1}};
assign read_addr = read_pointer;


// Control state machine implementation
always @(posedge M_AXIS_ACLK)
begin
if (!M_AXIS_ARESETN)
// Synchronous reset (active low)
begin
mst_exec_state <= IDLE;
count <= 0;
buffer_to_stream_error <= 0;
end
else
case (mst_exec_state)
IDLE:
// The slave starts accepting tdata when
// there tvalid is asserted to mark the
// presence of valid streaming data
if ( read_en == 1 )
begin
mst_exec_state <= INIT_COUNTER;
end
//else
// begin
// mst_exec_state <= IDLE;
// end

INIT_COUNTER: begin
// The slave starts accepting tdata when
// there tvalid is asserted to mark the
// presence of valid streaming data
if ( count == C_M_START_COUNT - 1 )
begin
mst_exec_state <= SEND_STREAM;
count <= 0;
end
else
begin
count <= count + 1;
mst_exec_state <= INIT_COUNTER;
end
// If read_en is high in this state, the tick has occured while packets will still being read
if ( read_en == 1 )
buffer_to_stream_error <= 1;

end
SEND_STREAM: begin
// The example design streaming master functionality starts
// when the master drives output tdata from the FIFO and the slave
// has finished storing the S_AXIS_TDATA
if (tx_done)
begin
mst_exec_state <= IDLE;
end
else
begin
mst_exec_state <= SEND_STREAM;
end
// If read_en is high in this state, the tick has occured while packets will still being read
if ( read_en == 1 )
buffer_to_stream_error <= 1;
end
endcase
end


//tvalid generation
//axis_tvalid is asserted when the control state machine's state is SEND_STREAM and
//number of output streaming data is less than the NUMBER_OF_OUTPUT_WORDS.
assign axis_tvalid = ((mst_exec_state == SEND_STREAM) && (read_pointer < num_packets));

// AXI tlast generation
// axis_tlast is asserted number of output streaming data is NUMBER_OF_OUTPUT_WORDS-1
// (0 to NUMBER_OF_OUTPUT_WORDS-1)
assign axis_tlast = (read_pointer == num_packets-1);


// Delay the axis_tvalid and axis_tlast signal by one clock cycle
// to match the latency of M_AXIS_TDATA
always @(posedge M_AXIS_ACLK)
begin
if (!M_AXIS_ARESETN)
begin
axis_tvalid_delay <= 1'b0;
axis_tlast_delay <= 1'b0;
end
else
begin
axis_tvalid_delay <= axis_tvalid;
axis_tlast_delay <= axis_tlast;
end
end


//read_pointer pointer

always@(posedge M_AXIS_ACLK)
begin
if(!M_AXIS_ARESETN)
begin
read_pointer <= 0;
tx_done <= 1'b0;
end
else
if (mst_exec_state == IDLE) begin
tx_done <= 1'b0;
read_pointer <= 0;
end
else if (read_pointer + 1 <= num_packets)
begin
if (tx_en)
// read pointer is incremented after every read from the FIFO
// when FIFO read signal is enabled.
begin
read_pointer <= read_pointer + 1;
tx_done <= 1'b0;
end
end
else if (read_pointer == num_packets)
begin
// tx_done is asserted when NUMBER_OF_OUTPUT_WORDS numbers of streaming data
// has been out.
tx_done <= 1'b1;
end
end


//FIFO read enable generation

assign tx_en = M_AXIS_TREADY && axis_tvalid;

// Streaming output data is read from FIFO
always @( posedge M_AXIS_ACLK )
begin
if(!M_AXIS_ARESETN)
begin
stream_data_out <= 0;
end
else if (tx_en)// && M_AXIS_TSTRB[byte_index]
begin
stream_data_out <= data;
end
end

// Add user logic here

// User logic ends

endmodule
Loading

0 comments on commit 79aa3e3

Please sign in to comment.