Make wishbone addresses be in units of doublewords or words
authorPaul Mackerras <paulus@ozlabs.org>
Wed, 15 Sep 2021 08:18:09 +0000 (18:18 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Wed, 15 Sep 2021 08:18:09 +0000 (18:18 +1000)
This makes the 64-bit wishbone buses have the address expressed in
units of doublewords (64 bits), and similarly for the 32-bit buses the
address is in units of words (32 bits).  This is to comply with the
wishbone spec.  Previously the addresses on the wishbone buses were in
units of bytes regardless of the bus data width, which is not correct
and caused problems with interfacing with externally-generated logic.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
21 files changed:
dcache.vhdl
dram_tb.vhdl
fpga/top-arty.vhdl
fpga/top-nexys-video.vhdl
gpio.vhdl
icache.vhdl
litedram/extras/litedram-wrapper-l2.vhdl
litedram/gen-src/dram-init-mem.vhdl
litedram/generated/acorn-cle-215/litedram-initmem.vhdl
litedram/generated/arty/litedram-initmem.vhdl
litedram/generated/genesys2/litedram-initmem.vhdl
litedram/generated/nexys-video/litedram-initmem.vhdl
litedram/generated/sim/litedram-initmem.vhdl
soc.vhdl
spi_flash_ctrl.vhdl
syscon.vhdl
wishbone_bram_tb.vhdl
wishbone_bram_wrapper.vhdl
wishbone_debug_master.vhdl
wishbone_types.vhdl
xics.vhdl

index d39f311af1b42791593cfa25a59969797583922e..705393a5aab909e1b25bc86c6bd3afc53453d9d6 100644 (file)
@@ -456,7 +456,7 @@ architecture rtl of dcache is
     -- Returns whether this is the last row of a line
     function is_last_row_addr(addr: wishbone_addr_type; last: row_in_line_t) return boolean is
     begin
-       return unsigned(addr(LINE_OFF_BITS-1 downto ROW_OFF_BITS)) = last;
+       return unsigned(addr(LINE_OFF_BITS - ROW_OFF_BITS - 1 downto 0)) = last;
     end;
 
     -- Returns whether this is the last row of a line
@@ -471,10 +471,10 @@ architecture rtl of dcache is
        variable result  : wishbone_addr_type;
     begin
        -- Is there no simpler way in VHDL to generate that 3 bits adder ?
-       row_idx := addr(LINE_OFF_BITS-1 downto ROW_OFF_BITS);
+       row_idx := addr(ROW_LINEBITS - 1 downto 0);
        row_idx := std_ulogic_vector(unsigned(row_idx) + 1);
        result := addr;
-       result(LINE_OFF_BITS-1 downto ROW_OFF_BITS) := row_idx;
+       result(ROW_LINEBITS - 1 downto 0) := row_idx;
        return result;
     end;
 
@@ -807,7 +807,7 @@ begin
     begin
         if rising_edge(clk) then
             addr := (others => '0');
-            addr(snoop_in.adr'left downto 0) := snoop_in.adr;
+            addr(snoop_in.adr'left + ROW_OFF_BITS downto ROW_OFF_BITS) := snoop_in.adr;
             snoop_tag_set <= cache_tags(get_index(addr));
             snoop_wrtag <= get_tag(addr);
             snoop_index <= get_index(addr);
@@ -1383,7 +1383,7 @@ begin
                -- Main state machine
                case r1.state is
                 when IDLE =>
-                    r1.wb.adr <= req.real_addr(r1.wb.adr'left downto 0);
+                    r1.wb.adr <= req.real_addr(r1.wb.adr'left + ROW_OFF_BITS downto ROW_OFF_BITS);
                     r1.wb.sel <= req.byte_sel;
                     r1.wb.dat <= req.data;
                     r1.dcbz <= req.dcbz;
@@ -1532,8 +1532,8 @@ begin
                         -- See if there is another store waiting to be done
                         -- which is in the same real page.
                         if req.valid = '1' then
-                            r1.wb.adr(SET_SIZE_BITS - 1 downto 0) <=
-                                req.real_addr(SET_SIZE_BITS - 1 downto 0);
+                            r1.wb.adr(SET_SIZE_BITS - ROW_OFF_BITS - 1 downto 0) <=
+                                req.real_addr(SET_SIZE_BITS - 1 downto ROW_OFF_BITS);
                             r1.wb.dat <= req.data;
                             r1.wb.sel <= req.byte_sel;
                         end if;
@@ -1598,7 +1598,7 @@ begin
         dcache_log: process(clk)
         begin
             if rising_edge(clk) then
-                log_data <= r1.wb.adr(5 downto 3) &
+                log_data <= r1.wb.adr(2 downto 0) &
                             wishbone_in.stall &
                             wishbone_in.ack &
                             r1.wb.stb & r1.wb.cyc &
index 852dbb7ae8de9ab64568d78b0e9313b3bc271279..10ca09e4f804b184e6be1999041ff63f03aa4291 100644 (file)
@@ -250,10 +250,10 @@ begin
         report "Back to back 4 stores 4 reads on hit...";
         clr_acks;
         for i in 0 to 3 loop
-            wb_write(add_off(a, i*8), make_pattern(i), x"ff");
+            wb_write(add_off(a, i), make_pattern(i), x"ff");
         end loop;
         for i in 0 to 3 loop
-            wb_read(add_off(a, i*8));
+            wb_read(add_off(a, i));
         end loop;
         wait_acks(8);
         for i in 0 to 7 loop
@@ -268,10 +268,10 @@ begin
         a(10) := '1';
         clr_acks;
         for i in 0 to 3 loop
-            wb_write(add_off(a, i*8), make_pattern(i), x"ff");
+            wb_write(add_off(a, i), make_pattern(i), x"ff");
         end loop;
         for i in 0 to 3 loop
-            wb_read(add_off(a, i*8));
+            wb_read(add_off(a, i));
         end loop;
         wait_acks(8);
         for i in 0 to 7 loop
@@ -286,8 +286,8 @@ begin
         a(10) := '1';
         clr_acks;
         for i in 0 to 3 loop
-            wb_write(add_off(a, i*8), make_pattern(i), x"ff");
-            wb_read(add_off(a, i*8));
+            wb_write(add_off(a, i), make_pattern(i), x"ff");
+            wb_read(add_off(a, i));
         end loop;
         wait_acks(8);
         for i in 0 to 3 loop
@@ -299,29 +299,29 @@ begin
         a(11) := '1';
         clr_acks;
         wb_write(add_off(a,  0), x"1111111100000000", x"ff");
-        wb_write(add_off(a,  8), x"3333333322222222", x"ff");
-        wb_write(add_off(a, 16), x"5555555544444444", x"ff");
-        wb_write(add_off(a, 24), x"7777777766666666", x"ff");
-        wb_write(add_off(a, 32), x"9999999988888888", x"ff");
-        wb_write(add_off(a, 40), x"bbbbbbbbaaaaaaaa", x"ff");
-        wb_write(add_off(a, 48), x"ddddddddcccccccc", x"ff");
-        wb_write(add_off(a, 56), x"ffffffffeeeeeeee", x"ff");
-        wb_write(add_off(a, 64), x"1111111100000000", x"ff");
-        wb_write(add_off(a, 72), x"3333333322222222", x"ff");
-        wb_write(add_off(a, 80), x"5555555544444444", x"ff");
-        wb_write(add_off(a, 88), x"7777777766666666", x"ff");
-        wb_write(add_off(a, 96), x"9999999988888888", x"ff");
-        wb_write(add_off(a,104), x"bbbbbbbbaaaaaaaa", x"ff");
-        wb_write(add_off(a,112), x"ddddddddcccccccc", x"ff");
-        wb_write(add_off(a,120), x"ffffffffeeeeeeee", x"ff");
+        wb_write(add_off(a,  1), x"3333333322222222", x"ff");
+        wb_write(add_off(a,  2), x"5555555544444444", x"ff");
+        wb_write(add_off(a,  3), x"7777777766666666", x"ff");
+        wb_write(add_off(a,  4), x"9999999988888888", x"ff");
+        wb_write(add_off(a,  5), x"bbbbbbbbaaaaaaaa", x"ff");
+        wb_write(add_off(a,  6), x"ddddddddcccccccc", x"ff");
+        wb_write(add_off(a,  7), x"ffffffffeeeeeeee", x"ff");
+        wb_write(add_off(a,  8), x"1111111100000000", x"ff");
+        wb_write(add_off(a,  9), x"3333333322222222", x"ff");
+        wb_write(add_off(a, 10), x"5555555544444444", x"ff");
+        wb_write(add_off(a, 11), x"7777777766666666", x"ff");
+        wb_write(add_off(a, 12), x"9999999988888888", x"ff");
+        wb_write(add_off(a, 13), x"bbbbbbbbaaaaaaaa", x"ff");
+        wb_write(add_off(a, 14), x"ddddddddcccccccc", x"ff");
+        wb_write(add_off(a, 15), x"ffffffffeeeeeeee", x"ff");
         wait_acks(16);
 
         report "Scattered from middle of line...";
         clr_acks;
-        wb_read(add_off(a,24));
-        wb_read(add_off(a,32));
+        wb_read(add_off(a, 3));
+        wb_read(add_off(a, 4));
         wb_read(add_off(a, 0));
-        wb_read(add_off(a,16));
+        wb_read(add_off(a, 2));
         wait_acks(4);
         read_data(d);
         assert d = x"7777777766666666" report "bad data (24), got " & to_hstring(d) severity failure;
index 6112c0adae2d25043180d6b281aef02d360d127d..7f475e4c505a68aae56d4593dbf995a27d476230 100644 (file)
@@ -550,7 +550,7 @@ begin
         wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;
 
         -- Remove top address bits as liteeth decoder doesn't know about them
-        wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(16 downto 2);
+        wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(14 downto 0);
 
         -- LiteETH isn't pipelined
         wb_eth_out.stall <= not wb_eth_out.ack;
@@ -640,7 +640,7 @@ begin
         -- Gate cyc with chip select from SoC
         wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
 
-        wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(15 downto 2);
+        wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(13 downto 0);
 
         wb_sdcard_out.stall <= not wb_sdcard_out.ack;
 
index 1cf1df2def4ef1e32e06852ed2ae694bd6a97aa8..6d947ead0d5fc508fbd2b7919fbbf8c01c421a5e 100644 (file)
@@ -444,7 +444,7 @@ begin
         wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;
 
         -- Remove top address bits as liteeth decoder doesn't know about them
-        wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(16 downto 2);
+        wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(14 downto 0);
 
         -- LiteETH isn't pipelined
         wb_eth_out.stall <= not wb_eth_out.ack;
@@ -533,7 +533,7 @@ begin
         -- Gate cyc with chip select from SoC
         wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
 
-        wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(15 downto 2);
+        wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(13 downto 0);
 
         wb_sdcard_out.stall <= not wb_sdcard_out.ack;
 
index bdce51940e1bdc1d777e3e03d439cf44ae04bb21..c1840f12502e34b3cb06b5f3a65842d8e714728a 100644 (file)
--- a/gpio.vhdl
+++ b/gpio.vhdl
@@ -58,7 +58,7 @@ begin
 
     -- Wishbone response
     wb_rsp.ack <= wb_in.cyc and wb_in.stb;
-    with wb_in.adr(GPIO_REG_BITS + 1 downto 2) select reg_out <=
+    with wb_in.adr(GPIO_REG_BITS - 1 downto 0) select reg_out <=
         reg_data when GPIO_REG_DATA_OUT,
         reg_in2  when GPIO_REG_DATA_IN,
         reg_dirn when GPIO_REG_DIR,
@@ -79,7 +79,7 @@ begin
                 wb_out.ack <= '0';
             else
                 if wb_in.cyc = '1' and wb_in.stb = '1' and wb_in.we = '1' then
-                    case wb_in.adr(GPIO_REG_BITS + 1 downto 2) is
+                    case wb_in.adr(GPIO_REG_BITS - 1 downto 0) is
                         when GPIO_REG_DATA_OUT =>
                             reg_data <= wb_in.dat(NGPIO - 1 downto 0);
                         when GPIO_REG_DIR =>
index 30dbd28226c1d55a2f0e80d92bd2eed73b5868bf..7937ff64f323e17c12d41a5f407a6ffc7cb716b7 100644 (file)
@@ -237,7 +237,7 @@ architecture rtl of icache is
     end;
 
     -- Return the cache row index (data memory) for an address
-    function get_row(addr: std_ulogic_vector(63 downto 0)) return row_t is
+    function get_row(addr: std_ulogic_vector) return row_t is
     begin
         return to_integer(unsigned(addr(SET_SIZE_BITS - 1 downto ROW_OFF_BITS)));
     end;
@@ -253,7 +253,7 @@ architecture rtl of icache is
     -- Returns whether this is the last row of a line
     function is_last_row_addr(addr: wishbone_addr_type; last: row_in_line_t) return boolean is
     begin
-       return unsigned(addr(LINE_OFF_BITS-1 downto ROW_OFF_BITS)) = last;
+       return unsigned(addr(LINE_OFF_BITS - ROW_OFF_BITS - 1 downto 0)) = last;
     end;
 
     -- Returns whether this is the last row of a line
@@ -269,10 +269,10 @@ architecture rtl of icache is
        variable result  : wishbone_addr_type;
     begin
        -- Is there no simpler way in VHDL to generate that 3 bits adder ?
-       row_idx := addr(LINE_OFF_BITS-1 downto ROW_OFF_BITS);
+       row_idx := addr(ROW_LINEBITS - 1 downto 0);
        row_idx := std_ulogic_vector(unsigned(row_idx) + 1);
        result := addr;
-       result(LINE_OFF_BITS-1 downto ROW_OFF_BITS) := row_idx;
+       result(ROW_LINEBITS - 1 downto 0) := row_idx;
        return result;
     end;
 
@@ -525,7 +525,7 @@ begin
        -- used for cache miss processing if needed
        --
        req_laddr <= (63 downto REAL_ADDR_BITS => '0') &
-                     real_addr(REAL_ADDR_BITS - 1 downto ROW_OFF_BITS) &
+                     real_addr(REAL_ADDR_BITS - 1 downto ROW_OFF_BITS)&
                     (ROW_OFF_BITS-1 downto 0 => '0');
 
        -- Test if pending request is a hit on any way
@@ -658,7 +658,7 @@ begin
                 -- Since we never write, any write should be snooped
                 snoop_valid <= wb_snoop_in.cyc and wb_snoop_in.stb and wb_snoop_in.we;
                 snoop_addr := (others => '0');
-                snoop_addr(wb_snoop_in.adr'left downto 0) := wb_snoop_in.adr;
+                snoop_addr(wb_snoop_in.adr'left + ROW_OFF_BITS downto ROW_OFF_BITS) := wb_snoop_in.adr;
                 snoop_index <= get_index(snoop_addr);
                 snoop_cache_tags := cache_tags(get_index(snoop_addr));
                 snoop_tag := get_tag(snoop_addr, '0');
@@ -717,7 +717,7 @@ begin
                        -- Prep for first wishbone read. We calculate the address of
                        -- the start of the cache line and start the WB cycle.
                        --
-                       r.wb.adr <= req_laddr(r.wb.adr'left downto 0);
+                       r.wb.adr <= req_laddr(r.wb.adr'left + ROW_OFF_BITS downto ROW_OFF_BITS);
                        r.wb.cyc <= '1';
                        r.wb.stb <= '1';
 
@@ -804,7 +804,7 @@ begin
                 log_data <= i_out.valid &
                             i_out.insn &
                             wishbone_in.ack &
-                            r.wb.adr(5 downto 3) &
+                            r.wb.adr(2 downto 0) &
                             r.wb.stb & r.wb.cyc &
                             wishbone_in.stall &
                             stall_out &
index 5823f199149e5350e0202405c8ebf15934b7b4c5..ff68601ad864d061ce981c440364a6ddc95bf77c 100644 (file)
@@ -163,7 +163,6 @@ architecture behaviour of litedram_wrapper is
     -- Select a WB word inside DRAM port width
     constant WB_WORD_COUNT              : positive := DRAM_DBITS/WBL;
     constant WB_WSEL_BITS               : positive := log2(WB_WORD_COUNT);
-    constant WB_WSEL_RIGHT              : positive := log2(WBL/8);
 
     -- BRAM organisation: We never access more than wishbone_data_bits at
     -- a time so to save resources we make the array only that wide, and
@@ -312,10 +311,20 @@ architecture behaviour of litedram_wrapper is
     -- Helper functions to decode incoming requests
     --
 
+    -- Return the DRAM real address from a wishbone address
+    function get_real_addr(addr: wishbone_addr_type) return std_ulogic_vector is
+        variable ra: std_ulogic_vector(REAL_ADDR_BITS - 1 downto 0) := (others => '0');
+    begin
+        ra(REAL_ADDR_BITS - 1 downto wishbone_log2_width) :=
+            addr(REAL_ADDR_BITS - wishbone_log2_width - 1 downto 0);
+        return ra;
+    end;
+
     -- Return the cache line index (tag index) for an address
     function get_index(addr: wishbone_addr_type) return index_t is
     begin
-        return to_integer(unsigned(addr(SET_SIZE_BITS - 1 downto LINE_OFF_BITS)));
+        return to_integer(unsigned(addr(SET_SIZE_BITS - wishbone_log2_width - 1 downto
+                                        LINE_OFF_BITS - wishbone_log2_width)));
     end;
 
     -- Return the cache row index (data memory) for an address
@@ -378,7 +387,8 @@ architecture behaviour of litedram_wrapper is
     -- Get the tag value from the address
     function get_tag(addr: wishbone_addr_type) return cache_tag_t is
     begin
-        return addr(REAL_ADDR_BITS - 1 downto SET_SIZE_BITS);
+        return addr(REAL_ADDR_BITS - wishbone_log2_width - 1 downto
+                    SET_SIZE_BITS - wishbone_log2_width);
     end;
 
     -- Read a tag from a tag memory row
@@ -447,7 +457,7 @@ begin
                 wb_ctrl_stb <= '0';
             else
                 -- XXX Maybe only update addr when cyc = '1' to save power ?
-                wb_ctrl_adr   <= x"0000" & wb_ctrl_in.adr(15 downto 2);
+                wb_ctrl_adr   <= x"0000" & wb_ctrl_in.adr(13 downto 0);
                 wb_ctrl_dat_w <= wb_ctrl_in.dat;
                 wb_ctrl_sel   <= wb_ctrl_in.sel;
                 wb_ctrl_we    <= wb_ctrl_in.we;
@@ -608,7 +618,7 @@ begin
             if stall = '1' and wb_out.stall = '0' and wb_in.cyc = '1' and wb_in.stb = '1' then
                  wb_stash <= wb_in;
                  if TRACE then
-                     report "stashed wb req ! addr:" & to_hstring(wb_in.adr) &
+                     report "stashed wb req ! addr:" & to_hstring(wb_in.adr & "000") &
                          " we:" & std_ulogic'image(wb_in.we) &
                          " sel:" & to_hstring(wb_in.sel);
                  end if;
@@ -621,7 +631,7 @@ begin
                     wb_req <= wb_stash;
                     wb_stash.cyc <= '0';
                     if TRACE then
-                        report "unstashed wb req ! addr:" & to_hstring(wb_stash.adr) &
+                        report "unstashed wb req ! addr:" & to_hstring(wb_stash.adr & "000") &
                             " we:" & std_ulogic'image(wb_stash.we) &
                             " sel:" & to_hstring(wb_stash.sel);
                     end if;
@@ -636,7 +646,7 @@ begin
 
                     if TRACE then
                         if wb_in.cyc = '1' and wb_in.stb = '1' then
-                            report "latch new wb req ! addr:" & to_hstring(wb_in.adr) &
+                            report "latch new wb req ! addr:" & to_hstring(wb_in.adr & "000") &
                                 " we:" & std_ulogic'image(wb_in.we) &
                                 " sel:" & to_hstring(wb_in.sel);
                         end if;
@@ -665,12 +675,12 @@ begin
 
             if TRACE then
                 if req_op = OP_LOAD_HIT then
-                    report "Load hit addr:" & to_hstring(wb_req.adr) &
+                    report "Load hit addr:" & to_hstring(wb_req.adr & "000") &
                         " idx:" & integer'image(req_index) &
                         " tag:" & to_hstring(req_tag) &
                         " way:" & integer'image(req_hit_way);
                 elsif req_op = OP_LOAD_MISS then
-                    report "Load miss addr:" & to_hstring(wb_req.adr);
+                    report "Load miss addr:" & to_hstring(wb_req.adr & "000");
                 end if;
                 if read_ack_0 = '1' then
                     report "read data:" & to_hstring(cache_out(read_way_0));
@@ -771,20 +781,19 @@ begin
     begin
         -- Extract line, row and tag from request
         req_index <= get_index(wb_req.adr);
-        req_row <= get_row(wb_req.adr(REAL_ADDR_BITS-1 downto 0));
+        req_row <= get_row(get_real_addr(wb_req.adr));
         req_tag <= get_tag(wb_req.adr);
 
         -- Calculate address of beginning of cache row, will be
         -- used for cache miss processing if needed
-        req_laddr <= wb_req.adr(REAL_ADDR_BITS - 1 downto ROW_OFF_BITS) &
-                     (ROW_OFF_BITS-1 downto 0 => '0');
+        req_laddr <= get_real_addr(wb_req.adr);
 
 
         -- Do we have a valid request in the WB latch ?
         valid := wb_req.cyc = '1' and wb_req.stb = '1';
 
         -- Store signals (hard wired for 64-bit wishbone at the moment)
-        req_wsl <= wb_req.adr(WB_WSEL_RIGHT+WB_WSEL_BITS-1 downto WB_WSEL_RIGHT);
+        req_wsl <= wb_req.adr(WB_WSEL_BITS-1 downto 0);
         for i in 0 to WB_WORD_COUNT-1 loop
             if to_integer(unsigned(req_wsl)) = i then
                 req_we(WBSL*(i+1)-1 downto WBSL*i) <= wb_req.sel;
@@ -892,7 +901,7 @@ begin
         variable stq_wsl  : std_ulogic_vector(WB_WSEL_BITS-1 downto 0);
     begin
         storeq_wr_data <= wb_req.dat & wb_req.sel &
-                          wb_req.adr(WB_WSEL_RIGHT+WB_WSEL_BITS-1 downto WB_WSEL_RIGHT);
+                          wb_req.adr(WB_WSEL_BITS-1 downto 0);
 
         -- Only queue stores if we can also send a command
         if req_op = OP_STORE_HIT or req_op = OP_STORE_MISS then
@@ -927,13 +936,13 @@ begin
             if rising_edge(system_clk) then
                 if req_op = OP_STORE_HIT then
                     report "Store hit to:" &
-                        to_hstring(wb_req.adr(DRAM_ABITS+3 downto 0)) &
+                        to_hstring(wb_req.adr(DRAM_ABITS downto 0) & "000") &
                         " data:" & to_hstring(req_wdata) &
                         " we:" & to_hstring(req_we) &
                         " V:" & std_ulogic'image(user_port0_cmd_ready);
                 else
                     report "Store miss to:" &
-                        to_hstring(wb_req.adr(DRAM_ABITS+3 downto 0)) &
+                        to_hstring(wb_req.adr(DRAM_ABITS downto 0) & "000") &
                         " data:" & to_hstring(req_wdata) &
                         " we:" & to_hstring(req_we) &
                         " V:" & std_ulogic'image(user_port0_cmd_ready);
@@ -954,7 +963,8 @@ begin
         if req_op = OP_STORE_HIT or req_op = OP_STORE_MISS then
             -- For stores, forward signals directly. Only send command if
             -- the FIFO can accept a store.
-            user_port0_cmd_addr  <= wb_req.adr(DRAM_ABITS+ROW_OFF_BITS-1 downto ROW_OFF_BITS);
+            user_port0_cmd_addr  <= wb_req.adr(DRAM_ABITS + ROW_OFF_BITS - wishbone_log2_width - 1 downto
+                                               ROW_OFF_BITS - wishbone_log2_width);
             user_port0_cmd_we    <= '1';
             user_port0_cmd_valid <= storeq_wr_ready;
         else
index 395602bb1d9216d2a8a8c494f19048971ff4a095..231249eddd7a5fd583e18073ec9f40f43915c3c0 100644 (file)
@@ -100,7 +100,7 @@ begin
         if rising_edge(clk) then
             oack <= '0';
             if (wb_in.cyc and wb_in.stb) = '1' then
-                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
+                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS - 3 downto 0))));
                 if wb_in.we = '0' then
                    obuf <= init_ram(adr);
                 else
index 395602bb1d9216d2a8a8c494f19048971ff4a095..231249eddd7a5fd583e18073ec9f40f43915c3c0 100644 (file)
@@ -100,7 +100,7 @@ begin
         if rising_edge(clk) then
             oack <= '0';
             if (wb_in.cyc and wb_in.stb) = '1' then
-                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
+                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS - 3 downto 0))));
                 if wb_in.we = '0' then
                    obuf <= init_ram(adr);
                 else
index 395602bb1d9216d2a8a8c494f19048971ff4a095..231249eddd7a5fd583e18073ec9f40f43915c3c0 100644 (file)
@@ -100,7 +100,7 @@ begin
         if rising_edge(clk) then
             oack <= '0';
             if (wb_in.cyc and wb_in.stb) = '1' then
-                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
+                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS - 3 downto 0))));
                 if wb_in.we = '0' then
                    obuf <= init_ram(adr);
                 else
index 395602bb1d9216d2a8a8c494f19048971ff4a095..231249eddd7a5fd583e18073ec9f40f43915c3c0 100644 (file)
@@ -100,7 +100,7 @@ begin
         if rising_edge(clk) then
             oack <= '0';
             if (wb_in.cyc and wb_in.stb) = '1' then
-                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
+                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS - 3 downto 0))));
                 if wb_in.we = '0' then
                    obuf <= init_ram(adr);
                 else
index 395602bb1d9216d2a8a8c494f19048971ff4a095..231249eddd7a5fd583e18073ec9f40f43915c3c0 100644 (file)
@@ -100,7 +100,7 @@ begin
         if rising_edge(clk) then
             oack <= '0';
             if (wb_in.cyc and wb_in.stb) = '1' then
-                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
+                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS - 3 downto 0))));
                 if wb_in.we = '0' then
                    obuf <= init_ram(adr);
                 else
index 796d45e312bd6fe4c215798a4deed818c6289890..ee03808650dbdd0df0c46a365e562557baf134b5 100644 (file)
@@ -100,7 +100,7 @@ begin
         if rising_edge(clk) then
             oack <= '0';
             if (wb_in.cyc and wb_in.stb) = '1' then
-                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
+                adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS - 3 downto 0))));
                 if wb_in.we = '0' then
                    obuf <= init_ram(adr);
                 else
