diff --git a/APB_DEVICES/apb_devices_list.txt b/APB_DEVICES/apb_devices_list.txt --- a/APB_DEVICES/apb_devices_list.txt +++ b/APB_DEVICES/apb_devices_list.txt @@ -12,3 +12,4 @@ device LPP_CHENILLARD 9 device LPP_IIR_CEL_FILTER 10 device LPP_FIFO 11 device LPP_FFT 12 +device LPP_MATRIX 13 diff --git a/LPP_drivers/Makefile b/LPP_drivers/Makefile --- a/LPP_drivers/Makefile +++ b/LPP_drivers/Makefile @@ -37,8 +37,9 @@ lib: make all -C libsrc doc: - rm -R Doc/html/* - cp -R Doc/ressources/* Doc/html/ + mkdir -p Doc/ressources/ + mkdir -p Doc/html/ + cp -f -R Doc/ressources/* Doc/html/ doxygen Doxyfile clean: diff --git a/LPP_drivers/includes/apb_fft_Driver.h b/LPP_drivers/includes/apb_fft_Driver.h --- a/LPP_drivers/includes/apb_fft_Driver.h +++ b/LPP_drivers/includes/apb_fft_Driver.h @@ -22,22 +22,38 @@ #ifndef APB_FFT_DRIVER_H #define APB_FFT_DRIVER_H -#define FFT_Empty 0x00100 -#define FFT_Full 0x01000 +/*! \file apb_fft_Driver.h + \brief LPP FFT driver. + + This library is written to work with LPP_APB_FFT VHDL module from LPP's FreeVHDLIB. It calculate a fast fourier transforms, + from an input data table. + + \todo Check "DEVICE1 => count = 2" function Open + \author Martin Morlot martin.morlot@lpp.polytechnique.fr +*/ + +#define FFT_Empty 0x00100 /**< Used to know when the data can be send to the FFT module */ +#define FFT_Full 0x01000 /**< Used to know when the data can be send to the FFT module */ /*=================================================== T Y P E S D E F ====================================================*/ - +/*! \struct FFT_Driver + \brief Sturcture representing the fft registers +*/ struct FFT_Driver { - int RWDataReg; - int ReadAddrReg; - int ConfigReg; - int Dummy1; - int Dummy0; - int WriteAddrReg; + int RWDataReg; /**< \brief Data register Write/Read */ + int ReadAddrReg; /**< \brief Address register for the reading operation */ + int ConfigReg; /**< \brief Configuration register composed of Read enable Flag [HEX 0] + Write enable Flag [HEX 1] + Empty Flag [HEX 2] + Full Flag [HEX 3] + Dummy "C" [HEX 4/5/6/7] */ + int Dummy1; /**< \brief Unused register, aesthetic interest */ + int Dummy0; /**< \brief Unused register, aesthetic interest */ + int WriteAddrReg; /**< \brief Address register for the writing operation */ }; typedef struct FFT_Driver FFT_Device; @@ -46,10 +62,36 @@ typedef struct FFT_Driver FFT_Device; /*=================================================== F U N C T I O N S ====================================================*/ - +/*! \fn FFT_Device* openFFT(int count); + \brief Return count FFT. + + This Function scans APB devices table and returns count FFT. + + \param count The number of the FFT you whant to get. For example if you have 3 FFTS on your SOC you want + to use FFT1 so count = 2. + \return The pointer to the device. +*/ FFT_Device* openFFT(int count); -int FftInput(int Tbl[],FFT_Device*); -int FftOutput(int Tbl[],FFT_Device*); + +/*! \fn int FftInput(int Tbl[],FFT_Device*); + \brief Fill in the Input for the FFT + + This function provides the data used by the FFT + + \param Tbl[] The Table which contains the Data. + \param dev The FFT pointer. +*/ +int FftInput(int Tbl[],FFT_Device* dev); + +/*! \fn int FftOutput(int Tbl[],FFT_Device*); + \brief Save data from the FFT + + This function save the data generated by the FFT + + \param Tbl[] The Table which will contains the Data. + \param dev The FFT pointer. +*/ +int FftOutput(int Tbl[],FFT_Device* dev); diff --git a/LPP_drivers/includes/apb_fifo_Driver.h b/LPP_drivers/includes/apb_fifo_Driver.h --- a/LPP_drivers/includes/apb_fifo_Driver.h +++ b/LPP_drivers/includes/apb_fifo_Driver.h @@ -21,22 +21,37 @@ -----------------------------------------------------------------------------*/ #ifndef APB_FIFO_DRIVER_H #define APB_FIFO_DRIVER_H + +/*! \file apb_fifo_Driver.h + \brief LPP FIFO driver. + This library is written to work with LPP_APB_FIFO VHDL module from LPP's FreeVHDLIB. It represents a standard FIFO working, + used in many type of application. + + \todo Check "DEVICE1 => count = 2" function Open + \author Martin Morlot martin.morlot@lpp.polytechnique.fr +*/ /*=================================================== T Y P E S D E F ====================================================*/ -/** Structure représentant le registre du FIFO */ +/*! \struct APB_FIFO_REG + \brief Sturcture representing the fifo registers +*/ struct APB_FIFO_REG { - int rwdata; /**< Registre de configuration: Flag Ready [1] ; Flag Enable [0] */ - int raddr; /**< Registre de donnée sur 16 bits */ - int cfgreg; - int dummy0; - int dummy1; - int waddr; + int rwdata; /**< \brief Data register Write/Read */ + int raddr; /**< \brief Address register for the reading operation */ + int cfgreg; /**< \brief Configuration register composed of Read enable Flag [HEX 0] + Write enable Flag [HEX 1] + Empty Flag [HEX 2] + Full Flag [HEX 3] + Dummy "C" [HEX 4/5/6/7] */ + int dummy0; /**< \brief Unused register, aesthetic interest */ + int dummy1; /**< \brief Unused register, aesthetic interest */ + int waddr; /**< \brief Address register for the writing operation */ }; typedef struct APB_FIFO_REG APB_FIFO_Device; @@ -45,10 +60,17 @@ typedef struct APB_FIFO_REG APB_FIFO_Dev F U N C T I O N S ====================================================*/ -/** Ouvre l'accé au FIFO */ +/*! \fn APB_FIFO_Device* apbfifoOpen(int count); + \brief Return count FIFO. + + This Function scans APB devices table and returns count FIFO. + + \param count The number of the FIFO you whant to get. For example if you have 3 FIFOS on your SOC you want + to use FIFO1 so count = 2. + \return The pointer to the device. +*/ APB_FIFO_Device* apbfifoOpen(int count); - #endif diff --git a/LPP_drivers/includes/apb_lcd_driver.h b/LPP_drivers/includes/apb_lcd_driver.h --- a/LPP_drivers/includes/apb_lcd_driver.h +++ b/LPP_drivers/includes/apb_lcd_driver.h @@ -26,7 +26,14 @@ #define lcdCharCnt 80 -/** @todo implemente some shift functions */ +/*! \file apb_lcd_driver.h + \brief APB char LCD driver. + + This library is written to work with apb_lcd VHDL module from LPP's VHDlib. It help you to drive char LCD. + + \author Alexis Jeandet + \todo implemente some shift functions +*/ /*=================================================== @@ -34,30 +41,31 @@ ====================================================*/ - -/** error type used for most of lcd functions */ -typedef int lcd_err; - /** lcd error ennum for higher abstraction level when error decoding */ enum lcd_error { - lcd_error_no_error, /**< no error append while function execution */ - lcd_error_not_ready, /**< the lcd isn't available*/ - lcd_error_not_openned, /**< the device guiven to the function isn't opened*/ - lcd_error_too_long /**< the string guiven to the lcd is bigger than the lcd frame buffer memory */ + lcd_error_no_error, /**< \brief no error append while function execution */ + lcd_error_not_ready, /**< \brief the lcd isn't available*/ + lcd_error_not_openned, /**< \brief the device guiven to the function isn't opened*/ + lcd_error_too_long /**< \brief the string guiven to the lcd is bigger than the lcd frame buffer memory */ }; +typedef enum lcd_error lcd_err; -/** for each command sended to the lcd driver a time should be guiven according to the lcd datasheet */ +/** for each command sended to the lcd driver a time should be guiven according to the lcd datasheet. +Don't worry about time, the lcd VHDL module should be aware of oscillator frequency. +*/ enum lcd_CMD_time { - lcd_4us = 0x0FF, + lcd_4us = 0x0FF, lcd_100us = 0x1FF, lcd_4ms = 0x2FF, lcd_20ms = 0x3FF }; -/** list of availiable lcd commands use whith an AND mask whith cmd time */ +/** list of availiable lcd commands use whith an AND mask whith cmd time +\todo implemente more commands. +*/ enum lcd_CMD { CursorON = 0xF0E, @@ -78,10 +86,24 @@ typedef struct lcd_driver lcd_device; F U N C T I O N S ====================================================*/ -/** says if the lcd is busy */ +/*! \fn int lcdbusy(lcd_device * lcd); + \brief Say if the lcd screen is busy + + \param lcd The lcd device to test. + \return True if the lcd is busy. +*/ int lcdbusy(lcd_device * lcd); -/** Opens and returns the counth lcd found on APB bus else NULL */ + +/*! \fn lcd_device* lcdopen(int count); + \brief Return counth LCD. + + This Function scans APB devices table and returns counth LCD. + + \param count The number of the LCD you whant to get. For example if you have 3 LCD on your SOC you whant + to use LCD1 so count = 2. + \return The pointer to the device. +*/ lcd_device* lcdopen(int count); /** Sends a command to the given device, don't forget to guive the time of the cmd */ diff --git a/LPP_drivers/includes/apb_uart_Driver.h b/LPP_drivers/includes/apb_uart_Driver.h --- a/LPP_drivers/includes/apb_uart_Driver.h +++ b/LPP_drivers/includes/apb_uart_Driver.h @@ -18,39 +18,101 @@ ------------------------------------------------------------------------------- -- Author : Martin Morlot -- Mail : martin.morlot@lpp.polytechnique.fr ------------------------------------------------------------------------------*/ +-----------------------------------------------------------------------------*/ #ifndef APB_UART_DRIVER_H -#define APB_UART_DRIVER_H - +#define APB_UART_DRIVER_H + +/*! \file apb_uart_Driver.h + \brief LPP Uart driver. + + This library is written to work with LPP_APB_UART VHDL module from LPP's FreeVHDLIB. It help you to print and get, + char or strings over uart. -#define BaudGenOnDuty 0 -#define DataSended 0x10 -#define NewData 0x100 - + \todo Check "DEVICE1 => count = 2" function Open + \author Martin Morlot martin.morlot@lpp.polytechnique.fr +*/ + + + +#define BaudGenOnDuty 0 /**< Used to reset the Baud Generator (Capture Flag) */ +#define DataSended 0x10 /**< Used to know when the data was send */ +#define NewData 0x100 /**< Used to know if a New data is ready to be send */ + /*=================================================== T Y P E S D E F -====================================================*/ +====================================================*/ -struct UART_Driver -{ - int ConfigReg; - int DataWReg; - int DataRReg; -}; - -typedef struct UART_Driver UART_Device; - - +/*! \struct UART_Driver + \brief Sturcture representing the uart registers +*/ +struct UART_Driver +{ + int ConfigReg; /**< \brief Configuration register composed of Capture Flag [HEX 0] + Sended Flag [HEX 1] + NewData Flag [HEX 2] + Dummy "E" [HEX 3/4] + BTrig Freq [HEX 5/6/7] */ + int DataWReg; /**< \brief Data Write register */ + int DataRReg; /**< \brief Data Read register */ +}; + +typedef struct UART_Driver UART_Device; + + /*=================================================== F U N C T I O N S -====================================================*/ - - -UART_Device* openUART(int count); -void uartputc(UART_Device* dev,char c); -void uartputs(UART_Device* dev,char* s); -char uartgetc(UART_Device* dev); -void uartgets(UART_Device* dev,char* s); - - -#endif +====================================================*/ + +/*! \fn UART_Device* openUART(int count); + \brief Return count UART. + + This Function scans APB devices table and returns count UART. + + \param count The number of the UART you whant to get. For example if you have 3 UARTS on your SOC you want + to use UART1 so count = 2. + \return The pointer to the device. +*/ +UART_Device* openUART(int count); + +/*! \fn void uartputc(UART_Device* dev,char c); + \brief Print char over given UART. + + This Function puts the given char over the given UART. + + \param dev The UART pointer. + \param c The char you whant to print. +*/ +void uartputc(UART_Device* dev,char c); + +/*! \fn void uartputs(UART_Device* dev,char* s); + \brief Print string over given UART. + + This Function puts the given string over the given UART. + + \param dev The UART pointer. + \param s The string you whant to print. +*/ +void uartputs(UART_Device* dev,char* s); + +/*! \fn char uartgetc(UART_Device* dev); + \brief Get char from given UART. + + This Function get char from the given UART. + + \param dev The UART pointer. + \return The read char. +*/ +char uartgetc(UART_Device* dev); + +/*! \fn void uartgets(UART_Device* dev,char* s); + \brief Get string from given UART. + + This Function get string from the given UART. + + \param dev The UART pointer. + \param s The read string. +*/ +void uartgets(UART_Device* dev,char* s); + + +#endif diff --git a/LPP_drivers/includes/lpp_apb_functions.h b/LPP_drivers/includes/lpp_apb_functions.h --- a/LPP_drivers/includes/lpp_apb_functions.h +++ b/LPP_drivers/includes/lpp_apb_functions.h @@ -22,41 +22,114 @@ #ifndef LPP_APB_FUNCTIONS_H #define LPP_APB_FUNCTIONS_H -#define APB_TBL_HEAD 0x800FF000 -#define APB_BASE_ADDRS 0x80000000 -#define APB_MAX_DEVICES 256 +#define APB_TBL_HEAD 0x800FF000 /**< Start address of APB devices list on AHB2APB bridge*/ +#define APB_BASE_ADDRS 0x80000000 /**< Start address of APB bus*/ +#define APB_MAX_DEVICES 256 /**< Maximun device count on APB bus*/ #include "apb_devices_list.h" -/** @todo implemente a descriptor structure for any APB device */ + +/*! \file lpp_apb_functions.h + \brief General purpose APB functions. + + This library is written to work with AHB2APB VHDL module from Gaisler's GRLIB. It help you to find your device + on the APB bus by providing scan functions, it extract information such as device Version, IRQ value, Address mask. + You can use it to print the APB devices list on your SOC. + + \author Alexis Jeandet alexis.jeandet@lpp.polytechnique.fr + \todo implemente a descriptor structure for any APB device + +*/ -/** Structure representing a device descriptor register on Grlib's AHB2APB brige with plug and play feature */ +/*! \struct apbPnPreg + \brief Structure representing a device descriptor register on Grlib's AHB2APB brige with plug and play feature +*/ struct apbPnPreg { - int idReg; /**< id register composed of Vendor ID [31:24], Device ID [23:12], CT [11:10], Version [9:5], IRQ [4:0] */ - int bar; /**< Bank Address Register composed of Device's ADDRESS [31:20], MASK [14:4], TYPE [3:0] */ + int idReg; /**< \brief id register composed of Vendor ID [31:24], Device ID [23:12], CT [11:10], Version [9:5], IRQ [4:0] */ + int bar; /**< \brief Bank Address Register composed of Device's ADDRESS [31:20], MASK [14:4], TYPE [3:0] */ }; + +/*! \struct apbdevinfo + \brief Structure holding an APB device informations + + This information are extracted from the descriptor registers on Grlib's AHB2APB brige with plug and play feature +*/ struct apbdevinfo { - int vendorID; - int productID; - int version; - int irq; - int address; - int mask; + int vendorID; /**< \brief Stores the Vendor ID of the current device */ + int productID; /**< \brief Stores the Product ID of the current device */ + int version; /**< \brief Stores the Version of the current device */ + int irq; /**< \brief Stores the interrupt Number of the current device */ + int address; /**< \brief Stores the base address of the current device */ + int mask; /**< \brief Stores the address mask of the current device, it gives the address space of this device */ }; -/** This Function scans APB devices table and returns counth device according to VID and PID */ + + + +/*! \fn int* apbgetdevice(int PID,int VID,int count); + \brief Find device with given VID/PID + + This Function scans APB devices table and returns counth device according to VID and PID + + \param PID The PID of the device you whant to get. + \param VID The VID of the device you whant to get. + \param count The number of the device you whant to get. For example if you have 3 UARTS on your SOC you whant + to use UART1 so count = 2. + + \return The pointer to the device. +*/ int* apbgetdevice(int PID,int VID,int count); -/** This Function scans APB devices table and returns counth device informations according VID and PID */ + +/*! \fn void apbgetdeviceinfofromid(int PID,int VID,int count,struct apbdevinfo* devinfo); + \brief Record device informations with given VID/PID + + This Function scans APB devices table and returns counth device informations according VID and PID. + + \param PID The PID of the device you whant to get. + \param VID The VID of the device you whant to get. + \param count The number of the device you whant to get. For example if you have 3 UARTS on your SOC you whant + to use UART1 so count = 2. + \param devinfo The device information structure to be populated. + \example scanAPB.c +*/ void apbgetdeviceinfofromid(int PID,int VID,int count,struct apbdevinfo* devinfo); + +/*! \fn void apbgetdeviceinfofromdevptr(const struct apbPnPreg* dev,struct apbdevinfo* devinfo); + \brief Record device informations with given AHB2APB Plugn'Play register. + + This Function extract device informations from the given AHB2APB Plugn'Play register end write them in devinfo. + + \param dev AHB2APB Plugn'Play register corresponding to the device. + \param devinfo The device information structure to be populated. +*/ void apbgetdeviceinfofromdevptr(const struct apbPnPreg* dev,struct apbdevinfo* devinfo); + +/*! \fn void apbprintdeviceinfo(struct apbdevinfo devinfo); + \brief Print given device informations in stdout. + + \param devinfo The device information structure to be printed. +*/ void apbprintdeviceinfo(struct apbdevinfo devinfo); + + +/*! \fn void apbprintdeviceslist(); + \brief Print APB devices informations in stdout. + + This function list all devices on APB bus and print theirs informations. + + \example scanAPB.c +*/ void apbprintdeviceslist(); + + + #endif // LPP_APB_FUNCTIONS_H + diff --git a/lib/lpp/dsp/lpp_fft/APB_FFT.vhd b/lib/lpp/dsp/lpp_fft/APB_FFT.vhd --- a/lib/lpp/dsp/lpp_fft/APB_FFT.vhd +++ b/lib/lpp/dsp/lpp_fft/APB_FFT.vhd @@ -71,12 +71,13 @@ signal AddrOut : std_logic_vecto signal start : std_logic; signal load : std_logic; signal rdy : std_logic; +signal zero : std_logic; begin APB : ApbDriver generic map(pindex,paddr,pmask,pirq,abits,LPP_FFT,Data_sz,Addr_sz,addr_max_int) - port map(clk,rst,ReadEnable,WriteEnable,FlagEmpty,FlagFull,DataIn,DataOut,AddrIn,AddrOut,apbi,apbo); + port map(clk,rst,ReadEnable,WriteEnable,FlagEmpty,FlagFull,zero,DataIn,DataOut,AddrIn,AddrOut,apbi,apbo); Extremum : Flag_Extremum @@ -99,6 +100,7 @@ begin port map(clk,start,rst,WriteEnable,ReadEnable,DataIn_im,DataIn_re,load,open,DataOut_im,DataOut_re,open,rdy); start <= not rst; +zero <= '0'; DataIn_re <= DataIn(31 downto 16); DataIn_im <= DataIn(15 downto 0); diff --git a/lib/lpp/lpp_matrix/ALU_Driver.vhd b/lib/lpp/lpp_matrix/ALU_Driver.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_matrix/ALU_Driver.vhd @@ -0,0 +1,195 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2010, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------- +-- Author : Martin Morlot +-- Mail : martin.morlot@lpp.polytechnique.fr +------------------------------------------------------------------------------- +library IEEE; +use IEEE.numeric_std.all; +use IEEE.std_logic_1164.all; + +--! Driver de l'ALU + +entity ALU_Driver is + generic( + Input_SZ_1 : integer := 16; + Input_SZ_2 : integer := 16); + port( + clk : in std_logic; --! Horloge du composant + reset : in std_logic; --! Reset general du composant + IN1 : in std_logic_vector(Input_SZ_1-1 downto 0); --! Donnée d'entrée + IN2 : in std_logic_vector(Input_SZ_2-1 downto 0); --! Donnée d'entrée + Take : in std_logic; --! Flag, opérande récupéré + Received : in std_logic; --! Flag, Résultat bien ressu + Valid : out std_logic; --! Flag, Résultat disponible + Read : out std_logic; --! Flag, opérande disponible + CTRL : out std_logic_vector(4 downto 0); --! Permet de sélectionner la/les opération désirée + OP1 : out std_logic_vector(Input_SZ_1-1 downto 0); --! Premier Opérande + OP2 : out std_logic_vector(Input_SZ_2-1 downto 0) --! Second Opérande +); +end ALU_Driver; + +--! @details Les opérandes sont issue des données d'entrées et associé aux bonnes valeurs sur CTRL, les différentes opérations sont effectuées + +architecture ar_ALU_Driver of ALU_Driver is + +signal OP1re : std_logic_vector(Input_SZ_1-1 downto 0); +signal OP1im : std_logic_vector(Input_SZ_1-1 downto 0); +signal OP2re : std_logic_vector(Input_SZ_2-1 downto 0); +signal OP2im : std_logic_vector(Input_SZ_2-1 downto 0); + +signal go_st : std_logic; +signal Take_reg : std_logic; +signal Received_reg : std_logic; + +type etat is (eX,e0,e1,e2,e3,e4,e5,idle,idle2,idle3); +signal ect : etat; +signal st : etat; + +begin + process(clk,reset) + begin + + if(reset='0')then + ect <= eX; + st <= e0; + go_st <= '0'; + CTRL <= "10000"; + Read <= '0'; + Valid <= '0'; + Take_reg <= '0'; + Received_reg <= '0'; + + elsif(clk'event and clk='1')then + Take_reg <= Take; + Received_reg <= Received; + + case ect is + when eX => + go_st <= '0'; + Read <= '1'; + CTRL <= "10000"; + ect <= e0; + + when e0 => + OP1re <= IN1; + OP2re <= IN2; + if(Take_reg='0' and Take='1')then + read <= '0'; + ect <= e1; + end if; + + when e1 => + OP1 <= OP1re; + OP2 <= OP2re; + CTRL <= "00001"; + Read <= '1'; + ect <= idle; + + when idle => + OP1im <= IN1; + OP2im <= IN2; + CTRL <= "00000"; + if(Take_reg='1' and Take='0')then + Read <= '0'; + ect <= e2; + end if; + + when e2 => + OP1 <= OP1im; + OP2 <= OP2im; + CTRL <= "00001"; + ect <= idle2; + + when idle2 => + CTRL <= "00000"; + go_st <= '1'; + if(Received_reg='0' and Received='1')then + ect <= e3; + end if; + + when e3 => + CTRL <= "10000"; + go_st <= '0'; + ect <= e4; + + when e4 => + OP1 <= OP1im; + OP2 <= OP2re; + CTRL <= "00001"; + ect <= e5; + + when e5 => + OP1 <= OP1re; + OP2 <= OP2im; + CTRL <= "01001"; + ect <= idle3; + + when idle3 => + CTRL <= "00000"; + go_st <= '1'; + if(Received_reg='1' and Received='0')then + ect <= eX; + end if; + end case; + + case st is + when e0 => + if(go_st='1')then + st <= e1; + end if; + + when e1 => + Valid <= '1'; + st <= e2; + + when e2 => + if(Received_reg='0' and Received='1')then + Valid <= '0'; + st <= idle; + end if; + + when idle => + st <= e3; + + when e3 => + if(go_st='1')then + st <= e4; + end if; + + when e4 => + Valid <= '1'; + st <= e5; + + when e5 => + if(Received_reg='1' and Received='0')then + Valid <= '0'; + st <= idle2; + end if; + + when idle2 => + st <= e0; + + when others => + null; + end case; + + end if; + end process; + +end ar_ALU_Driver; \ No newline at end of file diff --git a/lib/lpp/lpp_matrix/ALU_v2.vhd b/lib/lpp/lpp_matrix/ALU_v2.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_matrix/ALU_v2.vhd @@ -0,0 +1,66 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2010, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------- +-- Author : Martin Morlot +-- Mail : martin.morlot@lpp.polytechnique.fr +------------------------------------------------------------------------------- +library IEEE; +use IEEE.numeric_std.all; +use IEEE.std_logic_1164.all; + +--! Une ALU : Arithmetic and logical unit, permettant de réaliser une ou plusieurs opération + +entity ALU_v2 is +generic( + Arith_en : integer := 1; + Logic_en : integer := 1; + Input_SZ_1 : integer := 16; + Input_SZ_2 : integer := 9); +port( + clk : in std_logic; --! Horloge du composant + reset : in std_logic; --! Reset general du composant + ctrl : in std_logic_vector(4 downto 0); --! Permet de sélectionner la/les opération désirée + OP1 : in std_logic_vector(Input_SZ_1-1 downto 0); --! Premier Opérande + OP2 : in std_logic_vector(Input_SZ_2-1 downto 0); --! Second Opérande + RES : out std_logic_vector(Input_SZ_1+Input_SZ_2-1 downto 0) --! Résultat de l'opération +); +end ALU_v2; + +--! @details Sélection grace a l'entrée "ctrl" : +--! Pause : IDLE = 00000 +--! Multiplieur/Accumulateur : MAC = 0XX01 +--! Multiplication : MULT = 0XX10 +--! Addition : ADD = 0XX11 +--! Complement a 2 : 2C = 011XX +--! Reset du MAC : CLRMAC = 10000 + +architecture ar_ALU_v2 of ALU_v2 is + +signal clr_MAC : std_logic:='1'; + +begin + +clr_MAC <= '1' when ctrl = "10000" else '0'; + +arith : if Arith_en = 1 generate +MACinst : entity work.MAC_v2 +generic map(Input_SZ_1,Input_SZ_2) +port map(clk,reset,clr_MAC,ctrl(3 downto 0),OP1,OP2,RES); +end generate; + +end ar_ALU_v2; \ No newline at end of file diff --git a/lib/lpp/lpp_matrix/APB_Matrix.vhd b/lib/lpp/lpp_matrix/APB_Matrix.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_matrix/APB_Matrix.vhd @@ -0,0 +1,138 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2010, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------ +-- Author : Martin Morlot +-- Mail : martin.morlot@lpp.polytechnique.fr +------------------------------------------------------------------------------ +library ieee; +use ieee.std_logic_1164.all; +library grlib; +use grlib.amba.all; +use grlib.stdlib.all; +use grlib.devices.all; +library lpp; +use lpp.lpp_amba.all; +use lpp.apb_devices_list.all; +use lpp.lpp_matrix.all; + +--! Driver APB, va faire le lien entre l'IP VHDL du convertisseur et le bus Amba + +entity APB_Matrix is + generic ( + pindex : integer := 0; + paddr : integer := 0; + pmask : integer := 16#fff#; + pirq : integer := 0; + abits : integer := 8); + port ( + clk : in std_logic; --! Horloge du composant + rst : in std_logic; --! Reset general du composant + apbi : in apb_slv_in_type; --! Registre de gestion des entrées du bus + apbo : out apb_slv_out_type --! Registre de gestion des sorties du bus +); +end APB_Matrix; + + +architecture ar_APB_Matrix of APB_Matrix is + +constant REVISION : integer := 1; + +constant pconfig : apb_config_type := ( + 0 => ahb_device_reg (VENDOR_LPP, LPP_MATRIX, 0, REVISION, 0), + 1 => apb_iobar(paddr, pmask)); + +type MATRIX_ctrlr_Reg is record + MATRIX_Cfg : std_logic_vector(3 downto 0); + MATRIX_INPUT1 : std_logic_vector(15 downto 0); + MATRIX_INPUT2 : std_logic_vector(15 downto 0); + MATRIX_Result : std_logic_vector(31 downto 0); +end record; + +signal Valid : std_logic; +signal Read : std_logic; +signal Take : std_logic; +signal Received : std_logic; + +signal Rec : MATRIX_ctrlr_Reg; +signal Rdata : std_logic_vector(31 downto 0); + +begin + +Take <= Rec.MATRIX_Cfg(0); +Rec.MATRIX_Cfg(1) <= Read; +Received <= Rec.MATRIX_Cfg(2); +Rec.MATRIX_Cfg(3) <= Valid; + +SPEC_MATRIX : Matrix + generic map(16) + port map(clk,rst,Rec.MATRIX_INPUT1,Rec.MATRIX_INPUT2,Take,Received,Valid,Read,Rec.MATRIX_Result); + + process(rst,clk) + begin + if(rst='0')then + Rec.MATRIX_INPUT1 <= (others => '0'); + Rec.MATRIX_INPUT2 <= (others => '0'); + Rec.MATRIX_Cfg(0) <= '0'; + Rec.MATRIX_Cfg(2) <= '0'; + + elsif(clk'event and clk='1')then + + --APB Write OP + if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then + case apbi.paddr(abits-1 downto 2) is + when "000000" => + Rec.MATRIX_Cfg(0) <= apbi.pwdata(0); + Rec.MATRIX_Cfg(2) <= apbi.pwdata(8); + when "000001" => + Rec.MATRIX_INPUT1 <= apbi.pwdata(15 downto 0); + when "000010" => + Rec.MATRIX_INPUT2 <= apbi.pwdata(15 downto 0); + when others => + null; + end case; + end if; + + --APB READ OP + if (apbi.psel(pindex) and (not apbi.pwrite)) = '1' then + case apbi.paddr(abits-1 downto 2) is + when "000000" => + Rdata(31 downto 16) <= X"CCCC"; + Rdata(15 downto 12) <= "000" & Rec.MATRIX_Cfg(3); + Rdata(11 downto 8) <= "000" & Rec.MATRIX_Cfg(2); + Rdata(7 downto 4) <= "000" & Rec.MATRIX_Cfg(1); + Rdata(3 downto 0) <= "000" & Rec.MATRIX_Cfg(0); + when "000001" => + Rdata(31 downto 16) <= X"DDDD"; + Rdata(15 downto 0) <= Rec.MATRIX_INPUT1; + when "000010" => + Rdata(31 downto 16) <= X"DDDD"; + Rdata(15 downto 0) <= Rec.MATRIX_INPUT2; + when "000011" => + Rdata(31 downto 0) <= Rec.MATRIX_Result; + when others => + Rdata <= (others => '0'); + end case; + end if; + + end if; + apbo.pconfig <= pconfig; + end process; + +apbo.prdata <= Rdata when apbi.penable = '1'; + +end ar_APB_MATRIX; \ No newline at end of file diff --git a/lib/lpp/lpp_matrix/MAC_v2.vhd b/lib/lpp/lpp_matrix/MAC_v2.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_matrix/MAC_v2.vhd @@ -0,0 +1,308 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2010, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------- +-- Author : Martin Morlot +-- Mail : martin.morlot@lpp.polytechnique.fr +------------------------------------------------------------------------------- +library IEEE; +use IEEE.numeric_std.all; +use IEEE.std_logic_1164.all; + +--! Un MAC : Multiplier Accumulator Chip + +entity MAC_v2 is +generic( + Input_SZ_A : integer := 8; + Input_SZ_B : integer := 8); +port( + clk : in std_logic; --! Horloge du composant + reset : in std_logic; --! Reset general du composant + clr_MAC : in std_logic; --! Un reset spécifique au programme + MAC_MUL_ADD_2C : in std_logic_vector(3 downto 0); --! Permet de sélectionner la/les fonctionnalité désiré + OP1 : in std_logic_vector(Input_SZ_A-1 downto 0); --! Premier Opérande + OP2 : in std_logic_vector(Input_SZ_B-1 downto 0); --! Second Opérande + RES : out std_logic_vector(Input_SZ_A+Input_SZ_B-1 downto 0) --! Résultat du MAC +); +end MAC_v2; + + +architecture ar_MAC_v2 of MAC_v2 is + + +signal add,mult : std_logic; +signal MULTout : std_logic_vector(Input_SZ_A+Input_SZ_B-1 downto 0); + +signal ADDERinA : std_logic_vector(Input_SZ_A+Input_SZ_B-1 downto 0); +signal ADDERinB : std_logic_vector(Input_SZ_A+Input_SZ_B-1 downto 0); +signal ADDERout : std_logic_vector(Input_SZ_A+Input_SZ_B-1 downto 0); + +signal MACMUXsel : std_logic; +signal OP1_Resz : std_logic_vector(Input_SZ_A+Input_SZ_B-1 downto 0); +signal OP2_Resz : std_logic_vector(Input_SZ_A+Input_SZ_B-1 downto 0); + +signal OP1_2C : std_logic_vector(Input_SZ_A-1 downto 0); +signal OP2_2C : std_logic_vector(Input_SZ_B-1 downto 0); + +signal MACMUX2sel : std_logic; + +signal add_D : std_logic; +signal OP1_2C_D : std_logic_vector(Input_SZ_A-1 downto 0); +signal OP2_2C_D : std_logic_vector(Input_SZ_B-1 downto 0); +signal MULTout_D : std_logic_vector(Input_SZ_A+Input_SZ_B-1 downto 0); +signal MACMUXsel_D : std_logic; +signal MACMUX2sel_D : std_logic; +signal MACMUX2sel_D_D : std_logic; +signal clr_MAC_D : std_logic; +signal clr_MAC_D_D : std_logic; +signal MAC_MUL_ADD_2C_D : std_logic_vector(3 downto 0); + + +begin + + + +--============================================================== +--=============M A C C O N T R O L E R========================= +--============================================================== +MAC_CONTROLER1 : entity work.MAC_CONTROLER +port map( + ctrl => MAC_MUL_ADD_2C_D(1 downto 0), + MULT => mult, + ADD => add, + MACMUX_sel => MACMUXsel, + MACMUX2_sel => MACMUX2sel + +); +--============================================================== + + + + +--============================================================== +--=============M U L T I P L I E R============================== +--============================================================== +Multiplieri_nst : entity work.Multiplier +generic map( + Input_SZ_A => Input_SZ_A, + Input_SZ_B => Input_SZ_B +) +port map( + clk => clk, + reset => reset, + mult => mult, + OP1 => OP1_2C, + OP2 => OP2_2C, + RES => MULTout +); + +--============================================================== + + + + +--============================================================== +--======================A D D E R ============================== +--============================================================== +adder_inst : entity work.Adder +generic map( + Input_SZ_A => Input_SZ_A+Input_SZ_B, + Input_SZ_B => Input_SZ_A+Input_SZ_B +) +port map( + clk => clk, + reset => reset, + clr => clr_MAC_D_D, + add => add_D, + OP1 => ADDERinA, + OP2 => ADDERinB, + RES => ADDERout +); + +--============================================================== + + + + +--============================================================== +--===================TWO COMPLEMENTERS========================== +--============================================================== +TWO_COMPLEMENTER1 : entity work.TwoComplementer +generic map( + Input_SZ => Input_SZ_A +) +port map( + clk => clk, + reset => reset, + clr => clr_MAC, + TwoComp => MAC_MUL_ADD_2C(2), + OP => OP1, + RES => OP1_2C +); + + +TWO_COMPLEMENTER2 : entity work.TwoComplementer +generic map( + Input_SZ => Input_SZ_B +) +port map( + clk => clk, + reset => reset, + clr => clr_MAC, + TwoComp => MAC_MUL_ADD_2C(3), + OP => OP2, + RES => OP2_2C +); +--============================================================== + +CTRL : entity work.MAC_REG +generic map(size => 2) +port map( + reset => reset, + clk => clk, + D => MAC_MUL_ADD_2C(1 downto 0), + Q => MAC_MUL_ADD_2C_D(1 downto 0) +); + +clr_MACREG1 : entity work.MAC_REG +generic map(size => 1) +port map( + reset => reset, + clk => clk, + D(0) => clr_MAC, + Q(0) => clr_MAC_D +); + +clr_MACREG2 : entity work.MAC_REG +generic map(size => 1) +port map( + reset => reset, + clk => clk, + D(0) => clr_MAC_D, + Q(0) => clr_MAC_D_D +); + +addREG : entity work.MAC_REG +generic map(size => 1) +port map( + reset => reset, + clk => clk, + D(0) => add, + Q(0) => add_D +); + + +OP1REG : entity work.MAC_REG +generic map(size => Input_SZ_A) +port map( + reset => reset, + clk => clk, + D => OP1_2C, + Q => OP1_2C_D +); + + +OP2REG : entity work.MAC_REG +generic map(size => Input_SZ_B) +port map( + reset => reset, + clk => clk, + D => OP2_2C, + Q => OP2_2C_D +); + + +MULToutREG : entity work.MAC_REG +generic map(size => Input_SZ_A+Input_SZ_B) +port map( + reset => reset, + clk => clk, + D => MULTout, + Q => MULTout_D +); + + +MACMUXselREG : entity work.MAC_REG +generic map(size => 1) +port map( + reset => reset, + clk => clk, + D(0) => MACMUXsel, + Q(0) => MACMUXsel_D +); + + + +MACMUX2selREG : entity work.MAC_REG +generic map(size => 1) +port map( + reset => reset, + clk => clk, + D(0) => MACMUX2sel, + Q(0) => MACMUX2sel_D +); + + +MACMUX2selREG2 : entity work.MAC_REG +generic map(size => 1) +port map( + reset => reset, + clk => clk, + D(0) => MACMUX2sel_D, + Q(0) => MACMUX2sel_D_D +); + + +--============================================================== +--======================M A C M U X =========================== +--============================================================== +MACMUX_inst : entity work.MAC_MUX +generic map( + Input_SZ_A => Input_SZ_A+Input_SZ_B, + Input_SZ_B => Input_SZ_A+Input_SZ_B + +) +port map( + sel => MACMUXsel_D, + INA1 => ADDERout, + INA2 => OP2_Resz, + INB1 => MULTout, + INB2 => OP1_Resz, + OUTA => ADDERinA, + OUTB => ADDERinB +); +OP1_Resz <= std_logic_vector(resize(signed(OP1_2C_D),Input_SZ_A+Input_SZ_B)); +OP2_Resz <= std_logic_vector(resize(signed(OP2_2C_D),Input_SZ_A+Input_SZ_B)); +--============================================================== + + +--============================================================== +--======================M A C M U X2 ========================== +--============================================================== +MAC_MUX2_inst : entity work.MAC_MUX2 +generic map(Input_SZ => Input_SZ_A+Input_SZ_B) +port map( + sel => MACMUX2sel_D_D, + RES2 => MULTout_D, + RES1 => ADDERout, + RES => RES +); + + +--============================================================== + +end ar_MAC_v2; diff --git a/lib/lpp/lpp_matrix/Matrix.vhd b/lib/lpp/lpp_matrix/Matrix.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_matrix/Matrix.vhd @@ -0,0 +1,64 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2010, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------- +-- Author : Martin Morlot +-- Mail : martin.morlot@lpp.polytechnique.fr +------------------------------------------------------------------------------- +library IEEE; +use IEEE.numeric_std.all; +use IEEE.std_logic_1164.all; + +--! Programme de calcule de Matrice Spectral, composé d'une ALU et de son Driver + +entity Matrix is + generic( + Input_SZ : integer := 16); + port( + clk : in std_logic; --! Horloge du composant + raz : in std_logic; --! Reset general du composant + IN1 : in std_logic_vector(Input_SZ-1 downto 0); --! Donnée d'entrée + IN2 : in std_logic_vector(Input_SZ-1 downto 0); --! Donnée d'entrée + Take : in std_logic; --! Flag, opérande récupéré + Received : in std_logic; --! Flag, Résultat bien ressu + Valid : out std_logic; --! Flag, Résultat disponible + Read : out std_logic; --! Flag, opérande disponible + Result : out std_logic_vector(2*Input_SZ-1 downto 0) --! Résultat du calcul +); +end Matrix; + + +architecture ar_Matrix of Matrix is + +signal CTRL : std_logic_vector(4 downto 0); +signal OP1 : std_logic_vector(Input_SZ-1 downto 0); +signal OP2 : std_logic_vector(Input_SZ-1 downto 0); + +begin + +DRIVE : entity work.ALU_Driver + generic map(Input_SZ,Input_SZ) + port map(clk,raz,IN1,IN2,Take,Received,Valid,Read,CTRL,OP1,OP2); + + +ALU : entity work.ALU_v2 + generic map(1,0,Input_SZ,Input_SZ) + port map(clk,raz,CTRL,OP1,OP2,Result); + + +end ar_Matrix; + diff --git a/lib/lpp/lpp_matrix/TwoComplementer.vhd b/lib/lpp/lpp_matrix/TwoComplementer.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_matrix/TwoComplementer.vhd @@ -0,0 +1,72 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2010, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------- +-- Author : Martin Morlot +-- Mail : martin.morlot@lpp.polytechnique.fr +------------------------------------------------------------------------------- +library IEEE; +use IEEE.numeric_std.all; +use IEEE.std_logic_1164.all; + +--! Programme permetant de complémenter ou non les entrées de l'ALU, et ainsi de travailler avec des nombres négatifs + +entity TwoComplementer is +generic( + Input_SZ : integer := 16); +port( + clk : in std_logic; --! Horloge du composant + reset : in std_logic; --! Reset general du composant + clr : in std_logic; --! Un reset spécifique au programme + TwoComp : in std_logic; --! Autorise l'utilisation du complément + OP : in std_logic_vector(Input_SZ-1 downto 0); --! Opérande d'entrée + RES : out std_logic_vector(Input_SZ-1 downto 0) --! Résultat, opérande complémenté ou non +); +end TwoComplementer; + + +architecture ar_TwoComplementer of TwoComplementer is + +signal REG : std_logic_vector(Input_SZ-1 downto 0); +signal OPinteger : integer; +signal RESCOMP : std_logic_vector(Input_SZ-1 downto 0); + +begin + +RES <= REG; +OPinteger <= to_integer(signed(OP)); +RESCOMP <= std_logic_vector(to_signed(-OPinteger,Input_SZ)); + + process(clk,reset) + begin + + if(reset='0')then + REG <= (others => '0'); + elsif(clk'event and clk='1')then + + if(clr='1')then + REG <= (others => '0'); + elsif(TwoComp='1')then + REG <= RESCOMP; + else + REG <= OP; + end if; + + end if; + + end process; +end ar_TwoComplementer; \ No newline at end of file diff --git a/lib/lpp/lpp_matrix/lpp_matrix.vhd b/lib/lpp/lpp_matrix/lpp_matrix.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_matrix/lpp_matrix.vhd @@ -0,0 +1,133 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2010, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------ +-- Author : Martin Morlot +-- Mail : martin.morlot@lpp.polytechnique.fr +------------------------------------------------------------------------------ +library ieee; +use ieee.std_logic_1164.all; +library grlib; +use grlib.amba.all; +use std.textio.all; +library lpp; +use lpp.lpp_amba.all; + +--! Package contenant tous les programmes qui forment le composant intégré dans le léon + +package lpp_matrix is + +component APB_Matrix is + generic ( + pindex : integer := 0; + paddr : integer := 0; + pmask : integer := 16#fff#; + pirq : integer := 0; + abits : integer := 8); + port ( + clk : in std_logic; --! Horloge du composant + rst : in std_logic; --! Reset general du composant + apbi : in apb_slv_in_type; --! Registre de gestion des entrées du bus + apbo : out apb_slv_out_type --! Registre de gestion des sorties du bus +); +end component; + + +component Matrix is + generic( + Input_SZ : integer := 16); + port( + clk : in std_logic; + raz : in std_logic; + IN1 : in std_logic_vector(Input_SZ-1 downto 0); + IN2 : in std_logic_vector(Input_SZ-1 downto 0); + Take : in std_logic; + Received : in std_logic; + Valid : out std_logic; + Read : out std_logic; + Result : out std_logic_vector(2*Input_SZ-1 downto 0) +); +end component; + + +component ALU_Driver is + generic( + Input_SZ_1 : integer := 16; + Input_SZ_2 : integer := 16); + port( + clk : in std_logic; + reset : in std_logic; + IN1 : in std_logic_vector(Input_SZ_1-1 downto 0); + IN2 : in std_logic_vector(Input_SZ_2-1 downto 0); + Take : in std_logic; + Received : in std_logic; + Valid : out std_logic; + Read : out std_logic; + CTRL : out std_logic_vector(4 downto 0); + OP1 : out std_logic_vector(Input_SZ_1-1 downto 0); + OP2 : out std_logic_vector(Input_SZ_2-1 downto 0) +); +end component; + + +component ALU_v2 is +generic( + Arith_en : integer := 1; + Logic_en : integer := 1; + Input_SZ_1 : integer := 16; + Input_SZ_2 : integer := 9); +port( + clk : in std_logic; + reset : in std_logic; + ctrl : in std_logic_vector(4 downto 0); + OP1 : in std_logic_vector(Input_SZ_1-1 downto 0); + OP2 : in std_logic_vector(Input_SZ_2-1 downto 0); + RES : out std_logic_vector(Input_SZ_1+Input_SZ_2-1 downto 0) +); +end component; + + +component MAC_v2 is +generic( + Input_SZ_A : integer := 8; + Input_SZ_B : integer := 8); +port( + clk : in std_logic; + reset : in std_logic; + clr_MAC : in std_logic; + MAC_MUL_ADD_2C : in std_logic_vector(3 downto 0); + OP1 : in std_logic_vector(Input_SZ_A-1 downto 0); + OP2 : in std_logic_vector(Input_SZ_B-1 downto 0); + RES : out std_logic_vector(Input_SZ_A+Input_SZ_B-1 downto 0) +); +end component; + + +component TwoComplementer is +generic( + Input_SZ : integer := 16); +port( + clk : in std_logic; + reset : in std_logic; + clr : in std_logic; + TwoComp : in std_logic; + OP : in std_logic_vector(Input_SZ-1 downto 0); + RES : out std_logic_vector(Input_SZ-1 downto 0) +); +end component; + +end; \ No newline at end of file diff --git a/lib/lpp/lpp_memory/APB_FIFO.vhd b/lib/lpp/lpp_memory/APB_FIFO.vhd --- a/lib/lpp/lpp_memory/APB_FIFO.vhd +++ b/lib/lpp/lpp_memory/APB_FIFO.vhd @@ -57,6 +57,7 @@ signal ReadEnable : std_logic; signal WriteEnable : std_logic; signal FlagEmpty : std_logic; signal FlagFull : std_logic; +signal ReUse : std_logic; signal DataIn : std_logic_vector(Data_sz-1 downto 0); signal DataOut : std_logic_vector(Data_sz-1 downto 0); signal AddrIn : std_logic_vector(Addr_sz-1 downto 0); @@ -66,12 +67,12 @@ begin APB : ApbDriver generic map(pindex,paddr,pmask,pirq,abits,LPP_FIFO,Data_sz,Addr_sz,addr_max_int) - port map(clk,rst,ReadEnable,WriteEnable,FlagEmpty,FlagFull,DataIn,DataOut,AddrIn,AddrOut,apbi,apbo); + port map(clk,rst,ReadEnable,WriteEnable,FlagEmpty,FlagFull,ReUse,DataIn,DataOut,AddrIn,AddrOut,apbi,apbo); DEVICE : Top_FIFO generic map(Data_sz,Addr_sz,addr_max_int) - port map(clk,rst,ReadEnable,WriteEnable,DataIn,AddrOut,AddrIn,FlagFull,FlagEmpty,DataOut); + port map(clk,rst,ReadEnable,WriteEnable,ReUse,DataIn,AddrOut,AddrIn,FlagFull,FlagEmpty,DataOut); end ar_APB_FIFO; \ No newline at end of file diff --git a/lib/lpp/lpp_memory/ApbDriver.vhd b/lib/lpp/lpp_memory/ApbDriver.vhd --- a/lib/lpp/lpp_memory/ApbDriver.vhd +++ b/lib/lpp/lpp_memory/ApbDriver.vhd @@ -49,6 +49,7 @@ entity ApbDriver is WriteEnable : out std_logic; --! Instruction d'écriture en mémoire FlagEmpty : in std_logic; --! Flag, Mémoire vide FlagFull : in std_logic; --! Flag, Mémoire pleine + ReUse : out std_logic; --! Flag, Permet de relire la mémoire du début DataIn : out std_logic_vector(Data_sz-1 downto 0); --! Registre de données en entrée DataOut : in std_logic_vector(Data_sz-1 downto 0); --! Registre de données en sortie AddrIn : in std_logic_vector(Addr_sz-1 downto 0); --! Registre d'addresse (écriture) @@ -69,7 +70,7 @@ constant pconfig : apb_config_type := ( 1 => apb_iobar(paddr, pmask)); type DEVICE_ctrlr_Reg is record - DEVICE_Cfg : std_logic_vector(3 downto 0); + DEVICE_Cfg : std_logic_vector(4 downto 0); DEVICE_DataW : std_logic_vector(Data_sz-1 downto 0); DEVICE_DataR : std_logic_vector(Data_sz-1 downto 0); DEVICE_AddrW : std_logic_vector(Addr_sz-1 downto 0); @@ -88,6 +89,7 @@ Rec.DEVICE_Cfg(0) <= FlagRE; Rec.DEVICE_Cfg(1) <= FlagWR; Rec.DEVICE_Cfg(2) <= FlagEmpty; Rec.DEVICE_Cfg(3) <= FlagFull; +ReUse <= Rec.DEVICE_Cfg(4); DataIn <= Rec.DEVICE_DataW; Rec.DEVICE_DataR <= DataOut; @@ -102,6 +104,7 @@ Rec.DEVICE_AddrR <= AddrOut; Rec.DEVICE_DataW <= (others => '0'); FlagWR <= '0'; FlagRE <= '0'; + Rec.DEVICE_Cfg(4) <= '0'; elsif(clk'event and clk='1')then @@ -111,6 +114,8 @@ Rec.DEVICE_AddrR <= AddrOut; when "000000" => FlagWR <= '1'; Rec.DEVICE_DataW <= apbi.pwdata(Data_sz-1 downto 0); + when "000010" => + Rec.DEVICE_Cfg(4) <= apbi.pwdata(16); when others => null; end case; @@ -135,7 +140,8 @@ Rec.DEVICE_AddrR <= AddrOut; Rdata(7 downto 4) <= "000" & Rec.DEVICE_Cfg(1); Rdata(11 downto 8) <= "000" & Rec.DEVICE_Cfg(2); Rdata(15 downto 12) <= "000" & Rec.DEVICE_Cfg(3); - Rdata(31 downto 16) <= X"CCCC"; + Rdata(19 downto 16) <= "000" & Rec.DEVICE_Cfg(4); + Rdata(31 downto 20) <= X"CCC"; when others => Rdata <= (others => '0'); end case; diff --git a/lib/lpp/lpp_memory/Fifo_Read.vhd b/lib/lpp/lpp_memory/Fifo_Read.vhd --- a/lib/lpp/lpp_memory/Fifo_Read.vhd +++ b/lib/lpp/lpp_memory/Fifo_Read.vhd @@ -32,6 +32,7 @@ generic( port( clk,raz : in std_logic; --! Horloge et reset general du composant flag_RE : in std_logic; --! Flag, Demande la lecture de la mémoire + ReUse : in std_logic; --! Flag, Permet de relire la mémoire du début Waddr : in std_logic_vector(addr_sz-1 downto 0); --! Adresse du registre d'écriture dans la mémoire empty : out std_logic; --! Flag, Mémoire vide Raddr : out std_logic_vector(addr_sz-1 downto 0) --! Adresse du registre de lecture de la mémoire @@ -59,6 +60,7 @@ begin Wad_int_reg <= Wad_int; Rad_int_reg <= Rad_int; flag_reg <= flag_RE; + if(flag_reg ='0' and flag_RE='1')then if(Rad_int=addr_max_int-1)then @@ -68,15 +70,21 @@ begin end if; end if; - if(Rad_int_reg /= Rad_int)then - if(Rad_int=Wad_int)then - empty <= '1'; - else + if(ReUse='1')then + Rad_int <= 0; + empty <= '0'; + else + if(Rad_int_reg /= Rad_int)then + if(Rad_int=Wad_int)then + empty <= '1'; + else + empty <= '0'; + end if; + elsif(Wad_int_reg /= Wad_int)then empty <= '0'; - end if; - elsif(Wad_int_reg /= Wad_int)then - empty <= '0'; + end if; end if; + end if; end process; diff --git a/lib/lpp/lpp_memory/Link_Reg.vhd b/lib/lpp/lpp_memory/Link_Reg.vhd --- a/lib/lpp/lpp_memory/Link_Reg.vhd +++ b/lib/lpp/lpp_memory/Link_Reg.vhd @@ -32,6 +32,7 @@ port( clk,raz : in std_logic; --! Horloge et reset general du composant Data_one : in std_logic_vector(Data_sz-1 downto 0); --! Donnée en entrée de la FIFO, coté écriture Data_two : in std_logic_vector(Data_sz-1 downto 0); --! Donnée en sortie de la FIFO, coté lecture + ReUse : in std_logic; --! Flag, Permet de relire la mémoire du début flag_RE : in std_logic; --! Flag, Demande la lecture de la mémoire flag_WR : in std_logic; --! Flag, Demande l'écriture dans la mémoire empty : in std_logic; --! Flag, Mémoire vide @@ -57,6 +58,8 @@ begin if(flag_WR='1')then Data_out <= Data_one; ect <= e1; + elsif(ReUse='1')then + ect <= e1; end if; when e1 => diff --git a/lib/lpp/lpp_memory/Top_FIFO.vhd b/lib/lpp/lpp_memory/Top_FIFO.vhd --- a/lib/lpp/lpp_memory/Top_FIFO.vhd +++ b/lib/lpp/lpp_memory/Top_FIFO.vhd @@ -39,6 +39,7 @@ entity Top_FIFO is clk,raz : in std_logic; --! Horloge et reset general du composant flag_RE : in std_logic; --! Flag, Demande la lecture de la mémoire flag_WR : in std_logic; --! Flag, Demande l'écriture dans la mémoire + ReUse : in std_logic; --! Flag, Permet de relire la mémoire du début Data_in : in std_logic_vector(Data_sz-1 downto 0); --! Data en entrée du composant Addr_RE : out std_logic_vector(addr_sz-1 downto 0); --! Adresse d'écriture Addr_WR : out std_logic_vector(addr_sz-1 downto 0); --! Adresse de lecture @@ -88,11 +89,11 @@ begin link : Link_Reg generic map(Data_sz) - port map(clk,raz,Data_in,Data_int,s_flag_RE,s_flag_WR,s_empty,Data_out); + port map(clk,raz,Data_in,Data_int,ReUse,s_flag_RE,s_flag_WR,s_empty,Data_out); RE : Fifo_Read generic map(Addr_sz,addr_max_int) - port map(clk,raz,s_flag_RE,Waddr,s_empty,Raddr); + port map(clk,raz,s_flag_RE,ReUse,Waddr,s_empty,Raddr); process(clk,raz) begin diff --git a/lib/lpp/lpp_memory/lpp_memory.vhd b/lib/lpp/lpp_memory/lpp_memory.vhd --- a/lib/lpp/lpp_memory/lpp_memory.vhd +++ b/lib/lpp/lpp_memory/lpp_memory.vhd @@ -72,6 +72,7 @@ component ApbDriver is WriteEnable : in std_logic; FlagEmpty : in std_logic; FlagFull : in std_logic; + ReUse : in std_logic; DataIn : out std_logic_vector(Data_sz-1 downto 0); DataOut : in std_logic_vector(Data_sz-1 downto 0); AddrIn : in std_logic_vector(Addr_sz-1 downto 0); @@ -92,6 +93,7 @@ component Top_FIFO is clk,raz : in std_logic; flag_RE : in std_logic; flag_WR : in std_logic; + ReUse : in std_logic; Data_in : in std_logic_vector(Data_sz-1 downto 0); Addr_RE : out std_logic_vector(addr_sz-1 downto 0); Addr_WR : out std_logic_vector(addr_sz-1 downto 0); @@ -110,6 +112,7 @@ component Fifo_Read is clk : in std_logic; raz : in std_logic; flag_RE : in std_logic; + ReUse : in std_logic; Waddr : in std_logic_vector(addr_sz-1 downto 0); empty : out std_logic; Raddr : out std_logic_vector(addr_sz-1 downto 0) @@ -138,6 +141,7 @@ component Link_Reg is clk,raz : in std_logic; Data_one : in std_logic_vector(Data_sz-1 downto 0); Data_two : in std_logic_vector(Data_sz-1 downto 0); + ReUse : in std_logic; flag_RE : in std_logic; flag_WR : in std_logic; empty : in std_logic;