Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- library ieee;
- use ieee.std_logic_1164.ALL;
- use ieee.numeric_std.ALL;
- entity DualOperationRAM is
- generic (
- ram_addressWidth : positive := 13;
- ram_dataWidth : positive := 32;
- ram_byteenableWidth : positive := 4
- );
- port (
- ram_doubleClk : in std_logic;
- ram_address : out std_logic_vector( (ram_addressWidth-1) downto 0);
- ram_chipselect : out std_logic;
- ram_write : out std_logic;
- ram_readdata : in std_logic_vector( (ram_dataWidth-1) downto 0);
- ram_writedata : out std_logic_vector( (ram_dataWidth-1) downto 0);
- ram_byteenable : out std_logic_vector( (ram_byteenableWidth-1) downto 0);
- ram_clken : out std_logic;
- dualOperationRam_writeClk : in std_logic;
- dualOperationRam_write : in std_logic;
- dualOperationRam_writeAddress : in std_logic_vector( (ram_addressWidth-1) downto 0);
- dualOperationRam_writedata : in std_logic_vector( (ram_dataWidth-1) downto 0);
- dualOperationRam_writebyteenable: in std_logic_vector( (ram_byteenableWidth-1) downto 0);
- dualOperationRam_readClk : in std_logic;
- dualOperationRam_read : in std_logic;
- dualOperationRam_readAddress : in std_logic_vector( (ram_addressWidth-1) downto 0);
- dualOperationRam_readdata : out std_logic_vector( (ram_dataWidth-1) downto 0);
- dualOperationRam_readbyteenable : in std_logic_vector( (ram_byteenableWidth-1) downto 0)
- );
- end entity;
- architecture Test of DualOperationRAM is
- constant writeOperation : std_logic := '0';
- constant readOperation : std_logic := '1';
- signal operation : std_logic := writeOperation;
- signal readRequest : std_logic := '0';
- signal writeRequest : std_logic := '0';
- signal writeMask : std_logic := '0';
- signal readMask : std_logic := '0';
- signal read_q : std_logic_vector( (ram_dataWidth-1) downto 0) := (others => '0');
- begin
- -- Write/Read switch (na zmianę read/write)
- process(ram_doubleClk)
- begin
- if (rising_edge(ram_doubleClk)) then
- if (operation = readOperation) then
- operation <= writeOperation;
- else
- operation <= readOperation;
- end if;
- end if;
- end process;
- -- Holding write request until write cycle
- process(ram_doubleClk)
- begin
- if (rising_edge(ram_doubleClk)) then
- -- Kiedy wystawiono chęć zapisana, kiedy zegar zapisywania jest w stanie wysokim
- -- (aby uniknąc ponownego żądania zapisania, pojawiała się taka sytuacja bez drugiego warunku,
- -- bo maska "writeMask" jest zerowana gdy stan zegara przejdzie na 0)
- -- oraz kiedy maska jest równa 0 - aby nie wykonało dwóch żądań zapisu
- if (dualOperationRam_write = '1' and dualOperationRam_writeClk = '1' and writeMask = '0') then
- writeRequest <= '1';
- writeMask <= '1';
- elsif (operation = writeOperation) then
- writeRequest <= '0';
- end if;
- if (dualOperationRam_writeClk = '0' and writeRequest = '0') then
- writeMask <= '0';
- end if;
- end if;
- end process;
- -- Holding read request until read cycle
- process(ram_doubleClk)
- begin
- if (rising_edge(ram_doubleClk)) then
- -- Analogicznie jak przy zapisie
- if (dualOperationRam_read = '1' and dualOperationRam_readClk = '1' and readMask = '0') then
- readRequest <= '1';
- readMask <= '1';
- elsif (operation = readOperation) then
- readRequest <= '0';
- end if;
- if (dualOperationRam_readClk = '0' and readRequest = '0') then
- readMask <= '0';
- end if;
- end if;
- end process;
- -- Read data output
- process(dualOperationRam_readClk)
- begin
- if (rising_edge(dualOperationRam_readClk)) then
- dualOperationRam_readdata <= read_q;
- end if;
- end process;
- -- Transfering data to RAM
- process(ram_doubleClk)
- variable readPerformed : std_logic := '0';
- variable read_q_prepare : std_logic := '0';
- begin
- if (rising_edge(ram_doubleClk)) then
- if (readRequest = '1' and operation = readOperation) then
- ram_chipselect <= '1';
- ram_clken <= '1';
- ram_write <= '0';
- ram_address <= dualOperationRam_readAddress;
- ram_writedata <= (others => '0');
- ram_byteenable <= dualOperationRam_readbyteenable;
- readPerformed := '1';
- elsif (writeRequest= '1' and operation = writeOperation) then
- ram_chipselect <= '1';
- ram_write <= '1';
- ram_clken <= '1';
- ram_address <= dualOperationRam_writeAddress;
- ram_writedata <= dualOperationRam_writedata;
- ram_byteenable <= dualOperationRam_writebyteenable;
- else
- ram_address <= (others => '0');
- ram_writedata <= (others => '0');
- ram_byteenable <= (others => '0');
- ram_chipselect <= '0';
- ram_write <= '0';
- ram_clken <= '0';
- end if;
- -- Jeżeli w cyklu odczytywania wpiszemy adres i resztę danych, to zostaną one ustawione przez układ sekwencyjny dopiero w następnym takcie zegara
- -- Dlatego zapisujemy informację o tym że takie działanie zostało zapisane
- if (operation = writeOperation and readPerformed = '1') then
- read_q_prepare := '1';
- end if;
- -- ...i gdy miną dwa cykle - czyli znowu będzie odczytywanie (no i był sygnał że czekamy na danę)
- -- to wtedy na wyjściu portu ram będą dane do oczytu, które zapisujemy do sygnału read_q
- -- którego zawartość będzie wystawiona według taktowania zegara odczytującego
- if (operation = readOperation and readPerformed = '1' and read_q_prepare = '1') then
- read_q <= ram_readdata;
- readPerformed := '0';
- read_q_prepare := '0';
- end if;
- end if;
- end process;
- end architecture;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement