diff --git a/config/scalp_fast_router_registers.json b/config/scalp_fast_router_registers.json
new file mode 100644
index 0000000000000000000000000000000000000000..a9f357b04e1fe2077c9e68fd6e82055256681712
--- /dev/null
+++ b/config/scalp_fast_router_registers.json
@@ -0,0 +1,163 @@
+{
+    "config" : {
+        "entity_name"            : "scalp_fast_router_registers",
+        "entity_version"         : "1.4",
+        "entity_reg_io_access"   : true,
+        "block_name"             : "ScalpFastRouterRegisters",
+        "bd_name"                : "/scalp_axi4lite_0/SAXILitexDIO",
+        "bd_interface"           : "SAXILitexDIO",
+        "bd_slave_segment"       : "SAXILiteAddr",
+        "bd_master_base_address" : "0x43C00000",
+        "bd_range"               : "4K"  
+    },
+    "register_bank" : [
+        {
+            "register_status_active" : true,
+            "register_name"          : "LocalNetAddr",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "rw",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "RGBLed0",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "rw",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "RGBLed1",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "rw",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "DMAFifoTXWrDataCnt",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "DMAFifoTXRrDataCnt",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "DMAFifoTXStatus",
+            "register_size"          : "32",
+            "register_type"          : "stat",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "TX_PROG_EMPTY"         : 1,
+                "TX_PROG_FULL"          : 1,
+                "RESERVED"           : 30
+            }
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "DMAFifoRXWrDataCnt",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "DMAFifoRXRrDataCnt",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "DMAFifoRXStatus",
+            "register_size"          : "32",
+            "register_type"          : "stat",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "RX_PROG_EMPTY"      : 1,
+                "RX_PROG_FULL"       : 1,
+                "RESERVED"           : 30
+            }
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "QoSPhyStatus",
+            "register_size"          : "32",
+            "register_type"          : "stat",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "NORTH"              : 1,
+                "EAST"               : 1,
+                "SOUTH"              : 1,
+                "WEST"               : 1,
+                "TOP"                : 1,
+                "BOTTOM"             : 1,
+                "LOCAL"              : 1,
+                "RESERVED"           : 25
+            }
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "QoSDMAInitOcpCtrl",
+            "register_size"          : "32",
+            "register_type"          : "ocp",
+            "register_access_mode"   : "wo",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "NORTH"              : 1,
+                "EAST"               : 1,
+                "SOUTH"              : 1,
+                "WEST"               : 1,
+                "TOP"                : 1,
+                "BOTTOM"             : 1,
+                "LOCAL"              : 1,
+                "RESERVED"           : 25
+            }   
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "QoSDMAInitStatus",
+            "register_size"          : "32",
+            "register_type"          : "stat",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "NORTH"              : 1,
+                "EAST"               : 1,
+                "SOUTH"              : 1,
+                "WEST"               : 1,
+                "TOP"                : 1,
+                "BOTTOM"             : 1,
+                "LOCAL"              : 1,
+                "RESERVED"           : 25
+            }   
+        }
+    ]
+}
diff --git a/config/scalp_router_regbank.json b/config/scalp_router_regbank.json
new file mode 100644
index 0000000000000000000000000000000000000000..14558810b516e97fd3557e5ba1c507df1f7feda0
--- /dev/null
+++ b/config/scalp_router_regbank.json
@@ -0,0 +1,125 @@
+{
+    "config" : {
+        "entity_name"            : "scalp_router_regbank",
+        "entity_version"         : "0.1",
+        "entity_reg_io_access"   : true,
+        "block_name"             : "ScalpRouterRegBank",
+        "bd_name"                : "/scalp_axi4lite_0/SAXILitexDIO",
+        "bd_interface"           : "SAXILitexDIO",
+        "bd_slave_segment"       : "SAXILiteAddr",
+        "bd_master_base_address" : "0x43C00000",
+        "bd_range"               : "4K"  
+    },
+    "register_bank" : [
+        {
+            "register_status_active" : true,
+            "register_name"          : "ScalpPacketWriteData",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "rw",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "ScalpPacketReadData",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "ScalpPacketCtrl",
+            "register_size"          : "32",
+            "register_type"          : "ctrl",
+            "register_access_mode"   : "wo",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "WRITE_VALID"        : 1,
+                "WRITE_LAST"         : 1,
+                "WRITE_READY"        : 1,
+                "WRITE_NEXT"         : 1,
+                "RESET_ALL_FIFO"     : 1,
+                "WRITE_H0"           : 1,
+                "WRITE_H1"           : 1,
+                "WRITE_H2"           : 1,
+                "WRITE_PLD"          : 1,
+                "WRITE_NEW_PACKET"   : 1,
+                "READ_NEXT"          : 1,
+                "READ_NEW_PACKET"    : 1,
+                "RESERVED"           : 20
+            }
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "ScalpPacketStatus",
+            "register_size"          : "32",
+            "register_type"          : "stat",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "READ_VALID"         : 1,
+                "READ_LAST"          : 1,
+                "TX_PROG_FULL"       : 1,
+                "RX_PROG_FULL"       : 1,
+                "READ_WAIT_NEXT"     : 1,
+                "RESERVED"           : 27
+            }
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "TXWrDataCnt",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "TXRdDataCnt",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "RXWrDataCnt",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "RXRdDataCnt",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : false,
+            "register_initial_value" : 0
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "LocNetAddr",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "rw",
+            "register_multifield"    : false,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "SCALP_ADDR_X"       : 8,
+                "SCALP_ADDR_Y"       : 8,
+                "SCALP_ADDR_Z"       : 8,
+                "RESERVED"           : 8
+            }
+        }
+    ]
+}
diff --git a/config/scalp_router_regbank_wd.json b/config/scalp_router_regbank_wd.json
new file mode 100644
index 0000000000000000000000000000000000000000..6822ed67e21fcfa1e801c5c5a741b8e0603bd45d
--- /dev/null
+++ b/config/scalp_router_regbank_wd.json
@@ -0,0 +1,38 @@
+{
+    "reg1" :
+    [
+        {
+            "bits" : 16,
+            "name" : "ScalpPacketWriteData",
+            "type" : 1,
+            "attr" : [
+                "reg_type : data",
+                "reg_access_mode : rw",
+                "reg_address: 0x43C00000"
+            ]
+        },
+        {
+            "bits" : 16,
+            "name" : "ScalpPacketWriteData",
+            "type" : 1            
+        }
+    ],
+    "reg2" :
+    [
+        {
+            "bits" : 16,
+            "name" : "ScalpPacketReadData",
+            "type" : 1,
+            "attr" : [
+                "reg_type : data",
+                "reg_access_mode : ro",
+                "reg_address: 0x43C00004"
+            ]
+        },
+        {
+            "bits" : 16,
+            "name" : "ScalpPacketReadData",
+            "type" : 1            
+        }
+    ]
+}
diff --git a/config/scalp_safe_firmware_reg_bank.json b/config/scalp_safe_firmware_reg_bank.json
new file mode 100644
index 0000000000000000000000000000000000000000..a089a2d22cc97d8838d0765373a388f09ffd1ce7
--- /dev/null
+++ b/config/scalp_safe_firmware_reg_bank.json
@@ -0,0 +1,29 @@
+{
+    "config" : {
+        "entity_name"            : "scalp_safe_firmware_reg_bank",
+        "entity_version"         : "0.2",
+        "entity_reg_io_access"   : true,
+        "block_name"             : "ScalpSafeFirmwareRegBank",
+        "bd_name"                : "/scalp_axi4lite_0/SAXILitexDIO",
+        "bd_interface"           : "SAXILitexDIO",
+        "bd_slave_segment"       : "SAXILiteAddr",
+        "bd_master_base_address" : "0x43C10000",
+        "bd_range"               : "4K"  
+    },
+    "register_bank" : [
+        {
+            "register_status_active" : true,
+            "register_name"          : "RgbLedsCtrl",
+            "register_size"          : "32",
+            "register_type"          : "ctrl",
+            "register_access_mode"   : "rw",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "RgbLed1" : 3,
+                "RgbLed2" : 3,
+                "Unused"  : 26
+            }       
+        }
+    ]
+}
diff --git a/config/template_regbank.json b/config/template_regbank.json
new file mode 100644
index 0000000000000000000000000000000000000000..9e890852f6a36b93da1f1f126ab3c4e09c492c44
--- /dev/null
+++ b/config/template_regbank.json
@@ -0,0 +1,65 @@
+{
+    "config" : {
+        "entity_name"            : "scalp_safe_firmware_reg_bank",
+        "entity_version"         : "0.1",
+        "entity_reg_io_access"   : true,
+        "block_name"             : "ScalpSafeFirmwareRegBank",
+        "bd_name"                : "/scalp_axi4lite_0/SAXILitexDIO",
+        "bd_interface"           : "SAXILitexDIO",
+        "bd_slave_segment"       : "SAXILiteAddr",
+        "bd_master_base_address" : "0x43C00000",
+        "bd_range"               : "256"  
+    },
+    "register_bank" : [
+        {
+            "register_status_active" : true,
+            "register_name"          : "RgbLedsCtrl",
+            "register_size"          : "32",
+            "register_type"          : "ctrl",
+            "register_access_mode"   : "rw",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "RgbLed1" : 3,
+                "RgbLed2" : 3,
+                "Unused"  : 26
+            }       
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "Ctrl1",
+            "register_size"          : "32",
+            "register_type"          : "ctrl",
+            "register_access_mode"   : "wo",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "f0" : 1,
+                "f1" : 1,
+                "f2" : 30
+            }
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "Status",
+            "register_size"          : "32",
+            "register_type"          : "stat",
+            "register_access_mode"   : "ro",
+            "register_multifield"    : true,
+            "register_initial_value" : 0,
+            "register_fields"        : {
+                "f0" : 1,
+                "f1" : 31
+            }
+        },
+        {
+            "register_status_active" : true,
+            "register_name"          : "Data1",
+            "register_size"          : "32",
+            "register_type"          : "data",
+            "register_access_mode"   : "rw",
+            "register_multifield"    : false,
+            "register_initial_value" : 255
+        }
+    ]
+}
diff --git a/output/scalp_fast_router_registers/1.4/src/hdl/scalp_fast_router_registers.vhd b/output/scalp_fast_router_registers/1.4/src/hdl/scalp_fast_router_registers.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..77109ca691275a507930e3f1e52ff5157ddc0f70
--- /dev/null
+++ b/output/scalp_fast_router_registers/1.4/src/hdl/scalp_fast_router_registers.vhd
@@ -0,0 +1,408 @@
+-- THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+-- scalp_regedit v0.1 - 05.2021
+-- Author : Joachim Schmidt <joachim.schmidt@hesge.ch>
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.std_logic_unsigned.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_misc.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+entity scalp_fast_router_registers is
+
+    generic (
+        C_AXI4_ARADDR_SIZE : integer range 0 to 32 := 32;
+        C_AXI4_RDATA_SIZE  : integer range 0 to 32 := 32;
+        C_AXI4_RRESP_SIZE  : integer range 0 to 2  := 2;
+        C_AXI4_AWADDR_SIZE : integer range 0 to 32 := 32;
+        C_AXI4_WDATA_SIZE  : integer range 0 to 32 := 32;
+        C_AXI4_WSTRB_SIZE  : integer range 0 to 4  := 4;
+        C_AXI4_BRESP_SIZE  : integer range 0 to 2  := 2;
+        C_AXI4_ADDR_SIZE   : integer range 0 to 32 := 12;
+        C_AXI4_DATA_SIZE   : integer range 0 to 32 := 32);
+
+    port (
+        -- Clock and reset
+        SAxiClkxCI            : in  std_ulogic;
+        SAxiRstxRANI          : in  std_ulogic;
+        -- AXI4 Lite
+        -- Read Channel
+        -- Read Address Channel
+        SAxiARAddrxDI         : in  std_ulogic_vector((C_AXI4_ARADDR_SIZE - 1) downto 0);
+        SAxiARValidxSI        : in  std_ulogic;
+        SAxiARReadyxSO        : out std_ulogic;
+        -- Read Data Channel
+        SAxiRDataxDO          : out std_ulogic_vector((C_AXI4_RDATA_SIZE - 1) downto 0);
+        SAxiRRespxDO          : out std_ulogic_vector((C_AXI4_RRESP_SIZE - 1) downto 0);
+        SAxiRValidxSO         : out std_ulogic;
+        SAxiRReadyxSI         : in  std_ulogic;
+        -- Write Channel
+        -- Write Address Channel
+        SAxiAWAddrxDI         : in  std_ulogic_vector((C_AXI4_AWADDR_SIZE - 1) downto 0);
+        SAxiAWValidxSI        : in  std_ulogic;
+        SAxiAWReadyxSO        : out std_ulogic;
+        -- Write Data Channel
+        SAxiWDataxDI          : in  std_ulogic_vector((C_AXI4_WDATA_SIZE - 1) downto 0);
+        SAxiWStrbxDI          : in  std_ulogic_vector((C_AXI4_WSTRB_SIZE - 1) downto 0);
+        SAxiWValidxSI         : in  std_ulogic;
+        SAxiWReadyxSO         : out std_ulogic;
+        -- Write Response Channel
+        SAxiBRespxDO          : out std_ulogic_vector((C_AXI4_BRESP_SIZE - 1) downto 0);
+        SAxiBValidxSO         : out std_ulogic;
+        SAxiBReadyxSI         : in  std_ulogic;
+        -- Registers list IO
+        LocalNetAddrxDO       : out std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        RGBLed0xDO            : out std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        RGBLed1xDO            : out std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        DMAFifoTXWrDataCntxDI : in  std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        DMAFifoTXRrDataCntxDI : in  std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        DMAFifoTXStatusxDI    : in  std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        DMAFifoRXWrDataCntxDI : in  std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        DMAFifoRXRrDataCntxDI : in  std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        DMAFifoRXStatusxDI    : in  std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        QoSPhyStatusxDI       : in  std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        QoSDMAInitOcpCtrlxDO  : out std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0);
+        QoSDMAInitStatusxDI   : in  std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0));
+
+end scalp_fast_router_registers;
+
+architecture behavioral of scalp_fast_router_registers is
+
+    -- Constants
+    constant C_AXI4_RRESP_OKAY   : std_ulogic_vector((C_AXI4_RRESP_SIZE - 1) downto 0) := "00";
+    constant C_AXI4_RRESP_EXOKAY : std_ulogic_vector((C_AXI4_RRESP_SIZE - 1) downto 0) := "01";
+    constant C_AXI4_RRESP_SLVERR : std_ulogic_vector((C_AXI4_RRESP_SIZE - 1) downto 0) := "10";
+    constant C_AXI4_RRESP_DECERR : std_ulogic_vector((C_AXI4_RRESP_SIZE - 1) downto 0) := "11";
+    constant C_AXI4_BRESP_OKAY   : std_ulogic_vector((C_AXI4_BRESP_SIZE - 1) downto 0) := "00";
+    constant C_AXI4_BRESP_EXOKAY : std_ulogic_vector((C_AXI4_BRESP_SIZE - 1) downto 0) := "01";
+    constant C_AXI4_BRESP_SLVERR : std_ulogic_vector((C_AXI4_BRESP_SIZE - 1) downto 0) := "10";
+    constant C_AXI4_BRESP_DECERR : std_ulogic_vector((C_AXI4_BRESP_SIZE - 1) downto 0) := "11";
+
+    -- Signals
+    -- Clock and reset
+    signal SAxiClkxC                 : std_ulogic                                         := '0';
+    signal SAxiRstxRAN               : std_ulogic                                         := '0';
+    -- AXI4 Lite
+    signal SAxiARReadyxS             : std_ulogic                                         := '0';
+    signal SAxiRValidxS              : std_ulogic                                         := '0';
+    signal SAxiBValidxS              : std_ulogic                                         := '0';
+    signal SAxiWReadyxS              : std_ulogic                                         := '0';
+    signal SAxiAWReadyxS             : std_ulogic                                         := '0';
+    signal WrAddrxDN                 : std_ulogic_vector((C_AXI4_ADDR_SIZE - 1) downto 0) := (others => '0');
+    signal WrAddrxDP                 : std_ulogic_vector((C_AXI4_ADDR_SIZE - 1) downto 0) := (others => '0');
+    -- Signals of access to the register bank
+    signal RdAddrxD                  : std_ulogic_vector((C_AXI4_ADDR_SIZE - 1) downto 0) := (others => '0');
+    signal RdDataxD                  : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := (others => '0');
+    signal RdValidxS                 : std_ulogic                                         := '0';
+    signal WrAddrxD                  : std_ulogic_vector((C_AXI4_ADDR_SIZE - 1) downto 0) := (others => '0');
+    signal WrDataxD                  : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := (others => '0');
+    signal WrValidxS                 : std_ulogic                                         := '0';
+    -- Registers list
+    signal LocalNetAddrPortxDN       : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal LocalNetAddrPortxDP       : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal RGBLed0PortxDN            : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal RGBLed0PortxDP            : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal RGBLed1PortxDN            : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal RGBLed1PortxDP            : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoTXWrDataCntPortxDN : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoTXWrDataCntPortxDP : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoTXRrDataCntPortxDN : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoTXRrDataCntPortxDP : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoTXStatusPortxDN    : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoTXStatusPortxDP    : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoRXWrDataCntPortxDN : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoRXWrDataCntPortxDP : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoRXRrDataCntPortxDN : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoRXRrDataCntPortxDP : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoRXStatusPortxDN    : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal DMAFifoRXStatusPortxDP    : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal QoSPhyStatusPortxDN       : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal QoSPhyStatusPortxDP       : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal QoSDMAInitOcpCtrlPortxDN  : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal QoSDMAInitOcpCtrlPortxDP  : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal QoSDMAInitStatusPortxDN   : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+    signal QoSDMAInitStatusPortxDP   : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x"00000000";
+
+    -- Attributes
+    attribute mark_debug : string;
+    attribute keep       : string;
+    --
+    -- attribute mark_debug of                : signal is "true";
+    -- attribute keep of                      : signal is "true";
+
+begin
+
+    assert C_AXI4_RDATA_SIZE = C_AXI4_DATA_SIZE
+        report "RDATA and DATA vectors must be the same" severity failure;
+
+    assert C_AXI4_ARADDR_SIZE >= C_AXI4_ADDR_SIZE
+        report "ARADDR and ADDR vectors must be the same" severity failure;
+
+    assert C_AXI4_WDATA_SIZE = C_AXI4_DATA_SIZE
+        report "WDATA and DATA vectors must be the same" severity failure;
+
+    assert C_AXI4_AWADDR_SIZE >= C_AXI4_ADDR_SIZE
+        report "AWADDR and ADDR vectors must be the same" severity failure;
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+
+        -- Clock and reset
+        SAxiClkxAS     : SAxiClkxC                                  <= SAxiClkxCI;
+        SAxiRstxAS     : SAxiRstxRAN                                <= SAxiRstxRANI;
+        -- Read Channel
+        SAxiARReadyxAS : SAxiARReadyxSO                             <= SAxiARReadyxS;
+        SAxiRValidxAS  : SAxiRValidxSO                              <= SAxiRValidxS;
+        SAxiRDataxAS   : SAxiRDataxDO                               <= RdDataxD;
+        RdValidxAS     : RdValidxS                                  <= SAxiARValidxSI;
+        RdAddrxAS      : RdAddrxD((C_AXI4_ADDR_SIZE - 1) downto 0)  <= SAxiARAddrxDI((C_AXI4_ADDR_SIZE - 1) downto 0);
+        SAxiRRespxAS   : SAxiRRespxDO                               <= C_AXI4_RRESP_OKAY;
+        -- Write Channel
+        SAxiBRespxAS   : SAxiBRespxDO                               <= C_AXI4_BRESP_OKAY;
+        SAxiBValidxAS  : SAxiBValidxSO                              <= SAxiBValidxS;
+        SAxiWReadyxAS  : SAxiWReadyxSO                              <= SAxiWReadyxS;
+        SAxiAWReadyxAS : SAxiAWReadyxSO                             <= SAxiAWReadyxS;
+        WrValidxAS     : WrValidxS                                  <= SAxiWValidxSI;
+        WrDataxAS      : WrDataxD                                   <= SAxiWDataxDI;
+        WrAddrOutxAS   : WrAddrxD                                   <= WrAddrxDP;
+        WrAddrxAS      : WrAddrxDN((C_AXI4_ADDR_SIZE - 1) downto 0) <= SAxiAWAddrxDI((C_AXI4_ADDR_SIZE - 1) downto 0) when
+                                                                  SAxiAWValidxSI = '1' else
+                                                                  WrAddrxDP((C_AXI4_ADDR_SIZE - 1) downto 0);
+
+    end block EntityIOxB;
+
+    AXI4LitexB : block is
+    begin  -- block AXI4LitexB
+
+        ReadChannelxB : block is
+        begin  -- block ReadChannelxB
+
+            ReadAddrChanxP : process (SAxiClkxC, SAxiRstxRAN) is
+
+                variable StateAfterResetxS : boolean := true;
+
+            begin  -- process ReadAddrChanxP
+                if SAxiRstxRAN = '0' then
+                    SAxiARReadyxS     <= '0';
+                    StateAfterResetxS := true;
+                elsif rising_edge(SAxiClkxC) then
+                    if StateAfterResetxS = true then
+                        SAxiARReadyxS     <= '1';
+                        StateAfterResetxS := false;
+                    else
+                        SAxiARReadyxS <= SAxiARReadyxS;
+                    end if;
+
+                    if SAxiARValidxSI = '1' then
+                        SAxiARReadyxS <= '0';
+                    end if;
+
+                    if SAxiARReadyxS <= '0' and SAxiRReadyxSI = '1' then
+                        SAxiARReadyxS <= '1';
+                    end if;
+                end if;
+            end process ReadAddrChanxP;
+
+            ReadDataChanxP : process (SAxiClkxC, SAxiRstxRAN) is
+            begin  -- process ReadDataChanxP
+                if SAxiRstxRAN = '0' then
+                    SAxiRValidxS <= '0';
+                elsif rising_edge(SAxiClkxC) then
+                    SAxiRValidxS <= SAxiRValidxS;
+
+                    if SAxiARValidxSI = '1' and SAxiARReadyxS = '1' then
+                        SAxiRValidxS <= '1';
+                    end if;
+
+                    if SAxiRValidxS = '1' and SAxiRReadyxSI = '1' then
+                        SAxiRValidxS <= '0';
+                    end if;
+                end if;
+            end process ReadDataChanxP;
+
+        end block ReadChannelxB;
+
+        WriteChannelxB : block is
+        begin  --block WriteChannelxB        
+
+            WrAddrRegxP : process (SAxiClkxC, SAxiRstxRAN) is
+            begin  -- process WrAddrRegxP
+                if SAxiRstxRAN = '0' then
+                    WrAddrxDP <= (others => '0');
+                elsif rising_edge(SAxiClkxC) then
+                    WrAddrxDP <= WrAddrxDN;
+                end if;
+            end process WrAddrRegxP;
+
+            WriteAddrChanxP : process (SAxiClkxC, SAxiRstxRAN) is
+
+                variable StateAfterResetxS : boolean := true;
+
+            begin  -- process WriteAddrChanxP
+                if SAxiRstxRAN = '0' then
+                    SAxiAWReadyxS     <= '0';
+                    StateAfterResetxS := true;
+                elsif rising_edge(SAxiClkxC) then
+                    if StateAfterResetxS = true then
+                        SAxiAWReadyxS     <= '1';
+                        StateAfterResetxS := false;
+                    else
+                        SAxiAWReadyxS <= SAxiAWReadyxS;
+                    end if;
+
+                    if SAxiAWValidxSI = '1' then
+                        SAxiAWReadyxS <= '0';
+                    end if;
+
+                    if SAxiWValidxSI = '1' then
+                        SAxiAWReadyxS <= '1';
+                    end if;
+                end if;
+            end process WriteAddrChanxP;
+
+            WriteDataChanxP : process (SAxiClkxC, SAxiRstxRAN) is
+            begin  -- process WriteDataChanxP
+                if SAxiRstxRAN = '0' then
+                    SAxiWReadyxS <= '0';
+                elsif rising_edge(SAxiClkxC) then
+                    SAxiWReadyxS <= SAxiWReadyxS;
+
+                    if SAxiAWValidxSI = '1' and SAxiAWReadyxS = '1' then
+                        SAxiWReadyxS <= '1';
+                    end if;
+
+                    if SAxiWValidxSI = '1' and SAxiWReadyxS = '1' then
+                        SAxiWReadyxS <= '0';
+                    end if;
+                end if;
+            end process WriteDataChanxP;
+
+            WriteRespChanxP : process (SAxiClkxC, SAxiRstxRAN) is
+            begin  -- process WriteRespChanxP
+                if SAxiRstxRAN = '0' then
+                    SAxiBValidxS <= '0';
+                elsif rising_edge(SAxiClkxC) then
+                    SAxiBValidxS <= SAxiBValidxS;
+
+                    if SAxiWValidxSI = '1' and SAxiWReadyxS = '1' then
+                        SAxiBValidxS <= '1';
+                    end if;
+
+                    if SAxiBValidxS = '1' and SAxiBReadyxSI = '1' then
+                        SAxiBValidxS <= '0';
+                    end if;
+                end if;
+            end process WriteRespChanxP;
+
+        end block WriteChannelxB;
+
+    end block AXI4LitexB;
+
+    ScalpFastRouterRegistersxB : block is
+    begin  -- block ScalpFastRouterRegistersxB
+
+        WriteRegPortxP : process (DMAFifoRXRrDataCntxDI, DMAFifoRXStatusxDI,
+                                  DMAFifoRXWrDataCntxDI, DMAFifoTXRrDataCntxDI,
+                                  DMAFifoTXStatusxDI, DMAFifoTXWrDataCntxDI,
+                                  LocalNetAddrPortxDP,
+                                  QoSDMAInitOcpCtrlPortxDP,
+                                  QoSDMAInitStatusxDI, QoSPhyStatusxDI,
+                                  RGBLed0PortxDP, RGBLed1PortxDP, WrAddrxD,
+                                  WrDataxD, WrValidxS) is
+        begin  -- process WriteRegPortxP
+            LocalNetAddrPortxDN       <= LocalNetAddrPortxDP;
+            LocalNetAddrxDO           <= LocalNetAddrPortxDP;
+            RGBLed0PortxDN            <= RGBLed0PortxDP;
+            RGBLed0xDO                <= RGBLed0PortxDP;
+            RGBLed1PortxDN            <= RGBLed1PortxDP;
+            RGBLed1xDO                <= RGBLed1PortxDP;
+            DMAFifoTXWrDataCntPortxDN <= DMAFifoTXWrDataCntxDI;
+            DMAFifoTXRrDataCntPortxDN <= DMAFifoTXRrDataCntxDI;
+            DMAFifoTXStatusPortxDN    <= DMAFifoTXStatusxDI;
+            DMAFifoRXWrDataCntPortxDN <= DMAFifoRXWrDataCntxDI;
+            DMAFifoRXRrDataCntPortxDN <= DMAFifoRXRrDataCntxDI;
+            DMAFifoRXStatusPortxDN    <= DMAFifoRXStatusxDI;
+            QoSPhyStatusPortxDN       <= QoSPhyStatusxDI;
+            QoSDMAInitOcpCtrlPortxDN  <= (others => '0');
+            QoSDMAInitOcpCtrlxDO      <= QoSDMAInitOcpCtrlPortxDP;
+            QoSDMAInitStatusPortxDN   <= QoSDMAInitStatusxDI;
+
+            if WrValidxS = '1' then
+                case WrAddrxD is
+                    when x"000" => LocalNetAddrPortxDN      <= WrDataxD;
+                    when x"004" => RGBLed0PortxDN           <= WrDataxD;
+                    when x"008" => RGBLed1PortxDN           <= WrDataxD;
+                    when x"028" => QoSDMAInitOcpCtrlPortxDN <= WrDataxD;
+
+                    when others => null;
+                end case;
+            end if;
+        end process WriteRegPortxP;
+
+        ReadRegPortxP : process (SAxiClkxC, SAxiRstxRAN) is
+        begin  -- process ReadRegPortxP
+            if SAxiRstxRAN = '0' then
+                RdDataxD <= (others => '0');
+            elsif rising_edge(SAxiClkxC) then
+                RdDataxD <= RdDataxD;
+
+                if RdValidxS = '1' then
+                    case RdAddrxD is
+                        when x"000" => RdDataxD <= LocalNetAddrPortxDP;
+                        when x"004" => RdDataxD <= RGBLed0PortxDP;
+                        when x"008" => RdDataxD <= RGBLed1PortxDP;
+                        when x"00C" => RdDataxD <= DMAFifoTXWrDataCntPortxDP;
+                        when x"010" => RdDataxD <= DMAFifoTXRrDataCntPortxDP;
+                        when x"014" => RdDataxD <= DMAFifoTXStatusPortxDP;
+                        when x"018" => RdDataxD <= DMAFifoRXWrDataCntPortxDP;
+                        when x"01C" => RdDataxD <= DMAFifoRXRrDataCntPortxDP;
+                        when x"020" => RdDataxD <= DMAFifoRXStatusPortxDP;
+                        when x"024" => RdDataxD <= QoSPhyStatusPortxDP;
+                        when x"02C" => RdDataxD <= QoSDMAInitStatusPortxDP;
+
+                        when others => RdDataxD <= (others => '0');
+                    end case;
+                end if;
+            end if;
+        end process ReadRegPortxP;
+
+        UpdateRegBankxP : process (SAxiClkxC, SAxiRstxRAN) is
+        begin  -- process UpdateRegBankxP
+            if SAxiRstxRAN = '0' then
+                LocalNetAddrPortxDP       <= x"00000000";
+                RGBLed0PortxDP            <= x"00000000";
+                RGBLed1PortxDP            <= x"00000000";
+                DMAFifoTXWrDataCntPortxDP <= x"00000000";
+                DMAFifoTXRrDataCntPortxDP <= x"00000000";
+                DMAFifoTXStatusPortxDP    <= x"00000000";
+                DMAFifoRXWrDataCntPortxDP <= x"00000000";
+                DMAFifoRXRrDataCntPortxDP <= x"00000000";
+                DMAFifoRXStatusPortxDP    <= x"00000000";
+                QoSPhyStatusPortxDP       <= x"00000000";
+                QoSDMAInitOcpCtrlPortxDP  <= x"00000000";
+                QoSDMAInitStatusPortxDP   <= x"00000000";
+
+            elsif rising_edge(SAxiClkxC) then
+                LocalNetAddrPortxDP       <= LocalNetAddrPortxDN;
+                RGBLed0PortxDP            <= RGBLed0PortxDN;
+                RGBLed1PortxDP            <= RGBLed1PortxDN;
+                DMAFifoTXWrDataCntPortxDP <= DMAFifoTXWrDataCntPortxDN;
+                DMAFifoTXRrDataCntPortxDP <= DMAFifoTXRrDataCntPortxDN;
+                DMAFifoTXStatusPortxDP    <= DMAFifoTXStatusPortxDN;
+                DMAFifoRXWrDataCntPortxDP <= DMAFifoRXWrDataCntPortxDN;
+                DMAFifoRXRrDataCntPortxDP <= DMAFifoRXRrDataCntPortxDN;
+                DMAFifoRXStatusPortxDP    <= DMAFifoRXStatusPortxDN;
+                QoSPhyStatusPortxDP       <= QoSPhyStatusPortxDN;
+                QoSDMAInitOcpCtrlPortxDP  <= QoSDMAInitOcpCtrlPortxDN;
+                QoSDMAInitStatusPortxDP   <= QoSDMAInitStatusPortxDN;
+
+            end if;
+        end process UpdateRegBankxP;
+
+    end block ScalpFastRouterRegistersxB;
+
+end behavioral;
diff --git a/src/__pycache__/regedit.cpython-37.pyc b/src/__pycache__/regedit.cpython-37.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ffac352e8a0f7e3acd66d8249097a395639f65a2
Binary files /dev/null and b/src/__pycache__/regedit.cpython-37.pyc differ
diff --git a/src/__pycache__/regedit.cpython-39.pyc b/src/__pycache__/regedit.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ba26ce636beb11fd1851799ba1e213ce91d94cb7
Binary files /dev/null and b/src/__pycache__/regedit.cpython-39.pyc differ
diff --git a/src/__pycache__/utils.cpython-37.pyc b/src/__pycache__/utils.cpython-37.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6f799f3b1c198f5722eca2c153a77dba09bcb219
Binary files /dev/null and b/src/__pycache__/utils.cpython-37.pyc differ
diff --git a/src/__pycache__/utils.cpython-39.pyc b/src/__pycache__/utils.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..930bb0c26d9058b76a5a095ef87174e1d5b9e354
Binary files /dev/null and b/src/__pycache__/utils.cpython-39.pyc differ
diff --git a/src/regedit.py b/src/regedit.py
new file mode 100644
index 0000000000000000000000000000000000000000..17ffdf0f9bbf9b44383c2bd68bfc7339a3125d12
--- /dev/null
+++ b/src/regedit.py
@@ -0,0 +1,499 @@
+#!/usr/bin/python3
+
+import os
+import sys
+import utils
+import shutil
+import time
+import numpy as np
+from utils import *
+
+# Default directories
+PRJ_CONF_DIR      = os.path.join("..", "config")
+PRJ_OUT_DIR       = os.path.join("..", "output")
+SRC_DIR           = "src"
+HDL_DIR           = "hdl"
+LINUX_DIR         = "linux"
+BAREMETAL_DIR     = "baremetal"
+TEMPLATE_HDL_DIR  = os.path.join(".", "templates", "hdl")
+HDL_FILE_EXT      = ".vhd"
+TEMPLATE_HDL_FILE = "template_regbank" + HDL_FILE_EXT
+
+BD_RANGE = {
+    "128"  : 0,
+    "256"  : 1,
+    "512"  : 2,
+    "1K"   : 3,
+    "2K"   : 4,
+    "4K"   : 5,
+    "8K"   : 6,
+    "16K"  : 7,
+    "32K"  : 8,
+    "64K"  : 9,
+    "128K" : 10,
+    "256K" : 11,
+    "512K" : 12,
+    "1M"   : 13,
+    "2M"   : 14,
+    "4M"   : 15,
+    "8M"   : 16,
+    "16M"  : 17,
+    "32M"  : 18,
+    "64M"  : 19,
+    "128M" : 20,
+    "256M" : 21,
+    "512M" : 22,
+    "1G"   : 24
+}
+
+BD_RANGE_CONV = {
+    "128"  : 128,
+    "256"  : 256,
+    "512"  : 512,
+    "1K"   : 1024,
+    "2K"   : 2048,
+    "4K"   : 4096,
+    "8K"   : 8192,
+    "16K"  : 16384,
+    "32K"  : 32768,
+    "64K"  : 65536,
+    "128K" : 131072,
+    "256K" : 262144,
+    "512K" : 524288,
+    "1M"   : 1048576,
+    "2M"   : 2097152,
+    "4M"   : 4194304,
+    "8M"   : 8388608,
+    "16M"  : 16777216,
+    "32M"  : 33554432,
+    "64M"  : 67108864,
+    "128M" : 134217728,
+    "256M" : 268435456,
+    "512M" : 536870912,
+    "1G"   : 1073741824
+}
+
+#EGISTER_STATUS_ACTIVE = {
+#}
+
+DEFAULT_REGISTER_SIZE = "32"
+REGISTER_SIZE = {
+    DEFAULT_REGISTER_SIZE : 0
+}
+
+REGISTER_TYPE = {
+    "ctrl" : 0,
+    "stat" : 1,
+    "data" : 2,
+    "ocp"  : 3
+}
+
+REGISTER_ACCESS_MODE = {
+    "ro" : 0,
+    "wo" : 1,
+    "rw" : 2
+}
+
+class regedit_gen :
+    def __init__(self, entity_name = None, entity_version = "0.1", entity_reg_io_access = False, block_name = None, bd_name = None,
+                 bd_interface = None, bd_slave_segment = None, bd_master_base_address = "0x40000000",
+                 bd_range = "128", register_bank = None) :
+
+        self.entity_name            = entity_name
+        self.entity_version         = entity_version
+        self.entity_reg_io_access   = entity_reg_io_access
+        self.block_name             = block_name
+        self.bd_name                = bd_name
+        self.bd_interface           = bd_interface
+        self.bd_slave_segment       = bd_slave_segment
+        self.bd_master_base_address = bd_master_base_address
+        self.bd_range               = bd_range
+        self.register_bank          = register_bank
+        self.data_size              = "32"
+        # Directories
+        self.prj_out_dir            = PRJ_OUT_DIR
+        self.src_dir                = None
+        self.hdl_dir                = None
+        self.linux_dir              = None
+        self.baremetal_dir          = None
+        # Others
+        self.registers_list         = ""
+        self.registers_list_c2n     = ""
+        self.registers_list_n2c     = ""
+        self.registers_list_init_cv = ""
+        self.registers_list_cv      = ""
+        self.registers_list_cv_cnt  = 0
+        self.registers_list_ad_cnt  = 0
+        self.registers_list_wa      = ""
+        self.registers_list_ra      = ""
+        self.registers_list_entity_io = ""
+
+        if entity_name is None :
+            try :
+                self.entity_name = utils.get_time_str()
+
+                if not self.entity_name :
+                    raise ValueError("Empty string")
+            except ValueError as e :
+                print(e)        
+                
+        self.dir_name = self.prj_out_dir + "/" + self.entity_name + "/" + self.entity_version
+
+        try :
+            if type(self.entity_reg_io_access) is not bool :
+                self.entity_reg_io_access = False                
+                raise ValueError("Is not a boolean value")            
+        except ValueError as e :
+            print(e)
+
+        if block_name is None :
+            try :
+                self.block_name = utils.get_time_str()
+
+                if not self.block_name :
+                    raise ValueError("Empty string")
+            except ValueError as e :
+                print(e)
+
+        if bd_name is None :
+            try :
+                self.bd_name = utils.get_time_str()
+
+                if not self.bd_name :
+                    raise ValueError("Empty string")
+            except ValueError as e :
+                print(e)                                    
+
+        if bd_interface is None :
+            try :
+                self.bd_interface = utils.get_time_str()
+
+                if not self.bd_interface :
+                    raise ValueError("Empty string")
+            except ValueError as e :
+                print(e)
+
+        if bd_slave_segment is None :
+            try :
+                self.bd_slave_segment = utils.get_time_str()
+
+                if not self.bd_slave_segment :
+                    raise ValueError("Empty string")
+            except ValueError as e :
+                print(e)
+
+        if check_key(BD_RANGE, bd_range) is False :
+            print("#Error - __init__() : " + bd_range + " is not a valid value...")
+            sys.exit(-1)
+
+        if register_bank is None :
+            print("#Error - __init__() : the register bank is not defined in the config file...")
+            sys.exit(-1)
+
+        print("> Register bank directory   : " + self.dir_name)
+        print("> Register bank name        : " + self.entity_name)
+        print("> Register bank version     : " + self.entity_version)
+        print("> Block name                : " + self.block_name)
+        print("> Size of the register bank : " + str(len(self.register_bank)))
+        print("> Addtional information about block design")
+        print("> Bd name                   : " + self.bd_name)
+        print("> Bd interface              : " + self.bd_interface)
+        print("> Bd slave segment          : " + self.bd_slave_segment)
+        print("> Bd master base address    : " + self.bd_master_base_address)
+        print("> Bd range                  : " + self.bd_range)
+
+    def create_dir(self) :
+        if not os.path.exists(self.dir_name) :
+            os.makedirs(self.dir_name)            
+            print("\ncreate_dir() : " + self.dir_name + " directory created...")
+
+            self.src_dir = os.path.join(self.dir_name, SRC_DIR)
+            os.makedirs(self.src_dir)
+            print("create_dir() : " + self.src_dir + " directory created...")
+
+            self.hdl_dir = os.path.join(self.src_dir, HDL_DIR)
+            os.makedirs(self.hdl_dir)
+            print("create_dir() : " + self.hdl_dir + " directory created...")
+
+            self.linux_dir = os.path.join(self.src_dir, LINUX_DIR)
+            os.makedirs(self.linux_dir)
+            print("create_dir() : " + self.linux_dir + " directory created...")
+
+            self.baremetal_dir = os.path.join(self.src_dir, BAREMETAL_DIR)
+            os.makedirs(self.baremetal_dir)
+            print("create_dir() : " + self.baremetal_dir + " directory created...")
+                        
+            return 0
+        else :
+            print("#Error - create_dir() : " + self.dir_name + " Directory already exists...")
+            return -1
+        
+        return 0
+
+    def copy_hdl_template_file(self, file_name) :
+        in_file_name = os.path.join(TEMPLATE_HDL_DIR, TEMPLATE_HDL_FILE)
+        out_file_name = os.path.join(self.hdl_dir, file_name + HDL_FILE_EXT)
+
+        addr_size = int(np.trunc(np.log2(int(BD_RANGE_CONV[self.bd_range]))))
+
+        if addr_size < 8 :
+            addr_size = str(8)
+        elif addr_size > 8 and addr_size < 12 :
+            addr_size = str(12)
+        elif addr_size > 12 and addr_size < 16 :
+            addr_size = str(16)
+        elif addr_size > 16 and addr_size < 20 :
+            addr_size = str(20)
+        elif addr_size > 20 and addr_size < 24 :
+            addr_size = str(24)
+        elif addr_size > 24 and addr_size < 28 :
+            addr_size = str(28)
+        elif addr_size > 28 and addr_size < 32 :
+            addr_size = str(32)
+        else :
+            addr_size = str(addr_size)
+
+        print("copy_hdl_template_file() : Copy " + in_file_name + " to " + out_file_name)
+        shutil.copy(in_file_name, out_file_name)
+
+        utils.file_replace_pattern(out_file_name, "<entity_name>", self.entity_name)
+        utils.file_replace_pattern(out_file_name, "<data_size>", self.data_size)
+        utils.file_replace_pattern(out_file_name, "<addr_size>", addr_size)
+        utils.file_replace_pattern(out_file_name, "<block_name>", self.block_name)
+
+        first_call = True
+        
+        for i in range(len(self.register_bank)) :
+            ret = self.read_register(self.register_bank[i], i, first_call)
+            first_call = False
+
+            if ret < 0 :
+                sys.exit(-1)
+
+        utils.file_replace_pattern(out_file_name, "<registers_list>", self.registers_list)
+        utils.file_replace_pattern(out_file_name, "<registers_list_current_to_next>", self.registers_list_c2n)
+        utils.file_replace_pattern(out_file_name, "<registers_list_next_to_current>", self.registers_list_n2c)
+        utils.file_replace_pattern(out_file_name, "<registers_list_init_current_value>", self.registers_list_init_cv)        
+        utils.file_replace_pattern(out_file_name, "<registers_list_current_value>", self.registers_list_cv)
+        utils.file_replace_pattern(out_file_name, "<registers_list_write_access>", self.registers_list_wa)
+        utils.file_replace_pattern(out_file_name, "<registers_list_read_access>", self.registers_list_ra)
+        utils.file_replace_pattern(out_file_name, "<registers_list_entity_io>", self.registers_list_entity_io)        
+        
+        return 0
+
+    def read_register(self, register, idx, first_call) :
+        print("Register " + str(idx))
+        #addr = idx * 4
+        #print("Address : 0x" + hex32str2(addr, self.bd_range))
+
+        try :
+            self.register_status_active = register["register_status_active"]            
+        except KeyError as e :
+            print("KeyError : {}".format(e))                    
+            self.register_status_active = None
+            return -1
+
+        print("\tregister_status_active = " + str(self.register_status_active))
+
+        try :
+            self.register_name = register["register_name"]
+        except KeyError as e :
+            print("KeyError : {}".format(e))
+            self.register_name = utils.get_time_str()
+
+        print("\tregister_name = " + self.register_name)
+
+        try :
+            self.register_size = register["register_size"]
+        except KeyError as e :
+            print("KeyError : {}".format(e))
+            self.register_size = DEFAULT_REGISTER_SIZE;
+
+        if check_key(REGISTER_SIZE, self.register_size) is False :
+            print("#Error - read_register() : " + self.register_size + " is not a valid value...")
+            return -1
+
+        print("\tregister_size = " + self.register_size)
+
+        try :
+            self.register_type = register["register_type"]
+        except KeyError as e :
+            print("KeyError : {}".format(e))
+            self.register_type = None
+            return -1
+
+        if check_key(REGISTER_TYPE, self.register_type) is False :
+            print("#Error - read_register() : " + self.register_type + " is not a valid value...")
+            return -1
+
+        print("\tregister_type = " + self.register_type)
+
+        try :
+            self.register_access_mode = register["register_access_mode"]
+        except KeyError as e :
+            print("KeyError : {}".format(e))
+            self.register_access_mode = None
+            return -1
+
+        if check_key(REGISTER_ACCESS_MODE, self.register_access_mode) is False :
+            print("#Error - read_register() : " + self.register_access_mode + " is not a valid value...")
+            return -1
+
+        print("\tregister_access_mode = " + self.register_access_mode)
+
+        if self.register_type == "ocp" and self.register_access_mode != "wo" :
+            print("#Error - read_register() : Registers of type ocp are accessible only in wo mode.")
+            return -1                  
+
+        try :
+            self.register_multifield = register["register_multifield"]
+        except KeyError as e :
+            print("KeyError : {}".format(e))
+            self.register_multifield = None
+            return -1
+
+        print("\tregister_multifield = " + str(self.register_multifield))
+
+        try :
+            self.register_initial_value = register["register_initial_value"]
+        except KeyError as a :
+            print("KeyError : {}".format(e))
+            self.register_initial_value = None
+            return -1
+
+        print("\tregister_initial_value = " + hex32str(self.register_initial_value))
+
+        if self.register_multifield is True :
+            try :
+                self.register_fields = register["register_fields"]
+            except KeyError as e :
+                print("KeyError : {}".format(e))
+                self.register_fields = None
+                return -1
+
+            print("\tregister_fields = ")
+            for key in self.register_fields :
+                print("\t\tname = " + key + " : size = " + str(self.register_fields[key]))
+                
+        if self.register_status_active == True :
+            registers_list_entity_io = ""
+
+            if first_call == True :
+                print("\n\nFIRST CALL\n\n")
+                registers_list_entity_io = ";\n\t\t-- Registers list IO"
+
+            if self.register_access_mode == "rw" or self.register_access_mode == "wo" :
+                if first_call == True :
+                    registers_list_entity_io = registers_list_entity_io + "\n\t\t" + self.register_name + "xDO : out std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0)"
+                else :
+                    registers_list_entity_io = registers_list_entity_io + ";\n\t\t" + self.register_name + "xDO : out std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0)"
+            elif self.register_access_mode == "ro" :
+                if first_call == True :
+                    registers_list_entity_io = registers_list_entity_io + "\n\t\t" + self.register_name + "xDI : in std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0)"
+                else :
+                    registers_list_entity_io = registers_list_entity_io + ";\n\t\t" + self.register_name + "xDI : in std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0)"
+
+            self.registers_list_entity_io = self.registers_list_entity_io + registers_list_entity_io
+
+        if self.registers_list is not "" :
+            self.registers_list = self.registers_list + "\t"
+                
+        self.registers_list = self.registers_list + \
+            "signal " + self.register_name + "PortxDN : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x\"" + \
+            hex32str(self.register_initial_value) + "\";\n" + \
+            "\tsignal " + self.register_name + "PortxDP : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := x\"" + \
+            hex32str(self.register_initial_value) + "\";\n"
+
+        if self.registers_list_c2n is not "" :
+            self.registers_list_c2n = self.registers_list_c2n + "\t\t\t"
+
+        if self.register_status_active == True and self.register_access_mode == "ro" :
+            self.registers_list_c2n = self.registers_list_c2n + \
+                self.register_name + "PortxDN <= " + self.register_name + "xDI;\n"
+        else :
+            if self.register_type == "ocp" :
+                self.registers_list_c2n = self.registers_list_c2n + \
+                self.register_name + "PortxDN <= (others => '0');\n"
+            else :                
+                self.registers_list_c2n = self.registers_list_c2n + \
+                    self.register_name + "PortxDN <= " + self.register_name + "PortxDP;\n"
+            self.registers_list_c2n = self.registers_list_c2n + \
+                self.register_name + "xDO <= " + self.register_name + "PortxDP;\n"
+
+        if self.registers_list_n2c is not "" :
+            self.registers_list_n2c = self.registers_list_n2c + "\t\t\t\t"
+        
+        self.registers_list_n2c = self.registers_list_n2c + \
+            self.register_name + "PortxDP <= " + self.register_name + "PortxDN;\n"
+
+        if self.registers_list_init_cv is not "" :
+            self.registers_list_init_cv = self.registers_list_init_cv + "\t\t\t\t"
+
+        self.registers_list_init_cv = self.registers_list_init_cv + \
+            self.register_name + "PortxDP <= x\"" + \
+            hex32str(self.register_initial_value) + "\";\n"
+
+        if self.registers_list_cv_cnt > 0 and np.mod(self.registers_list_cv_cnt, 3) == 0 :
+            self.registers_list_cv = self.registers_list_cv + "\n\t\t\t\t\t\t\t\t"
+
+        if self.register_status_active == True and self.register_access_mode == "ro" :
+            self.registers_list_cv = self.registers_list_cv + \
+                self.register_name + "xDI"
+        else :
+            self.registers_list_cv = self.registers_list_cv + \
+                self.register_name + "PortxDP"
+
+        if self.registers_list_cv_cnt < len(self.register_bank) - 1 :
+            self.registers_list_cv = self.registers_list_cv + ","
+            
+        self.registers_list_cv_cnt = self.registers_list_cv_cnt + 1
+
+
+        addr = self.registers_list_ad_cnt * 4
+        print(self.bd_range)
+        print(BD_RANGE_CONV[self.bd_range])
+        print("Register address : 0x" + hex32str2(addr, str(BD_RANGE_CONV[self.bd_range])))                    
+
+        if self.register_type == "ctrl" :
+            addr1 = (self.registers_list_ad_cnt + 1) * 4
+            addr2 = (self.registers_list_ad_cnt + 2) * 4
+
+            if self.register_access_mode == "rw" or self.register_access_mode == "wo" :
+                if self.registers_list_wa is not "" :
+                    self.registers_list_wa = self.registers_list_wa + "\t\t\t\t\t"
+                    
+                self.registers_list_wa = self.registers_list_wa + \
+                    "when x\"" + hex32str2(addr, str(BD_RANGE_CONV[self.bd_range])) + "\" => " + self.register_name + "PortxDN <= WrDataxD;\n"
+                self.registers_list_wa = self.registers_list_wa + \
+                    "\t\t\t\t\twhen x\"" + hex32str2(addr1, str(BD_RANGE_CONV[self.bd_range])) + "\" => " + \
+                    self.register_name + "PortxDN <= " +  self.register_name + "PortxDP or WrDataxD;\n"
+                self.registers_list_wa = self.registers_list_wa + \
+                    "\t\t\t\t\twhen x\"" + hex32str2(addr2, str(BD_RANGE_CONV[self.bd_range])) + "\" => " + \
+                    self.register_name + "PortxDN <= " +  self.register_name + "PortxDP and not WrDataxD;\n"
+
+            if self.register_access_mode == "rw" or self.register_access_mode == "ro" :                
+                if self.registers_list_ra is not "" :
+                    self.registers_list_ra = self.registers_list_ra + "\t\t\t\t\t\t"
+
+                self.registers_list_ra = self.registers_list_ra + \
+                    "when x\"" + hex32str2(addr, str(BD_RANGE_CONV[self.bd_range])) + "\" => RdDataxD <= " + self.register_name + "PortxDP;\n"
+                    
+            self.registers_list_ad_cnt = self.registers_list_ad_cnt + 3
+        else :
+            if self.register_access_mode == "rw" or self.register_access_mode == "wo" :
+                if self.registers_list_wa is not "" :
+                    self.registers_list_wa = self.registers_list_wa + "\t\t\t\t\t"
+                    
+                self.registers_list_wa = self.registers_list_wa + \
+                    "when x\"" + hex32str2(addr, str(BD_RANGE_CONV[self.bd_range])) + "\" => " + self.register_name + "PortxDN <= WrDataxD;\n"
+
+            if self.register_access_mode == "rw" or self.register_access_mode == "ro" :                
+                if self.registers_list_ra is not "" :
+                    self.registers_list_ra = self.registers_list_ra + "\t\t\t\t\t\t"
+
+                self.registers_list_ra = self.registers_list_ra + \
+                    "when x\"" + hex32str2(addr, str(BD_RANGE_CONV[self.bd_range])) + "\" => RdDataxD <= " + self.register_name + "PortxDP;\n"
+            
+            self.registers_list_ad_cnt = self.registers_list_ad_cnt + 1
+        
+        return 0
diff --git a/src/regedit.pyc b/src/regedit.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f576278b49c5bf51046c02fa66443660c3f1ba2c
Binary files /dev/null and b/src/regedit.pyc differ
diff --git a/src/regedit_creator.py b/src/regedit_creator.py
new file mode 100755
index 0000000000000000000000000000000000000000..40e4871e8d1eefe36a214f7df7b7b799a007c0d8
--- /dev/null
+++ b/src/regedit_creator.py
@@ -0,0 +1,121 @@
+#!/usr/bin/python3
+
+import os
+import sys
+import getopt
+import json
+from utils import display_title
+from regedit import *
+
+VERSION = "0.1"
+# Default directories
+
+def help() :
+    print("Usage : ")
+    print("$ python3 regedit_creator <opt>")
+    print("Option : ")
+    print("\t-h || --help\tDisplay help")
+    print("\t-c || --config_file <json_file>\tUse a JSON file for the register bank configuration")
+
+if __name__ == "__main__" :
+    json_data = None
+
+    display_title(" Register Bank Creator v{} ".format(VERSION))
+
+    try :
+        opts, args = getopt.getopt(sys.argv[1:], "hc:", ["help", "config_file="])
+    except getopt.GetoptError :
+        help()
+        sys.exit(-1)
+    if not opts :
+        help()
+        sys.exit(-1)
+
+    for opt, arg in opts :
+        if opt in ("-h", "--help") :
+            help()
+            sys.exit()
+        elif opt in ("-c", "--config_file") :
+            print("> Load register bank information from " + arg)
+
+            with open(arg) as f :
+                json_data = json.load(f)
+
+    # Get config
+    #if "config" in json_data :
+    try :
+        config = json_data["config"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+        sys.exit(-1)
+
+    try :
+        entity_name = config["entity_name"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+
+    try :        
+        entity_version = config["entity_version"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+
+    try :
+        entity_reg_io_access = config["entity_reg_io_access"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+
+    try :
+        block_name = config["block_name"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+
+    try :
+        bd_name = config["bd_name"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+
+    try :
+        bd_interface = config["bd_interface"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+
+    try :
+        bd_slave_segment = config["bd_slave_segment"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+
+    try :
+        bd_master_base_address = config["bd_master_base_address"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+
+    try :
+        bd_range = config["bd_range"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+    
+    # Get register bank
+    try :
+        register_bank = json_data["register_bank"]
+    except KeyError as e :
+        print("KeyError : {}".format(e))
+        print("#Error - __main__() : the register bank is not defined in the config file...")
+        sys.exit(-1)
+
+    if len(register_bank) == 0 :
+        print("Error : Empty register bank");
+        sys.exit(-1)
+
+    try :
+        regedit_prj = regedit_gen(entity_name, entity_version, entity_reg_io_access, block_name,
+                                  bd_name, bd_interface, bd_slave_segment, bd_master_base_address,
+                                  bd_range, register_bank)
+    except ValueError as e :
+        print(e)
+    else :
+        ret = regedit_prj.create_dir()
+
+        if ret == 0 :
+            print("\n> " + entity_name + " register bank directory tree successfully created")
+        
+        ret = regedit_prj.copy_hdl_template_file(entity_name)
diff --git a/src/templates/hdl/template_regbank.vhd b/src/templates/hdl/template_regbank.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..fa97b192a43ade0b84b4db0cb39d19273a92bc53
--- /dev/null
+++ b/src/templates/hdl/template_regbank.vhd
@@ -0,0 +1,310 @@
+-- THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+-- scalp_regedit v0.1 - 05.2021
+-- Author : Joachim Schmidt <joachim.schmidt@hesge.ch>
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.std_logic_unsigned.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_misc.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+entity <entity_name> is
+
+    generic (
+        C_AXI4_ARADDR_SIZE : integer range 0 to 32 := 32;
+        C_AXI4_RDATA_SIZE  : integer range 0 to 32 := <data_size>;
+        C_AXI4_RRESP_SIZE  : integer range 0 to 2  := 2;
+        C_AXI4_AWADDR_SIZE : integer range 0 to 32 := 32;
+        C_AXI4_WDATA_SIZE  : integer range 0 to 32 := <data_size>;
+        C_AXI4_WSTRB_SIZE  : integer range 0 to 4  := 4;
+        C_AXI4_BRESP_SIZE  : integer range 0 to 2  := 2;
+        C_AXI4_ADDR_SIZE   : integer range 0 to 32 := <addr_size>;
+        C_AXI4_DATA_SIZE   : integer range 0 to 32 := <data_size>);
+
+    port (
+        -- Clock and reset
+        SAxiClkxCI     : in std_ulogic;
+        SAxiRstxRANI   : in std_ulogic;
+        -- AXI4 Lite
+        -- Read Channel
+        -- Read Address Channel
+        SAxiARAddrxDI  : in  std_ulogic_vector((C_AXI4_ARADDR_SIZE - 1) downto 0);
+        SAxiARValidxSI : in  std_ulogic;
+        SAxiARReadyxSO : out std_ulogic;
+        -- Read Data Channel
+        SAxiRDataxDO   : out std_ulogic_vector((C_AXI4_RDATA_SIZE - 1) downto 0);
+        SAxiRRespxDO   : out std_ulogic_vector((C_AXI4_RRESP_SIZE - 1) downto 0);
+        SAxiRValidxSO  : out std_ulogic;
+        SAxiRReadyxSI  : in  std_ulogic;
+        -- Write Channel
+        -- Write Address Channel
+        SAxiAWAddrxDI  : in  std_ulogic_vector((C_AXI4_AWADDR_SIZE - 1) downto 0);
+        SAxiAWValidxSI : in  std_ulogic;
+        SAxiAWReadyxSO : out std_ulogic;
+        -- Write Data Channel
+        SAxiWDataxDI   : in  std_ulogic_vector((C_AXI4_WDATA_SIZE - 1) downto 0);
+        SAxiWStrbxDI   : in  std_ulogic_vector((C_AXI4_WSTRB_SIZE - 1) downto 0);
+        SAxiWValidxSI  : in  std_ulogic;
+        SAxiWReadyxSO  : out std_ulogic;
+        -- Write Response Channel
+        SAxiBRespxDO   : out std_ulogic_vector((C_AXI4_BRESP_SIZE - 1) downto 0);
+        SAxiBValidxSO  : out std_ulogic;
+        SAxiBReadyxSI  : in  std_ulogic<registers_list_entity_io>);
+
+end <entity_name>;
+
+architecture behavioral of <entity_name> is
+
+    -- Constants
+    constant C_AXI4_RRESP_OKAY   : std_ulogic_vector((C_AXI4_RRESP_SIZE - 1) downto 0) := "00";
+    constant C_AXI4_RRESP_EXOKAY : std_ulogic_vector((C_AXI4_RRESP_SIZE - 1) downto 0) := "01";
+    constant C_AXI4_RRESP_SLVERR : std_ulogic_vector((C_AXI4_RRESP_SIZE - 1) downto 0) := "10";
+    constant C_AXI4_RRESP_DECERR : std_ulogic_vector((C_AXI4_RRESP_SIZE - 1) downto 0) := "11";
+    constant C_AXI4_BRESP_OKAY   : std_ulogic_vector((C_AXI4_BRESP_SIZE - 1) downto 0) := "00";
+    constant C_AXI4_BRESP_EXOKAY : std_ulogic_vector((C_AXI4_BRESP_SIZE - 1) downto 0) := "01";
+    constant C_AXI4_BRESP_SLVERR : std_ulogic_vector((C_AXI4_BRESP_SIZE - 1) downto 0) := "10";
+    constant C_AXI4_BRESP_DECERR : std_ulogic_vector((C_AXI4_BRESP_SIZE - 1) downto 0) := "11";
+
+    -- Signals
+    -- Clock and reset
+    signal SAxiClkxC      : std_ulogic                                         := '0';
+    signal SAxiRstxRAN    : std_ulogic                                         := '0';
+    -- AXI4 Lite
+    signal SAxiARReadyxS  : std_ulogic                                         := '0';
+    signal SAxiRValidxS   : std_ulogic                                         := '0';
+    signal SAxiBValidxS   : std_ulogic                                         := '0';
+    signal SAxiWReadyxS   : std_ulogic                                         := '0';
+    signal SAxiAWReadyxS  : std_ulogic                                         := '0';
+    signal WrAddrxDN      : std_ulogic_vector((C_AXI4_ADDR_SIZE - 1) downto 0) := (others => '0');
+    signal WrAddrxDP      : std_ulogic_vector((C_AXI4_ADDR_SIZE - 1) downto 0) := (others => '0');
+    -- Signals of access to the register bank
+    signal RdAddrxD       : std_ulogic_vector((C_AXI4_ADDR_SIZE - 1) downto 0) := (others => '0');
+    signal RdDataxD       : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := (others => '0');
+    signal RdValidxS      : std_ulogic                                         := '0';
+    signal WrAddrxD       : std_ulogic_vector((C_AXI4_ADDR_SIZE - 1) downto 0) := (others => '0');
+    signal WrDataxD       : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := (others => '0');
+    signal WrValidxS      : std_ulogic                                         := '0';
+    -- Registers list
+    <registers_list>
+    -- Attributes
+    attribute mark_debug                      : string;
+    attribute keep                            : string;
+    --
+    -- attribute mark_debug of                : signal is "true";
+    -- attribute keep of                      : signal is "true";
+    
+begin 
+
+    assert C_AXI4_RDATA_SIZE = C_AXI4_DATA_SIZE
+        report "RDATA and DATA vectors must be the same" severity failure;
+
+    assert C_AXI4_ARADDR_SIZE >= C_AXI4_ADDR_SIZE
+        report "ARADDR and ADDR vectors must be the same" severity failure;
+
+    assert C_AXI4_WDATA_SIZE = C_AXI4_DATA_SIZE
+        report "WDATA and DATA vectors must be the same" severity failure;
+
+    assert C_AXI4_AWADDR_SIZE >= C_AXI4_ADDR_SIZE
+        report "AWADDR and ADDR vectors must be the same" severity failure;
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+
+        -- Clock and reset
+        SAxiClkxAS     : SAxiClkxC                                  <= SAxiClkxCI;
+        SAxiRstxAS     : SAxiRstxRAN                                <= SAxiRstxRANI;
+        -- Read Channel
+        SAxiARReadyxAS : SAxiARReadyxSO                             <= SAxiARReadyxS;
+        SAxiRValidxAS  : SAxiRValidxSO                              <= SAxiRValidxS;
+        SAxiRDataxAS   : SAxiRDataxDO                               <= RdDataxD;
+        RdValidxAS     : RdValidxS                                  <= SAxiARValidxSI;
+        RdAddrxAS      : RdAddrxD((C_AXI4_ADDR_SIZE - 1) downto 0)  <= SAxiARAddrxDI((C_AXI4_ADDR_SIZE - 1) downto 0);
+        SAxiRRespxAS   : SAxiRRespxDO                               <= C_AXI4_RRESP_OKAY;
+        -- Write Channel
+        SAxiBRespxAS   : SAxiBRespxDO                               <= C_AXI4_BRESP_OKAY;
+        SAxiBValidxAS  : SAxiBValidxSO                              <= SAxiBValidxS;
+        SAxiWReadyxAS  : SAxiWReadyxSO                              <= SAxiWReadyxS;
+        SAxiAWReadyxAS : SAxiAWReadyxSO                             <= SAxiAWReadyxS;
+        WrValidxAS     : WrValidxS                                  <= SAxiWValidxSI;
+        WrDataxAS      : WrDataxD                                   <= SAxiWDataxDI;
+        WrAddrOutxAS   : WrAddrxD                                   <= WrAddrxDP;
+        WrAddrxAS      : WrAddrxDN((C_AXI4_ADDR_SIZE - 1) downto 0) <= SAxiAWAddrxDI((C_AXI4_ADDR_SIZE - 1) downto 0) when
+                                                                       SAxiAWValidxSI = '1' else
+                                                                       WrAddrxDP((C_AXI4_ADDR_SIZE - 1) downto 0);
+
+    end block EntityIOxB;
+    
+    AXI4LitexB : block is
+    begin  -- block AXI4LitexB
+
+        ReadChannelxB : block is
+        begin  -- block ReadChannelxB
+
+            ReadAddrChanxP : process (SAxiClkxC, SAxiRstxRAN) is
+
+                variable StateAfterResetxS : boolean := true;
+
+            begin  -- process ReadAddrChanxP
+                if SAxiRstxRAN = '0' then
+                    SAxiARReadyxS     <= '0';
+                    StateAfterResetxS := true;
+                elsif rising_edge(SAxiClkxC) then
+                    if StateAfterResetxS = true then
+                        SAxiARReadyxS     <= '1';
+                        StateAfterResetxS := false;
+                    else
+                        SAxiARReadyxS <= SAxiARReadyxS;
+                    end if;
+
+                    if SAxiARValidxSI = '1' then
+                        SAxiARReadyxS <= '0';
+                    end if;
+
+                    if SAxiARReadyxS <= '0' and SAxiRReadyxSI = '1' then
+                        SAxiARReadyxS <= '1';
+                    end if;
+                end if;
+            end process ReadAddrChanxP;
+
+            ReadDataChanxP : process (SAxiClkxC, SAxiRstxRAN) is
+            begin  -- process ReadDataChanxP
+                if SAxiRstxRAN = '0' then
+                    SAxiRValidxS <= '0';
+                elsif rising_edge(SAxiClkxC) then
+                    SAxiRValidxS <= SAxiRValidxS;
+
+                    if SAxiARValidxSI = '1' and SAxiARReadyxS = '1' then
+                        SAxiRValidxS <= '1';
+                    end if;
+
+                    if SAxiRValidxS = '1' and SAxiRReadyxSI = '1' then
+                        SAxiRValidxS <= '0';
+                    end if;
+                end if;
+            end process ReadDataChanxP;
+
+        end block ReadChannelxB;
+
+        WriteChannelxB : block is
+        begin  --block WriteChannelxB        
+
+            WrAddrRegxP : process (SAxiClkxC, SAxiRstxRAN) is
+            begin  -- process WrAddrRegxP
+                if SAxiRstxRAN = '0' then
+                    WrAddrxDP <= (others => '0');
+                elsif rising_edge(SAxiClkxC) then
+                    WrAddrxDP <= WrAddrxDN;
+                end if;
+            end process WrAddrRegxP;
+
+            WriteAddrChanxP : process (SAxiClkxC, SAxiRstxRAN) is
+
+                variable StateAfterResetxS : boolean := true;
+
+            begin  -- process WriteAddrChanxP
+                if SAxiRstxRAN = '0' then
+                    SAxiAWReadyxS     <= '0';
+                    StateAfterResetxS := true;
+                elsif rising_edge(SAxiClkxC) then
+                    if StateAfterResetxS = true then
+                        SAxiAWReadyxS     <= '1';
+                        StateAfterResetxS := false;
+                    else
+                        SAxiAWReadyxS <= SAxiAWReadyxS;
+                    end if;
+
+                    if SAxiAWValidxSI = '1' then
+                        SAxiAWReadyxS <= '0';
+                    end if;
+
+                    if SAxiWValidxSI = '1' then
+                        SAxiAWReadyxS <= '1';
+                    end if;
+                end if;
+            end process WriteAddrChanxP;
+
+            WriteDataChanxP : process (SAxiClkxC, SAxiRstxRAN) is
+            begin  -- process WriteDataChanxP
+                if SAxiRstxRAN = '0' then
+                    SAxiWReadyxS <= '0';
+                elsif rising_edge(SAxiClkxC) then
+                    SAxiWReadyxS <= SAxiWReadyxS;
+
+                    if SAxiAWValidxSI = '1' and SAxiAWReadyxS = '1' then
+                        SAxiWReadyxS <= '1';
+                    end if;
+
+                    if SAxiWValidxSI = '1' and SAxiWReadyxS = '1' then
+                        SAxiWReadyxS <= '0';
+                    end if;
+                end if;
+            end process WriteDataChanxP;
+
+            WriteRespChanxP : process (SAxiClkxC, SAxiRstxRAN) is
+            begin  -- process WriteRespChanxP
+                if SAxiRstxRAN = '0' then
+                    SAxiBValidxS <= '0';
+                elsif rising_edge(SAxiClkxC) then
+                    SAxiBValidxS <= SAxiBValidxS;
+
+                    if SAxiWValidxSI = '1' and SAxiWReadyxS = '1' then
+                        SAxiBValidxS <= '1';
+                    end if;
+
+                    if SAxiBValidxS = '1' and SAxiBReadyxSI = '1' then
+                        SAxiBValidxS <= '0';
+                    end if;
+                end if;
+            end process WriteRespChanxP;
+
+        end block WriteChannelxB;
+
+    end block AXI4LitexB;
+        
+    <block_name>xB : block is
+    begin  -- block <block_name>xB
+ 
+        WriteRegPortxP : process (WrAddrxD, WrDataxD, WrValidxS,
+                                  <registers_list_current_value>) is
+        begin  -- process WriteRegPortxP
+            <registers_list_current_to_next>
+            if WrValidxS = '1' then
+                case WrAddrxD is
+                    <registers_list_write_access>
+                    when others => null;
+                end case;
+            end if;
+        end process WriteRegPortxP;
+
+        ReadRegPortxP : process (SAxiClkxC, SAxiRstxRAN) is
+        begin  -- process ReadRegPortxP
+            if SAxiRstxRAN = '0' then
+                RdDataxD <= (others => '0');
+            elsif rising_edge(SAxiClkxC) then
+                RdDataxD <= RdDataxD;
+
+                if RdValidxS = '1' then
+                    case RdAddrxD is
+                        <registers_list_read_access>
+                        when others => RdDataxD <= (others => '0');
+                    end case;
+                end if;
+            end if;
+        end process ReadRegPortxP;
+
+        UpdateRegBankxP : process (SAxiClkxC, SAxiRstxRAN) is
+        begin  -- process UpdateRegBankxP
+            if SAxiRstxRAN = '0' then
+                <registers_list_init_current_value>
+            elsif rising_edge(SAxiClkxC) then
+                <registers_list_next_to_current>
+            end if;
+        end process UpdateRegBankxP;
+
+    end block <block_name>xB;
+
+end behavioral;
diff --git a/src/utils.py b/src/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..c53058aacd24fb4478bf3217a41c82e07a390b6a
--- /dev/null
+++ b/src/utils.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+
+import datetime
+import re
+import os
+import shutil
+import numpy as np
+
+def display_title(title_str):
+    print("\n" + ("-" * (len(title_str) + 6)))
+    print("-- " + title_str + " --")
+    print(("-" * (len(title_str) + 6)) + "\n")
+
+def get_time_str():
+    return datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
+
+def file_replace_pattern(file_path, pattern, replace_str):
+    # create the regex pattern
+    re_pattern = "(" + pattern + ")"
+    p = re.compile(re_pattern)
+    # create a temp file to apply the pattern
+    temp_file = file_path + "#"
+    fin = open(file_path, "r")
+    fout = open(temp_file, "w")
+    for line in fin.readlines():
+        # substitute the pattern
+        fout.write(p.sub(replace_str, line))
+    # replace the input file by the processed temp file
+    os.remove(file_path)
+    shutil.move(temp_file, file_path)
+
+def hex32str(value):
+    return "{:08X}".format(value)
+
+def hex32str2(value, bd_range):
+
+    size = int(np.ceil(int(np.trunc(np.log2(int(bd_range)))) / 4))
+    fstr = "{:0" + str(size) + "X}"
+    
+    return fstr.format(value)
+
+def check_key(dict, key) : 
+      
+    if key in dict.keys() : 
+        return True
+    else : 
+        return False
diff --git a/src/utils.pyc b/src/utils.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a619c405da5902cadb37e8dcf7bd563c7018e5f3
Binary files /dev/null and b/src/utils.pyc differ