RISC-V,  Verificación,  Verificación física

Verificación física RISC-V con LCD

El planteamiento de esta entrada es si podemos hacer una verificación física del RISC-V, en la placa DE2-115 mediante el LCD.

La controladora verilog de LCD proviene de la siguiente dirección y autoría:

https://gist.github.com/windhooked/40f6c9a6d35062a5d24503d2bcb07ddd

La adaptación que he realizado ha consistido fundamentalmente en generar una salida adicional que resetee el micro RISC-V mientras el LCD arranca, de forma que cuando esté el LCD inicializado, liberemos el micro RISC-V y pueda empezar a ejecutar sus instrucciones. Esa salida adicional se denomina RST_output.

Otro cambio que introduje fue un enable general denominado TC_general de un contador módulo 20 que nos garantice que los niveles a 1 de LCD_E sean superiores a 400 ns (trabajamos con un reloj de 50 MHz), aunque cómo veréis he multiplicado por 20 todas las temporizaciones y solo así he conseguido que funcionara.

module FPGA_2_LCD_RAFA(
	CLK, LCD_RS, LCD_RW, LCD_E, LCD_DB, RDY, DATA, OPER, ENB, RST, 		RST_output 
);
input CLK;			// For this code to work without modification, CLK should equal 24MHz
input [7:0] DATA;			// The Data to send to the LCD Module
input [1:0] OPER;			// The Type of operation to perform (data or instruction) 
input ENB;			// Tells the module that the data is valid and start reading DATA and OPER
input RST;
 
output RDY;			// Indicates that the module is Idle and ready to take more data
output RST_output;
output LCD_RS, LCD_RW, LCD_E;
output [7:0] LCD_DB;
 
reg RST_output;
wire [7:0] DATA;
wire [1:0] OPER;
wire ENB;
reg RDY;
 
reg [7:0] LCD_DB=0;
reg LCD_RW=0;			// always write to (and never read from) the LCD
reg LCD_RS=0;			// HI means Data, LOW means Instruction/Command
reg LCD_E=0;
 
/*----------------------SOME NOTES-------------------
when RS and R/W change STATE...wait for at least 20ns ( ~1clock cycle )
after that period of time bring E high and invert E every 400 ns (can be larger) ( ~20 clock cycles)
while E is HI, set DATA
when E goes LOW, maintain DATA for atleast 10ns
 
CLOCK=50MHz ==> 20 ns
-------------------------END OF NOTES-------------------*/
//===============================================================================================
//------------------------------Define the Timing Parameters-------------------------------------
//===============================================================================================
parameter [19:0] t_40ns 	= 1;		//20ns 		== ~1clk
parameter [19:0] t_250ns 	= 6;		//400ns 	== ~20clks
parameter [19:0] t_42us 	= 1008;		//21us 		== ~1008clks
parameter [19:0] t_100us 	= 2400;		//50us		== ~2400clks
parameter [19:0] t_1640us 	= 39360;	//0.82ms 	== ~39360clks
parameter [19:0] t_4100us 	= 98400;	//2.05ms    	== ~98400clks
parameter [19:0] t_15000us	= 360000;	//7,5ms 		== ~360000clks
 
//===============================================================================================
//------------------------------Define the BASIC Command Set-------------------------------------
//===============================================================================================
parameter [7:0] SETUP		= 8'b00111000;	//Execution time = 42us, sets to 8-bit interface, 2-line display, 5x7 dots
parameter [7:0] DISP_ON		= 8'b00001100;	//Execution time = 42us, Turn ON Display
parameter [7:0] ALL_ON		= 8'b00001111;	//Execution time = 42us, Turn ON All Display
parameter [7:0] ALL_OFF		= 8'b00001000;	//Execution time = 42us, Turn OFF All Display
parameter [7:0] CLEAR 		= 8'b00000001; 	//Execution time = 1.64ms, Clear Display
parameter [7:0] ENTRY_N		= 8'b00000110;	//Execution time = 42us, Normal Entry, Cursor increments, Display is not shifted
parameter [7:0] HOME 		= 8'b00000010; 	//Execution time = 1.64ms, Return Home
parameter [7:0] C_SHIFT_L 	= 8'b00010000; 	//Execution time = 42us, Cursor Shift
parameter [7:0] C_SHIFT_R 	= 8'b00010100; 	//Execution time = 42us, Cursor Shift
parameter [7:0] D_SHIFT_L 	= 8'b00011000; 	//Execution time = 42us, Display Shift
parameter [7:0] D_SHIFT_R 	= 8'b00011100; 	//Execution time = 42us, Display Shift
 
