dakies/OSS_Verilog huggingface dataset:
module uart_tx 
	(
		input clk,rst_n,
		input s_tick, tx_start,
		input[7:0] din,
		input[3:0] databits, //either 8 or 7 databits
		input[5:0] stopbits, //either 16 or 32 ticks for 1 and 2 stopbits,respectively
		input [1:0] paritybit, //0-no parity, 1=odd parity , 2=even parity
		output reg tx_done_tick,
		output tx
    );
	 //FSM state declarations
	 localparam[2:0] idle=3'd0,
							start=3'd1,
							data=3'd2,
							parity=3'd3,
							stop=3'd4;
	 reg[2:0] state_reg,state_nxt;
	 reg[5:0] s_reg,s_nxt; //count to 16 for every data bit
	 reg[2:0] n_reg,n_nxt; //count the number of data bits already transmitted
	 reg[7:0] din_reg,din_nxt; //stores the word to be transmitted
	 reg tx_reg,tx_nxt;
	 reg[7:0] din_temp;
	 //FSM register operation
	 always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			state_reg<=idle;
			s_reg<=0;
			n_reg<=0;
			din_reg<=0;
			tx_reg<=0;
		end
		else begin
			state_reg<=state_nxt;
			s_reg<=s_nxt;
			n_reg<=n_nxt;
			din_reg<=din_nxt;
			tx_reg<=tx_nxt;
		end
	 end
	 //FSM next-state logic
	 always @* begin
		 state_nxt=state_reg;
		 s_nxt=s_reg;
		 n_nxt=n_reg;
		 din_nxt=din_reg;
		 tx_nxt=tx_reg;
		 tx_done_tick=0;
		 din_temp=0;
		 case(state_reg)
				idle: begin //wait for the buffer to have at least one word stored
							tx_nxt=1;
							if(tx_start==0) begin //tx_start is  connected to the inverted empty port of fifo buffer
								din_nxt=din;

								s_nxt=0;
								state_nxt=start;
							end
						end
			  start: begin   //wait to finish the start bit
							tx_nxt=0;
							if(s_tick==1) begin
								if(s_reg==15) begin
									s_nxt=0;
									n_nxt=0;
									state_nxt=data;
								end
								else s_nxt=s_reg+1;
							end
						end
				data: begin  //wait for all data bits to be transmitted serially
							tx_nxt=din_reg[0];
							if(s_tick==1) begin
								if(s_reg==15) begin
									din_nxt=din_reg>>1;
									s_nxt=0;
									if(n_reg==databits-1) state_nxt=parity;
									else n_nxt=n_reg+1;
								end
								else s_nxt=s_reg+1;
							end
						end
						
				parity: begin
							if(paritybit==0) state_nxt=stop;
							else begin
								din_temp=(databits==8)? din : din[6:0];
								tx_nxt=(paritybit==1)? {!{^din_temp}} : {^din_temp};
								if(s_tick==1) begin
									if(s_reg==15) begin
										state_nxt=stop;
										s_nxt=0;
									end
									else s_nxt=s_reg+1;
								end
							end
							
						  end
				
				stop: begin  //wait to finish the stop bit
							tx_nxt=1;
							if(s_tick==1) begin
								if(s_reg==stopbits-1) begin
									tx_done_tick=1;
									state_nxt=idle;
								end
								else s_nxt=s_reg+1;
							end
						end
			default: state_nxt=idle;
		 endcase
	 end
	 assign tx=tx_reg;
	 
	 
 


endmodule
module parking_lot_counter_TEST(
	input clk,rst_n,
	input a,b,
	output[7:0] seg_out,
	output[5:0] sel_out
    );
	 reg[3:0] mod_16_reg=0;
	 wire[3:0] mod_16_nxt;
	 wire a_db,b_db,enter,exit;
	 reg[3:0] in0,in1;
	 
	 //debounce the button "a" and "b" first
	 debouncing_button db_m0(
	.clk(clk),
	.rst_n(rst_n),
	.sw_low(a), //active low
	.db(a_db) //active high
    );
	 debouncing_button db_m1(
	.clk(clk),
	.rst_n(rst_n),
	.sw_low(b), //active low
	.db(b_db) //active high
    );
	 
	 // instantiation of lot-counter circuit
	 parking_lot_counter lot_m0(
		.clk(clk), 
		.rst_n(rst_n), 
		.a(a_db), 
		.b(b_db), 
		.enter(enter), 
		.exit(exit)
	);
	
	//Mod-16 counter that increments/decrements based on the tick of enter/exit
	always @(posedge clk,negedge rst_n) begin
		if(!rst_n) mod_16_reg<=0;
		else mod_16_reg<=mod_16_nxt;
	end
		assign mod_16_nxt=enter? mod_16_reg+1:(exit? mod_16_reg-1:mod_16_reg);
	
	//Logic for converting hexadecimal to 2-digit BCD 
	always @* begin
		if(mod_16_reg>9) begin
			in0=mod_16_reg-4'd10;
			in1=4'd1;
		end
		else begin
			in0=mod_16_reg;
			in1=4'd0;
		end
	end
	//Instantiation of LED-mux module
		LED_mux led_mux
		(
		.clk(clk),
		.rst(rst_n),
		.in0(in0),
		.in1(in1),
		.in2(0),
		.in3(0),
		.in4(0),
		.in5(0),
		.seg_out(seg_out),
		.sel_out(sel_out)
		 );
		
endmodule
module parking_lot_counter(
	input clk,rst_n,
	input a,b,
	output reg enter,exit
    );
	 //FSM declarations
	 localparam[3:0] start=4'd0,
					enter1=4'd1,
					enter2=4'd2,
					enter3=4'd3,
					entered=4'd4,
					exit1=4'd5,
					exit2=4'd6,
					exit3=4'd7,
					exited=4'd8;
	 reg[3:0] state_reg,state_nxt;
	 
	 //FSM register operations
	 always @(posedge clk,negedge rst_n) begin
		if(!rst_n) state_reg<=start;
		else state_reg<=state_nxt;
	 end
	 
	 //FSM next-state and output logics
	 always @* begin
		state_nxt=state_reg;
		enter=0;
		exit=0;
			case(state_reg)
		/*00*/	start: if(a && !b) state_nxt=enter1;
								else if(!a && b) state_nxt=exit1;
		/*10*/	enter1: if(!a && !b) state_nxt=start;
								else if(a && b) state_nxt=enter2;
		/*11*/	enter2: if(a && !b) state_nxt=enter1;
								else if(!a && b)  state_nxt=enter3;
		/*01*/	enter3: if(a && b) state_nxt=enter2;
								else if(!a && !b) state_nxt=entered;
		/*00*/	entered: begin 
									enter=1;
									state_nxt=start;
								end
		/*01*/	exit1: if(!a && !b) state_nxt=start;
								else if(a && b) state_nxt=exit2;
		/*11*/	exit2: if(!a && b) state_nxt=exit1;
								else if(a && !b) state_nxt=exit3;
		/*10*/	exit3: if(a && b) state_nxt=exit2;
								else if(!a && !b) state_nxt=exited;
		/*00*/	exited: begin
									exit=1;
									state_nxt=start;
							  end
					default: state_nxt=start;
			endcase
					
	 end
					


endmodule
module parking_lot_counter_TB;

	// Inputs
	reg clk;
	reg rst_n;
	reg a;
	reg b;

	// Outputs
	wire enter;
	wire exit;

	// Instantiate the Unit Under Test (UUT)
	parking_lot_counter uut (
		.clk(clk), 
		.rst_n(rst_n), 
		.a(a), 
		.b(b), 
		.enter(enter), 
		.exit(exit)
	);
	always begin
		clk=0;
		#5;
		clk=1;
		#5;
	end

	initial begin
		// Initialize Inputs
		clk = 0;
		rst_n = 1;
		a = 0;
		b = 0;
	

		// Wait 100 ns for global reset to finish
		#100;
        
		// Add stimulus here
		{a,b}=2'b00;
		#50 {a,b}=2'b01;
		#50 {a,b}=2'b11;
		#50 {a,b}=2'b01;
		#50 {a,b}=2'b11;
		#50 {a,b}=2'b10;
		#50 {a,b}=2'b00; //exit=1
		
		#100;
		#50 {a,b}=2'b10;
		#50 {a,b}=2'b11;
		#50 {a,b}=2'b00;
		#50 {a,b}=2'b10;
		#50 {a,b}=2'b11;
		#50 {a,b}=2'b01;
		#50 {a,b}=2'b00; 
		#100 $stop;	//entered=1

	end
      
