mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-30 18:56:16 +00:00
Pipeline: - q16_lut_vcn.py: Q16_16 LUT generation + VCN frame encoding (8 ops) - braid_vcn_encoder.py: Delta+RLE → RS ECC → ChaCha20 → VCN → MKV - braid_search.py: Sidon set slots, soliton search, QUBO optimization - test_braid_pipeline.py: 67 tests covering full round-trip WebGPU/Scripts: - braid_fft.wgsl: Cooley-Tukey radix-2 FFT on phase vectors - reed_solomon_vcn.py: Reed-Solomon ECC for VCN frame data - chacha20_braid.py: ChaCha20 encryption + key derivation - polynomial_commitment.py: KZG scheme for receipt verification Lean: - BraidBitwiseODE.lean: XOR crossing, O(1) integration, 2 proved theorems FPGA (Tang Nano 9K): - q16_lut_core.v: 8-op arithmetic, 2-stage pipeline, BRAM reciprocal - braid_crossing_core.v: 4-stage crossing residual, 7 Q16 instances - Testbenches with edge cases + VCD dumps
232 lines
8.1 KiB
Verilog
232 lines
8.1 KiB
Verilog
// ============================================================================
|
|
// braid_crossing_core.v - Braid Crossing Residual Computation
|
|
// Target: Tang Nano 9K (GW1NR-9)
|
|
// Pipeline: 4 stages
|
|
// Stage 1: Input latch + strand decomposition
|
|
// Stage 2: Q16_16 arithmetic operations via q16_lut_core
|
|
// Stage 3: Crossing residual accumulation
|
|
// Stage 4: Output register + done flag
|
|
// ============================================================================
|
|
// Strand format: 128 bits = 4 x Q16_16 values
|
|
// strand[127:96] = x0 (head position x)
|
|
// strand[ 95:64] = y0 (head position y)
|
|
// strand[ 63:32] = x1 (tail position x)
|
|
// strand[ 31: 0] = y1 (tail position y)
|
|
//
|
|
// Crossing residual = cross product of direction vectors
|
|
// residual = (x1_a - x0_a)*(y1_b - y0_b) - (y1_a - y0_a)*(x1_b - x0_b)
|
|
// ============================================================================
|
|
|
|
module braid_crossing_core (
|
|
input wire clk,
|
|
input wire rst,
|
|
input wire start,
|
|
input wire [127:0] strand_a,
|
|
input wire [127:0] strand_b,
|
|
output reg [127:0] result,
|
|
output reg done
|
|
);
|
|
|
|
// ----------------------------------------------------------------
|
|
// Strand decomposition
|
|
// ----------------------------------------------------------------
|
|
// Strand A components (Q16.16)
|
|
wire [31:0] ax0 = strand_a[127:96];
|
|
wire [31:0] ay0 = strand_a[95:64];
|
|
wire [31:0] ax1 = strand_a[63:32];
|
|
wire [31:0] ay1 = strand_a[31:0];
|
|
|
|
// Strand B components (Q16.16)
|
|
wire [31:0] bx0 = strand_b[127:96];
|
|
wire [31:0] by0 = strand_b[95:64];
|
|
wire [31:0] bx1 = strand_b[63:32];
|
|
wire [31:0] by1 = strand_b[31:0];
|
|
|
|
// ----------------------------------------------------------------
|
|
// Q16_16 LUT core instances for arithmetic
|
|
// We need 4 subtractions and 2 multiplications + 1 subtraction
|
|
// ----------------------------------------------------------------
|
|
|
|
// Stage 2 arithmetic: compute direction vectors
|
|
// dx_a = ax1 - ax0, dy_a = ay1 - ay0
|
|
// dx_b = bx1 - bx0, dy_b = by1 - by0
|
|
wire [31:0] sub_dx_a_result, sub_dy_a_result;
|
|
wire [31:0] sub_dx_b_result, sub_dy_b_result;
|
|
wire sub_dx_a_valid, sub_dy_a_valid;
|
|
wire sub_dx_b_valid, sub_dy_b_valid;
|
|
|
|
// Subtraction units for direction vectors
|
|
reg sub_start;
|
|
reg [15:0] sub_a_dx_a, sub_b_dx_a;
|
|
reg [15:0] sub_a_dy_a, sub_b_dy_a;
|
|
reg [15:0] sub_a_dx_b, sub_b_dx_b;
|
|
reg [15:0] sub_a_dy_b, sub_b_dy_b;
|
|
|
|
q16_lut_core u_sub_dx_a (
|
|
.clk(clk), .rst(rst),
|
|
.op_select(3'd1), // sub
|
|
.a(sub_a_dx_a), .b(sub_b_dx_a),
|
|
.result(sub_dx_a_result), .valid(sub_dx_a_valid)
|
|
);
|
|
|
|
q16_lut_core u_sub_dy_a (
|
|
.clk(clk), .rst(rst),
|
|
.op_select(3'd1), // sub
|
|
.a(sub_a_dy_a), .b(sub_b_dy_a),
|
|
.result(sub_dy_a_result), .valid(sub_dy_a_valid)
|
|
);
|
|
|
|
q16_lut_core u_sub_dx_b (
|
|
.clk(clk), .rst(rst),
|
|
.op_select(3'd1), // sub
|
|
.a(sub_a_dx_b), .b(sub_b_dx_b),
|
|
.result(sub_dx_b_result), .valid(sub_dx_b_valid)
|
|
);
|
|
|
|
q16_lut_core u_sub_dy_b (
|
|
.clk(clk), .rst(rst),
|
|
.op_select(3'd1), // sub
|
|
.a(sub_a_dy_b), .b(sub_b_dy_b),
|
|
.result(sub_dy_b_result), .valid(sub_dy_b_valid)
|
|
);
|
|
|
|
// Stage 3 arithmetic: compute cross products
|
|
// cross1 = dx_a * dy_b
|
|
// cross2 = dy_a * dx_b
|
|
// residual = cross1 - cross2
|
|
reg [15:0] mul_a1, mul_b1;
|
|
reg [15:0] mul_a2, mul_b2;
|
|
wire [31:0] mul1_result, mul2_result;
|
|
wire mul1_valid, mul2_valid;
|
|
|
|
q16_lut_core u_mul1 (
|
|
.clk(clk), .rst(rst),
|
|
.op_select(3'd2), // mul
|
|
.a(mul_a1), .b(mul_b1),
|
|
.result(mul1_result), .valid(mul1_valid)
|
|
);
|
|
|
|
q16_lut_core u_mul2 (
|
|
.clk(clk), .rst(rst),
|
|
.op_select(3'd2), // mul
|
|
.a(mul_a2), .b(mul_b2),
|
|
.result(mul2_result), .valid(mul2_valid)
|
|
);
|
|
|
|
reg [15:0] sub_final_a, sub_final_b;
|
|
wire [31:0] residual_result;
|
|
wire residual_valid;
|
|
|
|
q16_lut_core u_sub_final (
|
|
.clk(clk), .rst(rst),
|
|
.op_select(3'd1), // sub
|
|
.a(sub_final_a), .b(sub_final_b),
|
|
.result(residual_result), .valid(residual_valid)
|
|
);
|
|
|
|
// ----------------------------------------------------------------
|
|
// Pipeline control
|
|
// ----------------------------------------------------------------
|
|
reg [3:0] pipe_valid;
|
|
reg computing;
|
|
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
pipe_valid <= 4'b0000;
|
|
computing <= 1'b0;
|
|
end else begin
|
|
// Shift pipeline valid bits
|
|
pipe_valid <= {pipe_valid[2:0], start & ~computing};
|
|
|
|
if (start && !computing) begin
|
|
computing <= 1'b1;
|
|
end
|
|
|
|
// Clear computing when done emerges
|
|
if (pipe_valid[3]) begin
|
|
computing <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
|
|
// ----------------------------------------------------------------
|
|
// Stage 1: Input latch + decompose into 16-bit operands
|
|
// ----------------------------------------------------------------
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
sub_a_dx_a <= 16'd0; sub_b_dx_a <= 16'd0;
|
|
sub_a_dy_a <= 16'd0; sub_b_dy_a <= 16'd0;
|
|
sub_a_dx_b <= 16'd0; sub_b_dx_b <= 16'd0;
|
|
sub_a_dy_b <= 16'd0; sub_b_dy_b <= 16'd0;
|
|
end else if (start && !computing) begin
|
|
// Feed 16-bit halves of Q16_16 values into subtractors
|
|
// Use lower 16 bits of each Q16_16 component
|
|
sub_a_dx_a <= ax1[15:0]; sub_b_dx_a <= ax0[15:0];
|
|
sub_a_dy_a <= ay1[15:0]; sub_b_dy_a <= ay0[15:0];
|
|
sub_a_dx_b <= bx1[15:0]; sub_b_dx_b <= bx0[15:0];
|
|
sub_a_dy_b <= by1[15:0]; sub_b_dy_b <= by0[15:0];
|
|
end
|
|
end
|
|
|
|
// ----------------------------------------------------------------
|
|
// Stage 2: Latch direction vectors, feed to multipliers
|
|
// ----------------------------------------------------------------
|
|
reg [31:0] dx_a_reg, dy_a_reg, dx_b_reg, dy_b_reg;
|
|
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
dx_a_reg <= 32'd0; dy_a_reg <= 32'd0;
|
|
dx_b_reg <= 32'd0; dy_b_reg <= 32'd0;
|
|
mul_a1 <= 16'd0; mul_b1 <= 16'd0;
|
|
mul_a2 <= 16'd0; mul_b2 <= 16'd0;
|
|
end else begin
|
|
dx_a_reg <= sub_dx_a_result;
|
|
dy_a_reg <= sub_dy_a_result;
|
|
dx_b_reg <= sub_dx_b_result;
|
|
dy_b_reg <= sub_dy_b_result;
|
|
// Feed to multipliers: cross1 = dx_a * dy_b, cross2 = dy_a * dx_b
|
|
mul_a1 <= sub_dx_a_result[15:0]; mul_b1 <= sub_dy_b_result[15:0];
|
|
mul_a2 <= sub_dy_a_result[15:0]; mul_b2 <= sub_dx_b_result[15:0];
|
|
end
|
|
end
|
|
|
|
// ----------------------------------------------------------------
|
|
// Stage 3: Latch cross products, feed to final subtractor
|
|
// ----------------------------------------------------------------
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
sub_final_a <= 16'd0;
|
|
sub_final_b <= 16'd0;
|
|
end else begin
|
|
sub_final_a <= mul1_result[15:0];
|
|
sub_final_b <= mul2_result[15:0];
|
|
end
|
|
end
|
|
|
|
// ----------------------------------------------------------------
|
|
// Stage 4: Output register + done flag
|
|
// ----------------------------------------------------------------
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
result <= 128'd0;
|
|
done <= 1'b0;
|
|
end else begin
|
|
done <= pipe_valid[3];
|
|
|
|
if (pipe_valid[3]) begin
|
|
// Pack residual into result:
|
|
// [127:96] = residual (Q16.16 crossing value)
|
|
// [95:64] = dx_a (direction A x)
|
|
// [63:32] = dy_b (direction B y)
|
|
// [31:0] = sign-extended residual (for downstream use)
|
|
result <= {
|
|
residual_result,
|
|
dx_a_reg,
|
|
dy_b_reg,
|
|
{16'd0, residual_result[15:0]}
|
|
};
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|