----------------------------------------------------------------------------------
-- Module Name: RAM - Behavioral
-- Project Name:
-- Target Devices: Cyclone
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- THIS piece of code is ABOUT THE RAM STORAGE PROCESS..
-- An adress is given by an external modulus, and an incrementation of 1 is done time a specific adress is accessed
-- tHE READING OPERATION IS ONLY DONE WHEN THE COMPUTER ASKS IT, WHEN WE WANT TO CHECK OUT WHAT IS IN THE RAM. The reading
-- Operation is done from the adress number 0 to the last adress, in one time, and checking successively each adress after another.
-- Every time a process is ended (reading or writting), it sends a flag to the controller, designed in VHDL, telling him that
-- the operation is over. When is time
---
---
--- __________ ____________
--- | adress | adress |____________|
--- | sender |-----------> |____________| datas
--- |_________| write |____________|-----------> to computer
--- |____________| read
--- |____________|
-- RAM BLOCK
------------------------------------------------------------------------------------------------------------------------------
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
-----------------------------------------------------------------------------------------------------------------------------
--
entity Bram is
generic (
width_in : integer := 8; --Width of data
addr_bits : integer := 11 --Depth of data (2^10 = 1024 addresses)
);
port (
clk : in std_logic; --System clock
rst : in std_logic; --System Reset
addr_out : in std_logic_vector (addr_bits - 1 downto 0); --Output Adress
fx_clock : in std_logic;
addr_in : in std_logic_vector (addr_bits - 1 downto 0); --Input Adresse
din_valid : in std_logic; --Input Adress Validation
finish : out std_logic; --Finish Signal
data_out : out unsigned (width_in - 1 downto 0); --Outut Adress Validation
dout_valid : out std_logic ; --Data Out Validation
aout_valid : in std_logic --Adress Out Validaion
);
end entity Bram;
architecture arc_ram_simple of Bram is
------------------ Types ------
type ram_arr is array (natural range <> ) of unsigned (width_in - 1 downto 0);
------------------ Signals ------
signal ram_data : ram_arr (0 to 2**addr_bits - 1):=(others =>(others =>'0'));
signal flag_wr : std_logic;
signal flag_rd : std_logic;
signal addr_ou : unsigned (width_in - 1 downto 0):=(others => '0');
------------------ Implementation ------
begin
----------------------------------------------------------------------------------------------------------------------
--------- Process din_proc -----------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------
-- This is the process which writes the data to the specific
-- adress sent by an externl modulus at Rising_edge
-- ------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------
din_proc : process (clk)
begin
if rising_edge(clk) then
if din_valid = '1' then
if(ram_data (conv_integer(unsigned(addr_in))) = 200) then
ram_data (conv_integer(unsigned(addr_in))) <=(others =>'0');
else
ram_data (conv_integer(unsigned(addr_in))) <= ram_data (conv_integer(unsigned(addr_in))) + 1;
flag_wr <= '1';
end if;
else
flag_wr <= '0';
end if;
end if;
end process din_proc;
-----------------------------------------------------------------------------------------------------------------------------------
--------- Process dout_proc ---------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------
-- The process' output is the required
-- data from a given address, when the
-- given address is valid.
----------------------------------------------------------------------------------------------------------------------------------
dout_proc : process (clk)
begin
if rising_edge(clk) then
if aout_valid = '1' then --Output address is valid
data_out <= ram_data (conv_integer(unsigned(addr_ou)));
flag_rd <= '1';
else
flag_rd <= '0';
end if;
end if;
end process dout_proc;
--------------------------------------------------------------------------------------------------------------------------
--- This is the process which sets the adress that shall be read
--- The adresses are read in line, one after another uninterruptedly
-----------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------
aout_procc : process (clk, addr_ou)
begin
if rising_edge(clk) then
if ((aout_valid = '1') and (addr_ou = 255))then
addr_ou <= (others=>'0');
else
if((aout_valid = '0'))then
addr_ou <= (others=>'0');
else
addr_ou <= addr_ou + 1;
end if;
end if;
end if;
end process aout_procc;
--------------------------------------------------------------------------------------------------------------------------
-- Set the signal to the controller, telling him that a writting operation or a reading is finished
----------------------------------------------------------------------------------------------------------------------------
finishion : process (clk)
begin
if rising_edge(clk) then
if( flag_rd ='1' or flag_wr='1')then
finish <= '1';
else
finish <= '0';
end if;
end if;
end process finishion;
-----------------------------------------------------------------------------------------------------------------------------
------- Process data_out_valid_proc ------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
-- Process telling that the datas are good
-- --------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
data_out_valid_proc : process (clk, rst)
begin
if (rst = '1') then --System Reset
dout_valid <= '0';
elsif rising_edge(clk) then
dout_valid <= aout_valid;
end if;
end process data_out_valid_proc;
end architecture arc_ram_simple;
library IEEE;
Library altera_mf;
USE altera_mf.altera_mf_components.all;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use ieee.std_logic_signed.all;
use ieee. math_real.all;
entity distributeur is
generic(
ADDRESS_WIDTH : integer := 11;
Lattency : integer := 2;
DATA_WIDTH : integer := 8;
DATA_OU_WIDTH : integer := 8
);
Port ( Clock : in std_logic; -- Horloge de la RAM 100Mhz
fx_clock : In std_logic; -- Horloge du fx2 48mhz
Data_in : in std_logic_vector (ADDRESS_WIDTH-1 downto 0) :=(others =>'0');
fin_lecture_perm : In std_logic;
demande_lecture_perm : In std_logic;
Data_out : out std_logic_vector (DATA_OU_WIDTH-1 downto 0));
end distributeur;
architecture Behavioral of distributeur is
type ETAT is (Ecriture,Lecture_perm, ready); -- Variable des états de la mémoire
Signal State : ETAT := Ready;
Signal a: unsigned(7 downto 0) := (others=>'0');
Signal b: unsigned(4 downto 0);
Signal reset: std_logic := '0';
Signal horlogue: std_logic := '0';
signal compteur : unsigned (2 downto 0);
Signal pass_adress: std_logic := '0';
signal rd_en : std_logic :='0';
signal wr_en : std_logic :='1';
signal wr_adress : unsigned(ADDRESS_WIDTH - 1 DOWNTO 0);
Signal write_address : std_logic_vector(ADDRESS_WIDTH - 1 DOWNTO 0);
signal read_address : std_logic_vector(ADDRESS_WIDTH - 1 DOWNTO 0);
signal adress_lec_perm : std_logic_vector(ADDRESS_WIDTH - 1 DOWNTO 0);
signal DATA : std_logic_vector(DATA_WIDTH - 1 DOWNTO 0) := (others =>'0');
signal DAT : std_logic_vector(DATA_WIDTH - 1 DOWNTO 0) := (others =>'0');
signal Sortie : std_logic_vector(DATA_WIDTH - 1 DOWNTO 0);
signal val_lue : std_logic_vector(DATA_WIDTH - 1 DOWNTO 0):=(others =>'0');
signal sort : std_logic_vector(DATA_WIDTH - 1 DOWNTO 0);
signal rd_adres_interm : std_logic_vector(11 downto 0);
signal fin_lecture: std_logic;
signal fx_clock_ena: std_logic :='1';
signal fin_lecture_clk2: std_logic;
--------------------------- HERE IS THE ALTSYNCRAM USED FOR DATA STORAGE------------------------------------------
------ IT IS A BIDIR DUAL PORT RAM where read and write can be operated at the same time
------ it possesses two adresses one for the port A and another one for the port B
------two different clocks are used for read and write
---------------------------------------------------------------------------------------------------------
COMPONENT altsyncram
GENERIC
(OPERATION_MODE : STRING := "BIDIR_DUAL_PORT";
WIDTH_A : INTEGER := DATA_WIDTH; -- 1;
WIDTHAD_A : INTEGER := ADDRESS_WIDTH; -- 1;
NUMWORDS_A : INTEGER := 2**ADDRESS_WIDTH; -- 1;
OUTDATA_REG_A : STRING := "CLOCK0";
ADDRESS_ACLR_A : STRING := "NONE";
OUTDATA_ACLR_A : STRING := "NONE";
INDATA_ACLR_A : STRING := "NONE";
WRCONTROL_ACLR_A : STRING := "NONE";
BYTEENA_ACLR_A : STRING := "NONE";
WIDTH_BYTEENA_A : INTEGER := DATA_WIDTH;
WIDTH_B : INTEGER := DATA_WIDTH; -- 1;
WIDTHAD_B : INTEGER := ADDRESS_WIDTH; -- 1;
NUMWORDS_B : INTEGER := 2**ADDRESS_WIDTH; -- 1;
RDCONTROL_REG_B : STRING := "CLOCK1";
ADDRESS_REG_B : STRING := "CLOCK1";
INDATA_REG_B : STRING := "CLOCK1";
WRCONTROL_WRADDRESS_REG_B : STRING := "CLOCK1";
BYTEENA_REG_B : STRING := "CLOCK1";
OUTDATA_REG_B : STRING := "UNREGISTERED";
OUTDATA_ACLR_B : STRING := "NONE";
RDCONTROL_ACLR_B : STRING := "NONE";
INDATA_ACLR_B : STRING := "NONE";
WRCONTROL_ACLR_B : STRING := "NONE";
ADDRESS_ACLR_B : STRING := "NONE";
BYTEENA_ACLR_B : STRING := "NONE";
WIDTH_BYTEENA_B : INTEGER := DATA_WIDTH;
BYTE_SIZE : INTEGER := DATA_WIDTH;
READ_DURING_WRITE_MODE_MIXED_PORTS : STRING := "DONT_CARE";
RAM_BLOCK_TYPE : STRING := "M4K";
INIT_FILE : STRING := "UNUSED";
INIT_FILE_LAYOUT : STRING := "PORT_A";
MAXIMUM_DEPTH : INTEGER := 2048;
INTENDED_DEVICE_FAMILY : STRING := "Cyclone";
LPM_HINT : STRING := "BOGUS");
PORT ( wren_a : IN STD_LOGIC := '0';
rden_b, clock0, clock1, clocken1 : IN STD_LOGIC := '1';
data_a : IN STD_LOGIC_VECTOR(WIDTH_A - 1 DOWNTO 0):= (OTHERS => '0');
address_a : IN STD_LOGIC_VECTOR(WIDTHAD_A - 1 DOWNTO 0) := (OTHERS => '0');
address_b : IN STD_LOGIC_VECTOR(WIDTHAD_B - 1 DOWNTO 0) := (OTHERS => '0');
q_a : OUT STD_LOGIC_VECTOR(WIDTH_A - 1 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR(WIDTH_B - 1 DOWNTO 0));
END COMPONENT;
begin
ram: altsyncram port map
(
clock0 => clock,
clock1 => fx_clock,
data_a => data,
clocken1 => fx_clock_ena,
address_a => write_address,
address_b => read_address,
wren_a => wr_en,
rden_b => rd_en,
q_a => sortie,
q_b => sort
);
----------------------- THE RAM STATE MACHINE -----------------------------------------------
-------------- It uses the slowest of both clocks, the fx_clock
-------------- Starts with writting and when reading is asked (demand_lecture_perm ='1') then it performs reading, but reading
-------------- only, and stops writting.In the end (fin_lecture_perm = '1'),we go back to the state READY,the writting
-------------- the state "Ready" is used for lattency, and worth a clock top.
-------------------------------------------------------------------------------------------------------------------------
Histogram_state_machine: process(fx_Clock)
begin
if(falling_edge(fx_Clock)) then
--Etat 1 de la mémoire: Si elle est occupée
--------------------------------------------
Case State is
--Etat 2 de la mémoire: lorsqu'elle est libre
---------------------------------------------
when ready =>
State <= Ecriture;
--Etat 2 de la mémoire: En lecture
---------------------------------------------
when Ecriture =>
if( demande_lecture_perm = '1') then
State <= lecture_perm ;
else
State <= Ecriture;
end if;
when lecture_perm =>
if(fin_lecture_perm = '1') then
State <= Ready;
else
State <= lecture_perm ;
end if;
end case;
end if;
end process;
-------------------------------READING PROCESS OF THE RAM --------------------------------------------
---------------- La RAM est lue de la première adresse à la dernière, successivement et sans intérruption
---------------- Cette incrémentation de l'adresse de lecture n'est faite que lorsque l'on est à l'état de
---------------- "lecture permanente". On revient à zero lorsque la dernière case de la mémoire est atteinte
-------------------------------------------------------------------------------------------------------------
process(fx_clock, read_address, compteur)
begin
if(rising_edge(fx_clock)) then
if ( state = Lecture_perm ) then
if( read_address = 2047 ) then
read_address <=(others =>'0');
else
read_address <= read_address + 1;
end if;
else
read_address <=(others =>'0');
end if;
end if;
end process;
data_out <= sort; ----- Donnée en sortie de la mémoire vers le module de communication
write_address <= Data_in; ----- L'adresse d'écriture corresponds au port "Data_in" à tout instant
Data <= sortie + 1 ; ----- Les données écrite à une adresse précise (write adress) sont: le résultat renvoyé deouis l'adresse en question, incrémenté de 1
with state select
wr_en <= '1' when Ecriture, ----- Permission d'écrire uniquement losque l'on est en mode écriture
'0' when others;
--Data_in(ADDRESS_WIDTH-1 downto 3);
end Behavioral;
if rising_edge(clk) then
...
if(ram_data (conv_integer(unsigned(addr_in))) = 200) then
ram_data (conv_integer(unsigned(addr_in))) <=(others =>'0');
else
ram_data (conv_integer(unsigned(addr_in))) <= ram_data (conv_integer(unsigned(addr_in))) +1;
flag_wr <= '1';
end if;
....
PORT ( wren_a : IN STD_LOGIC := '0';
clock0 : IN STD_LOGIC := '1';
data_a : IN STD_LOGIC_VECTOR(WIDTH_A - 1 DOWNTO 0):= (OTHERS => '0');
address_a : IN STD_LOGIC_VECTOR(WIDTHAD_A - 1 DOWNTO 0) := (OTHERS => '0');
q_a : OUT STD_LOGIC_VECTOR(WIDTH_A - 1 DOWNTO 0));
END COMPONENT;
begin
ram: altsyncram port map
(
clock0 => clock,
data_a => Data,
address_a => write_address,
wren_a => wr_en,
q_a => Sortie
);
----------------------- MACHINE D'ETAT DE LA RAM -----------------------------------------------
-------------- Elle change sous front montant de fx_clock
-------------- Au début elle commence en écriture
-------------- Ensuite, lorsqu'il y a demande d'une lecture (demande_lecture_perm ='1'), elle se met en mode lecture
-------------- seule et arrete d'écrite. Lorsque c'est fini (fin_lecture_perm = '1'), on repasse à l'etat ready, puis lecture
-------------- L'etat "Ready" sert ici d'étape créant une lattance équivalent à un coup d'horloge
-------------------------------------------------------------------------------------------------------------------------
------------------------------- Processus de Lecture de La RAM --------------------------------------------
---------------- La RAM est lue de la première adresse à la dernière, successivement et sans intérruption
---------------- Cette incrémentation de l'adresse de lecture n'est faite que lorsque l'on est à l'état de
---------------- "lecture permanente". On revient à zero lorsque la dernière case de la mémoire est atteinte
-------------------------------------------------------------------------------------------------------------
State_machine: process (clock)
begin
if(rising_edge(clock)) then
case state is
when Ready =>
if(signal_ent ='1') then
state <= lattence_1;
else
state <= Ready;
end if;
when lattence_1 =>
state <= Lecture;
when Lecture =>
if(demande_lecture_perm ='1') then
state <= Lattence_2;
else
state <= Ecriture;
end if;
when Ecriture =>
state <= Ready;
when lattence_2 =>
state <= Ecriture;
end case;
end if;
end process;
DATA <= sortie + 1 when state = Ecriture else
(others =>'0');
wr_en <= '1' when state= Ecriture else '0';
WR_ENA <= wr_en;
Data_out <= sortie;
end Behavioral;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?