From bb7b2a7a101c9084c71513a23e053fc94d621462 Mon Sep 17 00:00:00 2001 From: Markus Koch Date: Fri, 27 Sep 2024 14:42:38 +0200 Subject: [PATCH] fpga: servant_ram: Rewrite in VHDL --- fpga/hdl/design/servant_ram.vhd | 78 +++++++++++++++++---------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/fpga/hdl/design/servant_ram.vhd b/fpga/hdl/design/servant_ram.vhd index f7aca9c..f70c445 100644 --- a/fpga/hdl/design/servant_ram.vhd +++ b/fpga/hdl/design/servant_ram.vhd @@ -1,7 +1,7 @@ -- -------------------------------------------------------------------------- -- -- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs -- -- -------------------------------------------------------------------------- -- --- TODO +-- Servant-compatible RAM, rewritten in VHDL -- -------------------------------------------------------------------------- -- -- Author : Markus Koch -- Contributors : None @@ -11,6 +11,7 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; +use std.textio.all; library generics; use generics.wishbone_pkg.all; @@ -31,48 +32,31 @@ entity servant_ram_vhdl is end entity servant_ram_vhdl; architecture rtl of servant_ram_vhdl is - component servant_ram - generic( - depth : integer; - aw : integer; - memfile : string - ); - port( - i_wb_clk : in std_logic; - i_wb_rst : in std_logic; - i_wb_adr : in std_logic_vector; - i_wb_dat : in std_logic_vector; - i_wb_sel : in std_logic_vector; - i_wb_we : in std_logic; - i_wb_cyc : in std_logic; - o_wb_rdt : out std_logic_vector; - o_wb_ack : out std_logic - ); - end component servant_ram; + type mem_t is array (0 to 2 ** adr_width - 1) of std_logic_vector(wb_i.dat'range); + impure function init_ram_hex return mem_t is + file text_file : text open read_mode is memfile; + variable text_line : line; + variable ram_content : mem_t := (others => (others => '0')); + begin + for i in 0 to 2 ** adr_width - 1 loop + exit when endfile(text_file); + readline(text_file, text_line); + hread(text_line, ram_content(i)); + end loop; + + return ram_content; + end function; + + signal mem : mem_t := init_ram_hex; + signal mem_address : integer range mem'range; begin - servant_ram_inst : component servant_ram - generic map( - depth => 2 ** adr_width, - aw => adr_width, - memfile => memfile - ) - port map( - i_wb_clk => clk, - i_wb_rst => clr, - i_wb_adr => wb_i.adr(adr_width - 1 downto 2), - i_wb_dat => wb_i.dat, - i_wb_sel => wb_i.sel, - i_wb_we => wb_i.we, - i_wb_cyc => wb_i.cyc and wb_i.stb, - o_wb_rdt => wb_o.dat, - o_wb_ack => wb_o.ack - ); - wb_o.rty <= '0'; wb_o.err <= '0'; wb_o.stall <= '0'; + mem_address <= to_integer(unsigned(wb_i.adr(adr_width - 1 + 2 downto 2))); + rowarn : process(clk) is begin if rising_edge(clk) then @@ -87,4 +71,24 @@ begin end if; end process rowarn; + mem_p : process(clk) is + begin + if rising_edge(clk) then + wb_o.dat <= mem(mem_address); + wb_o.ack <= wb_i.stb; + if (wb_i.we) then + wb_o.dat <= (others => '-'); + for i in wb_i.sel'range loop + if wb_i.sel(i) then + mem(mem_address)((i + 1) * 8 - 1 downto (i * 8)) <= wb_i.dat((i + 1) * 8 - 1 downto (i * 8)); + end if; + end loop; + end if; + + if clr then + wb_o.dat <= (others => '-'); + wb_o.ack <= '0'; + end if; + end if; + end process mem_p; end architecture rtl;