]> git.the-white-hart.net Git - vhdl/commitdiff
Separate CYC for flash and ram in mem controller
authorrs <>
Sun, 29 Jun 2025 22:20:26 +0000 (17:20 -0500)
committerrs <>
Sun, 29 Jun 2025 22:20:26 +0000 (17:20 -0500)
libraries/nexys2/mem_wb8_0.vhd
libraries/nexys2/tests/test_nexys2_mem_wb8_0.vhd
libraries/nexys2/tests/test_sim_mem_wb8_0.vhd
libraries/utility/wb_mapper_a8d8.vhd [new file with mode: 0644]

index a08602f909c128b2e2fd119da40a5fe9ac64dbd2..59994021c818810c0f03f1885d1a285d1426dd23 100644 (file)
@@ -1,8 +1,9 @@
 --------------------------------------------------------------------------------
 -- mem_wb8_0 - Simple, non-caching 8-bit interface to Nexys2 onboard memory
 --
--- When adr_i(24) is clear, accesses go to flash
--- When adr_i(24) is set, accesses go to RAM
+-- Endianness of the interface is undefined, but for storage within the 16-bit
+-- memory, little-endian ordering is used (even bytes are stored in the least-
+-- significant byte, odd bytes are stored in the most-significant byte).
 --------------------------------------------------------------------------------
 -- WISHBONE DATASHEET
 --
 -- Operand sizes: 8-bit
 -- Endianness: undefined (port size same as granularity)
 -- Data transfer sequence: undefined
--- Clock constraints: none
+-- Clock constraints: max 50 MHz
 -- Signals:
 -- * rst_i
 -- * clk_i
--- * cyc_i
+-- * fls_cyc_i (CYC_I for flash)
+-- * ram_cyc_i (CYC_I for RAM)
 -- * stb_i
 -- * we_i
 -- * ack_o
--- * adr_i (25-bit)
+-- * adr_i (24-bit)
 -- * dat_i (8-bit)
 -- * dat_o (8-bit)
 --------------------------------------------------------------------------------
@@ -38,11 +40,12 @@ entity mem_wb8_0 is
                clk_i:       in  std_logic;
 
                -- Wishbone system interface
-               cyc_i:       in  std_logic;
+               fls_cyc_i:   in  std_logic;
+               ram_cyc_i:   in  std_logic;
                stb_i:       in  std_logic;
                we_i:        in  std_logic;
                ack_o:       out std_logic;
-               adr_i:       in  std_logic_vector(24 downto 0);
+               adr_i:       in  std_logic_vector(23 downto 0);
                dat_i:       in  std_logic_vector(7 downto 0);
                dat_o:       out std_logic_vector(7 downto 0);
 
@@ -85,8 +88,13 @@ architecture behavioral of mem_wb8_0 is
        signal mdr_reg:        std_logic_vector(15 downto 0);
        signal mdr_ld:         std_logic;
 
+       -- Replacement for original cyc_i when separating cyc for ram and flash
+       signal cyc_i:          std_logic;
+
 begin
 
+       cyc_i <= fls_cyc_i or ram_cyc_i;
+
        process (rst_i, clk_i, state_next)
        begin
                if rising_edge(clk_i) then
@@ -136,13 +144,13 @@ begin
        end process;
 
        -- Little-endian memory interface
-       RamCS                <= not (mem_enable and adr_i(24));
+       RamCS                <= not (mem_enable and ram_cyc_i);
        RamAdv               <= '0';
        RamClk               <= '0';
        RamCRE               <= '0';
        RamUB                <= not adr_i(0);
        RamLB                <=     adr_i(0);
-       FlashCS              <= not (mem_enable and (not adr_i(24)));
+       FlashCS              <= not (mem_enable and fls_cyc_i);
        FlashRp              <= '1';
        MemAdr               <= adr_i(23 downto 1);
        MemDB_o(15 downto 8) <= dat_i when adr_i(0) = '1' else (others => '0');
index d86880df0a11a67db72d4e37f2fe9513473f838f..1abd80d3ec6fe1fd9e4349ab0b75ba02095d1b81 100644 (file)
@@ -46,7 +46,8 @@ architecture behavioral of test_nexys2_mem_wb8_0 is
        signal clk:          std_logic;
        signal rst:          std_logic;
        signal cyc:          std_logic;
