Research-Stack/4-Infrastructure/hardware/metaprobe_stress_sensor.v

78 lines
3.7 KiB
Verilog

// Metaprobe Stress Sensor
// Uses Ring Oscillators to measure physical "frustration" (jitter/noise)
// Derived from Lean: Semantics/Metaprobe.lean
// Target: Gowin GW1NR-9 (Tang Nano 9K)
`timescale 1ns / 1ps
module metaprobe_stress_sensor (
input wire clk, // Reference clock (e.g. 27MHz)
input wire rst_n,
output wire [31:0] stress // Q16.16 stress signal
);
// ═══════════════════════════════════════════════════════════════════════════
// Ring Oscillator (RO) Array
// ═══════════════════════════════════════════════════════════════════════════
// We use a chain of inverters to create a free-running oscillator.
// The frequency is sensitive to temperature and voltage noise.
wire ro_out;
wire [7:0] ro_chain;
// Inverter chain (keep from being optimized away)
(* LUT_TYPE="RO" *) assign ro_chain[0] = ~ro_chain[7];
genvar i;
generate
for (i = 1; i < 8; i = i + 1) begin : gen_ro
assign ro_chain[i] = ~ro_chain[i-1];
end
endgenerate
assign ro_out = ro_chain[7];
// ═══════════════════════════════════════════════════════════════════════════
// Jitter Measurement (Frustration)
// ═══════════════════════════════════════════════════════════════════════════
// Compare RO cycles against ref clock to detect variance (stress).
reg [15:0] ro_counter;
reg [15:0] ref_counter;
reg [15:0] last_ro_count;
reg [15:0] jitter_accum;
always @(posedge ro_out or negedge rst_n) begin
if (!rst_n) ro_counter <= 16'd0;
else ro_counter <= ro_counter + 1;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
ref_counter <= 16'd0;
last_ro_count <= 16'd0;
jitter_accum <= 16'd0;
end else begin
ref_counter <= ref_counter + 1;
// Every 2^12 cycles of ref clock, sample RO counter
if (ref_counter[11:0] == 12'hFFF) begin
last_ro_count <= ro_counter;
// Jitter = absolute difference from expected nominal count
// (Nominal is arbitrary here, we care about change/variance)
if (ro_counter > last_ro_count)
jitter_accum <= ro_counter - last_ro_count;
else
jitter_accum <= last_ro_count - ro_counter;
end
end
end
// ═══════════════════════════════════════════════════════════════════════════
// Output Mapping
// ═══════════════════════════════════════════════════════════════════════════
// Map jitter to Q16.16 stress.
// baseline jitter = low stress. high variance = high stress.
assign stress = {16'b0, jitter_accum}; // Simple mapping for PoC
endmodule