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)
);