-       signal mem_cyc:      std_logic;
+       signal fls_cyc:      std_logic;
+       signal ram_cyc:      std_logic;
        signal host_cyc:     std_logic;
        signal stb:          std_logic;
        signal we:           std_logic;
@@ -54,7 +55,7 @@ architecture behavioral of test_nexys2_mem_wb8_0 is
        signal mem_ack:      std_logic;
        signal host_ack:     std_logic;
        signal adr:          std_logic_vector(7 downto 0);
-       signal mem_adr:      std_logic_vector(24 downto 0);
+       signal mem_adr:      std_logic_vector(23 downto 0);
        signal dat_mosi:     std_logic_vector(7 downto 0);
        signal dat_miso:     std_logic_vector(7 downto 0);
        signal mem_miso:     std_logic_vector(7 downto 0);
@@ -80,13 +81,14 @@ architecture behavioral of test_nexys2_mem_wb8_0 is
 
 begin
 
-       mem_adr <= adr(6) & "000000000000000000" & adr(5 downto 0);
+       mem_adr <= "000000000000000000" & adr(5 downto 0);
        e_mem: entity work.mem_wb8_0
                port map (
                        rst_i       => rst,
                        clk_i       => clk,
 
-                       cyc_i       => mem_cyc,
+                       fls_cyc_i   => fls_cyc,
+                       ram_cyc_i   => ram_cyc,
                        stb_i       => stb,
                        we_i        => we,
                        ack_o       => mem_ack,
@@ -113,26 +115,39 @@ begin
                        MemDB_o     => d_MemDB_o
                );
 
-       e_wb_mux: entity utility.wb_mux2
+
+       e_mapper: entity utility.wb_mapper_a8d8
                generic map (
-                       WIDTH => 8
+                       N => 3
                )
                port map (
-                       sel     => adr(7),
-
-                       cyc_i   => cyc,
-                       ack_o   => ack,
-                       dat_o   => dat_miso,
-
-                       cyc_o_0 => mem_cyc,
-                       ack_i_0 => mem_ack,
-                       dat_i_0 => mem_miso,
-
-                       cyc_o_1 => host_cyc,
-                       ack_i_1 => host_ack,
-                       dat_i_1 => host_miso
+                       cyc_i    => cyc,
+                       ack_o    => ack,
+                       adr_i    => adr,
+                       dat_o    => dat_miso,
+
+                       mask(0)  => "11000000",
+                       mask(1)  => "11000000",
+                       mask(2)  => "11000000",
+
+                       match(0) => "00000000",
+                       match(1) => "01000000",
+                       match(2) => "10000000",
+
+                       cyc_o(0) => fls_cyc,
+                       cyc_o(1) => ram_cyc,
+                       cyc_o(2) => host_cyc,
+
+                       ack_i(0) => mem_ack,
+                       ack_i(1) => mem_ack,
+                       ack_i(2) => host_ack,
+
+                       dat_i(0) => mem_miso,
+                       dat_i(1) => mem_miso,
+                       dat_i(2) => host_miso
                );
 
+
        e_wb_dbg: entity work.wishbone_debugger
                port map (
                        clk_o  => clk,
@@ -154,6 +169,7 @@ begin
                        btn    => btn
                );
 
