adding user project rtl files
diff --git a/verilog/rtl/braille_driver_controller.v b/verilog/rtl/braille_driver_controller.v
new file mode 100644
index 0000000..2504335
--- /dev/null
+++ b/verilog/rtl/braille_driver_controller.v
@@ -0,0 +1,222 @@
+// SPDX-FileCopyrightText: 2020 Efabless Corporation
+//
+// 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
+
+`default_nettype none
+/*
+ *-------------------------------------------------------------
+ *
+ * user_proj_example
+ *
+ * This is an example of a (trivially simple) user project,
+ * showing how the user project can connect to the logic
+ * analyzer, the wishbone bus, and the I/O pads.
+ *
+ * This project generates an integer count, which is output
+ * on the user area GPIO pads (digital output only).  The
+ * wishbone connection allows the project to be controlled
+ * (start and stop) from the management SoC program.
+ *
+ * See the testbenches in directory "mprj_counter" for the
+ * example programs that drive this user project.  The three
+ * testbenches are "io_ports", "la_test1", and "la_test2".
+ *
+ *-------------------------------------------------------------
+ */
+`ifndef MPRJ_IO_PADS
+  `define MPRJ_IO_PADS 38
+`endif
+
+
+module braille_driver_controller
+(
+`ifdef USE_POWER_PINS
+    inout vccd1,	// User area 1 1.8V supply
+    inout vssd1,	// User area 1 digital ground
+`endif
+
+    // Logic Analyzer Signals
+    input  wire [127:0] la_data_in,
+    output wire [127:0] la_data_out,
+    input  wire [127:0] la_oenb,
+
+    // IOs
+    input  wire [`MPRJ_IO_PADS-1:0] io_in,
+    output wire [`MPRJ_IO_PADS-1:0] io_out,
+    output wire [`MPRJ_IO_PADS-1:0] io_oeb,
+
+
+    // Independent clock (on independent integer divider)
+    input wire   user_clock2,
+
+    // User maskable interrupt signals
+    output wire [2:0] irq
+
+);
+    wire 	clk;
+    wire [37:0] user_data_out;
+    wire [37:0] user_data_oeb;
+    wire         enable_n; 
+    wire [4:0]   rows;
+    wire [1:0]   cols;
+    wire [4:0]   rows_enable;
+    wire [1:0]   cols_enable;
+    wire [9:0]   rows_hbrige;
+    wire [3:0]   cols_hbrige;
+    wire         trigger_out_n;
+    wire         trigger_in_n;
+    wire         latch_data_n;
+    wire         sclk;
+    wire         mosi;
+    wire         ss_n;
+    wire         miso;
+
+
+    // IRQ
+    assign irq = 3'b000;	// Unused
+
+    // Assuming LA probes [65:64] are for controlling the count clk & reset  
+    assign clk = (~la_oenb[64]) ? la_data_in[64]: user_clock2;
+
+    genvar i;
+    generate
+    for(i=0;i<38;i=i+1'b1)
+    begin : io_port_assignment
+        assign io_out[i]     = (~la_oenb[i]) ? la_data_in[i]    : user_data_out[i];
+	assign io_oeb[i]     = (~la_oenb[i+38]) ? la_data_in[i+38] : user_data_oeb[i];
+	assign la_data_out[i] = (~la_oenb[i]) ? 1'b0 : io_in[i];
+    end
+    endgenerate
+    // 15 16 18 19 21 23
+    //  0 14 17 20 22  0
+    // 12  0 13 24  0 25
+    //  0  0  0  0 26 27
+    //  0  0  0  0 28 29
+    //  0  0  0  0 30 31
+    //  0  0  0  0  0 32
+    //  0  0  0 33 34 35
+    //  0  0  0  0 36 37
+    //  0  0  0  0  0  0
+    //  28 decated pins
+
+    assign user_data_out = {
+	1'b0,		// 37 enable_n
+	1'b0,		// 36 trigger_in_n
+	1'b0,		// 35 latch_data_n
+	miso,		// 34 miso
+	1'b0,		// 33 mosi
+	1'b0,		// 32 ss_n
+	1'b0,		// 31 sclk
+	rows_hbrige[9],	// 30
+	rows_hbrige[8],	// 29
+	rows_hbrige[7],	// 28
+	rows_hbrige[6],	// 27
+	rows_hbrige[5],	// 26
+	rows_hbrige[4],	// 25
+	rows_hbrige[3],	// 24
+	rows_hbrige[2],	// 23
+	rows_hbrige[1],	// 22
+	rows_hbrige[0],	// 21
+	rows_hbrige[9],	// 20
+	cols_hbrige[3],	// 19
+	cols_hbrige[2],	// 18
+	cols_hbrige[1],	// 17
+	cols_hbrige[0],	// 16
+	trigger_out_n,	// 15
+	rows[4],	// 14	user_control_enable_6
+	rows[3],	// 13	user_control_enable_5
+	rows[2],	// 12	user_control_enable_4
+	rows[1],	// 11   user_control_enable_3
+	rows[0],	// 10	flash2_io  / user_control_enable_2
+	cols[1],	// 9	flash2_io  / user_control_enable_1
+	cols[0],	// 8	flash2_csb / user_control_enable_0
+	1'b0,		// 7	irq
+	1'b0,		// 6	ser_tx
+	1'b0,		// 5	ser_rx
+	1'b0,		// 4	SCK
+	1'b0,		// 3	CSB
+	1'b0,		// 2	SDI
+	1'b0,		// 1	SDO  / CPU_TO_IO
+	1'b0		// 0   	JTAG / IO_TO_CPU
+	};
+
+    assign user_data_oeb = {
+	1'b1,		// 37 	enable_n     	: input
+	1'b1,		// 36 	trigger_in_n 	: input  
+	1'b1,		// 35 	latch_data_n 	: input
+	1'b0,		// 34 	miso 	   	: output
+	1'b1,		// 33 	mosi 	   	: input
+	1'b1,		// 32 	ss_n 	   	: input
+	1'b1,		// 31 	sclk 	   	: input
+	1'b0,		// 30	hbrige_0 	: output
+	1'b0,		// 29	hbrige_0 	: output
+	1'b0,		// 28	hbrige_0 	: output
+	1'b0,		// 27	hbrige_0 	: output
+	1'b0,		// 26	hbrige_0 	: output
+	1'b0,		// 25	hbrige_0 	: output
+	1'b0,		// 24	hbrige_0 	: output
+	1'b0,		// 23	hbrige_0 	: output
+	1'b0,		// 22	hbrige_0 	: output
+	1'b0,		// 21	hbrige_0 	: output
+	1'b0,		// 20	hbrige_0 	: output
+	1'b0,		// 19	hbrige_0 	: output
+	1'b0,		// 18	hbrige_0 	: output
+	1'b0,		// 17	hbrige_0 	: output
+	1'b0,		// 16	hbrige_0 	: output
+	1'b0,		// 15   triger_out_n 	: output				
+	rows_enable[4],	// 14	user_control_enable_6
+	rows_enable[3],	// 13	user_control_enable_5
+	rows_enable[2],	// 12	user_control_enable_4
+	rows_enable[1],	// 11   user_control_enable_3
+	rows_enable[0],	// 10	flash2_io  / user_control_enable_2
+	cols_enable[1],	// 9	flash2_io  / user_control_enable_1
+	cols_enable[0],	// 8	flash2_csb / user_control_enable_0
+	1'b1,		// 7	irq
+	1'b1,		// 6	ser_tx
+	1'b1,		// 5	ser_rx
+	1'b1,		// 4	SCK
+	1'b1,		// 3	CSB
+	1'b1,		// 2	SDI
+	1'b1,		// 1	SDO  / IO_TO_CPU : input
+	1'b0		// 0   	JTAG / CPU_TO_IO : output
+	};
+
+	assign enable_n     =	io_in[37]; 	
+	assign trigger_in_n =   io_in[36]; 	  
+	assign latch_data_n =   io_in[35];	
+	assign mosi 	    =   io_in[33];	
+	assign ss_n 	    =   io_in[32];	
+	assign sclk 	    =   io_in[31];	
+    
+	top user_design (
+	  .clock		(clk		),
+	  .enable_n		(enable_n	), 
+	  .rows			(rows		),
+	  .cols			(cols		),
+	  .rows_enable		(rows_enable	),
+	  .cols_enable		(cols_enable	),
+	  .rows_hbrige		(rows_hbrige	),
+	  .cols_hbrige		(cols_hbrige	),
+	  .trigger_out_n	(trigger_out_n	),
+	  .trigger_in_n		(trigger_in_n	),
+	  .latch_data_n		(latch_data_n	),
+	  .sclk			(sclk		),
+	  .mosi			(mosi		),
+	  .ss_n			(ss_n		),
+	  .miso			(miso		)
+	);
+
+endmodule
+
+`default_nettype wire
diff --git a/verilog/rtl/cells_controller.v b/verilog/rtl/cells_controller.v
new file mode 100644
index 0000000..7138e0b
--- /dev/null
+++ b/verilog/rtl/cells_controller.v
@@ -0,0 +1,275 @@
+module cells_controller
+(
+  input wire clock,
+  input wire [15:0] cells_state,
+  input wire system_enable_n,
+  input wire [31:0] ccr0,
+  input wire [31:0] ccr1,
+  output reg update_done,
+  output wire [4:0] rows,
+  output wire [1:0] cols,
+  output reg [4:0] rows_enable,
+  output reg [1:0] cols_enable,
+  output wire [9:0] rows_hbrige,
+  output wire [3:0] cols_hbrige,
+  input wire p_select_active,
+  input wire cell_invert, 
+  input wire enable_sn 
+);
+  reg [31:0] count;
+  reg [10:0] cell_pos;
+  wire line_enable_n;
+  wire [9:0] cell_output_state;
+  reg [4:0] rows_output;
+  reg [1:0] cols_output;
+
+  reg  [1:0] pcell_mem [9:0] ;
+  wire  [9:0] cells_state_diff   ;
+  wire [9:0] cell_enable;
+  genvar cell_p;
+  
+
+ // 4 9 | 8 9 
+ // 3 8 | 6 7 
+ // 2 7 | 2 5 
+ // 1 6 | 1 4 
+ // 0 5 | 0 3   
+
+ // 00_0000_0001 0 
+ // 00_0000_0010 1
+ // 00_0000_0100 2
+ // 00_0010_0000 3
+ // 00_0100_0000 4
+ // 00_1000_0000 5
+ // 00_0000_1000 6
+ // 01_0000_0000 7
+ // 00_0001_0000 8
+ // 10_0000_0000 9
+
+  always@(posedge clock)
+  begin
+    case({system_enable_n,(ccr1==count)})
+      2'b00: count <= count+1'b1;
+      default: count <= 32'b0;
+    endcase
+  end
+
+
+
+  always@(posedge clock)
+  begin
+    case({system_enable_n,(ccr1 == count)})
+      3'b00: cell_pos <= cell_pos;
+      3'b01: cell_pos <= {cell_pos[9:0],cell_pos[10]};
+      default: cell_pos <= 11'h001;
+    endcase
+  end
+
+
+  assign line_enable_n = (count <= ccr0) ? system_enable_n : 1'b1;
+
+  assign {
+  cell_output_state[9], 
+  cell_output_state[4],
+  cell_output_state[8], 
+  cell_output_state[3], 
+  cell_output_state[7], 
+  cell_output_state[6], 
+  cell_output_state[5], 
+  cell_output_state[2], 
+  cell_output_state[1], 
+  cell_output_state[0] 
+  } =  cells_state[9:0];  // 10
+
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0000_0001: rows_output[0] <=  (cell_output_state[0]) ; 
+      11'b000_0010_0000: rows_output[0] <=  (cell_output_state[5]) ; 
+      default: rows_output[0] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0000_0010: rows_output[1] <= (cell_output_state[1]); 
+      11'b000_0100_0000: rows_output[1] <= (cell_output_state[6]); 
+      default: rows_output[1] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0000_0100: rows_output[2] <= (cell_output_state[2]); 
+      11'b000_1000_0000: rows_output[2] <= (cell_output_state[7]); 
+      default: rows_output[2] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0000_1000: rows_output[3] <= (cell_output_state[3]); 
+      11'b001_0000_0000: rows_output[3] <= (cell_output_state[8]); 
+      default: rows_output[3] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0001_0000: rows_output[4] <= (cell_output_state[4]) ; 
+      11'b010_0000_0000: rows_output[4] <= (cell_output_state[9]) ; 
+      default: rows_output[4] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0000_0001: cols_output[0] <= ~(cell_output_state[0]); 
+      11'b000_0000_0010: cols_output[0] <= ~(cell_output_state[1]); 
+      11'b000_0000_0100: cols_output[0] <= ~(cell_output_state[2]); 
+      11'b000_0000_1000: cols_output[0] <= ~(cell_output_state[3]); 
+      11'b000_0001_0000: cols_output[0] <= ~(cell_output_state[4]); 
+      default: cols_output[0] <= 1'b0;     
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b0_00_0010_0000: cols_output[1] <= ~(cell_output_state[5]); 
+      11'b0_00_0100_0000: cols_output[1] <= ~(cell_output_state[6]); 
+      11'b0_00_1000_0000: cols_output[1] <= ~(cell_output_state[7]); 
+      11'b0_01_0000_0000: cols_output[1] <= ~(cell_output_state[8]); 
+      11'b0_10_0000_0000: cols_output[1] <= ~(cell_output_state[9]); 
+      default: cols_output[1] <= 1'b0;
+    endcase
+  end
+
+  generate
+    for(cell_p=0;cell_p<2;cell_p=cell_p+1)
+    begin : cols_invert_block
+      assign cols[cell_p] = cell_invert ? ~cols_output[cell_p] : cols_output[cell_p];
+    end
+    for(cell_p=0;cell_p<5;cell_p=cell_p+1)
+    begin : rows_invert_block
+      assign rows[cell_p] = cell_invert ? ~rows_output[cell_p] : rows_output[cell_p];
+    end
+  endgenerate
+
+  generate
+    for(cell_p=0;cell_p<10;cell_p=cell_p+1)
+    begin : past_state_logic
+      always@(posedge clock)
+      begin
+        case({enable_sn,update_done})
+          2'b00: pcell_mem[cell_p] <= pcell_mem[cell_p]; 
+          2'b01: pcell_mem[cell_p] <= cell_output_state[cell_p] ? 2'b11 : 2'b00; 
+          2'b10: pcell_mem[cell_p] <= 2'b01; 
+          2'b11: pcell_mem[cell_p] <= 2'b01; 
+        endcase
+      end
+
+      assign cells_state_diff[cell_p] = |(pcell_mem[cell_p] ^ {cell_output_state[cell_p],cell_output_state[cell_p]});
+      assign cell_enable[cell_p] = cells_state_diff[cell_p]  | ~p_select_active;
+    end
+  endgenerate
+
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0000_0001: rows_enable[0] <= cell_enable[0]; 
+      11'b000_0010_0000: rows_enable[0] <= cell_enable[5]; 
+      default: rows_enable[0] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0000_0010: rows_enable[1] <= cell_enable[1]; 
+      11'b000_0100_0000: rows_enable[1] <= cell_enable[6]; 
+      default: rows_enable[1] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0000_0100: rows_enable[2] <= cell_enable[2]; 
+      11'b000_1000_0000: rows_enable[2] <= cell_enable[7]; 
+      default: rows_enable[2] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0000_1000: rows_enable[3] <= cell_enable[3]; 
+      11'b001_0000_0000: rows_enable[3] <= cell_enable[8]; 
+      default: rows_enable[3] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0001_0000: rows_enable[4] <= cell_enable[4]; 
+      11'b010_0000_0000: rows_enable[4] <= cell_enable[9]; 
+      default: rows_enable[4] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b000_0000_0001: cols_enable[0] <= cell_enable[0]; 
+      11'b000_0000_0010: cols_enable[0] <= cell_enable[1]; 
+      11'b000_0000_0100: cols_enable[0] <= cell_enable[2]; 
+      11'b000_0000_1000: cols_enable[0] <= cell_enable[3]; 
+      11'b000_0001_0000: cols_enable[0] <= cell_enable[4]; 
+      default: cols_enable[0] <= 1'b0;
+    endcase
+  end
+
+  always@(posedge clock)
+  begin
+    case({line_enable_n,cell_pos[9:0]})
+      11'b0_00_0010_0000: cols_enable[1] <= cell_enable[5]; 
+      11'b0_00_0100_0000: cols_enable[1] <= cell_enable[6]; 
+      11'b0_00_1000_0000: cols_enable[1] <= cell_enable[7]; 
+      11'b0_01_0000_0000: cols_enable[1] <= cell_enable[8]; 
+      11'b0_10_0000_0000: cols_enable[1] <= cell_enable[9]; 
+      default: cols_enable[1] <= 1'b0;
+    endcase
+  end
+
+  generate
+    for(cell_p=0;cell_p<2;cell_p=cell_p+1)
+    begin : cols_hbrige_logic
+      assign cols_hbrige[cell_p*2+1:cell_p*2] = cols_enable[cell_p] ? ~cols[cell_p] ? 2'b00 : 2'b11 : 2'b10;
+    end
+    for(cell_p=0;cell_p<5;cell_p=cell_p+1)
+    begin : rows_hbrige_logic
+      assign rows_hbrige[cell_p*2+1:cell_p*2] = rows_enable[cell_p] ? ~rows[cell_p] ? 2'b00 : 2'b11 : 2'b10;
+    end
+  endgenerate
+
+  always@(posedge clock)
+  begin
+  if((cell_pos[10] == 1'b1))
+  begin
+    update_done <= 1'b1;
+  end
+  else
+  begin
+    update_done <= 1'b0;
+  end
+  end
+endmodule
diff --git a/verilog/rtl/memory_controller.v b/verilog/rtl/memory_controller.v
new file mode 100644
index 0000000..05a4415
--- /dev/null
+++ b/verilog/rtl/memory_controller.v
@@ -0,0 +1,77 @@
+module memory_controller
+(
+  input wire          clock,
+  //input wire reset_sn,
+  input wire          memory_enable_n,
+  input wire          memory_write_n,
+  input wire          memory_read_n,
+  input wire  [7:0]   memory_address,
+  input wire  [15:0]  memory_data_in,
+  output wire [15:0]  memory_data_out,
+  output wire [15:0]  cell_state,
+//  output wire [15:0]  control_state,
+  output wire [31:0]  ccr0,
+  output wire [31:0]  ccr1,
+  output wire [31:0]  ccr2,
+  output wire [31:0]  ccr3
+);
+  localparam NUM_OF_MEM_ELEMENTS = 10;
+  reg [15:0] memory [0:9]; 
+  wire [3:0] row_sel;
+  reg [15:0] memory_data_reg;
+
+  //assign row_sel = system_data_in[$clog2(NUM_OF_MEM_ELEMENTS)+16-1:16];
+  assign row_sel = memory_address[3:0];
+/*
+  genvar mem_row;
+  generate
+    for(mem_row=0;mem_row<NUM_OF_MEM_ELEMENTS;mem_row=mem_row+1)
+    begin
+      always@(posedge clock)
+      begin
+        if(reset_sn)
+        begin
+        end
+          if(row_sel==mem_row)
+          begin
+            memory[mem_row] <= memory_enable_n ? memory[mem_row] : memory_write_n ? memory[mem_row] : system_data_in[15:0];
+          end
+        else
+        begin
+          memory[mem_row] <= 16'b0; 
+        end
+      end
+    end
+  endgenerate
+*/
+  genvar mem_row;
+  generate 
+    for(mem_row=0;mem_row<NUM_OF_MEM_ELEMENTS;mem_row=mem_row+1)
+    begin : reg_memroy_file
+      always@(posedge clock)
+      begin
+        if(row_sel==mem_row)
+        begin
+          case({memory_enable_n,memory_write_n})
+            2'b00: memory[mem_row] <= memory_data_in[15:0];
+            default: memory[mem_row] <= memory[mem_row];
+          endcase
+        end
+      end
+    end
+  endgenerate
+
+  always@(posedge clock)
+  begin
+    memory_data_reg = memory_enable_n | memory_read_n ? 16'b0 : memory[row_sel];
+  end
+  
+  assign cell_state = memory[0];
+  //assign control_state = memory[1];
+  assign ccr0 = {memory[3],memory[2]};
+  assign ccr1 = {memory[5],memory[4]};
+  assign ccr2 = {memory[7],memory[6]};
+  assign ccr3 = {memory[9],memory[8]};
+  assign memory_data_out = memory_data_reg;
+
+endmodule
diff --git a/verilog/rtl/spi_mod.v b/verilog/rtl/spi_mod.v
new file mode 100644
index 0000000..2d6b161
--- /dev/null
+++ b/verilog/rtl/spi_mod.v
@@ -0,0 +1,132 @@
+module spi_mod
+(
+  input wire clock,
+  input wire enable_sn,
+  input wire sclk,
+  input wire mosi,
+  input wire ss_n,
+  output wire miso,
+  input wire data_valid_n,
+  output wire [31:0] data_out,
+  input wire [31:0] data_in
+);
+
+
+
+  /*always@(*)
+  begin
+    case({ss_n,data_ready_n})
+      2'b00: data_sig <= {data_reg,mosi};
+      2'b01: data_sig <= {data_reg,mosi};
+      2'b10: data_sig <= data_in;
+      2'b11: data_sig <= {miso,data_reg};
+    endcase
+  end
+
+  always@(posedge sclk, negedge data_valid_n)
+  begin
+    if(data_valid_n == 1'b0)
+	   {miso,data_reg} <= data_in;
+	 else
+      {miso,data_reg} <= data_sig;
+  end
+  */
+/*
+  always@(posedge sclk , negedge data_valid_n)
+  begin
+    if(data_valid_n)
+    begin
+      if(ss_n)
+      begin
+       {miso,data_reg} <= {miso,data_reg};
+      end
+      else
+      begin
+       {miso,data_reg} <= {data_reg,mosi};
+      end
+    end
+    else
+    begin
+      {miso,data_reg} <= data_in; 
+    end
+  end
+*/
+  //assign data_out = {miso,data_reg};
+
+  reg [2:0] sclk_reg;
+  reg [2:0] ss_n_reg;
+  reg [2:0] mosi_reg;
+  reg [31:0] spi_data;
+  wire sclk_rising_edge;
+  //wire sclk_falling_edge;
+  wire ss_n_enable;
+  wire mosi_data;
+
+  always@(posedge clock)
+    sclk_reg <= {sclk_reg[1:0],sclk};
+
+  always@(posedge clock)
+    ss_n_reg <= {ss_n_reg[1:0],ss_n};
+
+  always@(posedge clock)
+    mosi_reg <= {mosi_reg[1:0],mosi};
+    
+  assign sclk_rising_edge = (sclk_reg[2:1] == 2'b01);
+  //assign sclk_falling_edge = (sclk_reg[1:0] == 2'b10);
+  assign ss_n_enable = (ss_n_reg[2:1] == 3'b11);
+  assign mosi_data = (mosi_reg[2:1] == 3'b11);
+
+/*
+  always@(posedge clock)
+  begin
+    if(~enable_sn)
+    begin
+      spi_data = 32'b0;
+    end
+    else
+    begin
+      if(~ss_n_enable)
+      begin
+        if(sclk_rising_edge)
+        begin
+          spi_data <= {spi_data[31:1],mosi_data};
+        end
+        else
+        begin
+          if(~data_valid_n)
+          begin
+            spi_data <= data_in;
+          end
+          else
+          begin
+            spi_data <= spi_data;
+          end
+        end
+      end
+      else
+      begin
+        spi_data = 32'b0;
+      end
+    end
+  end
+*/
+  always@(posedge clock)
+  begin
+    case({enable_sn,ss_n_enable,data_valid_n})
+      3'b000: spi_data <= sclk_rising_edge ? {spi_data[30:0],mosi_data} : spi_data;
+      3'b001: spi_data <= sclk_rising_edge ? {spi_data[30:0],mosi_data} : spi_data;
+      3'b001: spi_data <= sclk_rising_edge ? {spi_data[30:0],mosi_data} : spi_data;
+      3'b010: spi_data <= data_in;
+      3'b011: spi_data <= spi_data;
+      default: spi_data <= 32'hDEADBEEF;
+    endcase
+  end
+
+
+  assign data_out = spi_data;
+  assign miso = spi_data[31];
+
+
+endmodule
+
+
diff --git a/verilog/rtl/sync_reg.v b/verilog/rtl/sync_reg.v
new file mode 100644
index 0000000..2bd91ba
--- /dev/null
+++ b/verilog/rtl/sync_reg.v
@@ -0,0 +1,48 @@
+module sync_n(
+  input wire signal_n,
+  output wire signal_sn,
+  input wire clock
+);
+  reg [3:0] signal_state;
+
+  always@(posedge clock)
+  begin
+    if(signal_n)
+    begin
+      signal_state <= 3'b111;
+    end
+    else
+    begin
+      signal_state <= {signal_state[2:0],signal_n};
+    end
+  end
+
+  assign signal_sn = signal_state == 3'b000 ? 1'b0:1'b1;
+
+
+endmodule
+/*
+module sync(
+  input wire signal,
+  output wire signal,
+  input wire clock
+);
+  reg [3:0] signal_state;
+
+  always@(posedge clock)
+  begin
+    if(signal)
+    begin
+      signal_state <= {signal_state[2:0],signal_n};
+    end
+    else
+    begin
+      signal_state <= 3'b000;
+    end
+  end
+
+  assign signal_sn = signal_state == 3'b111 ? 1'b1:1'b0;
+
+
+endmodule
+*/
diff --git a/verilog/rtl/system_controller.v b/verilog/rtl/system_controller.v
new file mode 100644
index 0000000..17aa61e
--- /dev/null
+++ b/verilog/rtl/system_controller.v
@@ -0,0 +1,177 @@
+
+
+
+module system_controller
+(
+  input  wire         clock,
+  input  wire         enable_sn,
+  input  wire         update_done,
+  input  wire  [31:0] spi_data,
+  input  wire  [31:0] ccr2,
+  input  wire  [31:0] ccr3,
+  input  wire  [15:0] memory_data_in,
+  output wire [15:0]  memory_data_out,
+  output wire [15:0]  memory_data,
+  output wire         memory_enable_n,
+  output wire         memory_write_n,
+  output wire         memory_read_n,
+  output wire [7:0]   memory_address,
+  output wire         system_enable_n,
+  //output wire         data_ready_n,
+  output wire         data_valid_n,
+  output wire         trigger_out_n,
+  input  wire         trigger_in_sn,
+  input  wire         latch_data_sn,
+  output wire [7:0]   control_state
+
+);
+  
+  reg [1:0] mem_state;
+  reg [1:0] system_state;
+  reg [1:0] trigger_out_state;
+  reg [1:0] latch_data_state;
+  wire refresh_n;
+  reg [31:0] refresh_count;
+  reg [2:0] mem_read_state;
+  reg [15:0] memory_data_reg;
+  reg [31:0] system_data;
+
+  
+
+  always@(posedge clock)
+  begin
+    case({enable_sn,latch_data_state})
+      3'b0_00: latch_data_state <= latch_data_sn ? 2'b00 :  2'b01;
+      3'b0_01: latch_data_state <= 2'b10;
+      3'b0_10: latch_data_state <= 2'b11;
+      3'b0_11: latch_data_state <= latch_data_sn ? 2'b00 : 2'b11;
+      default latch_data_state <= 2'b00;
+    endcase
+  end
+
+  assign system_control_n = latch_data_state != 2'b10;
+
+  always@(posedge clock)
+  begin
+    case({enable_sn,latch_data_state})
+      3'b0_00: system_data <= system_data;
+      3'b0_01: system_data <= spi_data;
+      3'b0_10: system_data <= system_data;
+      3'b0_11: system_data <= system_data;
+      default: system_data <= 32'b0;
+    endcase
+  end
+
+  assign control_state = system_data[31:24];
+  assign memory_address = system_data[23:16];
+  assign memory_data_out = system_data[15:0];
+
+
+  always@(posedge clock)
+  begin
+    case({enable_sn,~system_control_n,control_state[1:0],mem_state})
+      6'b00_10_00: mem_state <= 2'b10;
+      6'b00_10_10: mem_state <= 2'b11;
+      6'b00_10_11: mem_state <= 2'b11;
+
+      6'b00_01_00: mem_state <= 2'b01;
+      6'b00_01_01: mem_state <= 2'b11;
+      6'b00_01_11: mem_state <= 2'b11;
+      default:    mem_state <= 2'b00;
+    endcase
+  end
+
+  assign memory_enable_n = (^mem_state)  ? 1'b0 : 1'b1;
+  assign memory_write_n = mem_state == 2'b10 ? 1'b0 : 1'b1;
+  assign memory_read_n = mem_state == 2'b01 ? 1'b0 : 1'b1;
+  
+
+  always@(posedge clock)
+  begin
+    case({enable_sn,mem_read_state})
+      5'b0_000: mem_read_state <= memory_read_n ? 3'b000 : 3'b001;
+      5'b0_001: mem_read_state <= 3'b010;
+      5'b0_010: mem_read_state <= 3'b011;
+      5'b0_011: mem_read_state <= 3'b000;
+      //5'b0_100: mem_read_state <= 3'b000;
+      default : mem_read_state <= 3'b000;
+    endcase
+  end
+
+  assign data_valid_n = (mem_read_state == 3'b011) ? 1'b0 : 1'b1;
+
+  always@(posedge clock)
+  begin
+    case({enable_sn,mem_read_state})
+      4'b0_001: memory_data_reg <= memory_data_in;
+      default: memory_data_reg <= memory_data_reg;
+    endcase
+  end
+
+
+  assign memory_data  = memory_data_reg;
+  //assign data_ready_n = mem_read_state[1] ? 1'b0 : 1'b1;
+
+
+  always@(posedge clock)
+  begin
+    case({enable_sn,~system_control_n,control_state[3:2],system_state})
+      6'b00_10_00: system_state <= trigger_in_sn ? 2'b00 : 2'b10;
+      6'b00_10_10: system_state <= update_done ? 2'b11 : 2'b10;
+      6'b00_10_11: system_state <= trigger_in_sn  ? 2'b00 : 2'b11;
+
+      6'b00_01_00: system_state <= 2'b10;
+      6'b00_01_10: system_state <= update_done ? 2'b11 : 2'b10;
+      6'b00_01_11: system_state <= refresh_n   ? 2'b11 : 2'b10;
+      default:    system_state <= 2'b00;
+    endcase
+  end
+
+  assign system_enable_n = ~^system_state;
+  
+  always@(posedge clock)
+  begin
+    case({enable_sn,trigger_out_state})
+      3'b0_00: trigger_out_state <= update_done ? 2'b01 : 2'b00;
+      3'b0_01: trigger_out_state <= 2'b10;
+      3'b0_10: trigger_out_state <= 2'b11;
+      default: trigger_out_state <= 2'b00;
+    endcase
+  end
+  
+  assign trigger_out_n = ~^trigger_out_state;
+  
+
+
+
+  always@(posedge clock)
+  begin
+    if(enable_sn | system_control_n)
+    begin
+      refresh_count <= 32'b0;
+    end
+    else
+    begin
+      if((control_state[2]) & (&system_state))
+      begin
+        if(refresh_count <= ccr3) 
+        begin
+          refresh_count <= refresh_count+1'b1;
+        end
+        else
+        begin
+          refresh_count <= 32'b0;
+        end
+      end
+      else
+      begin
+        refresh_count <= 32'b0;
+      end
+    end
+  end
+
+  assign refresh_n = (refresh_count != ccr2);
+
+
+
+endmodule
diff --git a/verilog/rtl/top.v b/verilog/rtl/top.v
new file mode 100644
index 0000000..14b71ef
--- /dev/null
+++ b/verilog/rtl/top.v
@@ -0,0 +1,142 @@
+module top (
+  input  wire         clock,
+  input  wire         enable_n, 
+  output wire [4:0]   rows,
+  output wire [1:0]   cols,
+  output wire [4:0]   rows_enable,
+  output wire [1:0]   cols_enable,
+  output wire [9:0]   rows_hbrige,
+  output wire [3:0]   cols_hbrige,
+  output wire         trigger_out_n,
+  input  wire         trigger_in_n,
+  input  wire         latch_data_n,
+  input  wire         sclk,
+  input  wire         mosi,
+  input  wire         ss_n,
+  output wire         miso
+);
+  // spi
+  wire  [31:0] spi_data_out;
+  wire [15:0]  spi_data_in;
+  //wire         data_ready_n;
+  wire         data_valid_n;
+  wire         update_done;
+  wire [31:0]  ccr0;
+  wire [31:0]  ccr1;
+  wire [31:0]  ccr2;
+  wire [31:0]  ccr3;
+  wire [7:0]   memory_address;
+  wire         memory_enable_n;
+  wire         memory_write_n;
+  wire         memory_read_n;
+  wire         system_enable_n;
+  wire [15:0]  mem_to_sys_data;
+  wire [15:0]  sys_to_mem_data;
+  wire [7:0]   control_state;
+  wire [15:0]  cell_state;
+  wire         enable_sn;
+  wire         trigger_in_sn;
+  wire         latch_data_sn;
+
+
+
+  sync_n trigger_sync
+  (
+    .signal_n         (trigger_in_n    ), 
+    .signal_sn        (trigger_in_sn   ),
+    .clock            (clock           )
+  );
+  sync_n latch_sync
+  (
+    .signal_n         (latch_data_n    ), 
+    .signal_sn        (latch_data_sn   ),
+    .clock            (clock           )
+  );
+
+  sync_n enable_sync
+  (
+    .signal_n         (enable_n       ), 
+    .signal_sn        (enable_sn        ),
+    .clock            (clock           )
+  );
+
+  spi_mod spi_core
+  (
+    .clock            (clock           ),
+    .enable_sn        (enable_sn       ),
+    .sclk             (sclk            ),
+    .mosi             (mosi            ),
+    .ss_n             (ss_n            ),
+    .miso             (miso            ),
+    .data_valid_n     (data_valid_n    ),
+    //.data_ready_n     (data_ready_n    ),
+    .data_out         (spi_data_out    ),
+    .data_in          ({16'b0,
+                       spi_data_in}    )
+  );
+
+
+  system_controller system_core
+  (
+    .clock            (clock           ),
+    .enable_sn        (enable_sn       ),
+    .update_done      (update_done     ),
+    .spi_data         (spi_data_out    ),
+    .ccr2             (ccr2            ),
+    .ccr3             (ccr3            ),
+    .memory_data_in   (mem_to_sys_data ),
+    .memory_data_out  (sys_to_mem_data ),
+    .memory_data      (spi_data_in     ),
+    .memory_enable_n  (memory_enable_n ),
+    .memory_write_n   (memory_write_n  ),
+    .memory_read_n    (memory_read_n   ),
+    .memory_address   (memory_address  ),
+    .system_enable_n  (system_enable_n ),
+    //.data_ready_n     (data_ready_n    ),
+    .data_valid_n     (data_valid_n    ),
+    .trigger_out_n    (trigger_out_n   ),
+    .trigger_in_sn    (trigger_in_sn   ),
+    .latch_data_sn    (latch_data_sn   ),
+    .control_state    (control_state   )
+  );
+
+  memory_controller mem_core
+  (
+    .clock            (clock           ),
+    .memory_enable_n  (memory_enable_n ),
+    .memory_write_n   (memory_write_n  ),
+    .memory_read_n    (memory_read_n   ),
+    .memory_address   (memory_address  ),
+    .memory_data_in   (sys_to_mem_data ),
+    .memory_data_out  (mem_to_sys_data ),
+    .cell_state       (cell_state      ),
+    //.control_state    (control_state   ),
+    .ccr0             (ccr0            ),
+    .ccr1             (ccr1            ),
+    .ccr2             (ccr2            ),
+    .ccr3             (ccr3            )
+  );
+
+
+  cells_controller cell_core
+  (
+    .clock            (clock           ),
+    .cells_state      (cell_state      ),
+    .system_enable_n  (system_enable_n ),
+    .ccr0             (ccr0            ),
+    .ccr1             (ccr1            ),
+    .update_done      (update_done     ),
+    .rows             (rows            ),
+    .cols             (cols            ),
+    .rows_enable      (rows_enable     ),
+    .cols_enable      (cols_enable     ),
+    .rows_hbrige      (rows_hbrige     ),
+    .cols_hbrige      (cols_hbrige     ),
+    .p_select_active  (control_state[5]),
+    .cell_invert      (control_state[4]), 
+    .enable_sn        (enable_sn       ) 
+  );
+
+
+
+endmodule
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v
index 3537de8..9836c73 100644
--- a/verilog/rtl/uprj_netlists.v
+++ b/verilog/rtl/uprj_netlists.v
@@ -25,4 +25,11 @@
 `else
     `include "user_project_wrapper.v"
     `include "user_proj_example.v"
-`endif
\ No newline at end of file
+    `include "cells_controller.v" 
+    `include "memory_controller.v"  
+    `include "spi_mod.v"
+    `include "sync_reg.v"
+    `include "system_controller.v"
+    `include "top.v"
+    `include "braille_driver_cotroller.v"
+`endif
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 5ee1cee..aee6365 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -82,26 +82,13 @@
 /* User project is instantiated  here   */
 /*--------------------------------------*/
 
-user_proj_example mprj (
+braille_driver_controller mprj
+(
 `ifdef USE_POWER_PINS
 	.vccd1(vccd1),	// User area 1 1.8V power
 	.vssd1(vssd1),	// User area 1 digital ground
 `endif
 
-    .wb_clk_i(wb_clk_i),
-    .wb_rst_i(wb_rst_i),
-
-    // MGMT SoC Wishbone Slave
-
-    .wbs_cyc_i(wbs_cyc_i),
-    .wbs_stb_i(wbs_stb_i),
-    .wbs_we_i(wbs_we_i),
-    .wbs_sel_i(wbs_sel_i),
-    .wbs_adr_i(wbs_adr_i),
-    .wbs_dat_i(wbs_dat_i),
-    .wbs_ack_o(wbs_ack_o),
-    .wbs_dat_o(wbs_dat_o),
-
     // Logic Analyzer
 
     .la_data_in(la_data_in),
@@ -114,6 +101,9 @@
     .io_out(io_out),
     .io_oeb(io_oeb),
 
+    // Independent clock (on independent integer divider)
+    .user_clock2 (user_clock2),
+
     // IRQ
     .irq(user_irq)
 );