///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------------------------------------------------------------------------------

/*
 * Copyright (C) 2026 Microchip Technology Inc. and its subsidiaries.
 * All rights reserved.
 * Subject to your compliance with the conditions set forth herein,
 * redistribution and use in source and binary forms, with or without
 * modification, are permitted.
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. Neither Microchip's name nor the names of any contributors may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS SUPPLIED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF
 * NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT WILL MICROCHIP OR ANY CONTRIBUTORS BE LIABLE FOR ANY INDIRECT,
 * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE
 * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF
 * ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE.
 */
//-------------------------------------------------------------------
// Title        : fabric_logic.v
// Created      : November-2017
// Description  : This module instantiates fabric logic (LUT/DFF), 
//                LSRAMs, uSRAMs and Mathblocks
// Hierarchy    :
//                
//                Top_Level
//                 -- Fabric_LSRAM_USRAM_MACC
//                  -- fabric_logic.v              <-- This module
//
// Target device: <Family:PolarFire> <Die:MPF300TS_ES> <Pkg:FCG1152>
//-------------------------------------------------------------------
module fabric_logic #(parameter WIDTH1 = 16,
                                WIDTH2 = 18)
                    (input CLK,                 //Fabric clock
                     input CLK1,                //uSRAM clock
                     input CLK2,                //LSRAM clock
                     input CLK3,                //MACC clock
                     input RST,                 //Reset for logic driven by CLK
                     input RST1,                //Reset for logic driven by CLK1
                     input RST2,                //Reset for logic driven by CLK2
                     input RST3,                //Reset for logic driven by CLK3    
                     input LD,                  //Load input
                     input[WIDTH1 - 1 : 0] DIN, //Input data for counter logic
                     output dout_or,
                     output LED_1,              //Fabric logic output
                     output LED_2,              //Fabric logic output
                     output LED_3,              //LSRAM logic output 
                     output LED_4,              //LSRAM logic output
                     output LED_5,              //uSRAM logic output
                     output LED_6,              //uSRAM logic output
                     output LED_7,              //Mathblock logic output
                     output LED_8               //Mathblock logic output
                    );
  wire[WIDTH1 - 1 : 0] REG_ARRAY1;
  wire[WIDTH1 - 1 : 0] REG_ARRAY3;
  wire signed[WIDTH2 - 1 : 0] REG_ARRAY4;
  wire signed[11 : 0] REG_ARRAY6;
  wire signed[47 : 0] REG_ARRAY5;
  wire[17 : 0] DOUT;

  reg[25 : 0] CNTVAL;
  reg[25 : 0] CNTVAL_t;
  reg[25 : 0] CNTVAL_t1;
  reg[25 : 0] CNTVAL_t2;
  reg[15 : 0] CNT_IN;
  reg[17 : 0] CNT_DIN;
  reg[17 : 0] CNT_DIN1;   
  reg[17 : 0] CNT_DIN2;  
  reg[11 : 0] CNT_DIN3;
  
  //Logic to counter input    
  always
    @(posedge CLK or
      negedge RST)
    begin
      if (RST == 1'b0)
        CNT_IN <= 'd0;
      else
        begin
          CNT_IN <= CNT_IN + 1'b1;
        end
    end
  //Logic to trigger counter using Fabric logic output 
  always
    @(posedge CLK or
      negedge RST)
    begin
      if (RST == 1'b0)
        CNTVAL <= { 26 { 1'b0 } };
      else
        begin
          if (REG_ARRAY1[15] == 1'b1)
            CNTVAL <= CNTVAL + 1'b1;
          else
            CNTVAL <= CNTVAL;
        end
    end
  //Logic to trigger counter using LSRAM logic output
  always
    @(posedge CLK2 or
      negedge RST2)
    begin: U7
      if (RST2 == 1'b0)
        CNTVAL_t <= { 26 { 1'b0 } };
      else
        begin
          if (REG_ARRAY4[15] == 1'b1)
            CNTVAL_t <= CNTVAL_t + 1'b1;
          else
            CNTVAL_t <= CNTVAL_t;
        end
    end
  //Logic to trigger counter using uSRAM logic output
  always
    @(posedge CLK1 or
      negedge RST1)
    begin: U8
      if (RST1 == 1'b0)
        CNTVAL_t2 <= { 26 { 1'b0 } };
      else
        begin
          if (REG_ARRAY6[10] == 1'b1)
            CNTVAL_t2 <= CNTVAL_t2 + 1'b1;
          else
            CNTVAL_t2 <= CNTVAL_t2;
        end
    end
  //Logic to trigger counter using Mathblock logic output
  always
    @(posedge CLK3 or
      negedge RST3)
    begin
      if (RST3 == 1'b0)
        CNTVAL_t1 <= { 26 { 1'b0 } };
      else
        begin
          if (REG_ARRAY5[10] == 1'b1)
            CNTVAL_t1 <= CNTVAL_t1 + 1'b1;
          else
            CNTVAL_t1 <= CNTVAL_t1;
        end
    end
  //Input data to LSRAM blocks        
  always
    @(posedge CLK2 or
      negedge RST2)
    begin: U11
      if (RST2 == 1'b0)
        CNT_DIN <= { 18 { 1'b0 } };
      else
        begin
          CNT_DIN <= CNT_DIN + 1'b1;
        end
    end
  //Input data to MACC blocks         
  always
    @(posedge CLK3 or
      negedge RST3)
    begin
      if (RST3 == 1'b0)
        CNT_DIN1 <= { 18 { 1'b0 } };
      else
        begin
          CNT_DIN1 <= CNT_DIN1 + 1'b1;
        end
    end
  always
    @(posedge CLK3 or
      negedge RST3)
    begin
      if (RST3 == 1'b0)
        CNT_DIN2 <= { 18 { 1'b0 } };
      else
        begin
          CNT_DIN2 <= CNT_DIN2 + 1'b1;
        end
    end
  //--------------------------
  //Input data to uSRAM blocks
  always
    @(posedge CLK1 or
      negedge RST1)
    begin
      if (RST1 == 1'b0)
        CNT_DIN3 <= { 12 { 1'b0 } };
      else
        begin
          CNT_DIN3 <= CNT_DIN3 + 1'b1;
        end
    end
  assign DOUT = (REG_ARRAY3 & REG_ARRAY5[17 : 0] & REG_ARRAY5[35 : 18]);
  assign dout_or = |(DOUT);
  //Fabric Counter outputs 
  assign LED_1 = CNTVAL[22];
  assign LED_2 = CNTVAL[23];
  //LSRAM outputs 
  assign LED_3 = CNTVAL_t[24];
  assign LED_4 = CNTVAL_t[25];
  //MACC outputs 
  assign LED_5 = CNTVAL_t1[24];
  assign LED_6 = CNTVAL_t1[25];
  //uSRAM outputs 
  assign LED_7 = CNTVAL_t2[20];
  assign LED_8 = CNTVAL_t2[21];
  //Fabric logic instantiation 
  cnt_up_cascade #(.WIDTH(WIDTH1), .NO_OF_STAGES(30)) U1(.CLK(CLK),
                                                         .RST(RST),
                                                         .DIN(CNT_IN),
                                                         .DOUT(REG_ARRAY1)
														 )/* synthesis syn_noprune=1 */;
  //uSRAM blocks instantiation 
  uSRAM_cascaded #(.WIDTH(12), .DEPTH(64), .ADDR(6), .NO_OF_STAGES(500)) U20(.clk(CLK1),
                                                                             .rst_n(RST1),
                                                                             .DIN(CNT_DIN3),
                                                                             .DOUT(REG_ARRAY6)
																			 )/* synthesis syn_noprune=1 */ ;

  //LSRAM blocks instantiation
  LSRAM_cascaded #(.WIDTH(WIDTH2), .DEPTH(1024), .ADDR(10), .NO_OF_STAGES(492)) U6(.clk(CLK2),
                                                                                   .rst(RST2),
                                                                                   .DIN(CNT_DIN),
                                                                                   .DOUT(REG_ARRAY4)
																				   )/* synthesis syn_noprune=1 */;

  //MACC blocks instantiation
  MACC_cascaded #(.WIDTH(WIDTH2), .NO_OF_STAGES(500)) U10(.clk(CLK3),
                                                          .rst(RST3),
                                                          .DIN1(CNT_DIN1),
                                                          .DIN2(CNT_DIN2),
                                                          .DOUT_t(REG_ARRAY5),
                                                          .DOUT()
														  )/* synthesis syn_noprune=1 */;

endmodule