+
        e_host_ctrl: entity work.host_ctrl
                port map (
                        clk_i        => clk,
index 64e2956fb455d145ddeb1c1bf50ae8b17ded6795..60c142ea234b99ee03096b38ea9de96abbe60203 100644 (file)
@@ -17,11 +17,12 @@ architecture behavior of test_sim_mem_wb8_0 is
        signal rst_i:       std_logic;
        signal clk_i:       std_logic;
 
-       signal cyc_i:       std_logic;
+       signal fls_cyc_i:   std_logic;
+       signal ram_cyc_i:   std_logic;
        signal stb_i:       std_logic;
        signal we_i:        std_logic;
        signal ack_o:       std_logic;
-       signal adr_i:       std_logic_vector(24 downto 0);
+       signal adr_i:       std_logic_vector(23 downto 0);
        signal dat_i:       std_logic_vector(7 downto 0);
        signal dat_o:       std_logic_vector(7 downto 0);
 
@@ -46,7 +47,8 @@ architecture behavior of test_sim_mem_wb8_0 is
 
        type test_name_t is (
                NONE,
-               RD_FLASH
+               RD_FLASH,
+               RD_RAM
        );
 
        signal test:        test_name_t;
@@ -57,7 +59,8 @@ begin
        begin
                -- Initial values
                test        <= NONE;
-               cyc_i       <= '0';
+               fls_cyc_i   <= '0';
+               ram_cyc_i   <= '0';
                stb_i       <= '0';
                we_i        <= '0';
                adr_i       <= (others => '0');
@@ -71,14 +74,24 @@ begin
                wait for 300 ns;  -- T_PHEL for flash
 
                -- Read from flash
-               test  <= RD_FLASH;
-               cyc_i <= '1';
-               stb_i <= '1';
-               we_i  <= '0';
-               adr_i <= "0000000000000000000000000";
+               test      <= RD_FLASH;
+               fls_cyc_i <= '1';
+               stb_i     <= '1';
+               we_i      <= '0';
+               adr_i     <= "000000000000000000000000";
                wait until ack_o = '1';
-               cyc_i <= '0';
-               stb_i <= '0';
+               fls_cyc_i <= '0';
+               stb_i     <= '0';
+
+               -- Read from RAM
+               test      <= RD_RAM;
+               ram_cyc_i <= '1';
+               stb_i     <= '1';
+               we_i      <= '0';
+               adr_i     <= "000000000000000000000000";
+               wait until ack_o = '1';
+               ram_cyc_i <= '0';
+               stb_i     <= '0';
 
                wait;
        end process;
@@ -88,7 +101,8 @@ begin
                        rst_i       => rst_i,
                        clk_i       => clk_i,
 
-                       cyc_i       => cyc_i,
+                       fls_cyc_i   => fls_cyc_i,
+                       ram_cyc_i   => ram_cyc_i,
                        stb_i       => stb_i,
                        we_i        => we_i,
                        ack_o       => ack_o,
diff --git a/libraries/utility/wb_mapper_a8d8.vhd b/libraries/utility/wb_mapper_a8d8.vhd
new file mode 100644 (file)
index 0000000..ca27523
--- /dev/null
@@ -0,0 +1,59 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_misc.all;
+
+library work;
+use work.types.all;
+
+
+entity wb_mapper_a8d8 is
+       generic (
+               N: integer := 8
+       );
+       port (
+               -- Master interface
+               cyc_i: in  std_logic;
+               ack_o: out std_logic;
+               adr_i: in  slv8;
+               dat_o: out slv8;
+
+               -- Configuration
+               mask:  in  slv8_array(N-1 downto 0);
+               match: in  slv8_array(N-1 downto 0);
+
+               -- Device interfaces
+               cyc_o: out std_logic_vector(N-1 downto 0);
+               ack_i: in  std_logic_vector(N-1 downto 0);
+               dat_i: in  slv8_array(N-1 downto 0)
+       );
+end wb_mapper_a8d8;
+
+
+architecture behavioral of wb_mapper_a8d8 is
+
+       signal sel:   std_logic_vector(N-1 downto 0);
+       signal dummy: std_logic;
+
+begin
+
+       g_sel: for n in 0 to n-1 generate
+               sel(n) <= '1' when (adr_i and mask(n)) = match(n) else '0';
+       end generate;
+       dummy <= not or_reduce(sel);
+
+       cyc_o <= sel when cyc_i = '1' else (others => '0');
+       ack_o <= or_reduce(sel and ack_i) or dummy;
+
+       process (sel, dat_i)
+               variable temp: slv8 := (others => '0');
+       begin
+               temp := (others => '0');
+               for n in 0 to N-1 loop
+                       if sel(n) = '1' then
+                               temp := temp or dat_i(n);
+                       end if;
+               end loop;
+               dat_o <= temp;
+       end process;
+
+end behavioral;