// Morphic Scalar FPGA Implementation - OPTIMIZED // Derived from Lean: Semantics/MorphicScalar.lean // Target: Gowin GW1NR-9 (Tang Nano 9K) // Q16.16 fixed-point arithmetic with aggressive optimizations // Implements quantum-inspired computational stem cell `timescale 1ns / 1ps // ═══════════════════════════════════════════════════════════════════════════ // Scalar State Encoding (4-bit state ID - minimal encoding) // ═══════════════════════════════════════════════════════════════════════════ localparam STATE_SUPERPOSED = 4'd0; localparam STATE_SCOUTING = 4'd1; localparam STATE_MEASURE_LOCAL_NEED = 4'd2; localparam STATE_COLLAPSED_PROFILE = 4'd3; localparam STATE_EXECUTE = 4'd4; localparam STATE_RECEIPT = 4'd5; localparam STATE_AMPLITUDE_UPDATE = 4'd6; localparam STATE_QUERY_COLLECTIVE = 4'd7; localparam STATE_COLLECTIVE_RESPONSE = 4'd8; localparam STATE_QUERY_LLM = 4'd9; localparam STATE_DIRECTED = 4'd10; localparam STATE_HOLD = 4'd11; localparam STATE_OPERATOR_ALERT = 4'd12; localparam STATE_LOW_POWER_PASSIVE = 4'd13; localparam STATE_QUARANTINE = 4'd14; localparam STATE_MIGRATE = 4'd15; // ═══════════════════════════════════════════════════════════════════════════ // OPTIMIZED Q16.16 Fixed-Point Arithmetic // ═══════════════════════════════════════════════════════════════════════════ // OPTIMIZATION: Use carry chain for addition (Lattice-specific) module q16_16_add_opt ( input signed [31:0] a, input signed [31:0] b, output signed [31:0] sum, output overflow ); wire signed [32:0] ext = $signed({a[31], a}) + $signed({b[31], b}); assign overflow = (a[31] == b[31]) && (ext[32] != a[31]); // OPTIMIZATION: Use ternary for mux, synthesis tool infers carry chain assign sum = overflow ? (a[31] ? 32'sh80000000 : 32'sh7FFFFFFF) : ext[31:0]; endmodule // OPTIMIZATION: Use DSP slices if available, otherwise optimized logic module q16_16_mul_opt ( input signed [31:0] a, input signed [31:0] b, output signed [31:0] product ); // OPTIMIZATION: Direct assignment, synthesis infers DSP or optimized multiplier wire signed [63:0] full = $signed(a) * $signed(b); assign product = full[47:16]; // Q16.16 multiply: keep middle 32 bits endmodule // OPTIMIZATION: Replace division by constant with multiplication by reciprocal // 1/100 in Q16.16 = 655.36/65536 ≈ 0x00000290 module q16_16_div_by_100_opt ( input signed [31:0] numerator, output signed [31:0] quotient ); // OPTIMIZATION: Multiply by reciprocal of 100 instead of division // 1/100 ≈ 0.009999... in Q16.16 = 0x00000290 localparam signed [31:0] RECIP_100 = 32'sh00000290; wire signed [63:0] full = $signed(numerator) * RECIP_100; assign quotient = full[47:16]; endmodule // OPTIMIZATION: Compare can be done in single cycle without extra logic module q16_16_compare_opt ( input signed [31:0] a, input signed [31:0] b, output lt, output eq, output gt ); // OPTIMIZATION: Direct comparison, synthesis infers optimized logic assign lt = (a < b); assign eq = (a == b); assign gt = (a > b); endmodule // ═══════════════════════════════════════════════════════════════════════════ // OPTIMIZED OEPI Calculation - PARALLEL TREE STRUCTURE // Derived from Lean: Semantics/OEPI.lean // OEPI = 0.25*uncertainty + 0.25*impact + 0.20*time_sensitivity + // 0.15*irreversibility + 0.15*live_voltage_risk // OPTIMIZATION: Parallel tree reduces latency from sequential to logarithmic // ═══════════════════════════════════════════════════════════════════════════ module oepi_calculator_opt ( input signed [31:0] uncertainty, input signed [31:0] impact, input signed [31:0] time_sensitivity, input signed [31:0] irreversibility, input signed [31:0] live_voltage_risk, output signed [31:0] oepi_score ); // Weights in Q16.16 localparam signed [31:0] W_UNCERTAINTY = 32'sh00004000; // 0.25 localparam signed [31:0] W_IMPACT = 32'sh00004000; // 0.25 localparam signed [31:0] W_TIME = 32'sh00003333; // 0.20 localparam signed [31:0] W_IRREVERSIBLE = 32'sh00002666; // 0.15 localparam signed [31:0] W_VOLTAGE = 32'sh00002666; // 0.15 localparam signed [31:0] W_DIVISOR = 32'sh00019000; // 100.0 // OPTIMIZATION: Parallel multiplication (all 5 multiplies in parallel) wire signed [31:0] w_uncertainty, w_impact, w_time, w_irreversible, w_voltage; q16_16_mul_opt mul_uncertainty (.a(uncertainty), .b(W_UNCERTAINTY), .product(w_uncertainty)); q16_16_mul_opt mul_impact (.a(impact), .b(W_IMPACT), .product(w_impact)); q16_16_mul_opt mul_time (.a(time_sensitivity), .b(W_TIME), .product(w_time)); q16_16_mul_opt mul_irreversible (.a(irreversibility), .b(W_IRREVERSIBLE), .product(w_irreversible)); q16_16_mul_opt mul_voltage (.a(live_voltage_risk), .b(W_VOLTAGE), .product(w_voltage)); // OPTIMIZATION: Tree-structured addition (reduces latency) // Level 1: 2 parallel adds wire signed [31:0] sum1a, sum1b; q16_16_add_opt add1a (.a(w_uncertainty), .b(w_impact), .sum(sum1a), .overflow()); q16_16_add_opt add1b (.a(w_time), .b(w_irreversible), .sum(sum1b), .overflow()); // Level 2: 1 parallel add + 1 remaining wire signed [31:0] sum2a; q16_16_add_opt add2a (.a(sum1a), .b(sum1b), .sum(sum2a), .overflow()); // Level 3: Final add wire signed [31:0] total; q16_16_add_opt add3 (.a(sum2a), .b(w_voltage), .sum(total), .overflow()); // OPTIMIZATION: Use reciprocal multiplication instead of division q16_16_div_by_100_opt div_normalizer (.a(total), .quotient(oepi_score)); endmodule // ═══════════════════════════════════════════════════════════════════════════ // OPTIMIZED OEPI Threshold Classifier // OPTIMIZATION: Single-cycle comparison with constants // ═══════════════════════════════════════════════════════════════════════════ module oepi_threshold_classifier_opt ( input signed [31:0] oepi_score, output [1:0] threshold // 00=low, 01=medium, 10=critical ); localparam signed [31:0] THRESHOLD_MEDIUM = 32'sh00008C00; // 70.0 localparam signed [31:0] THRESHOLD_CRITICAL = 32'sh0000BE00; // 95.0 // OPTIMIZATION: Direct comparison, no extra modules wire score_ge_medium = (oepi_score >= THRESHOLD_MEDIUM); wire score_ge_critical = (oepi_score >= THRESHOLD_CRITICAL); // OPTIMIZATION: Priority encoder logic assign threshold = score_ge_critical ? 2'b10 : (score_ge_medium ? 2'b01 : 2'b00); endmodule // ═══════════════════════════════════════════════════════════════════════════ // OPTIMIZED Scalar State Machine // OPTIMIZATION: One-hot encoding for faster state transitions (more FFs but faster) // Alternative: Binary encoding (4 bits) for minimal FFs // ═══════════════════════════════════════════════════════════════════════════ module scalar_state_machine_opt ( input wire clk, input wire rst_n, input wire transition_trigger, input wire [3:0] target_state, input wire operator_available, output reg [3:0] current_state, output reg in_pool ); // OPTIMIZATION: Minimal flip-flops with binary encoding always @(posedge clk or negedge rst_n) begin if (!rst_n) begin current_state <= STATE_SUPERPOSED; in_pool <= 1'b1; end else if (transition_trigger) begin current_state <= target_state; // OPTIMIZATION: Combinational pool status based on state case (target_state) STATE_SUPERPOSED, STATE_SCOUTING, STATE_LOW_POWER_PASSIVE: in_pool <= 1'b1; default: in_pool <= 1'b0; endcase end else if (!operator_available && (current_state == STATE_OPERATOR_ALERT)) begin // Auto-transition to low power passive mode when operator unavailable current_state <= STATE_LOW_POWER_PASSIVE; in_pool <= 1'b1; end end endmodule // ═══════════════════════════════════════════════════════════════════════════ // OPTIMIZED Amplitude Update // OPTIMIZATION: Single-cycle addition with saturation // ═══════════════════════════════════════════════════════════════════════════ module amplitude_update_opt ( input signed [31:0] amplitude_old, input signed [31:0] delta, output signed [31:0] amplitude_new ); wire overflow; q16_16_add_opt update_inst (.a(amplitude_old), .b(delta), .sum(amplitude_new), .overflow(overflow)); // OPTIMIZATION: Saturation already handled in add module endmodule // ═══════════════════════════════════════════════════════════════════════════ // OPTIMIZED Profile Collapse Selector // OPTIMIZATION: Pure combinational logic, no registers needed // ═══════════════════════════════════════════════════════════════════════════ module profile_collapse_opt ( input wire collapse_trigger, input wire [7:0] profile_id, output wire collapse_valid, output wire [7:0] collapsed_profile ); // OPTIMIZATION: Direct assignment, no logic needed assign collapse_valid = collapse_trigger; assign collapsed_profile = profile_id; endmodule // ═══════════════════════════════════════════════════════════════════════════ // OPTIMIZED Morphic Scalar Top-Level with Pipelining // OPTIMIZATION: 3-stage pipeline for higher throughput // Stage 1: OEPI calculation // Stage 2: Threshold classification + state update // Stage 3: Amplitude update + collapse // ═══════════════════════════════════════════════════════════════════════════ module morphic_scalar_top_opt ( // Clock and reset input wire clk, // Pin 52 (27MHz) input wire rst_n, // Pin 4 (Reset_Button) // User input input wire user_btn, // Pin 3 (User_Button) // LED outputs output wire [5:0] led, // Pins 10,11,13,14,15,16 // UART output wire uart_tx, // Pin 17 input wire uart_rx, // Pin 18 // MEMS microphone input wire pdm_data, // Pin 77 output wire pdm_clk, // Pin 76 // State machine control input wire state_transition, input wire [3:0] target_state, input wire operator_available, // OEPI inputs input signed [31:0] uncertainty, input signed [31:0] impact, input signed [31:0] time_sensitivity, input signed [31:0] irreversibility, input signed [31:0] live_voltage_risk, // Amplitude update inputs input wire amplitude_update_trigger, input signed [31:0] amplitude_old, input signed [31:0] amplitude_delta, // Profile collapse inputs input wire collapse_trigger, input wire [7:0] profile_id, // Outputs (registered for timing) output reg [3:0] scalar_state, output reg scalar_in_pool, output reg signed [31:0] oepi_output, output reg [1:0] oepi_threshold, output reg signed [31:0] amplitude_new, output reg collapse_valid, output reg [7:0] collapsed_profile ); // Pipeline Stage 1: OEPI calculation wire signed [31:0] oepi_stage1; reg signed [31:0] oepi_stage1_reg; oepi_calculator_opt oepi_inst ( .uncertainty(uncertainty), .impact(impact), .time_sensitivity(time_sensitivity), .irreversibility(irreversibility), .live_voltage_risk(live_voltage_risk), .oepi_score(oepi_stage1) ); always @(posedge clk or negedge rst_n) begin if (!rst_n) begin oepi_stage1_reg <= 32'sd0; end else begin oepi_stage1_reg <= oepi_stage1; end end // Pipeline Stage 2: Threshold classification + state machine wire [1:0] threshold_stage2; wire [3:0] state_stage2; wire pool_stage2; reg [1:0] threshold_stage2_reg; reg [3:0] state_stage2_reg; reg pool_stage2_reg; oepi_threshold_classifier_opt threshold_inst ( .oepi_score(oepi_stage1_reg), .threshold(threshold_stage2) ); always @(posedge clk or negedge rst_n) begin if (!rst_n) begin threshold_stage2_reg <= 2'b00; state_stage2_reg <= 4'd0; pool_stage2_reg <= 1'b0; end else begin threshold_stage2_reg <= threshold_stage2; state_stage2_reg <= state_stage2; pool_stage2_reg <= pool_stage2; end end // Pipeline Stage 3: Amplitude update + collapse wire signed [31:0] amplitude_stage3; wire collapse_valid_stage3; wire [7:0] collapsed_profile_stage3; amplitude_update_opt amplitude_inst ( .amplitude_old(amplitude_old), .delta(amplitude_delta), .amplitude_new(amplitude_stage3) ); profile_collapse_opt collapse_inst ( .collapse_trigger(collapse_trigger), .profile_id(profile_id), .collapse_valid(collapse_valid_stage3), .collapsed_profile(collapsed_profile_stage3) ); // Output registers (Stage 3) always @(posedge clk or negedge rst_n) begin if (!rst_n) begin scalar_state <= STATE_SUPERPOSED; scalar_in_pool <= 1'b1; oepi_output <= 32'sd0; oepi_threshold <= 2'b00; amplitude_new <= 32'sd0; collapse_valid <= 1'b0; collapsed_profile <= 8'h00; end else begin scalar_state <= state_stage2_reg; scalar_in_pool <= pool_stage2_reg; oepi_output <= oepi_stage1_reg; oepi_threshold <= threshold_stage2_reg; amplitude_new <= amplitude_update_trigger ? amplitude_stage3 : amplitude_old; collapse_valid <= collapse_valid_stage3; collapsed_profile <= collapsed_profile_stage3; end end // ═══════════════════════════════════════════════════════════════════════════ // LED Status Indicator // ═══════════════════════════════════════════════════════════════════════════ wire pattern_match_detected; led_status_opt led_inst ( .scalar_state(scalar_state), .scalar_in_pool(scalar_in_pool), .oepi_threshold(oepi_threshold), .collapse_valid(collapse_valid), .pattern_match(pattern_match_detected), .led(led) ); // ═══════════════════════════════════════════════════════════════════════════ // MEMS Microphone Interface // ═══════════════════════════════════════════════════════════════════════════ wire signed [31:0] audio_sample; wire sample_valid; wire [9:0] sample_addr; wire pattern_match; // Generate PDM clock (divide 27MHz by ~11 for ~2.4MHz) reg [3:0] pdm_clk_div; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin pdm_clk_div <= 4'd0; end else begin pdm_clk_div <= pdm_clk_div + 1'b1; end end assign pdm_clk = pdm_clk_div[3]; // 27MHz / 16 = 1.6875MHz mems_mic_interface_opt mic_inst ( .clk(clk), .mic_clk(pdm_clk), .mic_data(pdm_data), .mic_lr(1'b0), .audio_sample(audio_sample), .sample_valid(sample_valid), .sample_addr(sample_addr), .pattern_we(1'b0), .pattern_addr(10'd0), .pattern_threshold(32'sd0), .pattern_match(pattern_match) ); assign pattern_match_detected = pattern_match; // ═══════════════════════════════════════════════════════════════════════════ // UART Debug Output // ═══════════════════════════════════════════════════════════════════════════ reg uart_tx_start; reg [7:0] uart_tx_data; wire uart_tx_busy; uart_tx_opt uart_inst ( .clk(clk), .rst_n(rst_n), .tx_start(uart_tx_start), .tx_data(uart_tx_data), .uart_tx(uart_tx), .tx_busy(uart_tx_busy) ); // Simple UART transmission for state monitoring (transmit state on change) reg [3:0] prev_state; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin prev_state <= 4'd0; uart_tx_start <= 1'b0; uart_tx_data <= 8'd0; end else begin if (scalar_state != prev_state && !uart_tx_busy) begin prev_state <= scalar_state; uart_tx_data <= {4'h53, scalar_state}; // 'S' + state uart_tx_start <= 1'b1; end else begin uart_tx_start <= 1'b0; end end end // ═══════════════════════════════════════════════════════════════════════════ // User Button Integration // ═══════════════════════════════════════════════════════════════════════════ // User button triggers state transition to MEASURE_LOCAL_NEED reg user_btn_prev; wire user_btn_pressed = (user_btn && !user_btn_prev); always @(posedge clk or negedge rst_n) begin if (!rst_n) begin user_btn_prev <= 1'b0; end else begin user_btn_prev <= user_btn; end end // Override state transition when button pressed wire effective_state_transition = state_transition || user_btn_pressed; wire [3:0] effective_target_state = user_btn_pressed ? STATE_MEASURE_LOCAL_NEED : target_state; // Update state machine instantiation with effective signals scalar_state_machine_opt state_machine_inst_eff ( .clk(clk), .rst_n(rst_n), .transition_trigger(effective_state_transition), .target_state(effective_target_state), .operator_available(operator_available), .current_state(state_stage2), .in_pool(pool_stage2) ); endmodule // ═══════════════════════════════════════════════════════════════════════════ // BRAM Partial LUT for Pattern Matching // Stores adaptive pattern matching thresholds and weights // ═══════════════════════════════════════════════════════════════════════════ module bram_pattern_lut_opt ( input wire clk, input wire we, input wire [9:0] pattern_id, input signed [31:0] match_threshold, output reg signed [31:0] current_threshold, output wire match_detected ); // BRAM storage (1024 x 32-bit Q16.16) reg signed [31:0] pattern_memory [0:1023]; always @(posedge clk) begin if (we) begin pattern_memory[pattern_id] <= match_threshold; end current_threshold <= pattern_memory[pattern_id]; end // Match detection (threshold >= 0.5) localparam signed [31:0] MATCH_THRESHOLD = 32'sh00008000; // 0.5 in Q16.16 assign match_detected = (current_threshold >= MATCH_THRESHOLD); endmodule // ═══════════════════════════════════════════════════════════════════════════ // UART Debug Module (115200 baud @ 27MHz) // Simple UART transmitter for debugging // ═══════════════════════════════════════════════════════════════════════════ module uart_tx_opt ( input wire clk, input wire rst_n, input wire tx_start, input wire [7:0] tx_data, output reg uart_tx, output reg tx_busy ); // Baud rate generator for 115200 @ 27MHz // 27MHz / 115200 = 234.375 ≈ 234 localparam BAUD_DIV = 16'd234; reg [15:0] baud_counter; reg [2:0] bit_counter; reg [7:0] tx_shift; reg [2:0] state; // 0=IDLE, 1=START, 2-9=DATA, 10=STOP always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state <= 3'd0; baud_counter <= 16'd0; bit_counter <= 3'd0; tx_shift <= 8'd0; uart_tx <= 1'b1; tx_busy <= 1'b0; end else begin case (state) 3'd0: begin // IDLE uart_tx <= 1'b1; tx_busy <= 1'b0; if (tx_start) begin tx_shift <= tx_data; bit_counter <= 3'd0; baud_counter <= 16'd0; state <= 3'd1; tx_busy <= 1'b1; end end 3'd1: begin // START bit uart_tx <= 1'b0; if (baud_counter == BAUD_DIV) begin baud_counter <= 16'd0; state <= 3'd2; end else begin baud_counter <= baud_counter + 1'b1; end end 3'd2, 3'd3, 3'd4, 3'd5, 3'd6, 3'd7, 3'd8, 3'd9: begin // DATA bits uart_tx <= tx_shift[bit_counter]; if (baud_counter == BAUD_DIV) begin baud_counter <= 16'd0; if (bit_counter == 3'd7) begin state <= 3'd10; end else begin bit_counter <= bit_counter + 1'b1; end end else begin baud_counter <= baud_counter + 1'b1; end end 3'd10: begin // STOP bit uart_tx <= 1'b1; if (baud_counter == BAUD_DIV) begin state <= 3'd0; end else begin baud_counter <= baud_counter + 1'b1; end end endcase end end endmodule // ═══════════════════════════════════════════════════════════════════════════ // LED Status Indicator Module // Maps morphic scalar state to LED outputs // ═══════════════════════════════════════════════════════════════════════════ module led_status_opt ( input wire [3:0] scalar_state, input wire scalar_in_pool, input wire [1:0] oepi_threshold, input wire collapse_valid, input wire pattern_match, output reg [5:0] led ); always @(*) begin // LED[5]: State high nibble (bit 3) led[5] = scalar_state[3]; // LED[4]: State low nibble (bit 2) led[4] = scalar_state[2]; // LED[3]: OEPI threshold indicator (10 = critical) led[3] = (oepi_threshold == 2'b10); // LED[2]: Pool status led[2] = scalar_in_pool; // LED[1]: Collapse valid led[1] = collapse_valid; // LED[0]: Pattern match detected led[0] = pattern_match; end endmodule // ═══════════════════════════════════════════════════════════════════════════ // MEMS Microphone Interface (SPH0645) // I2S/PDM digital output interface for acoustic input // ═══════════════════════════════════════════════════════════════════════════ module mems_mic_interface_opt ( input wire clk, // System clock (27MHz) input wire mic_clk, // MEMS mic clock (typically 2.4MHz) input wire mic_data, // MEMS mic data (PDM or I2S) input wire mic_lr, // Left/Right select (I2S only) output reg signed [31:0] audio_sample, // Q16.16 audio sample output output reg sample_valid // Sample valid flag output reg [9:0] sample_addr // BRAM address for pattern matching input wire pattern_we, // Pattern match write enable input wire [9:0] pattern_addr, // Pattern match address input signed [31:0] pattern_threshold, // Pattern match threshold output wire pattern_match // Pattern match detected ); // PDM to PCM conversion (simplified) reg signed [15:0] pdm_accumulator; reg [7:0] pdm_counter; always @(posedge mic_clk) begin pdm_accumulator <= pdm_accumulator + {16'b0, mic_data}; pdm_counter <= pdm_counter + 1; if (pdm_counter == 8'd255) begin // Convert to Q16.16 (shift by 16) audio_sample <= {pdm_accumulator, 16'b0}; sample_valid <= 1'b1; pdm_accumulator <= 16'sd0; pdm_counter <= 8'd0; end else begin sample_valid <= 1'b0; end end // Pattern matching address generation assign sample_addr = audio_sample[9:0]; // Use lower 10 bits as address // Pattern match detection localparam signed [31:0] MATCH_THRESHOLD = 32'sh00008000; // 0.5 in Q16.16 assign pattern_match = (audio_sample >= MATCH_THRESHOLD); endmodule // ═══════════════════════════════════════════════════════════════════════════ // OPTIMIZED Testbench // ═══════════════════════════════════════════════════════════════════════════ module morphic_scalar_tb_opt; reg clk; reg rst_n; // User input reg user_btn; // UART wire uart_tx; reg uart_rx; // MEMS microphone reg pdm_data; wire pdm_clk; // State machine control reg state_transition; reg [3:0] target_state; reg operator_available; // OEPI inputs reg signed [31:0] uncertainty; reg signed [31:0] impact; reg signed [31:0] time_sensitivity; reg signed [31:0] irreversibility; reg signed [31:0] live_voltage_risk; // Amplitude update inputs reg amplitude_update_trigger; reg signed [31:0] amplitude_old; reg signed [31:0] amplitude_delta; // Profile collapse inputs reg collapse_trigger; reg [7:0] profile_id; // Outputs wire [3:0] scalar_state; wire scalar_in_pool; wire signed [31:0] oepi_output; wire [1:0] oepi_threshold; wire signed [31:0] amplitude_new; wire collapse_valid; wire [7:0] collapsed_profile; wire [5:0] led; // Instantiate DUT morphic_scalar_top_opt dut ( .clk(clk), .rst_n(rst_n), .user_btn(user_btn), .led(led), .uart_tx(uart_tx), .uart_rx(uart_rx), .pdm_data(pdm_data), .pdm_clk(pdm_clk), .state_transition(state_transition), .target_state(target_state), .operator_available(operator_available), .uncertainty(uncertainty), .impact(impact), .time_sensitivity(time_sensitivity), .irreversibility(irreversibility), .live_voltage_risk(live_voltage_risk), .amplitude_update_trigger(amplitude_update_trigger), .amplitude_old(amplitude_old), .amplitude_delta(amplitude_delta), .collapse_trigger(collapse_trigger), .profile_id(profile_id), .scalar_state(scalar_state), .scalar_in_pool(scalar_in_pool), .oepi_output(oepi_output), .oepi_threshold(oepi_threshold), .amplitude_new(amplitude_new), .collapse_valid(collapse_valid), .collapsed_profile(collapsed_profile) ); // Clock generation (27MHz - 37.037ns period) initial clk = 0; always #18.5185 clk = ~clk; // Test stimulus with pipeline verification initial begin // Initialize inputs rst_n = 0; user_btn = 0; uart_rx = 1; pdm_data = 0; state_transition = 0; target_state = 4'd0; operator_available = 1; uncertainty = 32'sh00008000; // 50.0 in Q16.16 impact = 32'sh00004E00; // 30.0 time_sensitivity = 32'sh00003333; // 20.0 irreversibility = 32'sh00001A00; // 10.0 live_voltage_risk = 32'sh00000D00; // 5.0 amplitude_update_trigger = 0; amplitude_old = 32'sh00008000; // 50.0 amplitude_delta = 32'sh00001000; // 10.0 collapse_trigger = 0; profile_id = 8'h01; #100; rst_n = 1; #200; $display("Initial State: %d", scalar_state); $display("In Pool: %b", scalar_in_pool); $display("LED Status: %b", led); // Test OEPI calculation (3 cycle latency due to pipeline) #200; $display("OEPI Score: %d", oepi_output); $display("OEPI Threshold: %b", oepi_threshold); $display("LED Status: %b", led); // Test state transition #200; target_state = STATE_MEASURE_LOCAL_NEED; state_transition = 1; #20; state_transition = 0; #200; $display("State after transition: %d", scalar_state); $display("LED Status: %b", led); // Test user button press #200; user_btn = 1; #50; user_btn = 0; #200; $display("State after button press: %d", scalar_state); $display("LED Status: %b", led); // Test amplitude update #200; amplitude_update_trigger = 1; #20; amplitude_update_trigger = 0; #200; $display("Amplitude New: %d", amplitude_new); $display("LED Status: %b", led); // Test profile collapse #200; collapse_trigger = 1; #20; collapse_trigger = 0; #200; $display("Collapse Valid: %b", collapse_valid); $display("Collapsed Profile: %d", collapsed_profile); $display("LED Status: %b", led); // Test operator unavailable -> low power passive mode #200; target_state = STATE_OPERATOR_ALERT; state_transition = 1; #20; state_transition = 0; #200; $display("State after operator alert: %d", scalar_state); $display("LED Status: %b", led); #100; operator_available = 0; #200; $display("State after operator unavailable: %d", scalar_state); $display("LED Status: %b", led); #200; $finish; end endmodule