`timescale 1ns / 1ps (* KEEP = "TRUE" *) ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: Churbanov S. // // Create Date: 15:24:31 08/20/2019 // Design Name: // Module Name: gain_master // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.02 - File Modified // Additional Comments: 16.09.2019 file modified in assotiate with task. // ////////////////////////////////////////////////////////////////////////////////// module GainControl #( parameter AdcNcoMultWidth = 35, parameter ThresholdWidth = 24, parameter AdcDataWidth = 14, parameter MeasPeriod = 32 ) ( input Rst_i, input Clk_i, input StartMeas_i, input GainAutoEn_i, input signed [AdcNcoMultWidth-1:0] AdcCos_i, input signed [AdcNcoMultWidth-1:0] AdcSin_i, input [ThresholdWidth-1:0] GainLowThreshold_i, input [ThresholdWidth-1:0] GainHighThreshold_i, output GainNewState_o, output SensEn_o, output MeasStart_o ); //================================================================================ // LOCALPARAMS localparam CntWidth = 32; localparam Delay = 100; localparam AverageDelay = MeasPeriod+Delay-1; localparam SumWidth = AdcNcoMultWidth+6-1; //================================================================================ // REG/WIRE reg [CntWidth-1:0] measCnt; reg signed [SumWidth-1:0] adcSinSum; reg signed [SumWidth-1:0] adcCosSum; reg measWind; wire measEnd = (measCnt==AverageDelay-1)&measWind; reg gainNewStateR; reg gainNewState; wire sensEn = ((gainNewStateR& (!gainNewState))|(!gainNewStateR&gainNewState)); reg signed [SumWidth-1:0] sinShifted; reg signed [SumWidth-1:0] cosShifted; wire signed [ThresholdWidth-5:0] sinShiftedCut = sinShifted [(SumWidth-1)-:20]; //width is 20 wire signed [ThresholdWidth-5:0] cosShiftedCut = cosShifted [(SumWidth-1)-:20]; //width is 20 wire signed [(ThresholdWidth*2)-9:0] sinSumSquared = (sinShiftedCut*sinShiftedCut); // width is 40 wire signed [(ThresholdWidth*2)-9:0] cosSumSquared = (cosShiftedCut*cosShiftedCut); // width is 40 wire signed [(ThresholdWidth*2)-9:0] sumSquared = (cosSumSquared+sinSumSquared); //width is 40 wire [(ThresholdWidth*2)-9:0] lowThresholdCompl = {10'b0,GainLowThreshold_i,6'b0}; wire [(ThresholdWidth*2)-9:0] highThresholdCompl = {10'b0,GainHighThreshold_i,6'b0}; wire accWind = (measCnt>0 & measCnt <=MeasPeriod-2); //================================================================================ // ASSIGNMENTS assign GainNewState_o = gainNewState; assign SensEn_o = sensEn; assign MeasStart_o = GainAutoEn_i? measEnd:StartMeas_i; //================================================================================ // CODING always @(posedge Clk_i) begin if (!Rst_i) begin if (GainAutoEn_i) begin if (StartMeas_i) begin measWind <= 1'b1; end else if (measEnd) begin measWind <= 1'b0; end end else begin measWind <= 1'b0; end end else begin measWind <= 1'b0; end end always @(posedge Clk_i) begin if (measWind) begin if (measCnt == MeasPeriod-2) begin sinShifted <= adcSinSum>>>2; cosShifted <= adcCosSum>>>2; end end end always @(posedge Clk_i) begin if (!Rst_i) begin if (measWind) begin if (measCnt != AverageDelay-1) begin measCnt <= measCnt + 3'd1; end end else begin measCnt <= 3'd0; end end else begin measCnt <= 3'd0; end end always @(posedge Clk_i) begin if (!Rst_i) begin if (!accWind) begin adcSinSum <= AdcSin_i; adcCosSum <= AdcCos_i; end else begin adcSinSum <= adcSinSum + AdcSin_i; adcCosSum <= adcCosSum + AdcCos_i; end end else begin adcSinSum <= 0; adcCosSum <= 0; end end always @(posedge Clk_i) begin if (!Rst_i) begin if (GainAutoEn_i) begin if (measCnt == MeasPeriod-1) begin if (gainNewState) begin if (sumSquared > highThresholdCompl) begin gainNewState <= 1'b0; end else begin gainNewState <= gainNewState; end end else begin if (sumSquared < lowThresholdCompl) begin gainNewState <= 1'b1; end else begin gainNewState <= gainNewState; end end end end else begin gainNewState <= 1'b0; end end else begin gainNewState <= 1'b0; end gainNewStateR <= gainNewState; end endmodule