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