From 62899050c3d0fb7e438c403f707add9218a2c928 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Mon, 20 Feb 2023 12:37:59 +0100 Subject: exposed ram module implemented --- basys3/basys3.srcs/er_ram.vhd | 53 ++++++++++ basys3/basys3.srcs/er_ram_mod.vhd | 34 ++++++ basys3/basys3.srcs/er_ram_mod_tb.vhd | 81 ++++++++++++++ basys3/basys3.srcs/er_ram_tb.vhd | 116 +++++++++++++++++++++ .../basys3.srcs/sources_1/ip/ppu_bam/ppu_bam.xci | 2 +- .../basys3.srcs/sources_1/ip/ppu_tmm/ppu_tmm.xci | 2 +- basys3/basys3.xpr | 49 +++++++-- 7 files changed, 325 insertions(+), 12 deletions(-) create mode 100644 basys3/basys3.srcs/er_ram.vhd create mode 100644 basys3/basys3.srcs/er_ram_mod.vhd create mode 100644 basys3/basys3.srcs/er_ram_mod_tb.vhd create mode 100644 basys3/basys3.srcs/er_ram_tb.vhd diff --git a/basys3/basys3.srcs/er_ram.vhd b/basys3/basys3.srcs/er_ram.vhd new file mode 100644 index 0000000..a35514c --- /dev/null +++ b/basys3/basys3.srcs/er_ram.vhd @@ -0,0 +1,53 @@ +library ieee; +library work; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity er_ram is -- exposed register RAM + generic( + ADDR_W : natural := 2; -- ADDR line width + DATA_W : natural := 2; -- DATA line width + ADDR_LOW : natural := 16#0000#; -- starting address + ADDR_RANGE : natural := 16#0002#); -- amount of valid addresses after ADDR_LOW + port( + CLK : in std_logic; -- clock + RST : in std_logic; -- async memory clear + WEN : in std_logic; -- write enable + ADDR : in std_logic_vector(ADDR_W-1 downto 0); -- address line + DATA : in std_logic_vector(DATA_W-1 downto 0); -- data input + REG : out std_logic_vector((ADDR_W*DATA_W)-1 downto 0)); -- exposed register output +end er_ram; + +architecture Behavioral of er_ram is + component er_ram_mod + generic( + W : natural := 1; -- module data width + ADDR_W : natural := 1; -- address width + ADDR_M : std_logic_vector(ADDR_W-1 downto 0) := (others => '0')); -- address match + port( + CLK : in std_logic; -- clock + RST : in std_logic; -- async memory clear + WEN : in std_logic; -- write enable + ADDR : in std_logic_vector(ADDR_W-1 downto 0); + DATA : in std_logic_vector(W-1 downto 0); -- data + REG : out std_logic_vector(W-1 downto 0)); -- direct register out + end component; + signal INT_REG : std_logic_vector((ADDR_RANGE*DATA_W)-1 downto 0); +begin + REG <= INT_REG; + + registers : for idx in ADDR_LOW to ADDR_LOW + ADDR_RANGE - 1 generate + reg : component er_ram_mod + generic map( + W => DATA_W, + ADDR_W => ADDR_W, + ADDR_M => std_logic_vector(to_unsigned(idx, ADDR_W))) + port map( + CLK => CLK, + RST => RST, + WEN => WEN, + ADDR => ADDR, + DATA => DATA, + REG => INT_REG(idx*DATA_W+DATA_W-1 downto idx*DATA_W)); + end generate; +end Behavioral; diff --git a/basys3/basys3.srcs/er_ram_mod.vhd b/basys3/basys3.srcs/er_ram_mod.vhd new file mode 100644 index 0000000..ae680b1 --- /dev/null +++ b/basys3/basys3.srcs/er_ram_mod.vhd @@ -0,0 +1,34 @@ +library ieee; +library work; +use ieee.std_logic_1164.all; + +entity er_ram_mod is -- exposed register RAM module (single register) + generic( + W : natural := 1; -- module data width + ADDR_W : natural := 1; -- address width + ADDR_M : std_logic_vector(ADDR_W-1 downto 0) := (others => '0')); -- address match + port( + CLK : in std_logic; -- clock + RST : in std_logic; -- async memory clear + WEN : in std_logic; -- write enable + ADDR : in std_logic_vector(ADDR_W-1 downto 0); -- RAM address line + DATA : in std_logic_vector(W-1 downto 0); -- RAM input data line + REG : out std_logic_vector(W-1 downto 0)); -- direct register output lines +end er_ram_mod; + +architecture Behavioral of er_ram_mod is + signal DATA_REG : std_logic_vector(W-1 downto 0); +begin + REG <= DATA_REG; + + process(CLK, RST) + begin + if RST = '1' then + DATA_REG <= (others => '0'); + elsif rising_edge(CLK) then + if WEN = '1' and ADDR = ADDR_M then + DATA_REG <= DATA; + end if; + end if; + end process; +end Behavioral; diff --git a/basys3/basys3.srcs/er_ram_mod_tb.vhd b/basys3/basys3.srcs/er_ram_mod_tb.vhd new file mode 100644 index 0000000..aa77a56 --- /dev/null +++ b/basys3/basys3.srcs/er_ram_mod_tb.vhd @@ -0,0 +1,81 @@ +library ieee; +library unisim; + +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use unisim.vcomponents.all; + +entity er_ram_mod_tb is +end er_ram_mod_tb; + +architecture behavioral of er_ram_mod_tb is + component er_ram_mod + generic( + W : natural := 1; -- module data width + ADDR_W : natural := 1; -- address width + ADDR_M : std_logic_vector(ADDR_W-1 downto 0) := (others => '0')); -- address match + port( + CLK : in std_logic; -- clock + RST : in std_logic; -- async memory clear + WEN : in std_logic; -- write enable + ADDR : in std_logic_vector(ADDR_W-1 downto 0); + DATA : in std_logic_vector(W-1 downto 0); -- data + REG : out std_logic_vector(W-1 downto 0)); -- direct register out + end component; + + signal CLK, RST, WEN : std_logic := '0'; + signal ADDR : std_logic_vector(3 downto 0); + signal DATA : std_logic_vector(7 downto 0); + signal REG : std_logic_vector(7 downto 0); +begin + uut : component er_ram_mod + generic map( + W => 8, + ADDR_W => 4, + ADDR_M => x"5") + port map( + CLK => CLK, + RST => RST, + WEN => WEN, + ADDR => ADDR, + DATA => DATA, + REG => REG); + + tb : process + begin + wait for 5 ns; + + -- async reset (safety) + RST <= '1'; + wait for 5 ns; + RST <= '0'; + wait for 5 ns; + + -- set 0xef at address 0x5 (exists) + DATA <= x"ef"; + ADDR <= x"5"; + WEN <= '1'; + + CLK <= '1'; + wait for 5 ns; + CLK <= '0'; + wait for 5 ns; + + -- set 0x34 at address 0x4 (doesn't exist) + ADDR <= x"4"; + DATA <= x"34"; + + CLK <= '1'; + wait for 5 ns; + CLK <= '0'; + wait for 5 ns; + + -- reset + RST <= '1'; + wait for 5 ns; + RST <= '0'; + wait for 5 ns; + + wait; -- stop for simulator + end process; +end; diff --git a/basys3/basys3.srcs/er_ram_tb.vhd b/basys3/basys3.srcs/er_ram_tb.vhd new file mode 100644 index 0000000..d360442 --- /dev/null +++ b/basys3/basys3.srcs/er_ram_tb.vhd @@ -0,0 +1,116 @@ +library ieee; +library unisim; + +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use unisim.vcomponents.all; + +entity er_ram_tb is +end er_ram_tb; + +architecture behavioral of er_ram_tb is + component er_ram + generic( + ADDR_W : natural := 2; -- ADDR line width + DATA_W : natural := 2; -- DATA line width + ADDR_LOW : natural := 16#0000#; -- starting address + ADDR_RANGE : natural := 16#0002#); -- amount of valid addresses after ADDR_LOW + port( + CLK : in std_logic; -- clock + RST : in std_logic; -- async memory clear + WEN : in std_logic; -- write enable + ADDR : in std_logic_vector(ADDR_W-1 downto 0); + DATA : in std_logic_vector(DATA_W-1 downto 0); + REG : out std_logic_vector((ADDR_W*DATA_W)-1 downto 0)); + end component; + + signal CLK, RST, WEN : std_logic := '0'; + signal ADDR : std_logic_vector(3 downto 0); + signal DATA : std_logic_vector(7 downto 0); + signal REG : std_logic_vector(31 downto 0); +begin + uut : component er_ram + generic map( + ADDR_W => 4, + DATA_W => 8, + ADDR_LOW => 0, + ADDR_RANGE => 4) + port map( + CLK => CLK, + RST => RST, + WEN => WEN, + ADDR => ADDR, + DATA => DATA, + REG => REG); + + tb : process + begin + wait for 5 ns; + + -- async reset (safety) + RST <= '1'; + wait for 5 ns; + RST <= '0'; + wait for 5 ns; + + -- set 0xef at address 0x1 (exists) + DATA <= x"ef"; + ADDR <= x"1"; + WEN <= '1'; + + CLK <= '1'; + wait for 5 ns; + CLK <= '0'; + wait for 5 ns; + + -- set 0x34 at address 0x4 (doesn't exist) + ADDR <= x"4"; + DATA <= x"34"; + + CLK <= '1'; + wait for 5 ns; + CLK <= '0'; + wait for 5 ns; + + -- reset + RST <= '1'; + wait for 5 ns; + RST <= '0'; + wait for 5 ns; + + -- set REG to 0x12345678 + ADDR <= x"0"; + DATA <= x"12"; + + CLK <= '1'; + wait for 1 ns; + CLK <= '0'; + wait for 1 ns; + + ADDR <= x"1"; + DATA <= x"34"; + + CLK <= '1'; + wait for 1 ns; + CLK <= '0'; + wait for 1 ns; + + ADDR <= x"2"; + DATA <= x"56"; + + CLK <= '1'; + wait for 1 ns; + CLK <= '0'; + wait for 1 ns; + + ADDR <= x"3"; + DATA <= x"78"; + + CLK <= '1'; + wait for 1 ns; + CLK <= '0'; + wait for 1 ns; + + wait; -- stop for simulator + end process; +end; diff --git a/basys3/basys3.srcs/sources_1/ip/ppu_bam/ppu_bam.xci b/basys3/basys3.srcs/sources_1/ip/ppu_bam/ppu_bam.xci index f5e1696..e299ea1 100644 --- a/basys3/basys3.srcs/sources_1/ip/ppu_bam/ppu_bam.xci +++ b/basys3/basys3.srcs/sources_1/ip/ppu_bam/ppu_bam.xci @@ -163,7 +163,7 @@ "BOARD_CONNECTIONS": [ { "value": "" } ], "DEVICE": [ { "value": "xc7a35t" } ], "PACKAGE": [ { "value": "cpg236" } ], - "PREFHDL": [ { "value": "VERILOG" } ], + "PREFHDL": [ { "value": "VHDL" } ], "SILICON_REVISION": [ { "value": "" } ], "SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ], "SPEEDGRADE": [ { "value": "-1" } ], diff --git a/basys3/basys3.srcs/sources_1/ip/ppu_tmm/ppu_tmm.xci b/basys3/basys3.srcs/sources_1/ip/ppu_tmm/ppu_tmm.xci index 51914b1..24d2b58 100644 --- a/basys3/basys3.srcs/sources_1/ip/ppu_tmm/ppu_tmm.xci +++ b/basys3/basys3.srcs/sources_1/ip/ppu_tmm/ppu_tmm.xci @@ -163,7 +163,7 @@ "BOARD_CONNECTIONS": [ { "value": "" } ], "DEVICE": [ { "value": "xc7a35t" } ], "PACKAGE": [ { "value": "cpg236" } ], - "PREFHDL": [ { "value": "VERILOG" } ], + "PREFHDL": [ { "value": "VHDL" } ], "SILICON_REVISION": [ { "value": "" } ], "SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ], "SPEEDGRADE": [ { "value": "-1" } ], diff --git a/basys3/basys3.xpr b/basys3/basys3.xpr index d5ba760..a63514c 100644 --- a/basys3/basys3.xpr +++ b/basys3/basys3.xpr @@ -42,6 +42,7 @@