// SPDX-FileCopyrightText: 2021 renzym.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileContributor: Yasir Javed <info@renzym.com>


//////////////////////////////////////////////////////////////////////////////////
// Company: 		Renzym
// Engineer: 		Yasir Javed
// Design Name: 	Address Generation Unit
// Module Name:		agu
// Description: 	AGU generates BRAM address for 3xN convolution. It is assumed that image
//					and kernels are stored in external BRAMs. The results are written  
//					back to external BRAM too. Simlarly configurations are also assumed
//					to be external. Based on configurations, this block will start
//					working when start signal is asserted (level signal) and when done
//					done signal will be asserted. There is an optional maxpool layer too.
//
//					Configs and BRAMs are kept external, so that this generic block can 
//					remain independent and can mux between different configs and datas.
//					It also keeps provision of making it cascadable open.
//
//					External config block also ensures that there can be different such 
//					blocks for different interfaces (e.g. AXI, Wishbone etc.) without affecting
//					rest of the design.
// 
// Dependencies:	Configs and BRAMs. 
//
//////////////////////////////////////////////////////////////////////////////////
module agu
	#(
	parameter KERN_COL_WIDTH 	= 3,
	parameter COL_WIDTH 		= 8,
	parameter KERN_CNT_WIDTH 	= 3,
	parameter IMG_ADDR_WIDTH 	= 8,
	parameter RSLT_ADDR_WIDTH 	= 8
	
	)
	(
	input								clk,
	input								reset,
	input								start,
	input								en_result_addr,
	
	// Configurations
	input 		[KERN_COL_WIDTH-1:0]	kern_cols,
	input		[COL_WIDTH-1:0]			cols,
	input		[KERN_CNT_WIDTH-1:0]	kerns,
	input		[IMG_ADDR_WIDTH-1:0]	stride,
	input								kern_addr_mode,
	input		[RSLT_ADDR_WIDTH-1:0]	result_cols,
	
	//
	output	reg	[KERN_CNT_WIDTH+KERN_COL_WIDTH-1:0]	kern_addr,
	output	reg	[IMG_ADDR_WIDTH-1:0]				img_addr,
	output	reg	[RSLT_ADDR_WIDTH-1:0]				result_addr,
	output	reg										clr_k_col_cnt,
	output	reg										clr_col_cnt,
	output	reg										done
	);

	reg start_d;
	reg start_res;
	reg	start_pedge;

	reg [KERN_COL_WIDTH-1:0]	k_col_cnt;	// kernel col count
	//reg							clr_k_col_cnt;
	reg							en_k_col_cnt;
	
	reg	[COL_WIDTH-1:0]			col_cnt;	// image col count
	//reg							clr_col_cnt;
	reg							en_col_cnt;
	
	reg	[KERN_CNT_WIDTH-1:0]	kerns_cnt;		// kernel# count
	reg							clr_kerns_cnt;
	reg							en_kerns_cnt;

	reg	[IMG_ADDR_WIDTH-1:0]	img_st;		
	reg							clr_img_st;
	reg							en_img_st;

	reg							clr_img_addr;
	reg							en_img_addr;
	reg							clr_result_addr;
	//reg							en_result_addr;
	
	// Kernel col counter
	always@(posedge clk)
		if(reset | clr_k_col_cnt)	k_col_cnt <= 0;
		else if(en_k_col_cnt) 		k_col_cnt <= k_col_cnt + 1;

	always@* clr_k_col_cnt 	= (k_col_cnt == kern_cols) & start;
	always@* en_k_col_cnt	= start;

	// Image col counter
	always@(posedge clk)
		if(reset | clr_col_cnt)	col_cnt <= 0;
		else if(en_col_cnt) 		col_cnt <= col_cnt + 1;

	always@* clr_col_cnt 	= (col_cnt == cols) & en_col_cnt;
	always@* en_col_cnt	= clr_k_col_cnt;

	// Kernel#  counter
	always@(posedge clk)
		if(reset | clr_kerns_cnt)	kerns_cnt <= 0;
		else if(en_kerns_cnt) 		kerns_cnt <= kerns_cnt + 1;

	always@* clr_kerns_cnt 	= (kerns_cnt == kerns) & en_kerns_cnt;
	always@* en_kerns_cnt	= clr_col_cnt;

	// Image address start value counter
	always@(posedge clk)
		if(reset | clr_img_st | start_pedge)	// ##TODO## Verify whether this works for 1x1 convolution case
			img_st <= stride;
		else if(en_img_st) 
			img_st <= img_st + stride;

	always@* clr_img_st = clr_col_cnt;
	always@* en_img_st	= clr_k_col_cnt;
	
	
	// Image BRAM Address
	always@(posedge clk)
		if(reset | clr_img_st)	img_addr <= 0;
		else if(clr_img_addr)	img_addr <= img_st;
		else if(en_img_addr) 	img_addr <= img_addr + 1;

	always@* clr_img_addr 	= clr_k_col_cnt;
	always@* en_img_addr	= start;
	
	always@* kern_addr = kern_addr_mode ? {kerns_cnt,k_col_cnt}:{1'b0,kerns_cnt,k_col_cnt[KERN_COL_WIDTH-2:0]};

	
	always@(posedge clk)
		if(reset)	start_d <= 0;
		else		start_d <= start;

	always@* start_pedge = start & ~start_d;
	
	// Results RAM address
	always@(posedge clk)
		if(reset | clr_result_addr)	result_addr <= 0;
		else if(en_result_addr) 	result_addr <= result_addr + 1;

	always@* clr_result_addr	= (result_addr == result_cols) & en_result_addr;
//	always@* en_result_addr		= start_res;	
	
	wire [7:0] clr_kerns_cnt_d;
	serial_shift
	#(
	.DLY_WIDTH 	(8				)
	)
	ser_shift_done
	(
	.clk		(clk			),
	.reset		(reset			),
	.ser_in		(clr_kerns_cnt	),
	.par_out	(clr_kerns_cnt_d)
	);
	
	always@(posedge clk)
		if(reset)					done <= 0;
		else if(clr_kerns_cnt_d[3])	done <= 1;
	

endmodule
