module affichage
  (lclk, reset_n, 
   ledslo, ledshi,
   sseglo, sseghi,
   lcd_cmd, lcd_data,
   sync,
   n_en_cmd,
   n_en_data,
   db, adr,
   cs, we, oe);

   input        lclk, reset_n;
   input [7:0] 	ledshi;
   input [7:0] 	ledslo;
   input [7:0] 	sseghi;
   input [7:0] 	sseglo;
   
   input [7:0] 	lcd_cmd;
   input [7:0] 	lcd_data;
   output	sync;
   input 	n_en_cmd;
   input 	n_en_data;
   
   output [7:0] db;
   output [5:0] adr;
   output       cs, we, oe;


   reg [7:0] 	data_conf_lcd;
   reg [4:0] 	count;
   reg [3:0] 	init_count;
   reg [7:0] 	db;
   reg [5:0] 	adr;
   reg 		cs, we;
   wire 	conf;


   assign 	conf = (init_count != 10);
   assign 	sync = (count==0) & ~conf;
   
   always @(posedge lclk or negedge reset_n)
     if(reset_n==0)
       begin
	  count <= 0;
       	  init_count <= 0;
       end
     else
       begin
       	  count <= count + 1;
	  if(count == 5'b10111)
	    count <= 0;

	  if ((count == 5'b10111) && (init_count != 10))
	    init_count <= init_count + 1;  // init_count reste à 10 apres la configuration
	  
	  // codage cs , actif à 0	
   	  if (count[4]==1)
	    if(count[4:2] == 3'b100)
	      cs <= (count[1:0] != 2'b10) | (n_en_cmd &!conf);
	    else
	      cs <= (count[1:0] != 2'b10) | (n_en_data &!conf) | conf;
	  else
	    cs <=(count[1:0] == 2'b00);
	  
	  // codage we , actif à 0			
    	  if (count[4]==1)
	    if(count[4:2] == 3'b100)
	      we <= (count[1:0] == 2'b00) | (n_en_cmd &!conf);
	    else
	      we  <= (count[1:0] == 2'b00) | (n_en_data &!conf)  | conf;
	  else   
	    we <= (count[1:0] != 2'b01);
	  
	  adr <= {3'b000, count[4:2]};
	  
       end
   
   assign       oe = 1;
   
   
   always @*
     begin
        db = 8'b01001111;
        casex (adr)
          6'b000000 : db = ledslo;
          6'b000001 : db = ledshi;
          6'b000010 : db = sseglo;
          6'b000011 : db = sseghi;
          6'b000100 : db = (conf) ? data_conf_lcd : lcd_cmd;
          6'b000101 : db = lcd_data;
          6'b000110 : db = 8'b00000000;		  
          6'b000111 : db = 8'b00000000;
	  
        endcase
     end
   
   always @(init_count)
     begin
	data_conf_lcd <= 0;
	casex (init_count)
	  1  : data_conf_lcd <= 8'b00000001 ; // clears entire lcd
	  2  : data_conf_lcd <= 8'b00000001 ; // clears entire lcd
	  3  : data_conf_lcd <= 8'b00000010 ; // return home
	  4  : data_conf_lcd <= 8'b00111000 ; // mode 8 bits, 2lines, small font
	  5  : data_conf_lcd <= 8'b00001111 ; // display on, cursor on, blinking on
	  6  : data_conf_lcd <= 8'b00000110 ; // set displacement to the right / no display shift
	  7  : data_conf_lcd <= 8'b00000000 ; // pause
	  8  : data_conf_lcd <= 8'b00000000 ; // pause
	  9  : data_conf_lcd <= 8'b10000000 ; // retour en haut a gauche
	  10 : data_conf_lcd <= 8'b00000000 ; // fin :)
	endcase // casex(init_count)
     end
   
endmodule // affichage