endmodule
module sine_func_TB;

	// Inputs
	reg clk;
	reg rst_n;
	reg [9:0] x;

	// Outputs
	wire [7:0] y;
	reg[9:0] counter=0;

	// Instantiate the Unit Under Test (UUT)
	sine_func uut (
		.clk(clk), 
		.rst_n(rst_n), 
		.x(x), 
		.y(y)
	);
	always begin
		clk=0;
		#5;
		clk=1;
		#5;
	end
	always @(posedge clk) begin
		counter=counter+1'b1;
		x=counter;
	end

	initial begin
		rst_n = 1;
		@(negedge clk);
		wait(counter==0);
		@(negedge clk);
		wait(counter==0);
		@(negedge clk);
		wait(counter==0);
		@(negedge clk);
		wait(counter==0);
		@(negedge clk);
		wait(counter==0);
		@(negedge clk);
		wait(counter==0);
		@(negedge clk);
		wait(counter==0);
		@(negedge clk);
		wait(counter==0);
		$stop;
	end
      
endmodule
module sine_func( 
	input clk,rst_n,
	input[9:0] x, //input has a 10-bit resolution(from 0 to 2pi)
	output[7:0] y //output has 8-bit resolution(from -1 to 1)
    );
	 
	reg[7:0] y_q=0,y_d;
	reg[7:0] x_addr; //determines the address to be inserted in ROM
	wire[6:0] dout;
	
	always  @(posedge clk,negedge rst_n) begin
		if(!rst_n) y_q<=0;
		else y_q<=y_d;
	end
	
	//logic to obtain values of other quadrants
	always @* begin
		y_d=dout;
		case(x[9:8])
			2'b00: begin	
						x_addr=x[7:0]; //first quadrant(0 to pi/2) 
						y_d=dout+2**7; // middle point of sine wave is at 2^7
					end
			2'b01: begin
						x_addr=255-x[7:0]; //second quadrant(pi/2 to pi)
						y_d=dout+2**7;
					 end
			2'b10: begin  //third quadrant(pi to 3pi/2)
						x_addr=x[7:0];
						y_d=2**7-dout; //negative sign
					 end
			2'b11: begin  //fourth quadrant(3pi/2 to 2pi)
						x_addr=255-x[7:0];
						y_d=2**7-dout; //negative sign
					 end
		endcase

	end
	
	assign y=y_q;

	 rom_syn m0
	(
		.clk(clk),
		.addr(x_addr),  
		.dout(dout)
	);


endmodule
module top_module
	(
		input clk, rst_n,
		input rx, //player 1 paddle controller: "w" for up, "s" for down
		input[1:0] key, //player 2 paddle controller: key[0] for up, key[1] for down
		output[4:0] vga_out_r,
		output[5:0] vga_out_g,
		output[4:0] vga_out_b,
		output vga_out_vs,vga_out_hs
    );
	 
	wire clk_out;
	wire video_on;
	wire[11:0] pixel_x,pixel_y;
	reg rd_uart;
	reg[1:0] player2_q,player2_d;
	wire[7:0] rd_data;
	wire rx_empty;
	 
	 
	 //register logic for player 2(uses keyboard via UART)
	 always @(posedge clk_out,negedge rst_n) begin
		if(!rst_n) player2_q<=0;
		else player2_q<=player2_d;
	 end
	 
	 
	 //uart logic for controlling the paddle of player_2
	 always @* begin
		player2_d=player2_q;
		rd_uart=0;
		
			if((pixel_y==500 && pixel_x==10)||(pixel_y==500 && pixel_x==20)) begin 
				rd_uart=1; //empty the uart fifo when no display(i.e. during refresh)
				player2_d=0;
			end
			else if(!rx_empty) begin
				if(rd_data==8'h73) player2_d=2'b10; //move down when "s" is pressed
				else if(rd_data==8'h77) player2_d=2'b01; //move up "w" is pressed
			end
	end
	
	
	//instantiate modules
	dcm_25MHz m0
   (// Clock in ports
		 .clk(clk),      // IN
		 // Clock out ports
		 .clk_out(clk_out),     // OUT
		 // Status and control signals
		 .RESET(RESET),// IN
		 .LOCKED(LOCKED)
	 );
	 vga_core m1
	(
		.clk(clk_out),
		.rst_n(rst_n), //clock must be 25MHz for 640x480 
		.hsync(vga_out_hs),
		.vsync(vga_out_vs),
		.video_on(video_on),
		.pixel_x(pixel_x),
		.pixel_y(pixel_y)
    );
	 
	 pong_animated m2 //pong game with 2 players. Player 1 uses FPGA board switch. Player 2 uses keyboard via UART
	 (
		.clk(clk_out),
		.rst_n(rst_n),
		.key({player2_q,key}),
		.video_on(video_on),
		.pixel_x(pixel_x),
		.pixel_y(pixel_y),
		.r(vga_out_r),
		.g(vga_out_g),
		.b(vga_out_b)
    );	
	 
	 uart m3
	(
		.clk(clk),
		.rst_n(rst_n),
		.rd_uart(rd_uart),
		.wr_uart(),
		.wr_data(),
		.rx(rx),
		.tx(),
		.rd_data(rd_data),
		.rx_empty(rx_empty),
		.tx_full()
    );
			
	
	 
	 
	 
endmodule
module vga_core(
	input clk,rst_n, //clock must be 25MHz for 640x480 
	output hsync,vsync,
	output reg video_on,
	output[11:0] pixel_x,pixel_y
    );	
	 //640x480 parameters
	 localparam HD=640, //Horizontal Display
					HR=16, //Right Border
					HRet=96, //Horizontal Retrace
					HL=48, //Left Border
					
					VD=480, //Vertical Display
					VB=10, //Bottom Border
					VRet=2, //Vertical Retrace
					VT=33; //Top Border
					
	reg[11:0] vctr_q=0,vctr_d; //counter for vertical scan
	reg[11:0] hctr_q=0,hctr_d; //counter for horizontal scan
	reg hsync_q=0,hsync_d; //horizontal sync is buffered for a glitchless output
	reg vsync_q=0,vsync_d; ////vertical sync is buffered for a glitchless output
	
	//vctr and hctr register operation
	always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			vctr_q<=0;
			hctr_q<=0;
			vsync_q<=0;
			hsync_q<=0;
		end
		else begin
			vctr_q<=vctr_d;
			hctr_q<=hctr_d;
			vsync_q<=vsync_d;
			hsync_q<=hsync_d;
		end
	end
	
	//horizontal and vertical counter logic for horizontal sync and vertical sync
	always @* begin
		vctr_d=vctr_q;
		hctr_d=hctr_q;
		video_on=0;
		hsync_d=1; 
		vsync_d=1; 
		
		if(hctr_q==HD+HR+HRet+HL-1) hctr_d=0; //horizontal counter
		else hctr_d=hctr_q+1'b1;
		
		if(vctr_q==VD+VB+VRet+VT-1) vctr_d=0; //vertical counter
		else if(hctr_q==HD+HR+HRet+HL-1) vctr_d=vctr_q+1'b1;
		
		if(hctr_q<HD && vctr_q<VD) video_on=1; //video_on 
		
		if( (hctr_d>=HD+HR) && (hctr_d<=HD+HR+HRet-1) ) hsync_d=0; //d-input is used as condition (not the present "q")to remove the one-clock delay due to buffering the horizontal sync 
		if( (vctr_d>=VD+VB) && (vctr_d<=VD+VB+VRet-1) ) vsync_d=0; //d-input is used as condition (not the present "q")to remove the one-clock delay due to buffering the vertical sync 
				
	end
		assign vsync=vsync_q;
		assign hsync=hsync_q;
		assign pixel_x=hctr_q;
		assign pixel_y=vctr_q;

endmodule
module top_module(
	input clk,rst_n,
	input key,
	output vga_out_vs,vga_out_hs,
	output[4:0] vga_out_r,
	output[5:0] vga_out_g,
	output[4:0] vga_out_b	
    );
	 
	wire video_on;
	wire[11:0] pixel_x,pixel_y;
	
	//module instantiations
	clk_25MHz m0
   (// Clock in ports
		 .clk(clk),      // IN
		 // Clock out ports
		 .clk_out(clk_out),     // OUT
		 // Status and control signals
		 .RESET(RESET),// IN
		 .LOCKED(LOCKED)
	 );  
	 
	vga_core m1
	(
		.clk(clk_out),
		.rst_n(rst_n), //clock must be 25MHz for 640x480 
		.hsync(vga_out_hs),
		.vsync(vga_out_vs),
		.video_on(video_on),
		.pixel_x(pixel_x),
		.pixel_y(pixel_y)
    );
	 
	 vga_test_pattern m2 //generates horizontal or vertical strip pattern
	 (								//depending if key is pressed or not
		.key(key),
		.video_on(video_on),
		.pixel_x(pixel_x),
		.pixel_y(pixel_y),
		.r(vga_out_r),
		.g(vga_out_g),
		.b(vga_out_b)
    ); 


endmodule
module bitmap_gen(
	input clk,rst_n,
	input[3:0] key,
	input video_on,
	input[11:0] pixel_x,pixel_y,
	output reg[4:0] vga_out_r,
	output reg[5:0] vga_out_g,
	output reg[4:0] vga_out_b
    );
	 
					//screen boundary for a 256x256 box at the center of screen
	localparam  MAX_X=447,
					MIN_X=192,
					MIN_Y=112,
					MAX_Y=367,
					SIZE=256, //screen box size
					ball_V=1;//ball velocity
	
	reg[15:0] rd_addr,wr_addr;
	wire[15:0] addr; //read and write address for the 128k by 3 single port ram
	reg we;
	reg[7:0] ball_x_q=0,ball_x_d; //stores X value of the dot
	reg[7:0] ball_y_q=0,ball_y_d; //stores Y value of the dot
	reg ball_xdelta_q=0,ball_xdelta_d;
	reg ball_ydelta_q=0,ball_ydelta_d;
	wire[2:0] dout;
	wire key3_tick;
	
	 
	 //register for tracing dot
	 always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			ball_x_q<=0;
			ball_y_q<=0;
			ball_xdelta_q<=0;
			ball_xdelta_q<=0;
		end
		else begin
			ball_x_q<=ball_x_d;
			ball_y_q<=ball_y_d;
			ball_xdelta_q<=ball_xdelta_d;
			ball_ydelta_q<=ball_ydelta_d;
		end
	 end
	 
	 //bouncing ball location logic
	 always @* begin
		ball_x_d=ball_x_q;
		ball_y_d=ball_y_q;
		ball_xdelta_d=ball_xdelta_q;
		ball_ydelta_d=ball_ydelta_q;
		wr_addr=0;
		we=0;
		
		if(key3_tick) begin //if key3 is pushed, the ball will move to the current location of scan(which would appear random to our eyes)
			ball_x_d=pixel_x;
			ball_y_d=pixel_y;
		end
		else if(pixel_y==500 && pixel_x==0) begin//1 tick when video is surely off
			//bouncing ball logic
			if(ball_x_q<=ball_V) ball_xdelta_d=1; //bounce from left wall
			else if((SIZE-ball_V-1)<=ball_x_q) ball_xdelta_d=0; //bounce from right wall
			if(ball_y_q<=ball_V) ball_ydelta_d=1; //bounce from top
			else if((SIZE-ball_V-1)<=ball_y_q) ball_ydelta_d=0; //bounce from bottom
			
			ball_x_d=ball_xdelta_d? (ball_x_q+ball_V):(ball_x_q-ball_V);
			ball_y_d=ball_ydelta_d? (ball_y_q+ball_V):(ball_y_q-ball_V);
			wr_addr={ball_x_q,ball_y_q}; //write the new trace location during refresh period i.e. when not reading
			we=1;
		end
	 end
	 
	
	//display logic
	always @* begin
		vga_out_r=0;
		vga_out_g=0;
		vga_out_b=0;
		rd_addr=0;
		if(video_on) begin
			if(MIN_X<=pixel_x && pixel_x<=MAX_X && MIN_Y<=pixel_y && pixel_y<=MAX_Y) begin //if inside the box
				rd_addr[15:8]=pixel_x-MIN_X;
				rd_addr[7:0]=pixel_y-MIN_Y;
				if(dout[0]) vga_out_r=5'b111_11;
				if(dout[1]) vga_out_g=6'b111_111;
				if(dout[2]) vga_out_b=5'b111_11;
			end
			else begin //color outside box
				vga_out_r=5'b111_11;
				vga_out_g=6'b111_111;
				vga_out_b=5'b111_11;
			end
		end
	end
	
	assign addr=we? wr_addr : rd_addr; 
	
	single_port_syn m0 //64k by 3
	(
		.clk(clk),
		.we(we),
		.addr(addr),
		.din((~key[2:0])),
		.dout(dout)
	);
	
	debounce_explicit m1
	(
		.clk(clk),
		.rst_n(rst_n),
		.sw(!key[3]),
		.db_level(),
		.db_tick(key3_tick)
    );

					
endmodule
module single_port_syn //128k by 3 single port sync ram(uses block ram)
#(parameter ADDR_WIDTH=16,
				DATA_WIDTH=3)
(
	input clk,
	input we,
	input[ADDR_WIDTH-1:0] addr,
	input[DATA_WIDTH-1:0] din,
	output[DATA_WIDTH-1:0] dout
);
	reg[DATA_WIDTH-1:0] ram[2**ADDR_WIDTH-1:0];
	reg[ADDR_WIDTH-1:0] addr_q;
	
	always @(posedge clk) begin
		if(we) ram[addr]=din;
		addr_q<=addr;
	end
	assign dout=ram[addr_q];
endmodule
module top_bitmap_gen
	(
		input clk, rst_n,
		input[3:0] key,
		output[4:0] vga_out_r,
		output[5:0] vga_out_g,
		output[4:0] vga_out_b,
		output vga_out_vs,vga_out_hs
    );
	 
	wire clk_out;
	wire video_on;
	wire[11:0] pixel_x,pixel_y;
	dcm_25MHz m0
   (// Clock in ports
		 .clk(clk),      // IN
		 // Clock out ports
		 .clk_out(clk_out),     // OUT
		 // Status and control signals
		 .RESET(RESET),// IN
		 .LOCKED(LOCKED)
	 );
	 vga_core m1
	(
		.clk(clk_out),
		.rst_n(rst_n), //clock must be 25MHz for 640x480 
		.hsync(vga_out_hs),
		.vsync(vga_out_vs),
		.video_on(video_on),
		.pixel_x(pixel_x),
		.pixel_y(pixel_y)
    );
	 
	 bitmap_gen m2 
	 (
		.clk(clk_out),
		.rst_n(rst_n),
		.key(key),
		.video_on(video_on),
		.pixel_x(pixel_x),
		.pixel_y(pixel_y),
		.vga_out_r(vga_out_r),
		.vga_out_g(vga_out_g),
		.vga_out_b(vga_out_b)
    );	
	 
	 
	 
endmodule
module uart
	#(parameter DBIT=8,SB_TICK=16,DVSR=326,DVSR_WIDTH=9,FIFO_W=2)
	(
	input clk,rst_n,
	input rd_uart,
	input rx,
	output[7:0] rd_data,
	output rx_empty
    );

	 wire s_tick,rx_done_tick,empty;
	 wire[7:0] dout,rd_data_tx;
	 
	 
	baud_generator #(.N(DVSR),.N_width(DVSR_WIDTH)) m0
	(
	.clk(clk),
	.rst_n(rst_n),
	.s_tick(s_tick)
    );
	 
	 uart_rx #(.DBIT(DBIT),.SB_TICK(SB_TICK)) m1 //DBIT=data bits , SB_TICK=ticks for stop bit (16 for 1 bit ,32 for 2 bits)
	(
		.clk(clk),
		.rst_n(rst_n),
		.rx(rx),
		.s_tick(s_tick),
		.rx_done_tick(rx_done_tick),
		.dout(dout)
    );
	 fifo #(.W(FIFO_W),.B(DBIT)) m2
	(
		.clk(clk),
		.rst_n(rst_n),
		.wr(rx_done_tick),
		.rd(rd_uart),
		.wr_data(dout),
		.rd_data(rd_data),
		.full(),
		.empty(rx_empty)
    );
	

endmodule
module rotating_LED_TEST(
	input clk,rst_n,
	input rx,
	output[7:0] seg_out,
	output[5:0] sel_out
    );
	 wire [4:0] in0,in1,in2,in3,in4,in5;
	 rotating_LED #(.turns(25_000_000)) //Frequency will be 50MHz/turns = 50MHz/15M = 3.33Hz(0.3 sec per move)
		 rot_led
			(
			.clk(clk),
			.rst_n(rst_n),
			.rx(rx),
			.in0(in0),
			.in1(in1),
			.in2(in2),
			.in3(in3),
			.in4(in4),
			.in5(in5)
			 );
	 
	LED_mux led_mux
		(
		.clk(clk),
		.rst(rst_n),
		.in0(in0),
		.in1(in1),
		.in2(in2),
		.in3(in3),
		.in4(in4),
		.in5(in5),
		.seg_out(seg_out),
		.sel_out(sel_out)
		 );

endmodule
module rotating_LED
	#(parameter turns=25_000_000) ///Frequency will be 50MHz/turns = 50MHz/15M = 3.33Hz(0.3 sec per move)
	(
	input clk,rst_n,
	input rx,
	output [4:0] in0,in1,in2,in3,in4,in5 //{decimalpoint,hexadecimal}
    );
	 localparam W=10; //number of all letters/numbers to be displayed
	 
	 reg[24:0] mod_turns=0;
	 reg[5*W-1:0] words={  ////  word=0123456789 
								{1'b0,4'h0},
								{1'b0,4'h1},
								{1'b0,4'h2},
								{1'b0,4'h3},
								{1'b0,4'h4},
								{1'b0,4'h5},
								{1'b0,4'h6},
								{1'b0,4'h7},
								{1'b0,4'h8},
								{1'b0,4'h9}			
								}; //Note: If  "W" is greater than the words initialized here, it will be displayed as default zero on the leftmost digit
	  reg[5*W-1:0] words_nxt;
	  reg en=0,en_nxt;
	  reg dir=0,dir_nxt;
	  reg rd_uart;
	  wire mod_turns_max;
	  wire rx_empty;
	  wire[7:0] rd_data;
	  wire[24:0] mod_turns_nxt;
	  //registers
	  always @(posedge clk,negedge rst_n) begin
			if(!rst_n) begin
				mod_turns<=0;
				words<={ {1'b0,4'h0},
						  {1'b0,4'h1},
						  {1'b0,4'h2},
						  {1'b0,4'h3},
						  {1'b0,4'h4},
						  {1'b0,4'h5},
						  {1'b0,4'h6},
						  {1'b0,4'h7},
						  {1'b0,4'h8},
						  {1'b0,4'h9}			
						  };
				en<=0;
				dir<=0;
			end
			
			else begin
				en<=en_nxt;
				dir<=dir_nxt;
				if(en) begin
					mod_turns<=mod_turns_nxt;
					words<=words_nxt;
			   end	
			end
			
	  end
	  //next-state logics
	  assign mod_turns_nxt=(mod_turns==turns)?0:mod_turns+1;
	  assign mod_turns_max=(mod_turns==turns)?1:0;
	
	  always @* begin
		  rd_uart=0;
		  en_nxt=en;
		  dir_nxt=dir;
		  words_nxt=words;
		  
		  if(mod_turns_max) words_nxt=(!dir)? {words[5*W-6:0],words[5*W-1:5*W-5]}  :  {words[4:0],words[5*W-1:5]} ;  //if dir is not asserted: move left , else:move right
		  
		  //UART-logic when accepting ASCII numbers to be added to the banner
		  if(!rx_empty) begin
				if(rd_data[7:4]==4'h3)  words_nxt={{1'b0,rd_data[3:0]},words[5*W-1:5]};  //new number to be added at the banner
				else if(rd_data==8'h47 || rd_data==8'h67) en_nxt=1;  //"g" or "G" for play
				else if(rd_data==8'h50 || rd_data==8'h70) en_nxt=0;  //"p" or "P" for pause
				else if(rd_data==8'h44 || rd_data==8'h64) dir_nxt=!dir; //"d" or "D" to reverse the direction of rotation
				rd_uart=1;
			end
	  end
	  
	  //output logic to be be used by the LED Multiplexing circuit (6 5-bit outputs that determine what number will be displayed on the sevensegments)
	  assign in5=words[5*W-1:5*W-5],
				in4=words[5*W-6:5*W-10],
				in3=words[5*W-11:5*W-15],
				in2=words[5*W-16:5*W-20],
				in1=words[5*W-21:5*W-25],
				in0=words[5*W-26:5*W-30];
				
	
	uart #(.DBIT(8),.SB_TICK(16),.DVSR(326),.DVSR_WIDTH(9),.FIFO_W(2)) m0
	(
		.clk(clk),
		.rst_n(rst_n),
		.rd_uart(rd_uart),
		.rx(rx),
		.rd_data(rd_data),
		.rx_empty(rx_empty)
    );		
				
				