//===============================================================================================
//-----------------------------Create the counting mechanisms------------------------------------
//===============================================================================================
reg [19:0] cnt_timer=0; 			//39360 clks, used to delay the STATEmachine during a command execution (SEE above command set)
reg flag_250ns=0,flag_42us=0,flag_100us=0,flag_1640us=0,flag_4100us=0,flag_15000us=0;
reg flag_rst=1;					//Start with flag RST set. so that the counting has not started
reg flag_40ns;
reg  [4:0] idea;

wire TC_general;
assign TC_general=(idea==5'b10011)?1'b1:1'b0;
always @(posedge CLK, negedge RST) begin
if (!RST)
begin
		flag_40ns   <=1'b0;
		flag_250ns	<=	1'b0;		//Unlatch the flag
		flag_42us	<=	1'b0;		//Unlatch the flag
		flag_100us	<=	1'b0;		//Unlatch the flag
		flag_1640us	<=	1'b0;		//Unlatch the flag
		flag_4100us	<=	1'b0;		//Unlatch the flag
		flag_15000us    <=	1'b0;		//Unlatch the flag
		cnt_timer	<=	20'b0;
		idea<=5'b00000;

end
else
begin
if (idea==5'b10011)
	idea<=5'b00000;
else
	idea<=idea+1;
if (TC_general)
		if(flag_rst ) begin
			flag_40ns   <=1'b0;
			flag_250ns	<=	1'b0;		//Unlatch the flag
			flag_42us	<=	1'b0;		//Unlatch the flag
			flag_100us	<=	1'b0;		//Unlatch the flag
			flag_1640us	<=	1'b0;		//Unlatch the flag
			flag_4100us	<=	1'b0;		//Unlatch the flag
			flag_15000us    <=	1'b0;		//Unlatch the flag
			cnt_timer	<=	20'b0;		
		end
		else 
		begin
			flag_40ns<=	cnt_timer[0]; //si el reloj es de 50 MHz , esta señal es de 25 MHz
			if(cnt_timer>=t_250ns) begin			
				flag_250ns	<=	1'b1;
			end
			else begin			
				flag_250ns	<=	flag_250ns;
			end
			//----------------------------
			if(cnt_timer>=t_42us) begin			
				flag_42us	<=	1'b1;
			end
			else begin			
				flag_42us	<=	flag_42us;
			end
			//----------------------------
			if(cnt_timer>=t_100us) begin			
				flag_100us	<=	1'b1;
			end
			else begin			
				flag_100us	<=	flag_100us;
			end
			//----------------------------
			if(cnt_timer>=t_1640us) begin			
				flag_1640us	<=	1'b1;
			end
			else begin			
				flag_1640us	<=	flag_1640us;
			end
			//----------------------------
			if(cnt_timer>=t_4100us) begin			
				flag_4100us	<=	1'b1;
			end
			else begin			
				flag_4100us	<=	flag_4100us;
			end
			//----------------------------
			if(cnt_timer>=t_15000us) begin			
				flag_15000us	<=	1'b1;
			end
			else begin			
				flag_15000us	<=	flag_15000us;
			end
			//----------------------------
			cnt_timer	<= cnt_timer + 1;
		end
end
end
 
//##########################################################################################
//-----------------------------Create the STATE MACHINE------------------------------------
//##########################################################################################
reg [3:0] STATE;
reg [1:0] SUBSTATE;
 
always @(posedge CLK, negedge RST) begin
if (!RST)
begin
			LCD_RS	<=		1'b0;										//Indicate an instruction is to be sent soon
			LCD_RW	<= 	1'b0;										//Indicate a write operation
			LCD_E		<=		1'b0;										//We are in the initial setup, keep low until 250ns has past
			LCD_DB 	<= 	8'b00000000;
			RDY					<= 1'b0;								//Indicate that the module is busy
			SUBSTATE	<=		0;
			STATE<=0;
			flag_rst			<=	1'b0; 
		   RST_output <=1'b0;
end
else
   if (TC_general)
 	case(STATE)
		//---------------------------------------------------------------------------------------
		0: begin //---------------Initiate Command Sequence (RS=LOW)-----------------------------
			LCD_RS	<=		1'b0;										//Indicate an instruction is to be sent soon
			LCD_RW	<= 	1'b0;										//Indicate a write operation
			LCD_E		<=		1'b0;										//We are in the initial setup, keep low until 250ns has past
			LCD_DB 	<= 	8'b00000000;
			RDY					<= 1'b0;								//Indicate that the module is busy
			SUBSTATE	<=		0;
			if(!flag_15000us) begin									//WAIT 15ms...worst case scenario
				STATE				<=	STATE;						//Remain in current STATE
				flag_rst			<=	1'b0; 						//Start or Continue counting				
			end
			else begin 				
				STATE				<=	STATE+1;						//Go to next STATE
				flag_rst			<=	1'b1; 						//Stop counting				
			end		
		end
		//---------------------------------------------------------------------------------------
		1: begin //-----------SET FUNCTION #1, 8-bit interface, 2-line display, 5x7 dots---------
			LCD_RS				<=	1'b0;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;					
				SUBSTATE			<=	1;
			end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= SETUP;					//Data Valid
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(!flag_4100us) begin						//WAIT at least 4.1ms (required for Initialization)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 		
					STATE			<=	STATE+1;					//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end	
		end	
		//---------------------------------------------------------------------------------------
		2: begin //-----------SET FUNCTION #2, 8-bit interface, 2-line display, 5x7 dots---------
			LCD_RS				<=	1'b0;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation	
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;				
				SUBSTATE			<=	1;
			end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= SETUP;					//Data Valid
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(!flag_100us) begin						//WAIT at least 100us (required for Initialization)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 		
					STATE			<=	STATE+1;					//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end	
		end
		//---------------------------------------------------------------------------------------
		3: begin //-----------SET FUNCTION #3, 8-bit interface, 2-line display, 5x7 dots---------
			LCD_RS				<=	1'b0;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation	
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;				
				SUBSTATE			<=	1;
				end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= SETUP;					//Data Valid
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(!flag_100us) begin						//WAIT at least 100us (required for Initialization)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 		
					STATE			<=	STATE+1;					//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
		end
		//---------------------------------------------------------------------------------------
		4: begin //-----------SET FUNCTION #4, 8-bit interface, 2-line display, 5x7 dots---------
			LCD_RS				<=	1'b0;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation	
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;					
				SUBSTATE			<=	1;
			end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= SETUP;					//Data Valid
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(!flag_100us) begin						//WAIT at least 100us (required for Initialization)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 		
					STATE			<=	STATE+1;					//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
		end
		//---------------------------------------------------------------------------------------
		5: begin //-----------------DISPLAY, Display OFF, Cursor OFF, Blinking OFF------------------
			LCD_RS				<=	1'b0;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation	
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;				
				SUBSTATE			<=	1;
			end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= ALL_OFF;					//Data Valid
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(!flag_42us) begin							//WAIT at least 42us (required for operation to process)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 		
					STATE			<=	STATE+1;					//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
		end
		//---------------------------------------------------------------------------------------
		6: begin //-------------------DISPLAY CLEAR, clear the display screen--------------------
			LCD_RS				<=	1'b0;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation	
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;				
				SUBSTATE			<=	1;
			end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= CLEAR;					//Data Valid
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(!flag_1640us) begin						//WAIT at least 1640us (required for operation to process)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 		
					STATE			<=	STATE+1;					//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end			
		end
		//---------------------------------------------------------------------------------------
		7: begin //---------Normal ENTRY, Cursor increments, Display is not shifted--------------
			LCD_RS				<=	1'b0;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation	
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;				
				SUBSTATE			<=	1;
			end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= ENTRY_N;					//Data Valid
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(!flag_42us) begin							//WAIT at least 42us (required for operation to process)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 		
					STATE			<=	STATE+1;					//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
		end
		//---------------------------------------------------------------------------------------
		8: begin //-----------------DISPLAY, Display ON, Cursor ON, Blinking ON------------------
			LCD_RS				<=	1'b0;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation	
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;				
				SUBSTATE			<=	1;
			end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= DISP_ON;//ALL_ON;					//Data Valid
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(!flag_42us) begin							//WAIT at least 42us (required for operation to process)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 		
					STATE			<=	STATE+1;					//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
		end
		//---------------------------------------------------------------------------------------
		9: begin //-------------------DISPLAY CLEAR, clear the display screen--------------------		
			LCD_RS				<=	1'b0;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation	
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;				
				SUBSTATE			<=	1;
			end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= CLEAR;					//Data Valid
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(!flag_1640us) begin						//WAIT at least 1640us (required for operation to process)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 		
					STATE			<=	15;						//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
		end
		//---------------------------------------------------------------------------------------
		10: begin//----------------------------- WRITE DATA -------------------------------------
			LCD_RS				<=	1'b1;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation	
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;				
				SUBSTATE			<=	1;
				flag_rst		<=	1'b1; 
			end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= DATA;						//WRITE THE CHARACTER
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(flag_250ns&& !flag_rst) begin	
					STATE			<=	15;//STATE+1;			//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 
				end	
				else begin 		
				//WAIT at least 250ns (required for LCD_E)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
			end		
		end	
		//---------------------------------------------------------------------------------------
		11: begin//----------------------- WRITE INSTRUCTION ------------------------------------
			LCD_RS				<=	1'b0;						//Indicate an instruction is to be sent soon
			LCD_RW				<=	1'b0;						//Indicate a write operation	
			RDY					<= 1'b0;						//Indicate that the module is busy
			if(SUBSTATE==0)begin	 		
				LCD_E				<=	1'b0;						//Disable Bus
				LCD_DB 			<=	LCD_DB;					//Maintain Previous Data on the Bus
				STATE				<=	STATE;				
				SUBSTATE			<=	1;
			end			
			if(SUBSTATE==1)begin				
				LCD_E				<=	1'b1;						//Enable Bus		
				LCD_DB 			<= DATA;						//Data Valid
				if(!flag_250ns) begin						//WAIT at least 250ns (required for LCD_E)
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 				
					SUBSTATE		<=	SUBSTATE+1;				//Go to next SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
			if(SUBSTATE==2)begin
				LCD_E				<=	1'b0;						//Disable Bus, Triggers LCD to read BUS
				LCD_DB 			<= LCD_DB;					//Keep Data Valid
				if(!flag_42us) begin							//WAIT at least 49us (required for operation to process)
					STATE			<=	STATE;					//Maintain current STATE
					SUBSTATE		<=	SUBSTATE;				//Maintain current SUBSTATE
					flag_rst		<=	1'b0; 					//Start or Continue counting									
				end
				else begin 		
					STATE			<=	15;//STATE+1;			//Go to next STATE
					SUBSTATE		<=	0;							//Reset SUBSTATE
					flag_rst		<=	1'b1; 					//Stop counting					
				end
			end
		end
		//---------------------------------------------------------------------------------------
		default: begin//----------This is the IDLE STATE, DO NOTHING UNTIL OPER is set-----------
			LCD_RS	<=		LCD_RS;								//Indicate an instruction is to be sent soon
			LCD_RW	<= 	1'b0;									//Indicate a write operation
			LCD_DB 	<= 	LCD_DB;								//Maintain Data Bus
			LCD_E		<=		1'b0;									//Disable Bus
			RDY		<=		1'b1;	
			RST_output <=1'b1;			//Indicate that the system is ready to taking in data
			if(ENB==1)begin
				case(OPER)
					0:STATE<=STATE; 	//IDLE
					1:STATE<=10;		//WRITE CHARACTER
					2:STATE<=11;		//WRITE INSTRUCTION (assumes 49us or less time to process instr)
					3:STATE<=0;			//RESET
				endcase
			end

		end
	endcase
end
endmodule

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *