`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////
// Company: Tair
// Engineer: Churbanov S.
// 
// Create Date:     
// Design Name: 
// Module Name:    InterfaceArbiter
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////

module TopSbTmsgTb();

//================================================================================
//  REG/WIRE
	
	parameter OUTWORDWIDTH = 24;
	parameter SSPIWORDWIDTH = 24;
	parameter QSPIWORDWIDTH = 6;
	
	localparam [1:0] IDLE = 0;
	localparam [1:0] SINGLE = 1;
	localparam [1:0] DELAY = 2;
	localparam [1:0] QUAD = 3;
	
	reg spiMode = 1'b0; //0 - single 1- quad
	
	reg [31:0] tbCnt;
	reg [31:0] delCnt;
	reg stateCnt;
	
	reg Clk100;
	reg Clk10;
	
	reg [1:0] currState;
	reg [1:0] nextState;
	
	reg rst;
	
	wire txStart = (tbCnt == 100 | tbCnt == 3000);
	wire txDoneS;
	wire txDoneQ;
	
	
	wire sckS;
	wire sckQ;
	wire ssS;
	wire ssQ;
	
	wire ss;
	wire sck;
	
	wire mosi0S;
	wire mosi0Q;
	wire mosi1Q;
	wire mosi2Q;
	wire mosi3Q;
	
	wire delDone = (delCnt == 500);
//================================================================================
//  ASSIGNMENTS
	
	assign sck = (currState==SINGLE) ? sckS:sckQ;
	assign ss = (currState==SINGLE) ? ssS:ssQ;
	assign mosi0 = (currState==SINGLE) ? mosi0S:mosi0Q;
	assign mosi1 = (currState==SINGLE) ? 1'b1:mosi1Q;
	assign mosi2 = (currState==SINGLE) ? 1'b1:mosi2Q;
	assign mosi3 = (currState==SINGLE) ? 1'b1:mosi3Q;
//================================================================================
//clocks gen
	always	#5 Clk100	=	~Clk100;	
	always	#50 Clk10	=	~Clk10;	
	
	
//================================================================================
//  CODING

initial begin
	Clk100	=	1'b1;
	Clk10	=	1'b1;
	rst		=	1'b1;
#100;
	rst		=	1'b0;
end	
	
always	@(negedge	Clk100)	begin
	if	(!rst)		begin
		tbCnt	<=	tbCnt+1;
	end	else	begin
		tbCnt	<=	0;
	end
end

always	@(posedge	Clk100)	begin
	if	(!rst)		begin
		if (currState == DELAY) begin
			delCnt	<=	delCnt+1;
		end	else	begin
			delCnt	<=	0;
		end
	end else	begin
		delCnt	<=	0;
	end
end

always	@(negedge	Clk10)	begin
	if	(!rst)		begin
		if (txDoneS|txDoneQ) begin
			stateCnt	<=	stateCnt+1;
		end	
	end else begin
		stateCnt <= 0;
	end
end

always	@(posedge	Clk100)	begin
	if	(!rst)		begin
		case (stateCnt)
			0:	begin
					spiMode <= 1'b0;
				end
			1:	begin
					spiMode <= 1'b1;
				end
			default:begin
						spiMode <= 1'b0;
					end
		endcase
	end else begin
		spiMode <= 1'b0;
	end
end

always	@(posedge	Clk100)	begin
	if	(rst)	begin
		currState	<=	IDLE;
	end	else	begin
		currState	<=	nextState;
	end
end


always @(*) begin
	nextState	=	IDLE;
	case(currState)
	IDLE	:	begin
					if (txStart)	begin
						case (spiMode)
							1'b0:	begin
											nextState = SINGLE;
										end
							1'b1:		begin
											nextState = QUAD;
										end
						endcase
					end	else begin
						nextState = IDLE;
					end
				end
				
	SINGLE	:	begin
					if (txDoneS)	begin
						nextState = DELAY;
					end	else begin
						nextState = SINGLE;
					end
				end
				
	DELAY	:	begin
					if (delDone)	begin
						nextState = QUAD;
					end	else begin
						nextState = DELAY;
					end
				end
				
	QUAD		:	begin
					if (txDoneQ) begin
						nextState  = IDLE;
					end	else begin
						nextState  = QUAD;
					end
				end
	endcase
end

ExtSpiMEmul SingleSpiSm
(
	.Rst_i		(rst),
	.Clk_i		(Clk10),
	
	.Start_i	((currState==SINGLE)),
	.TxDone_o	(txDoneS),
	
	.Sck_o		(sckS),
	.Ss_o		(ssS),
	.Mosi_o		(mosi0S)
	
);

ExtQSpiMEmul QuadSpiSm
(
	.Rst_i		(rst),
	.Clk_i		(Clk10),
	
	.Start_i	((currState==QUAD)),
	.TxDone_o	(txDoneQ),
	
	.Sck_o		(sckQ),
	.Ss_o		(ssQ),
	.Mosi0_o	(mosi0Q),
	.Mosi1_o	(mosi1Q),
	.Mosi2_o	(mosi2Q),
	.Mosi3_o	(mosi3Q)
	
);

TopSbTmsg DUT
(
	.Clk_i	(Clk100),
	.Rst_i	(rst),
	
	.Sck_i	(sck),
	.Ss_i	(ss),
	
	.Mosi0_i	(mosi0),
	.Mosi1_io	(mosi1),
	.Mosi2_i	(mosi2),
	.Mosi3_i	(mosi3),
	
	.Miso1_i		(),
	.Miso2_i		(),
	.MisoMax2870_i	(),
	
	.I2CSck_o	(),
	.I2CSda_io	(),
	
	.Ss_o		(),
	.Sck_o		(),
	.Mosi_o		(),
	
	.Gpio_o		()
);

endmodule



