endmodule
module ps2_rxtx(
	input clk,rst_n,
	input[7:0] din, //8 bit data for tx
	input wr_ps2,
	inout ps2d,ps2c,
	output[10:0] dout, //11bit-data received from rx
	output rx_done_tick,
	output tx_done_tick
    );
	 wire tx_idle;
	 
	 ps2_rx m0
	 (
		.clk(clk),
		.rst_n(rst_n),
		.rx_en(tx_idle),
		.ps2d(ps2d),
		.ps2c(ps2c),
		.dout(dout), //startbit,8databits,paritybit,stopbit
		.rx_done_tick(rx_done_tick)
    );
	 
	 ps2_tx m1
	 (
		.clk(clk),
		.rst_n(rst_n),
		.wr_ps2(wr_ps2),
		.din(din),
		.ps2d(ps2d),
		.ps2c(ps2c),
		.tx_idle(tx_idle),
		.tx_done_tick(tx_done_tick)
    );


endmodule
module ps2_tx(
	input clk,rst_n,
	input wr_ps2,
	input[7:0] din,
	inout ps2d,ps2c,
	output reg tx_idle,tx_done_tick
    );
	 //FSM state declarations
	 localparam[2:0] idle=3'd0,
							rts=3'd1,
							start=3'd2,
							data=3'd3,
							stop=3'd4;
	 reg[2:0] state_reg,state_nxt;
	 reg[12:0] counter_reg,counter_nxt;
	 reg[3:0] n_reg,n_nxt;
	 reg[8:0] data_reg,data_nxt;
	 reg[7:0] filter_reg;
	 wire[7:0] filter_nxt;
	 reg ps2c_reg;
	 wire ps2c_nxt;
	 reg ps2c_out,ps2d_out;
	 reg tri_c,tri_d;
	 wire fall_edg;
	
	//FSM register operations
	always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			state_reg<=idle;
			counter_reg<=0;
			n_reg<=0;
			data_reg<=0;
		end
		else begin
			state_reg<=state_nxt;
			counter_reg<=counter_nxt;
			n_reg<=n_nxt;
			data_reg<=data_nxt;
		end
	end
	//FSM next-state logics
	always @* begin
		state_nxt=state_reg;
		counter_nxt=counter_reg;
		n_nxt=n_reg;
		data_nxt=data_reg;
		tx_idle=0;
		tx_done_tick=0;
		ps2c_out=1; //default clock out
		ps2d_out=1; //drfault data out  
		tri_c=0; //tri-state data bus is default off(high Z)
		tri_d=0; //tri-state clock bus is default off(high Z)
		case(state_reg)
			   idle: begin  //wait for wr_ps2 signal to be asserted(signal for transmitting data to ps2)
							tx_idle=1;
							if(wr_ps2==1) begin
								counter_nxt=0;
								n_nxt=0;
								data_nxt={!(^din),din}; //data={oddparity,8-bitdata}
								state_nxt=rts;
							end
						end
			    rts: begin //forces the clock line to be 0 for at least 100us(signal for request to send)
							ps2c_out=0;
							tri_c=1;
							if(counter_reg==13'h1fff) state_nxt=start; 
							else counter_nxt=counter_reg+1;
						end
			  start: begin //forces the data line to be 0(signal for start bit) and disable the rts(back to hi-Z)
							ps2d_out=0;
							tri_d=1;
							if(fall_edg==1) state_nxt=data;
						end
			   data: begin //shifts the next data bit for every falling edge of the clock line
							ps2d_out=data_reg[0];
							tri_d=1;
							if(fall_edg==1) begin
								data_nxt={1'b0,data_reg[8:1]};
								if(n_reg==8) state_nxt=stop; //finishes all data bits and 1 parity bit
								else n_nxt=n_reg+1;
							end
						end
			   stop: begin
							if(fall_edg==1) begin
								tx_done_tick=1;
								state_nxt=idle;
							end
						end
			default: state_nxt=idle;
		endcase
	end
		 
	  //filtering the ps2 clock from very short glitches, with falling edge detector
	 always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			filter_reg<=0;
			ps2c_reg<=0;
		end
		else begin
			filter_reg<=filter_nxt;
			ps2c_reg<=ps2c_nxt;
		end
	 end
	 assign filter_nxt={ps2c,filter_reg[7:1]};
	 assign ps2c_nxt=(filter_reg==8'hff)?1:
							(filter_reg==8'h00)?0:
							 ps2c_reg;
	 assign fall_edg=(ps2c_reg && !ps2c_nxt)? 1:0;
	 
	 //tri-state logic for ps2c and ps2d
	 assign ps2c=tri_c?ps2c_out:1'bz;
	 assign ps2d=tri_d?ps2d_out:1'bz;
							  


endmodule
module mouse(
	input clk,rst_n,
	inout ps2c,ps2d,
	output[8:0] x,y,
	output[2:0] btn,
	output reg m_done_tick
    );
	 
	 //FSM state-declarations
	 localparam[2:0] idle=3'd0,
							response=3'd1,
							byte1=3'd2,
							byte2=3'd3,
							byte3=3'd4,
							done=3'd5;
	 reg[2:0] state_reg,state_nxt;
	 reg[8:0] x_reg,x_nxt;
	 reg[8:0] y_reg,y_nxt;
	 reg[2:0] btn_reg,btn_nxt;
	 reg wr_ps2;
	 
	 wire[7:0] rx_data;
	 wire[10:0] dout;
	 wire rx_done_tick,tx_done_tick;
	 
	 //FSM register operations
	 always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			state_reg<=idle;
			x_reg<=0;
			y_reg<=0;
			btn_reg<=0;
		end
		else begin
			state_reg<=state_nxt;
			x_reg<=x_nxt;
			y_reg<=y_nxt;
			btn_reg<=btn_nxt;
		end
	 end
	 //FSM nexr-state logics
	 always @* begin
		state_nxt=state_reg;
		x_nxt=x_reg;
		y_nxt=y_reg;
		btn_nxt=btn_reg;
		wr_ps2=0;
		m_done_tick=0;
		case(state_reg)
			   idle: begin //transmit code F4 for enable stream
							wr_ps2=1;
							if(tx_done_tick==1) state_nxt=response;
						end
			response: if(rx_done_tick==1) state_nxt=byte1;//wait for the acknowledge response FE
			  byte1: if(rx_done_tick==1) begin //first packet
							x_nxt[8]=rx_data[5]; //4
							y_nxt[8]=rx_data[6]; //5
							btn_nxt=rx_data[3:1]; //2:0
							state_nxt=byte2;
						end
			  byte2: if(rx_done_tick==1) begin //2nd packet
							x_nxt[7:0]=rx_data;
							state_nxt=byte3;
						end
			  byte3: if(rx_done_tick==1) begin //3rd packet
							y_nxt[7:0]=rx_data;
							state_nxt=done;
						end
			   done: begin
							m_done_tick=1;
							state_nxt=byte1;
						end
			default: state_nxt=idle;
		endcase
	 end
	 
	ps2_rxtx m0
	(
		.clk(clk),
		.rst_n(rst_n),
		.din({8'hf4}), //transmitted data is always F4(enable stream mode of mouse)
		.wr_ps2(wr_ps2),
		.ps2d(ps2d),
		.ps2c(ps2c),
		.dout(dout), //11bit-data received from rx
		.rx_done_tick(rx_done_tick),
		.tx_done_tick(tx_done_tick)
    );
	 assign rx_data=dout[8:1]; //real data extracted(no start,parity,and stop bits)
	 
	 assign x=x_reg;
	 assign y=y_reg;
	assign btn=btn_reg;
	 
	 
	
	


endmodule
module ps2_rx(
	input clk,rst_n,
	input rx_en,
	input ps2d,ps2c,
	output[10:0] dout, //startbit,8databits,paritybit,stopbit
	output reg rx_done_tick
    );
	 //FSM state declarations
	 localparam[1:0] idle=2'd0,
							scan=2'd1,
							done=2'd2;
	 reg[1:0] state_reg,state_nxt;
	 reg[10:0] data_reg,data_nxt;
	 reg[3:0] n_reg,n_nxt;
	 reg[7:0] filter_reg,filter_nxt;
	 reg ps2c_f_reg,ps2c_f_nxt;
	 reg ps2c_reg;
	 wire ps2c_edg;
	 //FSM register operations
	 always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			state_reg<=0;
			data_reg<=0;
			n_reg<=0;
			filter_reg<=0;
			ps2c_f_reg<=0;
			ps2c_reg<=0;
		end
		else begin
			state_reg<=state_nxt;
			data_reg<=data_nxt;
			n_reg<=n_nxt;
			filter_reg<=filter_nxt;
			ps2c_f_reg<=ps2c_f_nxt;
			ps2c_reg<=ps2c_f_reg;
		end
	 end
	 
	 //FSM next-state logic
	 always @* begin
		state_nxt=state_reg;
		data_nxt=data_reg;
		n_nxt=n_reg;
		rx_done_tick=0;
		case(state_reg)
			   idle: if(ps2c_edg && rx_en) begin //wait for the falling edge of the start bit
							data_nxt={ps2d,data_reg[10:1]};
							n_nxt=0;
							state_nxt=scan;
						end						
			   scan: if(ps2c_edg) begin //wait to finish receiving all data bits(startbit,bit0-7,paritybit,then stopbit)
							data_nxt={ps2d,data_reg[10:1]};
							if(n_reg==9) state_nxt=done;
							else n_nxt=n_reg+1;
						end
			   done: begin //finish
							rx_done_tick=1;
							state_nxt=idle;
						end
			default: state_nxt=idle;	
		endcase
	 end
	 //ps2c filter logic. The ps2c_f_reg is the filtered output.
	 always @* begin 
		filter_nxt={ps2c,filter_reg[7:1]}; 
		if(filter_reg==8'b1111_1111) ps2c_f_nxt=1;  //Any glitches shorter than 8 turns will be ignored
		else if(filter_reg==8'b0000_0000) ps2c_f_nxt=0; 
		else ps2c_f_nxt=ps2c_f_reg;
	 end
	 //falling edge detection for ps2c_f_reg
	 assign ps2c_edg=(ps2c_reg && !ps2c_f_reg)?1:0;
	assign dout=data_reg;
endmodule
module uart_plus_stopwatch(
	input clk,rst_n,
	input rx,
	output[7:0] seg_out,
	output[5:0] sel_out,
	output tx
    );
	 
	 reg rd_uart;
	 wire rx_empty;
	 wire[7:0] rd_data;
	 reg clr; //clr=1 is clear
	 reg up_reg=1,up_nxt; //up=1 is upward
	 reg go_reg=0,go_nxt; //go=1 is play
	 reg wr_uart;
	 reg[7:0] displaytime[5:0];
	 reg[7:0] wr_data,wr_data_nxt;
	 wire[4:0] in0,in1,in2,in3,in4,in5;
	 reg[2:0] index=0,index_nxt; //index to determine what wr_data will be written to UART. This will be the index for the register file
	 reg lock=0,lock_nxt; //this will stay at "1' until all necessary wr_data is transmitted
	Enhanced_Stopwatch m0
	(   
		.clk(clk),
		.rst_n(rst_n),
		.up(up_reg),
		.go(go_reg),
		.clr(clr), // up-> 1:Count up 0:Count down    go->1:play 0:pause    clr-->back to 0.00.0
		.in0(in0),
		.in1(in1),
		.in2(in2),
		.in3(in3),
		.in4(in4),
		.in5(in5)
    );
	 
	 LED_mux m1
	(
		.clk(clk),
		.rst(rst_n),
		.in0(in0),
		.in1(in1),
		.in2(in2),
		.in3(in3),
		.in4(in4),
		.in5(in5),
		.seg_out(seg_out),
		.sel_out(sel_out)
    );
	 uart #(.DBIT(8),.SB_TICK(16),.DVSR(326),.DVSR_WIDTH(9),.FIFO_W(4)) m2
	(
		.clk(clk),
		.rst_n(rst_n),
		.rd_uart(rd_uart),
		.wr_uart(wr_uart),
		.wr_data(wr_data),
		.rx(rx),
		.tx(tx),
		.rd_data(rd_data),
		.rx_empty(rx_empty),
		.tx_full()
    );
	 
	 always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			index<=0;
			up_reg<=1;
			go_reg<=0;
			lock<=0;

		end
		else begin
			index<=index_nxt;
			up_reg<=up_nxt;
			go_reg<=go_nxt;
			lock<=lock_nxt;

		end
	 end
	 always @* begin
		up_nxt=up_reg;
		go_nxt=go_reg;
		lock_nxt=lock;
		index_nxt=index;
		wr_uart=0;
		rd_uart=0;
		clr=0;
		
		if(!rx_empty) begin
			if(rd_data==8'h43 || rd_data==8'h63) begin //c or C clears stopwatch
				clr=1;
				up_nxt=1;
			end
			else if (rd_data==8'h47|| rd_data==8'h67) begin //g or G plays the stopwatch
				go_nxt=1;
			end
			else if (rd_data==8'h50 || rd_data==8'h70) begin //p or P pauses stopwatch
				go_nxt=0;
			end
			else if(rd_data==8'h55 || rd_data==8'h75) begin //u or U reverses direction of stopwatch
				up_nxt=!up_reg;
			end
			else if(rd_data==8'h52 || rd_data==8'h72) begin //r or R transmits current time to UART tx
				lock_nxt=1;
				index_nxt=0;
			end
			rd_uart=1;
		end
		
		if(lock) begin
			wr_data=displaytime[index];
			wr_uart=1;
			if(index==5) lock_nxt=0; //finish transmitting all data btyes
			else index_nxt=index+1;
		end	
	 end
	 
	 always @* begin //
		displaytime[0]={4'h3,in3[3:0]};//minutes
		displaytime[1]=8'h3a; //":"
		displaytime[2]={4'h3,in2[3:0]}; //second-digit of seconds
		displaytime[3]={4'h3,in1[3:0]}; //first-digit of seconds
		displaytime[4]=8'h3a; //":"
		displaytime[5]={4'h3,in0[3:0]};	//decimal or the 100ms
	 end
	 


endmodule
module int_to_fp(
	input wire[7:0] integ,
	output reg[12:0] fp	
    );
	 integer i; 
	 reg finish;
	 
	 always @(integ) begin
	 fp=13'b0;
	 i=0;
	 finish=1'b0;
	 fp[12]=integ[7];  //sign bit of fp is same with integ
	 for(i=6;i>=0;i=i-1)   //find loc of first bit 1 in the integ
		 if(integ[i]==1'b1 && finish==1'b0) begin
		 	fp[7:0] = {1'b0,integ[6:0]}<<(7-i); //8 bit frac value of fp must be normalized so the first bit "1"(excluding the signed bit) of integ must moved to 8th bit
			fp[11:8] = i+1;   // 4 bit exp value e.g. integ 0000_1111(i=3) willl become fp frac of .1111_0000 when normalized so an exp must be 3+1=4
			finish=1'b1;
		 end
	 end
	 


endmodule
module fp_to_int_TB;

	// Inputs
	reg [12:0] fp;

	// Outputs
	wire [7:0] integ;
	wire over;
	wire under;

	// Instantiate the Unit Under Test (UUT)
	fp_to_int uut (
		.fp(fp), 
		.integ(integ), 
		.over(over), 
		.under(under)
	);
	reg[3:0] i;
	initial begin
		// Initialize Inputs
		fp = 0;

		// Wait 100 ns for global reset to finish
		#100;
		
		
		//overflow test
		$display("OVERFLOW TEST");
		$display("FloatingPoint Integer  Over Under");
		for(i=4'b1111;i>7;i=i-1) begin
			#5 fp={1'b1,i,8'b1010_1111}; 
			#5 fp={1'b0,i,8'b1010_1111}; 
			#5 fp={1'b0,i,8'b0000_0000}; //test overflow exp BUT with zero frac(integer must be all be 0)
			#5 $display(" ");
			   $display(" ");
		end
		
		//underflow test
		$display("UNDERFLOW TEST");
		$display("FloatingPoint Integer  Over Under");
			#5 fp={1'b1,4'b0000,8'b1010_1111}; 
			#5 fp={1'b0,4'b0000,8'b1010_1111}; 
			#5 fp={1'b0,4'b0000,8'b0000_0000};  //test underflow BUT with zero frac(integer must all be 0)
		#5 $display(" "); 
		   $display(" ");
		
		//normal test
		$display("NORMAL TEST");
		$display("FloatingPoint Integer  Over Under");
		for(i=4'b0111;i>0;i=i-1) begin
		#5 fp={1'b1,i,8'b1111_1111};
		#5 fp={1'b0,i,8'b1111_1111};
		#5 $display(" ");
		end
		#5 fp={1'b1,i,8'b1111_1111};
		#5 fp={1'b0,i,8'b1111_1111};
			#100 $finish;
   end
	
	initial begin
      $monitor("%b %b %b    %b",fp,integ,over,under);
		end
		
		
endmodule
module fp_to_int(
	input wire[12:0] fp,
	output reg[7:0] integ,
	output reg over,under
    );
	 reg[3:0] exp;
	 reg[7:0] frac;
	 always@(fp) begin
		 integ=8'b0;
		 over=1'b0;
		 under=1'b0;
		 frac=fp[7:0];
		 exp=fp[11:8];
		 
		 integ[7]=fp[12];   //sign bit of fp is same with int
		 
		 if(exp>7 && frac[7]) begin //overflow
			integ[6:0]=7'b111_1111;  
			over=1'b1;
		 end
		 else if(exp==0 && frac[7]) begin //underflow
			integ[6:0]=7'b000_0000;
			under=1'b1;
		 end
		 else if(exp<=7 && frac[7]) begin
			integ[6:0]=frac>>(8-exp);
		 end
	 end
	 
endmodule
module int_to_fp_to_int_TB;


	reg [7:0] integ;
	wire [12:0] fp;
	int_to_fp uut (
		.integ(integ), 
		.fp(fp)
	);
	
	reg[12:0] fp_new;
	wire[7:0] integ_new;
	wire over,under;
	fp_to_int uut2(
		.fp(fp_new), 
		.integ(integ_new), 
		.over(over), 
		.under(under)
	 );
	 
	initial begin
		// Initialize Inputs
		integ = 0;

		// Wait 100 ns for global reset to finish
		#100;
		for(integ={8{1'b1}};integ>0;integ=integ-1) begin  //test from 1111_1111 to 0000_0000
			#5
			fp_new=fp;
			#5;
			if(integ!=integ_new) $display("ERRROORRRRR");  
			#5 $display("%b %b",integ,integ_new);
			$display(" ");
		end
		#100 $finish;
	end
	
	
	initial begin
	$display("integ    integ_new");
	end
      
endmodule
module int_to_fp_TB;

	// Inputs
	reg [7:0] integ;

	// Outputs
	wire [12:0] fp;
   
	// Instantiate the Unit Under Test (UUT)
	int_to_fp uut (
		.integ(integ), 
		.fp(fp)
	);

	initial begin
		// Initialize Inputs
		integ = 0;

		// Wait 100 ns for global reset to finish
		#100;
		for(integ={8{1'b1}};integ>0;integ=integ-1) begin
		#5 ;
		end
		#100 $finish;
		// Add stimulus here
	end
	initial begin
	$display("Integer  FloatingPoint");
	$monitor("%b %b",integ,fp);
	end
	
      
endmodule
module alt_bcd_counter(
	input clk,rst_n,
	input go,
	output reg[3:0] s1,s0,ms0
    );
	 reg[22:0] counter_reg=0;
	 always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			s1<=0;
			s0<=0;
			ms0<=0;
			counter_reg<=0;
		end
		else if(go) begin //nested-if for describing the BCD-counter
			if(counter_reg!=4_999_999)	counter_reg<=counter_reg+1;
			else begin
				counter_reg<=0;
				if(ms0!=9) ms0<=ms0+1;
				else begin
					ms0<=0;
					if(s0!=9) s0<=s0+1;
					else begin
						s0<=0;
						if(s1!=9) s1<=s1+1;
						else s1<=0;
					end
				end
			end
		end
	 end


endmodule
module top_module(
	input clk,rst_n,
	input go,
	output[7:0] seg_out,
	output[5:0] sel_out	
    );
	 wire[3:0] ms0,s0,s1;
	 
	alt_bcd_counter m0
	(
		.clk(clk),
		.rst_n(rst_n),
		.go(go),
		.s1(s1),
		.s0(s0),
		.ms0(ms0)
    );
	 LED_mux m1
	 (
		.clk(clk),
		.rst(rst_n),
		.in0({1'b0,ms0}),
		.in1({1'b1,s0}),
		.in2({1'b0,s1}),
		.in3(0),
		.in4(0),
		.in5(0), //format: {dp,hex[3:0]}
		.seg_out(seg_out),
		.sel_out(sel_out)
    );


endmodule
module rotate_sq_TEST(
	input clk,rst_n,
	input cw,en,
	output [7:0] seg_out,
	output [5:0] sel_out
    );
	 wire[7:0] in0,in1,in2,in3,in4,in5;
	 
	 rotate_sq rot_sq(
	 .clk(clk),
	 .rst_n(rst_n),
	 .cw(cw),
	 .en(en),
	 .in0(in0),
	 .in1(in1),
	 .in2(in2),
	 .in3(in3),
	 .in4(in4),
	 .in5(in5) 
    );
	 LED_mux led_mux(
	.clk(clk),
	.rst(rst_n),
	.in0(in0),
	.in1(in1),
	.in2(in2),
	.in3(in3),
	.in4(in4),
	.in5(in5),
	.seg_out(seg_out),
	.sel_out(sel_out)
    );


endmodule
module rotate_sq_TB;

	// Inputs
	reg clk;
	reg rst_n;
	reg cw;
	reg en;

	// Outputs
	wire [7:0] in0;
	wire [7:0] in1;
	wire [7:0] in2;
	wire [7:0] in3;
	wire [7:0] in4;
	wire [7:0] in5;

	// Instantiate the Unit Under Test (UUT)
	rotate_sq #(.base_counter(5)) uut //100 ns per box
	( 
		.clk(clk), 
		.rst_n(rst_n), 
		.cw(cw), 
		.en(en), 
		.in0(in0), 
		.in1(in1), 
		.in2(in2), 
		.in3(in3), 
		.in4(in4), 
		.in5(in5)
	);
	always begin
	clk=1'b0;
	#10;
	clk=1'b1;
	#10;
	end
	
	initial begin
		// Initialize Inputs
		clk = 0;
		rst_n = 1'b1;
		cw = 0;
		en = 1'b1;
		
	

	end
	
      
endmodule
module rotate_sq
	#(parameter base_counter=10_000_000) ////frequency of rotating square is 50MHz/base_counter=50MHz/10M=5Hz (0.2 sec per box)
	(
	 input clk,rst_n,
	 input cw,en,
	 output reg[7:0] in0,in1,in2,in3,in4,in5 //1 bit=Decimal point(active low) 7 bits=seven-segment value(active low)
    );

	 reg[23:0] mod_10M=0; 
	 reg[3:0] mod_12=0; //12 turns since the square will rotate in 6 seven-segments
	 wire[23:0] mod_10M_nxt;
	 reg[3:0] mod_12_nxt=0;
	 
	 //registers
	 always @(posedge clk,negedge rst_n) begin
		 if(!rst_n) begin
			mod_10M<=0;
			mod_12<=0;
			end	
		else begin
			if(en) begin //if not enable then do nothing
				mod_10M<=mod_10M_nxt;
				mod_12<=mod_12_nxt;
				end
			end		
	end
	
	//next-state logic for mod_25M
	assign mod_10M_nxt=(mod_10M==base_counter-1)?24'd0:mod_10M+1'b1;
	assign mod_10M_max=(mod_10M==base_counter-1)?1'b1:1'b0;
	
	//next-state logic for mod_12
	always @* begin
	mod_12_nxt=mod_12;
		if(mod_10M_max) begin
			if(cw) mod_12_nxt=(mod_12==11)?4'd0: mod_12+1'b1; //clock-wise= 0-to-11 then back to zero
			else mod_12_nxt=(mod_12==0)?4'd11:mod_12-1'b1;    //counterclock-wise= 11-to-zero then back to 11
		end
	end
	
	
	//mod_12 tells which of the 6 seven-segments will turn-on and whether its the upper box or lower box 
	always @* begin
	   in0=8'hff; in1=8'hff; in2=8'hff; in3=8'hff; in4=8'hff; in5=8'hff; //default off(active low)
		case(mod_12) 
			4'd0: in5={1'b1,7'b0011100}; //Upper box
			4'd1: in4={1'b1,7'b0011100};
			4'd2: in3={1'b1,7'b0011100};
			4'd3: in2={1'b1,7'b0011100};
			4'd4: in1={1'b1,7'b0011100};
			4'd5: in0={1'b1,7'b0011100};
			
			4'd6: in0={1'b1,7'b1100010}; //Lower box
			4'd7: in1={1'b1,7'b1100010};
			4'd8: in2={1'b1,7'b1100010};
			4'd9: in3={1'b1,7'b1100010};
		  4'd10: in4={1'b1,7'b1100010};
		  4'd11: in5={1'b1,7'b1100010};
		endcase
	end
	
endmodule
module full_screen_gen(
	input clk,rst_n,
	input rx,
	input[2:0] key, //key[0] to move cursor to right,key[1] to move cursor down, key[2] to change waveform pattern
	input[9:0] pixel_x,pixel_y,
	input video_on,
	output reg[2:0] rgb
    );
	 
	 wire key0_tick,key1_tick,key2_tick;
	 reg[1:0] din_q=0;
	 wire[1:0] dout;
	 wire on;
	 wire[7:0] font_data;
	 wire font_bit;
	 wire underline_on,cursor_on;
	 reg[2:0] y_cursor_q,y_cursor_d; 
	 reg[6:0] x_cursor_q,x_cursor_d;
	 reg[9:0] pixel_x_q,pixel_x_q2,pixel_y_q,pixel_y_q2; //buffer to delay the pixel_x and pixel_y by two clk times,
																					//retrieving data from syn_rom and syn_dualport_ram causes 2 clk
																							//delays so we need to delay the pixel_x and pixel_y by 2 clk delays too
																							
	 
	 //register operation to update current cursor
	 always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			y_cursor_q<=0;
			x_cursor_q<=0;
			pixel_x_q<=0;
			pixel_x_q2<=0;
			pixel_y_q<=0;
			pixel_y_q2<=0;
			din_q<=0;
		end
		else begin
			y_cursor_q<=y_cursor_d;
			x_cursor_q<=x_cursor_d;
			pixel_x_q<=pixel_x;
			pixel_x_q2<=pixel_x_q;
			pixel_y_q<=pixel_y;
			pixel_y_q2<=pixel_y_q;
			din_q<=key2_tick? din_q+1:din_q;
		end
	 end
	 always @* begin
		x_cursor_d=x_cursor_q;
		y_cursor_d=y_cursor_q;
		if(key0_tick) x_cursor_d= (x_cursor_q<80)? x_cursor_q+1:0; //wrap around if beyond the display range(0-to-79 patterns for x-axis)
		if(key1_tick) y_cursor_d= (y_cursor_q<7)? y_cursor_q+1:0;  //wrap around if beyond the display range(0-to-6 patterns for y-axis)
	 end
	  
	  
	  assign font_bit=on && font_data[~pixel_x_q2[2:0]];
	  assign cursor_on= (pixel_y_q2[8:6]==y_cursor_q && pixel_x_q2[9:3]==x_cursor_q); //current cursor
	  assign underline_on= cursor_on && (pixel_y_q2[5:0]>=60); //current scan is at the last 4 rows(60-to-63) of the current cursor
	  
	 //rgb logic 
	 always @* begin
		rgb=0;
		if(!video_on) 	rgb=0;
		else if(underline_on) rgb=3'b011; //underline the current cursor
		else rgb=font_bit? 3'b010:3'b000;
	 end
	 
	 
	 //module instantiations
	 
	squarewave_rom m0
	(
		.clk(clk),
		.addr({dout,pixel_y[5:0]}), //7:6 for square-wave pattern , 5:0 for column address of that pattern
		.data(font_data)
    );
	
	dual_port_syn #(.ADDR_WIDTH(10),.DATA_WIDTH(3)) m1
	(
		.clk(clk),
		.we(1),
		.din({1'b1,din_q}), //write data
		.addr_a({y_cursor_q,x_cursor_q}), //write addr
		.addr_b({pixel_y[8:6],pixel_x[9:3]}), //read addr
		.dout_a(),
		.dout_b({on,dout}) //read data	
	);
	
	
	debounce_explicit m2
	(
		.clk(clk),
		.rst_n(rst_n),
		.sw({!key[0]}),
		.db_level(),
		.db_tick(key0_tick)//move right
    );
	 
	 
	debounce_explicit m3
	(
		.clk(clk),
		.rst_n(rst_n),
		.sw({!key[1]}),
		.db_level(),
		.db_tick(key1_tick)//move down
    );
	 
	debounce_explicit m4
	(
		.clk(clk),
		.rst_n(rst_n),
		.sw({!key[2]}),
		.db_level(),
		.db_tick(key2_tick)//write to current cursor
    );


endmodule
module squarewave_disp
	(
	input clk,rst_n,
	input[2:0] key, //key[0] to move cursor to right,key[1] to move cursor down, key[2] to change waveform pattern
	output[4:0] vga_out_r,
	output[5:0] vga_out_g,
	output[4:0] vga_out_b,
	output vga_out_vs,vga_out_hs
    );
	 
	 wire[11:0] pixel_x,pixel_y;
	 wire video_on;
	 wire[2:0] rgb;
	 
	 
	 assign vga_out_r=rgb[2]? 5'b111_11:0 ;
	 assign vga_out_g=rgb[1]? 6'b111_111:0 ;
	 assign vga_out_b=rgb[0]? 5'b111_11:0 ;
	 

	 vga_core m0
	(
		.clk(clk_out),  //clock must be 25MHz for 640x480 
		.rst_n(rst_n),
		.hsync(vga_out_hs),
		.vsync(vga_out_vs),
		.video_on(video_on),
		.pixel_x(pixel_x),
		.pixel_y(pixel_y)
    );	
	 
	full_screen_gen m1 //generates square-wave patterns with variable cursor location
	(
		.clk(clk_out),
		.rst_n(rst_n),
		.key(key),
		.pixel_x(pixel_x),
		.pixel_y(pixel_y),
		.video_on(video_on),
		.rgb(rgb)
    );
	
	 dcm_25MHz m2
		(// Clock in ports
		 .clk(clk),      // IN
		 // Clock out ports
		 .clk_out(clk_out),     // OUT
		 // Status and control signals
		 .RESET(RESET),// IN
		 .LOCKED(LOCKED)
	 );      
	
endmodule
module binary_decoder_3x8_TB;

	// Inputs
	reg [2:0] a;

	// Outputs
	wire [7:0] bcode;
	
	// Instantiate the Unit Under Test (UUT)
	binary_decoder_3x8 uut ( 
		.a(a), 
		.bcode(bcode)
	);
	
	reg[3:0] counter;
	initial begin
		$display("a[2] a[1] a[0] bcode");
		for(counter=0;counter<=7;counter=counter+1'b1) begin
			a=counter[2:0];
			$strobe(" %b    %b    %b   %b",a[2],a[1],a[0],bcode);
			#10;
		end
	end      
endmodule
module binary_decoder_3x8(
	input[2:0] a,
	output[7:0] bcode
    );
	 
	 binary_decoder_2x4 m0
	 (
		 .en({!a[2]}),
		 .a(a[1:0]),
		 .bcode(bcode[3:0])
    );
	 
	 binary_decoder_2x4 m1
	 (
		 .en(a[2]),
		 .a(a[1:0]),
		 .bcode(bcode[7:4])
    );


endmodule
module binary_decoder_4x16(
	input[3:0] a,
	output[15:0] bcode
    );
	 binary_decoder_2x4 m0
	 (
		 .en({!a[3] && !a[2]}),
		 .a(a[1:0]),
		 .bcode(bcode[3:0])
    );
	 
	 binary_decoder_2x4 m1
	 (
		 .en({!a[3] && a[2]}),
		 .a(a[1:0]),
		 .bcode(bcode[7:4])
    );
	 
	 binary_decoder_2x4 m2
	 (
		 .en({a[3] && !a[2]}),
		 .a(a[1:0]),
		 .bcode(bcode[11:8])
    ); 
	 
	 binary_decoder_2x4 m3
	 (
		 .en({a[3] && a[2]}),
		 .a(a[1:0]),
		 .bcode(bcode[15:12])
    );
	 


endmodule
module binary_decoder_2x4_TB;

	// Inputs
	reg en;
	reg [1:0] a;

	// Outputs
	wire [3:0] bcode;

	// Instantiate the Unit Under Test (UUT)
	binary_decoder_2x4 uut (
		.en(en), 
		.a(a), 
		.bcode(bcode)
	);
	reg[3:0] counter;
	initial begin
		$display("en a[1] a[0] bcode");
		for(counter=0;counter<=7;counter=counter+1'b1) begin
			{en,a}=counter[2:0];
			$strobe("%b   %b    %b   %b",en,a[1],a[0],bcode);
			#10;
		end
	end
      
endmodule
module binary_decoder_2x4(
	input en,
	input[1:0] a,
	output[3:0] bcode
    );
	 assign bcode[0]= en && !a[1] && !a[0],
				bcode[1]= en && !a[1] && a[0],
				bcode[2]= en && a[1] && !a[0],
				bcode[3]= en && a[1] && a[0]; 


endmodule
module binary_decoder_4x16_TB;

	// Inputs
	reg [3:0] a;

	// Outputs
	wire [15:0] bcode;

	// Instantiate the Unit Under Test (UUT)
	binary_decoder_4x16 uut (
		.a(a), 
		.bcode(bcode)
	);

	reg[4:0] counter;
	initial begin
		$display("a[3]  a[2] a[1] a[0] bcode");
		for(counter=0;counter<=15;counter=counter+1'b1) begin
			a=counter[3:0];
			$strobe(" %b     %b    %b    %b   %b",a[3],a[2],a[1],a[0],bcode);
			#10;
		end
	end   
      
endmodule
module kb_control_circuit(
	input clk,rst_n,
	input key0,key1,key2,
	inout ps2d,ps2c	
    );
	 //FSM state-declarations
	 localparam[1:0] idle=2'd0,
							byte1=2'd1,
							byte2=2'd2,
							done=2'd3;
	 reg[1:0] state_reg,state_nxt;
	 reg[3:0] hex_reg,hex_nxt;
	 reg wr_ps2;
	 reg[7:0] din;
	 wire tx_done_tick;
	 wire key0_tick,key1_tick,key2_tick;
	 
	 //FSM register operations
	 always @(posedge clk,negedge rst_n) begin
		if(!rst_n) begin
			state_reg<=0;
			hex_reg<=0;
		end
		else begin
			state_reg<=state_nxt;
			hex_reg<=hex_nxt;
		end
	 end
	 
	 //FSM next-state logics
	 always @* begin
		state_nxt=state_reg;
		wr_ps2=0;
		din=0;
		hex_nxt=hex_reg;
		case(state_reg) 
		  	   idle: begin //wait for the tick of any button
							if(key0_tick) hex_nxt=4'b0010; //on num-lock led
							else if(key1_tick) hex_nxt=4'b0001; //on scroll-lock led
							else if(key2_tick) hex_nxt=4'b0100;//on caps-lock led
							if(key0_tick||key1_tick||key2_tick) state_nxt=byte1;
						end
			  byte1: begin //send first byte 
							din=8'hed;
							wr_ps2=1;
							if(tx_done_tick) state_nxt=byte2;
						end
			  byte2: begin //send second byte(contains the data on which led to turn on)
							din={4'h0,hex_reg};
							wr_ps2=1;
							if(tx_done_tick) state_nxt=done;
						end
			   done: state_nxt=idle;
			default: state_nxt=idle;
		endcase
	 end
	 
	 
	 
	 //module instantations
	ps2_tx m0
	(
		.clk(clk),
		.rst_n(rst_n),
		.wr_ps2(wr_ps2),
		.din(din),
		.ps2d(ps2d),
		.ps2c(ps2c),
		.tx_idle(),
		.tx_done_tick(tx_done_tick)
    );
	 
	 debounce_explicit m1
	 (
		.clk(clk),
		.rst_n(rst_n),
		.sw({!key0}),
		.db_level(),
		.db_tick(key0_tick)
    );
	 debounce_explicit m2
	 (
		.clk(clk),
		.rst_n(rst_n),
		.sw({!key1}),
		.db_level(),
		.db_tick(key1_tick)
    );
	 debounce_explicit m3
	 (
		.clk(clk),
		.rst_n(rst_n),
		.sw({!key2}),
		.db_level(),
		.db_tick(key2_tick)
    );


endmodule
module led_dimmer_PLUS_sevenseg(
 input clk,rst_n,
 input sw,
 output[7:0] seg_out,
 output[5:0] sel_out
    );
	 reg[3:0] w_counter=0; //each press of sw will increment w_counter by 1 which would then be used as the duty cycle for the pwm output(control brightness of LED 7-segment)
	 reg holder=0;
	 wire[7:0] seg_out_temp0,seg_out_temp1;
	 wire key;
	 
	 
	 //button circuit
	 debouncer m0(
	.clk(clk),
	.rst_n(rst_n),
	.pushbutton(sw),  
	.key(key)                
	); 
	 always @(posedge clk,negedge rst_n) begin
		 if(!rst_n) begin
			w_counter=0;
			holder=0;
		 end
		 else begin
				 if(key) begin
					if(!holder) begin
						w_counter=w_counter+1'b1;
						holder=1;
						end
				 end 		
				 else holder=0; 
		  end
	 end
	 
	//w_counter will control the brightness of seven-segments while displaying the value of w_counter itself
	LED_mux ledmux
	(
	.clk(clk),
	.rst(rst_n),
	.in0({1'b0,w_counter}),
	.in1(0),
	.in2(0),
	.in3(0),
	.in4(0),
	.in5(0), //format: {dp,hex[3:0]} dp is active high
	.seg_out(seg_out_temp0),  
	.sel_out(sel_out)
    );
	 
	 
	 genvar i; //makes 8 circuits
	 for(i=0;i<=7;i=i+1) begin
	 
		led_dimmer dimmer(
		.clk(clk),
		.rst_n(rst_n),
		.w(w_counter),
		.en(!seg_out_temp0[i]), //en accepts active high input only so reverse the input first
		.pwm(seg_out_temp1[i]) 
		 );
		 
		 assign seg_out[i]=!seg_out_temp1[i]; //reverse the signal since seven segment needs active inputs
		 
	 end

endmodule