Skip to content
Snippets Groups Projects
Commit 5ef14703 authored by dam1n19's avatar dam1n19
Browse files

Added Message Builder

parent dd4d87f0
No related branches found
No related tags found
No related merge requests found
.DS_Store 0 → 100644
File added
module message_build (
input logic clk,
input logic nrst,
input logic en,
// Synchronous, localised reset
input logic sync_rst,
// Data In data and Handshaking
input logic [511:0] data_in,
input logic data_in_last,
input logic data_in_valid,
output logic data_in_ready,
// Config data and Handshaking
input logic [63:0] cfg_size,
input logic [1:0] cfg_scheme,
input logic cfg_valid,
output logic cfg_ready,
// Data Out data and Handshaking
output logic [511:0] data_out,
output logic data_out_last,
output logic data_out_valid,
input logic data_out_ready
);
logic [9:0] data_word_rem, next_data_word_rem; // Remainder number of bits after 512 division
logic [63:0] cfg_size_reg, next_cfg_size;
logic [2:0] state, next_state; // State Machine State
logic [53:0] data_word_count, next_data_word_count;
logic [511:0] last_word_mask;
logic [511:0] end_marker;
logic [511:0] last_data_word;
// Create Mask for last Data Word
// - If Muliple of 512, then no mask needed, else mask off valid data
assign last_word_mask = |data_word_rem ? ((512'd1 << 512) - 1) << (512 - data_word_rem) : ((512'd1 << 512) - 1);
// Create Position Marker to show end of data message (place a "1")
// - only if not a multiple of 512
assign end_marker = |data_word_rem ? 1 << (512 - data_word_rem - 1) : 512'd0;
// Combine Last Data (after being masked) with end marker and size
assign last_data_word = (data_in & last_word_mask) | end_marker;
always_ff @(posedge clk, negedge nrst) begin
if ((!nrst) | sync_rst) begin
state <= 3'd0;
data_in_ready <= 1'b0;
cfg_ready <= 1'b1;
cfg_size_reg <= 64'd0;
data_word_rem <= 9'd0;
data_out_valid <= 1'b0;
data_out <= 512'd0;
data_word_count <= 54'd0;
end else begin
state <= next_state;
data_in_ready <= next_data_in_ready;
cfg_ready <= next_cfg_ready;
cfg_size_reg <= next_cfg_size;
data_word_rem <= next_data_word_rem;
data_out_valid <= next_data_out_valid;
data_out <= next_data_out;
data_word_count <= next_data_word_count;
end
end
always_comb begin
// Default
next_state = state;
next_data_in_ready = data_in_ready;
next_cfg_ready = cfg_ready;
next_cfg_size = cfg_size_reg;
next_data_word_rem = data_word_rem;
next_data_out_valid = data_out_valid;
next_data_out = data_out;
next_data_word_count = data_word_count;
// Override
case (state)
3'd0: begin // First time State
next_cfg_ready = 1'b1;
end
3'd1: begin // Initial Config Read
if (cfg_valid == 1'b1) begin
// Handshake to Acknowledge Config Has been Read
next_cfg_size = cfg_size;
next_cfg_ready = 1'b0;
next_data_in_ready = 1'b1;
next_data_word_count = (cfg_size >> 9) + |cfg_size[8:0]; // Divide by 512 and round up
next_data_word_rem = cfg_size[8:0];
if (next_data_word_count > 1) begin
next_state = 3'd2;
end else begin
next_state = 3'd3;
end
end
end
3'd2: begin // Pass through Data Blocks
// Check outputs can be written to
if (data_out_valid && !data_out_ready) begin
// If data out is valid and ready is low, there is already data waiting to be transferred
next_data_in_ready = 1'b0;
// If there is no Valid data at the output or there is a valid transfer happening on this clock cycle
end else begin
// These can be overloaded later if data is written to the outputs
next_data_out_valid = 1'b0;
next_data_in_ready = 1'b1;
// Check Inputs have data
if (data_in_valid && data_in_ready) begin
// Valid Handshake and data can be processed
// Data Processing Algorithm
next_data_word_count = data_word_count - 1;
// Write Input Data to Output
next_data_out = data_in;
next_data_out_valid = 1'b1;
if (data_word_count == 1) begin
// Last Input Data Word
next_state = 3'd3;
end
end
end
end
3'd3: begin // Process Last Read Word
// Check outputs can be written to
if (data_out_valid && !data_out_ready) begin
// If data out is valid and ready is low, there is already data waiting to be transferred
next_data_in_ready = 1'b0;
// If there is no Valid data at the output or there is a valid transfer happening on this clock cycle
end else begin
// These can be overloaded later if data is written to the outputs
next_data_out_valid = 1'b0;
next_data_in_ready = 1'b1;
// Check Inputs have data
if (data_in_valid && data_in_ready) begin
// Valid Handshake and data can be processed
if ((data_word_rem - 1) > 9'd446) begin
// If can't fit size in last word
next_data_out = last_data_word;
next_data_out_valid = 1'b1;
// NEXT STATE: Generate Additional Word
next_state = 3'd4;
next_data_in_ready = 1'b0;
else
// Size can fit in last data word
next_data_out = last_data_word | cfg_size_reg;
next_data_out_valid = 1'b1;
// NEXT STATE: Read Next Config
next_state = 3'd1;
next_data_in_ready = 1'b0;
next_cfg_ready = 1'b1;
end
end
end
end
3'd4: begin // Generate Extra Word
// Check outputs can be written to
if (data_out_valid && !data_out_ready) begin
// If data out is valid and ready is low, there is already data waiting to be transferred
next_data_in_ready = 1'b0;
// If there is no Valid data at the output or there is a valid transfer happening on this clock cycle
end else begin
// Size can fit in last data word
next_data_out = {~|data_word_rem, 447'd0, cfg_size_reg};
next_data_out_valid = 1'b1;
// NEXT STATE: Read Next Config
next_state = 3'd1;
next_data_in_ready = 1'b0;
next_cfg_ready = 1'b1;
end
end
default: begin
next_state = 3'd0;
end
endcase
end
endmodule
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment