Research-Stack/hardware/tangnano9k/rtl/generated/RGFlowFAMM.v

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