index 3cbba7a8dfc7dcc3c0ad123f6f926a5a548dfa38..640c94cc47fa03c388dd50dd0de7aea545bc828d 100644 (file)
--- a/soc.vhdl
+++ b/soc.vhdl
@@ -248,10 +248,10 @@ architecture behaviour of soc is
     function wishbone_widen_data(wb : wb_io_master_out) return wishbone_master_out is
         variable wwb : wishbone_master_out;
     begin
-        wwb.adr := wb.adr & "00";       -- XXX note wrong adr usage in wishbone_master_out
+        wwb.adr := wb.adr(wb.adr'left downto 1);
         wwb.dat := wb.dat & wb.dat;
         wwb.sel := x"00";
-        if wwb.adr(2) = '0' then
+        if wb.adr(0) = '0' then
             wwb.sel(3 downto 0) := wb.sel;
         else
             wwb.sel(7 downto 4) := wb.sel;
@@ -405,7 +405,7 @@ begin
         variable top_decode : std_ulogic_vector(3 downto 0);
     begin
        -- Top-level address decoder
-        top_decode := wb_master_out.adr(31 downto 29) & dram_at_0;
+        top_decode := wb_master_out.adr(28 downto 26) & dram_at_0;
         slave_top := SLAVE_TOP_BRAM;
        if    std_match(top_decode, "0000") then
            slave_top := SLAVE_TOP_BRAM;
@@ -491,7 +491,7 @@ begin
 
                         -- Copy write enable to IO out, copy address as well
                         wb_sio_out.we <= wb_io_in.we;
-                        wb_sio_out.adr <= wb_io_in.adr(wb_sio_out.adr'left downto 3) & "000";
+                        wb_sio_out.adr <= wb_io_in.adr(wb_sio_out.adr'left - 1 downto 0) & '0';
 
                         -- Do we have a top word and/or a bottom word ?
                         has_top := wb_io_in.sel(7 downto 4) /= "0000";
@@ -515,7 +515,7 @@ begin
                             wb_sio_out.sel <= wb_io_in.sel(7 downto 4);
 
                             -- Bump address
-                            wb_sio_out.adr(2) <= '1';
+                            wb_sio_out.adr(0) <= '1';
 
                             -- Wait for ack
                             state := WAIT_ACK_TOP;
@@ -543,7 +543,7 @@ begin
                             wb_sio_out.sel <= wb_io_in.sel(7 downto 4);
 
                             -- Bump address and set STB
-                            wb_sio_out.adr(2) <= '1';
+                            wb_sio_out.adr(0) <= '1';
                             wb_sio_out.stb <= '1';
 
                             -- Wait for new ack
@@ -601,7 +601,7 @@ begin
 
        -- Simple address decoder.
        slave_io := SLAVE_IO_NONE;
-        match := "11" & wb_sio_out.adr(29 downto 12);
+        match := "11" & wb_sio_out.adr(27 downto 10);
         if    std_match(match, x"FF---") and HAS_DRAM then
            slave_io := SLAVE_IO_EXTERNAL;
         elsif std_match(match, x"F----") then
@@ -638,11 +638,11 @@ begin
         -- Only give xics 8 bits of wb addr (for now...)
        wb_xics_icp_in <= wb_sio_out;
        wb_xics_icp_in.adr <= (others => '0');
-       wb_xics_icp_in.adr(7 downto 0) <= wb_sio_out.adr(7 downto 0);
+       wb_xics_icp_in.adr(5 downto 0) <= wb_sio_out.adr(5 downto 0);
        wb_xics_icp_in.cyc  <= '0';
        wb_xics_ics_in <= wb_sio_out;
        wb_xics_ics_in.adr <= (others => '0');
-       wb_xics_ics_in.adr(11 downto 0) <= wb_sio_out.adr(11 downto 0);
+       wb_xics_ics_in.adr(9 downto 0) <= wb_sio_out.adr(9 downto 0);
        wb_xics_ics_in.cyc  <= '0';
 
        wb_ext_io_in <= wb_sio_out;
@@ -667,22 +667,22 @@ begin
             --
             -- DRAM init is special at 0xFF* so we just test the top
             -- bit. Everything else is at 0xC8* so we test only bits
-            -- 23 downto 16.
+            -- 23 downto 16 (21 downto 14 in the wishbone addr).
             --
             ext_valid := false;
-            if wb_sio_out.adr(29) = '1' and HAS_DRAM then  -- DRAM init is special
+            if wb_sio_out.adr(27) = '1' and HAS_DRAM then  -- DRAM init is special
                 wb_ext_is_dram_init <= '1';
                 ext_valid := true;
-            elsif wb_sio_out.adr(23 downto 16) = x"00" and HAS_DRAM then
+            elsif wb_sio_out.adr(21 downto 14) = x"00" and HAS_DRAM then
                 wb_ext_is_dram_csr  <= '1';
                 ext_valid := true;
-            elsif wb_sio_out.adr(23 downto 16) = x"02" and HAS_LITEETH then
+            elsif wb_sio_out.adr(21 downto 14) = x"02" and HAS_LITEETH then
                 wb_ext_is_eth       <= '1';
                 ext_valid := true;
-            elsif wb_sio_out.adr(23 downto 16) = x"03" and HAS_LITEETH then
+            elsif wb_sio_out.adr(21 downto 14) = x"03" and HAS_LITEETH then
                 wb_ext_is_eth       <= '1';
                 ext_valid := true;
-            elsif wb_sio_out.adr(23 downto 16) = x"04" and HAS_SD_CARD then
+            elsif wb_sio_out.adr(21 downto 14) = x"04" and HAS_SD_CARD then
                 wb_ext_is_sdcard    <= '1';
                 ext_valid := true;
             end if;
@@ -709,7 +709,7 @@ begin
        when SLAVE_IO_SPI_FLASH_MAP =>
             -- Clear top bits so they don't make their way to the
             -- fash chip.
-            wb_spiflash_in.adr(29 downto 28) <= "00";
+            wb_spiflash_in.adr(27 downto 26) <= "00";
            wb_spiflash_in.cyc <= wb_sio_out.cyc;
            wb_sio_in <= wb_spiflash_out;
             wb_spiflash_is_map <= '1';
@@ -767,7 +767,7 @@ begin
                txd => uart0_txd,
                rxd => uart0_rxd,
                irq => uart0_irq,
-               wb_adr_in => wb_uart0_in.adr(11 downto 0),
+               wb_adr_in => wb_uart0_in.adr(9 downto 0) & "00",
                wb_dat_in => wb_uart0_in.dat(7 downto 0),
                wb_dat_out => uart0_dat8,
                wb_cyc_in => wb_uart0_in.cyc,
@@ -784,7 +784,7 @@ begin
            port map (
                wb_clk_i   => system_clk,
                wb_rst_i   => rst_uart,
-               wb_adr_i   => wb_uart0_in.adr(4 downto 2),
+               wb_adr_i   => wb_uart0_in.adr(2 downto 0),
                wb_dat_i   => wb_uart0_in.dat(7 downto 0),
                wb_dat_o   => uart0_dat8,
                wb_we_i    => wb_uart0_in.we,
@@ -826,7 +826,7 @@ begin
            port map (
                wb_clk_i   => system_clk,
                wb_rst_i   => rst_uart,
-               wb_adr_i   => wb_uart1_in.adr(4 downto 2),
+               wb_adr_i   => wb_uart1_in.adr(2 downto 0),
                wb_dat_i   => wb_uart1_in.dat(7 downto 0),
                wb_dat_o   => uart1_dat8,
                wb_we_i    => wb_uart1_in.we,
index d45be902ed5a72859a9b2fce194f2441c537297c..27e89263b5cad033324b47c47b012df868249cc1 100644 (file)
@@ -43,7 +43,7 @@ architecture rtl of spi_flash_ctrl is
     -- Register indices
     constant SPI_REG_BITS       : positive := 3;
 
-    -- Register addresses (matches wishbone addr downto 2, ie, 4 bytes per reg)
+    -- Register addresses (matches wishbone addr downto 0, ie, 4 bytes per reg)
     constant SPI_REG_DATA         : std_ulogic_vector(SPI_REG_BITS-1 downto 0) := "000";
     constant SPI_REG_CTRL         : std_ulogic_vector(SPI_REG_BITS-1 downto 0) := "001";
     constant SPI_REG_AUTO_CFG     : std_ulogic_vector(SPI_REG_BITS-1 downto 0) := "010";
@@ -162,7 +162,7 @@ begin
     wb_map_valid <= wb_valid and wb_sel_map;
 
     -- Register decode. For map accesses, make it look like "invalid"
-    wb_reg       <= wb_req.adr(SPI_REG_BITS+1 downto 2) when wb_reg_valid else SPI_REG_INVALID;
+    wb_reg       <= wb_req.adr(SPI_REG_BITS - 1 downto 0) when wb_reg_valid else SPI_REG_INVALID;
 
     -- Shortcut because we test that a lot: data register access
     wb_reg_dat_v <= '1' when wb_reg = SPI_REG_DATA else '0';
@@ -393,7 +393,7 @@ begin
 
         -- Convert wishbone address into a flash address. We mask
         -- off the 4 top address bits to get rid of the "f" there.
-        addr := "00" & wb_req.adr(29 downto 2) & "00";
+        addr := "00" & wb_req.adr(27 downto 0) & "00";
 
         -- Calculate the next address for store & compare later
         auto_lad_next <= std_ulogic_vector(unsigned(addr) + 4);
index 2f8bd474d65b8442e334ec4c36ea9b344b777585..5e6cb0091a64a147112d76a0a3caf0cda5bebadb 100644 (file)
@@ -171,7 +171,7 @@ begin
 
     -- Wishbone response
     wb_rsp.ack <= wishbone_in.cyc and wishbone_in.stb;
-    with wishbone_in.adr(SYS_REG_BITS+2 downto 3) select reg_out <=
+    with wishbone_in.adr(SYS_REG_BITS downto 1) select reg_out <=
        SIG_VALUE       when SYS_REG_SIG,
        reg_info        when SYS_REG_INFO,
        reg_braminfo    when SYS_REG_BRAMINFO,
@@ -183,7 +183,7 @@ begin
         reg_uart0info   when SYS_REG_UART0_INFO,
         reg_uart1info   when SYS_REG_UART1_INFO,
        (others => '0') when others;
-    wb_rsp.dat   <= reg_out(63 downto 32) when wishbone_in.adr(2) = '1' else
+    wb_rsp.dat   <= reg_out(63 downto 32) when wishbone_in.adr(0) = '1' else
                   reg_out(31 downto 0);
     wb_rsp.stall <= '0';
 
@@ -205,8 +205,8 @@ begin
            else
                if wishbone_in.cyc and wishbone_in.stb and wishbone_in.we then
                     -- Change this if CTRL ever has more than 32 bits
-                   if wishbone_in.adr(SYS_REG_BITS+2 downto 3) = SYS_REG_CTRL and
-                        wishbone_in.adr(2) = '0' then
+                   if wishbone_in.adr(SYS_REG_BITS downto 1) = SYS_REG_CTRL and
+                        wishbone_in.adr(0) = '0' then
                        reg_ctrl(SYS_REG_CTRL_BITS-1 downto 0) <=
                            wishbone_in.dat(SYS_REG_CTRL_BITS-1 downto 0);
                    end if;
index 7c00eb1db38e0ae4d833c9aba92f916963ca0940..afb45b8f2463a6e636d15bacd136521251dbf0de 100644 (file)
@@ -19,7 +19,7 @@ architecture behave of wishbone_bram_tb is
 
     impure function to_adr(a: integer) return std_ulogic_vector is
     begin
-        return std_ulogic_vector(to_unsigned(a, w_out.adr'length));
+        return std_ulogic_vector(to_unsigned(a / 8, w_out.adr'length));
     end;
 begin
     simple_ram_0: entity work.wishbone_bram_wrapper
index 9464c11bb8a73c398bba66c7b85000ea2cde9afe..182fd29d745c1eb0b1943334204056ce949a48ff 100644 (file)
@@ -54,7 +54,7 @@ begin
            );
 
     -- Wishbone interface
-    ram_addr <= wishbone_in.adr(ram_addr_bits + 2 downto 3);
+    ram_addr <= wishbone_in.adr(ram_addr_bits - 1 downto 0);
     ram_we <= wishbone_in.stb and wishbone_in.cyc and wishbone_in.we;
     ram_re <= wishbone_in.stb and wishbone_in.cyc and not wishbone_in.we;
     wishbone_out.stall <= '0';
index e0d5923e40fe567205a9569fcfbfcd616676f0c9..272f56076d08c5e2f4d2cf2e2791d5b7717e7cb4 100644 (file)
@@ -118,7 +118,7 @@ begin
     dmi_ack <= dmi_req when (dmi_addr /= DBG_WB_DATA or state = DMI_WAIT) else '0';
 
         -- Some WB signals are direct wires from registers or DMI
-    wb_out.adr <= reg_addr(wb_out.adr'left downto 0);
+    wb_out.adr <= reg_addr(wb_out.adr'left + wishbone_log2_width downto wishbone_log2_width);
     wb_out.dat <= dmi_din;
     wb_out.sel <= reg_ctrl(7 downto 0);
     wb_out.we  <= dmi_wr;
index 2df1eb314960343ac7e67bfa57e64fdff08d1797..8cb3e9b010889fd5e1456d8c6c253bcd47ade9bd 100644 (file)
@@ -3,11 +3,13 @@ use ieee.std_logic_1164.all;
 
 package wishbone_types is
     --
-    -- Main CPU bus. 32-bit address, 64-bit data
+    -- Main CPU bus. 32-bit address, 64-bit data,
+    -- so the wishbone address is in units of 8 bytes.
     --
-    constant wishbone_addr_bits : integer := 32;
+    constant wishbone_addr_bits : integer := 29;
     constant wishbone_data_bits : integer := 64;
     constant wishbone_sel_bits : integer := wishbone_data_bits/8;
+    constant wishbone_log2_width : integer := 3;
 
     subtype wishbone_addr_type is std_ulogic_vector(wishbone_addr_bits-1 downto 0);
     subtype wishbone_data_type is std_ulogic_vector(wishbone_data_bits-1 downto 0);
index 45758f8a7c93cb8d45a173210ac285f0d3f68df0..0e3a1da7b504313944b66457aa15e3dace94357d 100644 (file)
--- a/xics.vhdl
+++ b/xics.vhdl
@@ -111,7 +111,7 @@ begin
             v.wb_ack := '1'; -- always ack
             if wb_in.we = '1' then -- write
                 -- writes to both XIRR are the same
-                case wb_in.adr(7 downto 0) is
+                case wb_in.adr(5 downto 0) & "00" is
                 when XIRR_POLL =>
                     report "ICP XIRR_POLL write";
                     v.cppr := be_in(31 downto 24);
@@ -138,7 +138,7 @@ begin
 
             else -- read
 
-                case wb_in.adr(7 downto 0) is
+                case wb_in.adr(5 downto 0) & "00" is
                 when XIRR_POLL =>
                     report "ICP XIRR_POLL read";
                     be_out := r.cppr & r.xisr;
@@ -308,12 +308,12 @@ begin
 
     assert SRC_NUM = 16 report "Fixup address decode with log2";
 
-    reg_is_xive   <= wb_in.adr(11);
-    reg_is_config <= '1' when wb_in.adr(11 downto 0) = x"000" else '0';
-    reg_is_debug  <= '1' when wb_in.adr(11 downto 0) = x"004" else '0';
+    reg_is_xive   <= wb_in.adr(9);
+    reg_is_config <= '1' when wb_in.adr(9 downto 0) = 10x"000" else '0';
+    reg_is_debug  <= '1' when wb_in.adr(9 downto 0) = 10x"001" else '0';
 
     -- Register index XX FIXME: figure out bits from SRC_NUM
-    reg_idx <= to_integer(unsigned(wb_in.adr(5 downto 2)));
+    reg_idx <= to_integer(unsigned(wb_in.adr(3 downto 0)));
 
     -- Latch interrupt inputs for timing
     int_latch: process(clk)