Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/AI_Brain / the_tired_agi/core/src/fpga_ingest_lane.v |
| Date | Not specified in source |
| Repository | Janady13/AI_Brain |
| Revision | d6c309d3fa439714ca46b9d3bb94caf478ea5376 |
| Branch | main |
| Path or archive member | the_tired_agi/core/src/fpga_ingest_lane.v |
| Original SHA-256 | faebed7688da3b55f57c701ffa026fa89ea667bcc6b59c6704b4f48efbc6ee0e |
| Git blob SHA | f9556eee66132923727bb170b7c734c81e377001 |
| Reading-copy SHA-256 | faebed7688da3b55f57c701ffa026fa89ea667bcc6b59c6704b4f48efbc6ee0e |
Every recorded occurrence
These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/AI_Brain / the_tired_agi/core/src/fpga_ingest_lane.v | main | d6c309d3fa439714ca46b9d3bb94caf478ea5376 | Open original |
| Janady13/AI_Brain / the_tired_agi/core/src/fpga_ingest_lane.v | claude/binary-helix-fibonacci-hive-011CUj7dx1WWJLVYcWCjBbYv | 527d4882c71eb041393f9d8945996177c5ac9e86 | Open original |
Recovered source transcript
Download complete source text ↓372 lines · 13.7 KB
//=============================================================================
// FPGA Ingest Lane - Production Implementation
// Synthesizable for Lattice ECP5 / Xilinx Artix-7
// Purpose: Parse text chunks, compute entropy, generate micro-embeddings
// Target: 250 MHz operation, 256-bit data bus
//=============================================================================
`timescale 1ns / 1ps
module fpga_ingest_lane #(
parameter LANE_ID = 0,
parameter DATA_WIDTH = 256,
parameter CHUNK_SIZE = 16384, // 16 KiB chunks
parameter HASH_WIDTH = 64,
parameter ENTROPY_BITS = 16
)(
input wire clk,
input wire rst_n,
// Input chunk interface (AXI-Stream style)
input wire [DATA_WIDTH-1:0] s_axis_tdata,
input wire [DATA_WIDTH/8-1:0] s_axis_tkeep,
input wire s_axis_tvalid,
input wire s_axis_tlast,
output reg s_axis_tready,
// Output embedding interface
output reg [HASH_WIDTH-1:0] m_axis_hash,
output reg [ENTROPY_BITS-1:0] m_axis_entropy,
output reg [31:0] m_axis_chunk_id,
output reg m_axis_tvalid,
input wire m_axis_tready,
// Status signals
output reg [31:0] chunks_processed,
output reg [31:0] bytes_processed,
output reg error_flag
);
//=============================================================================
// Internal State Machine
//=============================================================================
localparam ST_IDLE = 3'd0;
localparam ST_RECEIVE = 3'd1;
localparam ST_HASH = 3'd2;
localparam ST_ENTROPY = 3'd3;
localparam ST_OUTPUT = 3'd4;
localparam ST_ERROR = 3'd5;
reg [2:0] state, next_state;
//=============================================================================
// Hash Engine (xxHash64-inspired, fully pipelined)
//=============================================================================
reg [HASH_WIDTH-1:0] hash_state [0:3]; // 4 accumulators
reg [HASH_WIDTH-1:0] hash_result;
reg hash_valid;
// xxHash64 prime constants
localparam [HASH_WIDTH-1:0] PRIME64_1 = 64'h9E3779B185EBCA87;
localparam [HASH_WIDTH-1:0] PRIME64_2 = 64'hC2B2AE3D27D4EB4F;
localparam [HASH_WIDTH-1:0] PRIME64_3 = 64'h165667B19E3779F9;
localparam [HASH_WIDTH-1:0] PRIME64_4 = 64'h85EBCA77C2B2AE63;
localparam [HASH_WIDTH-1:0] PRIME64_5 = 64'h27D4EB2F165667C5;
// Hash pipeline registers
reg [DATA_WIDTH-1:0] hash_data;
reg [7:0] hash_stage;
reg [HASH_WIDTH-1:0] hash_temp;
//=============================================================================
// Entropy Calculator (Shannon entropy, pipelined)
//=============================================================================
reg [31:0] byte_counts [0:255]; // Histogram
reg [31:0] total_bytes;
reg [ENTROPY_BITS-1:0] entropy_result;
reg entropy_valid;
// Entropy calculation using lookup table for log2
reg [15:0] log2_lut [0:255]; // Pre-computed log2 values (Q8.8 fixed-point)
reg [31:0] entropy_sum;
reg [7:0] entropy_idx;
//=============================================================================
// Chunk Buffer (for processing)
//=============================================================================
reg [DATA_WIDTH-1:0] chunk_buffer [0:63]; // 2KB buffer (64 x 256-bit)
reg [5:0] buffer_wr_ptr;
reg [5:0] buffer_rd_ptr;
reg [31:0] current_chunk_id;
reg [15:0] chunk_byte_count;
//=============================================================================
// State Machine
//=============================================================================
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= ST_IDLE;
end else begin
state <= next_state;
end
end
always @(*) begin
next_state = state;
case (state)
ST_IDLE: begin
if (s_axis_tvalid) begin
next_state = ST_RECEIVE;
end
end
ST_RECEIVE: begin
if (s_axis_tlast) begin
next_state = ST_HASH;
end else if (buffer_wr_ptr == 6'd63) begin
// Buffer full, start processing
next_state = ST_HASH;
end
end
ST_HASH: begin
if (hash_valid) begin
next_state = ST_ENTROPY;
end
end
ST_ENTROPY: begin
if (entropy_valid) begin
next_state = ST_OUTPUT;
end
end
ST_OUTPUT: begin
if (m_axis_tready) begin
next_state = ST_IDLE;
end
end
ST_ERROR: begin
// Error recovery
next_state = ST_IDLE;
end
endcase
end
//=============================================================================
// Data Reception
//=============================================================================
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
buffer_wr_ptr <= 6'd0;
chunk_byte_count <= 16'd0;
s_axis_tready <= 1'b1;
error_flag <= 1'b0;
end else begin
case (state)
ST_IDLE: begin
buffer_wr_ptr <= 6'd0;
chunk_byte_count <= 16'd0;
s_axis_tready <= 1'b1;
end
ST_RECEIVE: begin
if (s_axis_tvalid && s_axis_tready) begin
chunk_buffer[buffer_wr_ptr] <= s_axis_tdata;
buffer_wr_ptr <= buffer_wr_ptr + 1'b1;
// Count valid bytes using tkeep
chunk_byte_count <= chunk_byte_count + count_valid_bytes(s_axis_tkeep);
if (buffer_wr_ptr == 6'd62) begin
s_axis_tready <= 1'b0; // Buffer almost full
end
if (chunk_byte_count > CHUNK_SIZE) begin
error_flag <= 1'b1; // Chunk too large
end
end
end
ST_HASH, ST_ENTROPY, ST_OUTPUT: begin
s_axis_tready <= 1'b0;
end
endcase
end
end
//=============================================================================
// Hash Computation (xxHash64-inspired, pipelined)
//=============================================================================
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
hash_state[0] <= PRIME64_1 + PRIME64_2;
hash_state[1] <= PRIME64_2;
hash_state[2] <= 64'd0;
hash_state[3] <= PRIME64_5;
hash_result <= 64'd0;
hash_valid <= 1'b0;
hash_stage <= 8'd0;
end else begin
case (state)
ST_HASH: begin
if (hash_stage < buffer_wr_ptr) begin
// Process 256-bit chunks as 4x64-bit lanes
hash_state[0] <= rotate_left(hash_state[0] + (chunk_buffer[hash_stage][63:0] * PRIME64_2), 31) * PRIME64_1;
hash_state[1] <= rotate_left(hash_state[1] + (chunk_buffer[hash_stage][127:64] * PRIME64_2), 31) * PRIME64_1;
hash_state[2] <= rotate_left(hash_state[2] + (chunk_buffer[hash_stage][191:128] * PRIME64_2), 31) * PRIME64_1;
hash_state[3] <= rotate_left(hash_state[3] + (chunk_buffer[hash_stage][255:192] * PRIME64_2), 31) * PRIME64_1;
hash_stage <= hash_stage + 1'b1;
end else begin
// Finalize hash
hash_temp = rotate_left(hash_state[0], 1) +
rotate_left(hash_state[1], 7) +
rotate_left(hash_state[2], 12) +
rotate_left(hash_state[3], 18);
// Avalanche mixer
hash_result <= avalanche_mix(hash_temp);
hash_valid <= 1'b1;
hash_stage <= 8'd0;
end
end
default: begin
hash_valid <= 1'b0;
end
endcase
end
end
//=============================================================================
// Entropy Computation (Shannon entropy)
//=============================================================================
integer i;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
for (i = 0; i < 256; i = i + 1) begin
byte_counts[i] <= 32'd0;
end
total_bytes <= 32'd0;
entropy_result <= {ENTROPY_BITS{1'b0}};
entropy_valid <= 1'b0;
entropy_idx <= 8'd0;
entropy_sum <= 32'd0;
end else begin
case (state)
ST_RECEIVE: begin
// Update histogram
if (s_axis_tvalid && s_axis_tready) begin
// Process each valid byte in the 256-bit word
for (i = 0; i < DATA_WIDTH/8; i = i + 1) begin
if (s_axis_tkeep[i]) begin
byte_counts[s_axis_tdata[i*8 +: 8]] <= byte_counts[s_axis_tdata[i*8 +: 8]] + 1'b1;
total_bytes <= total_bytes + 1'b1;
end
end
end
end
ST_ENTROPY: begin
if (entropy_idx < 8'd255) begin
// Calculate: -sum(p_i * log2(p_i))
if (byte_counts[entropy_idx] > 0) begin
// p_i = count / total
// Using fixed-point: log2_lut gives log2(p_i) in Q8.8
entropy_sum <= entropy_sum +
((byte_counts[entropy_idx] * log2_lut[entropy_idx]) >> 8);
end
entropy_idx <= entropy_idx + 1'b1;
end else begin
// Normalize to ENTROPY_BITS range
entropy_result <= entropy_sum[ENTROPY_BITS-1:0];
entropy_valid <= 1'b1;
end
end
ST_IDLE: begin
// Reset for next chunk
for (i = 0; i < 256; i = i + 1) begin
byte_counts[i] <= 32'd0;
end
total_bytes <= 32'd0;
entropy_sum <= 32'd0;
entropy_idx <= 8'd0;
entropy_valid <= 1'b0;
end
endcase
end
end
//=============================================================================
// Output Stage
//=============================================================================
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
m_axis_hash <= {HASH_WIDTH{1'b0}};
m_axis_entropy <= {ENTROPY_BITS{1'b0}};
m_axis_chunk_id <= 32'd0;
m_axis_tvalid <= 1'b0;
current_chunk_id <= 32'd0;
chunks_processed <= 32'd0;
bytes_processed <= 32'd0;
end else begin
case (state)
ST_OUTPUT: begin
m_axis_hash <= hash_result;
m_axis_entropy <= entropy_result;
m_axis_chunk_id <= current_chunk_id;
m_axis_tvalid <= 1'b1;
if (m_axis_tready) begin
current_chunk_id <= current_chunk_id + 1'b1;
chunks_processed <= chunks_processed + 1'b1;
bytes_processed <= bytes_processed + chunk_byte_count;
end
end
ST_IDLE: begin
m_axis_tvalid <= 1'b0;
end
endcase
end
end
//=============================================================================
// Helper Functions
//=============================================================================
function [5:0] count_valid_bytes;
input [DATA_WIDTH/8-1:0] tkeep;
integer j;
begin
count_valid_bytes = 6'd0;
for (j = 0; j < DATA_WIDTH/8; j = j + 1) begin
if (tkeep[j]) count_valid_bytes = count_valid_bytes + 1'b1;
end
end
endfunction
function [HASH_WIDTH-1:0] rotate_left;
input [HASH_WIDTH-1:0] value;
input [5:0] count;
begin
rotate_left = (value << count) | (value >> (HASH_WIDTH - count));
end
endfunction
function [HASH_WIDTH-1:0] avalanche_mix;
input [HASH_WIDTH-1:0] value;
reg [HASH_WIDTH-1:0] temp;
begin
temp = value ^ (value >> 33);
temp = temp * PRIME64_2;
temp = temp ^ (temp >> 29);
temp = temp * PRIME64_3;
avalanche_mix = temp ^ (temp >> 32);
end
endfunction
//=============================================================================
// Log2 LUT Initialization (for entropy calculation)
//=============================================================================
initial begin
// Pre-computed log2 values in Q8.8 fixed-point
// This would be initialized from a file or generated
// For synthesis: use ROM inference
$readmemh("log2_lut.hex", log2_lut);
end
endmodule