mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
179 lines
6.7 KiB
Verilog
179 lines
6.7 KiB
Verilog
// Auto-generated from Lean: Semantics.Hardware.TangNano9K.RGFlowFAMM.emitRGFlowFAMM
|
|
// Source of truth: Semantics.Hardware.TangNano9K.RGFlowFAMM.rgflowStep + fammUpdate
|
|
// Theorems: rgflowSigmaBounded, rgflowRPBounded, fammCountersBounded, fammWarnCorrect
|
|
//
|
|
// DO NOT EDIT BY HAND. Regenerate via: lake exe tangnano9k_emitter
|
|
|
|
`timescale 1ns / 1ps
|
|
|
|
module rgflow_famm #(
|
|
parameter W = 12,
|
|
parameter THRESH = 16'd650,
|
|
parameter NEAR_MISS_BAND = 8'd160,
|
|
parameter DECAY_FRUST = 8'd6,
|
|
parameter DECAY_TORS = 8'd4,
|
|
parameter DECAY_BASIN = 8'd2,
|
|
parameter BASIN_INC = 8'd2,
|
|
parameter NEAR_BASIN_INC = 8'd1,
|
|
parameter WARN_AT = 8'd240
|
|
)(
|
|
input wire clk,
|
|
input wire rst,
|
|
input wire valid_in,
|
|
input wire signed [W-1:0] nii_a,
|
|
input wire signed [W-1:0] nii_t,
|
|
input wire signed [W-1:0] nii_g,
|
|
input wire signed [W-1:0] nii_c,
|
|
input wire [7:0] coherence,
|
|
input wire [7:0] compression,
|
|
input wire [7:0] failure,
|
|
input wire [7:0] expand_prior,
|
|
output reg valid_out,
|
|
output reg [9:0] sigma,
|
|
output reg [7:0] reject_pressure,
|
|
output reg [7:0] torsion_delta,
|
|
output reg [7:0] famm_frustration,
|
|
output reg [7:0] famm_basin,
|
|
output reg [7:0] famm_torsion,
|
|
output reg [2:0] verdict_oh,
|
|
output reg warn_frustration,
|
|
output reg warn_torsion,
|
|
output reg warn_basin,
|
|
output reg warn_any,
|
|
output reg sat_frustration,
|
|
output reg sat_torsion,
|
|
output reg sat_basin,
|
|
output reg sat_any,
|
|
output reg famm_changed,
|
|
output reg [7:0] status_byte
|
|
);
|
|
wire [W-1:0] abs_a = nii_a[W-1] ? -nii_a : nii_a;
|
|
wire [W-1:0] abs_t = nii_t[W-1] ? -nii_t : nii_t;
|
|
wire [W-1:0] abs_g = nii_g[W-1] ? -nii_g : nii_g;
|
|
wire [W-1:0] abs_c = nii_c[W-1] ? -nii_c : nii_c;
|
|
wire [W+1:0] surprise_mag = (abs_a + abs_t + abs_g + abs_c) >> 2;
|
|
|
|
function [7:0] lin_decay;
|
|
input [7:0] x;
|
|
input [7:0] d;
|
|
begin
|
|
lin_decay = (x > d) ? (x - d) : 8'd0;
|
|
end
|
|
endfunction
|
|
|
|
function [7:0] sat8_add;
|
|
input [7:0] a;
|
|
input [7:0] b;
|
|
reg [8:0] s;
|
|
begin
|
|
s = a + b;
|
|
sat8_add = s[8] ? 8'hff : s[7:0];
|
|
end
|
|
endfunction
|
|
|
|
reg signed [16:0] sigma_tmp;
|
|
reg [7:0] rp;
|
|
reg [7:0] td;
|
|
reg [7:0] frust_d, tors_d, basin_d;
|
|
reg [7:0] frust_n, tors_n, basin_n;
|
|
reg [2:0] verdict_n;
|
|
reg warn_n_any, sat_n_any, famm_chg_n;
|
|
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
valid_out <= 1'b0;
|
|
sigma <= 10'd0;
|
|
reject_pressure <= 8'd0;
|
|
torsion_delta <= 8'd0;
|
|
famm_frustration <= 8'd0;
|
|
famm_basin <= 8'd0;
|
|
famm_torsion <= 8'd0;
|
|
verdict_oh <= 3'b000;
|
|
warn_frustration <= 1'b0;
|
|
warn_torsion <= 1'b0;
|
|
warn_basin <= 1'b0;
|
|
warn_any <= 1'b0;
|
|
sat_frustration <= 1'b0;
|
|
sat_torsion <= 1'b0;
|
|
sat_basin <= 1'b0;
|
|
sat_any <= 1'b0;
|
|
famm_changed <= 1'b0;
|
|
status_byte <= 8'h00;
|
|
end else begin
|
|
valid_out <= valid_in;
|
|
if (valid_in) begin
|
|
sigma_tmp = $signed(17'sd256)
|
|
+ ($signed({9'd0, coherence}) <<< 1)
|
|
+ $signed({9'd0, expand_prior})
|
|
+ $signed({9'd0, compression})
|
|
- ($signed({9'd0, failure}) <<< 1)
|
|
- $signed({9'd0, surprise_mag[7:0]})
|
|
- $signed({9'd0, famm_frustration})
|
|
- $signed({9'd0, famm_torsion});
|
|
|
|
if (sigma_tmp < 0) sigma <= 10'd0;
|
|
else if (sigma_tmp > $signed(17'sd1023)) sigma <= 10'd1023;
|
|
else sigma <= sigma_tmp[9:0];
|
|
|
|
if (sigma_tmp >= $signed({1'b0, THRESH})) begin
|
|
rp = 8'd0;
|
|
verdict_n = 3'b001;
|
|
end else begin
|
|
rp = (THRESH - sigma_tmp[15:0] > 16'd255) ? 8'hff
|
|
: (THRESH - sigma_tmp[15:0]);
|
|
verdict_n = (rp <= NEAR_MISS_BAND) ? 3'b010 : 3'b100;
|
|
end
|
|
if (verdict_n == 3'b001) td = 8'd0;
|
|
else if (verdict_n == 3'b010) td = (rp >> 1);
|
|
else td = rp;
|
|
|
|
frust_d = lin_decay(famm_frustration, DECAY_FRUST);
|
|
tors_d = lin_decay(famm_torsion, DECAY_TORS);
|
|
basin_d = lin_decay(famm_basin, DECAY_BASIN);
|
|
|
|
case (verdict_n)
|
|
3'b001: begin
|
|
basin_n = sat8_add(basin_d, BASIN_INC);
|
|
frust_n = (frust_d != 0) ? frust_d - 1'b1 : 8'd0;
|
|
tors_n = tors_d;
|
|
end
|
|
3'b010: begin
|
|
basin_n = sat8_add(basin_d, NEAR_BASIN_INC);
|
|
frust_n = sat8_add(frust_d, rp / 8'd16);
|
|
tors_n = sat8_add(tors_d, td / 8'd32);
|
|
end
|
|
default: begin
|
|
basin_n = basin_d;
|
|
frust_n = sat8_add(frust_d, rp / 8'd12);
|
|
tors_n = sat8_add(tors_d, td / 8'd24);
|
|
end
|
|
endcase
|
|
|
|
warn_frustration <= (frust_n >= WARN_AT);
|
|
warn_torsion <= (tors_n >= WARN_AT);
|
|
warn_basin <= (basin_n >= WARN_AT);
|
|
warn_n_any = (frust_n >= WARN_AT) | (tors_n >= WARN_AT) | (basin_n >= WARN_AT);
|
|
warn_any <= warn_n_any;
|
|
sat_frustration <= (frust_n == 8'hff);
|
|
sat_torsion <= (tors_n == 8'hff);
|
|
sat_basin <= (basin_n == 8'hff);
|
|
sat_n_any = (frust_n == 8'hff) | (tors_n == 8'hff) | (basin_n == 8'hff);
|
|
sat_any <= sat_n_any;
|
|
famm_chg_n = (frust_n != famm_frustration)
|
|
| (tors_n != famm_torsion)
|
|
| (basin_n != famm_basin);
|
|
famm_changed <= famm_chg_n;
|
|
|
|
famm_frustration <= frust_n;
|
|
famm_torsion <= tors_n;
|
|
famm_basin <= basin_n;
|
|
|
|
verdict_oh <= verdict_n;
|
|
status_byte <= {1'b0, 1'b0, famm_chg_n, sat_n_any, warn_n_any,
|
|
verdict_n[2], verdict_n[1], verdict_n[0]};
|
|
reject_pressure <= rp;
|
|
torsion_delta <= td;
|
|
end
|
|
end
|
|
end
|
|
endmodule
|