---------------------------------------------------------------------------- -- reg_bram.vhd -- ZedBoard simple VHDL example -- Version 1.0 -- -- Copyright (C) 2013 H.Poetzl -- -- 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 -- 2 of the License, or (at your option) any later version. -- ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.ALL; library unisim; use unisim.VCOMPONENTS.all; entity reg_bram is port ( m_axi_aclk : in std_logic; -- m_axi_aresetn : in std_logic; -- write address m_axi_awid : in std_logic_vector(11 downto 0); m_axi_awaddr : in std_logic_vector(31 downto 0); m_axi_awvalid : in std_logic; m_axi_awready : out std_logic; -- write data m_axi_wdata : in std_logic_vector(31 downto 0); m_axi_wstrb : in std_logic_vector(3 downto 0); m_axi_wlast : in std_logic; m_axi_wvalid : in std_logic; m_axi_wready : out std_logic; -- write response m_axi_bid : out std_logic_vector(11 downto 0); m_axi_bresp : out std_logic_vector(1 downto 0); m_axi_bvalid : out std_logic; m_axi_bready : in std_logic; -- read address m_axi_arid : in std_logic_vector(11 downto 0); m_axi_araddr : in std_logic_vector(31 downto 0); m_axi_arvalid : in std_logic; m_axi_arready : out std_logic; -- read data m_axi_rid : out std_logic_vector(11 downto 0); m_axi_rdata : out std_logic_vector(31 downto 0); m_axi_rresp : out std_logic_vector(1 downto 0); m_axi_rvalid : out std_logic; m_axi_rready : in std_logic; -- bram_clk : in std_logic; -- bram address bram_addr : in std_logic_vector(14 downto 5); -- bram data bram_din : in std_logic_vector(31 downto 0); bram_dout : out std_logic_vector(31 downto 0); -- bram parity bram_pin : in std_logic_vector(3 downto 0); bram_pout : out std_logic_vector(3 downto 0); -- bram control bram_en : in std_logic; bram_ce : in std_logic; bram_we : in std_logic ); end entity reg_bram; architecture RTL of reg_bram is signal bram_addr_a : std_logic_vector(15 downto 0); signal bram_we_a : std_logic_vector(3 downto 0); signal bram_dout_b : std_logic_vector(31 downto 0); signal bram_pout_b : std_logic_vector(3 downto 0); signal bram_addr_b : std_logic_vector(15 downto 0); signal bram_clk_b : std_logic; signal bram_din_b : std_logic_vector(31 downto 0); signal bram_pin_b : std_logic_vector(3 downto 0); signal bram_en_b : std_ulogic; signal bram_ce_b : std_ulogic; signal bram_we_b7 : std_logic_vector(7 downto 0); signal bram_we_b : std_logic_vector(3 downto 0); begin bram_inst : RAMB36E1 generic map ( READ_WIDTH_A => 36, READ_WIDTH_B => 36, WRITE_WIDTH_A => 36, WRITE_WIDTH_B => 36 ) port map ( CASCADEOUTA => open, -- out std_ulogic; CASCADEOUTB => open, -- out std_ulogic; DBITERR => open, -- out std_ulogic; DOADO => bram_dout, -- out std_logic_vector(31 downto 0); DOBDO => bram_dout_b, -- out std_logic_vector(31 downto 0); DOPADOP => bram_pout, -- out std_logic_vector(3 downto 0); DOPBDOP => bram_pout_b, -- out std_logic_vector(3 downto 0); ECCPARITY => open, -- out std_logic_vector(7 downto 0); RDADDRECC => open, -- out std_logic_vector(8 downto 0); SBITERR => open, -- out std_ulogic; ADDRARDADDR => bram_addr_a, -- in std_logic_vector(15 downto 0); ADDRBWRADDR => bram_addr_b, -- in std_logic_vector(15 downto 0); CASCADEINA => '0', -- in std_ulogic; CASCADEINB => '0', -- in std_ulogic; CLKARDCLK => bram_clk, -- in std_ulogic; CLKBWRCLK => bram_clk_b, -- in std_ulogic; DIADI => bram_din, -- in std_logic_vector(31 downto 0); DIBDI => bram_din_b, -- in std_logic_vector(31 downto 0); DIPADIP => bram_pin, -- in std_logic_vector(3 downto 0); DIPBDIP => bram_pin_b, -- in std_logic_vector(3 downto 0); ENARDEN => bram_en, -- in std_ulogic; ENBWREN => bram_en_b, -- in std_ulogic; INJECTDBITERR => '0', -- in std_ulogic; INJECTSBITERR => '0', -- in std_ulogic; REGCEAREGCE => bram_ce, -- in std_ulogic; REGCEB => bram_ce_b, -- in std_ulogic; RSTRAMARSTRAM => '0', -- in std_ulogic; RSTRAMB => '0', -- in std_ulogic; RSTREGARSTREG => '0', -- in std_ulogic; RSTREGB => '0', -- in std_ulogic; WEA => bram_we_a, -- in std_logic_vector(3 downto 0); WEBWE => bram_we_b7 -- in std_logic_vector(7 downto 0) ); bram_addr_a(14 downto 5) <= bram_addr; bram_we_a <= (others => bram_we); bram_we_b7(3 downto 0) <= bram_we_b; bram_clk_b <= m_axi_aclk; bram_pin_b <= "0000"; reg_rwseq_proc : process( m_axi_aclk, m_axi_aresetn, m_axi_araddr, m_axi_arvalid, m_axi_rready, m_axi_awaddr, m_axi_awvalid, m_axi_wdata, m_axi_wstrb, m_axi_wvalid, m_axi_bready, bram_dout_b) variable rwid : std_logic_vector(11 downto 0); variable addr : std_logic_vector(31 downto 0); type rw_state is ( idle, r_addr, r_data, r_done, w_addr, w_data, w_resp, w_done); variable state : rw_state := idle; begin if rising_edge(m_axi_aclk) then if m_axi_aresetn = '0' then rwid := (others => '0'); addr := (others => '0'); m_axi_arready <= '0'; m_axi_rvalid <= '0'; m_axi_awready <= '0'; m_axi_wready <= '0'; m_axi_bvalid <= '0'; state := idle; else case state is when idle => if m_axi_arvalid = '1' then -- address _is_ valid m_axi_arready <= '1'; -- we are ready for transfer state := r_addr; elsif m_axi_awvalid = '1' then -- address _is_ valid m_axi_awready <= '1'; -- we are ready for transfer state := w_addr; end if; -- ARVALID ---> RVALID Master -- \ /` \ -- \, / \, -- ARREADY RREADY Slave when r_addr => if m_axi_arvalid = '1' then -- actual transfer rwid := m_axi_arid; addr := m_axi_araddr; bram_en_b <= '1'; bram_ce_b <= '1'; state := r_data; else state := idle; end if; when r_data => m_axi_rresp <= "00"; m_axi_rvalid <= '1'; -- data is valid if m_axi_rready = '1' then state := r_done; end if; when r_done => m_axi_arready <= '0'; m_axi_rvalid <= '0'; bram_en_b <= '0'; bram_ce_b <= '0'; state := idle; -- AWVALID ---> WVALID _ BREADY Master -- \ --__ /` \ --__ /` -- \, /--__ \, --_ / -- AWREADY -> WREADY ---> BVALID Slave when w_addr => if m_axi_awvalid = '1' then -- address transfer rwid := m_axi_awid; addr := m_axi_awaddr; bram_en_b <= '1'; m_axi_wready <= '1'; -- we are ready for data state := w_data; else state := idle; end if; when w_data => if m_axi_wvalid = '1' then -- data transfer m_axi_bresp <= "00"; -- transfer OK bram_we_b <= "1111"; if m_axi_wlast = '1' then -- last write m_axi_bvalid <= '1'; -- response valid state := w_resp; end if; end if; when w_resp => if m_axi_bready = '1' then -- master ready state := w_done; end if; when w_done => m_axi_awready <= '0'; m_axi_wready <= '0'; m_axi_bvalid <= '0'; bram_en_b <= '0'; bram_we_b <= "0000"; state := idle; end case; end if; end if; bram_addr_b(14 downto 5) <= addr(11 downto 2); m_axi_rdata <= bram_dout_b; bram_din_b <= m_axi_wdata; m_axi_rid <= rwid; m_axi_bid <= rwid; -- m_axi_wid <= rwid; end process; end RTL;