@ -163,7 +163,6 @@ architecture behaviour of litedram_wrapper is
-- Select a WB word inside DRAM port width
-- Select a WB word inside DRAM port width
constant WB_WORD_COUNT : positive := DRAM_DBITS/WBL;
constant WB_WORD_COUNT : positive := DRAM_DBITS/WBL;
constant WB_WSEL_BITS : positive := log2(WB_WORD_COUNT);
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
-- 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
-- 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
-- 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
-- Return the cache line index (tag index) for an address
function get_index(addr: wishbone_addr_type) return index_t is
function get_index(addr: wishbone_addr_type) return index_t is
begin
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;
end;
-- Return the cache row index (data memory) for an address
-- 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
-- Get the tag value from the address
function get_tag(addr: wishbone_addr_type) return cache_tag_t is
function get_tag(addr: wishbone_addr_type) return cache_tag_t is
begin
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;
end;
-- Read a tag from a tag memory row
-- Read a tag from a tag memory row
@ -447,7 +457,7 @@ begin
wb_ctrl_stb <= '0';
wb_ctrl_stb <= '0';
else
else
-- XXX Maybe only update addr when cyc = '1' to save power ?
-- 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_dat_w <= wb_ctrl_in.dat;
wb_ctrl_sel <= wb_ctrl_in.sel;
wb_ctrl_sel <= wb_ctrl_in.sel;
wb_ctrl_we <= wb_ctrl_in.we;
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
if stall = '1' and wb_out.stall = '0' and wb_in.cyc = '1' and wb_in.stb = '1' then
wb_stash <= wb_in;
wb_stash <= wb_in;
if TRACE then
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) &
" we:" & std_ulogic'image(wb_in.we) &
" sel:" & to_hstring(wb_in.sel);
" sel:" & to_hstring(wb_in.sel);
end if;
end if;
@ -621,7 +631,7 @@ begin
wb_req <= wb_stash;
wb_req <= wb_stash;
wb_stash.cyc <= '0';
wb_stash.cyc <= '0';
if TRACE then
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) &
" we:" & std_ulogic'image(wb_stash.we) &
" sel:" & to_hstring(wb_stash.sel);
" sel:" & to_hstring(wb_stash.sel);
end if;
end if;
@ -636,7 +646,7 @@ begin
if TRACE then
if TRACE then
if wb_in.cyc = '1' and wb_in.stb = '1' 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) &
" we:" & std_ulogic'image(wb_in.we) &
" sel:" & to_hstring(wb_in.sel);
" sel:" & to_hstring(wb_in.sel);
end if;
end if;
@ -665,12 +675,12 @@ begin
if TRACE then
if TRACE then
if req_op = OP_LOAD_HIT 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) &
" idx:" & integer'image(req_index) &
" tag:" & to_hstring(req_tag) &
" tag:" & to_hstring(req_tag) &
" way:" & integer'image(req_hit_way);
" way:" & integer'image(req_hit_way);
elsif req_op = OP_LOAD_MISS then
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;
end if;
if read_ack_0 = '1' then
if read_ack_0 = '1' then
report "read data:" & to_hstring(cache_out(read_way_0));
report "read data:" & to_hstring(cache_out(read_way_0));
@ -771,20 +781,19 @@ begin
begin
begin
-- Extract line, row and tag from request
-- Extract line, row and tag from request
req_index <= get_index(wb_req.adr);
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);
req_tag <= get_tag(wb_req.adr);
-- Calculate address of beginning of cache row, will be
-- Calculate address of beginning of cache row, will be
-- used for cache miss processing if needed
-- used for cache miss processing if needed
req_laddr <= wb_req.adr(REAL_ADDR_BITS - 1 downto ROW_OFF_BITS) &
req_laddr <= get_real_addr(wb_req.adr);
(ROW_OFF_BITS-1 downto 0 => '0');
-- Do we have a valid request in the WB latch ?
-- Do we have a valid request in the WB latch ?
valid := wb_req.cyc = '1' and wb_req.stb = '1';
valid := wb_req.cyc = '1' and wb_req.stb = '1';
-- Store signals (hard wired for 64-bit wishbone at the moment)
-- 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
for i in 0 to WB_WORD_COUNT-1 loop
if to_integer(unsigned(req_wsl)) = i then
if to_integer(unsigned(req_wsl)) = i then
req_we(WBSL*(i+1)-1 downto WBSL*i) <= wb_req.sel;
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);
variable stq_wsl : std_ulogic_vector(WB_WSEL_BITS-1 downto 0);
begin
begin
storeq_wr_data <= wb_req.dat & wb_req.sel &
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
-- Only queue stores if we can also send a command
if req_op = OP_STORE_HIT or req_op = OP_STORE_MISS then
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 rising_edge(system_clk) then
if req_op = OP_STORE_HIT then
if req_op = OP_STORE_HIT then
report "Store hit to:" &
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) &
" data:" & to_hstring(req_wdata) &
" we:" & to_hstring(req_we) &
" we:" & to_hstring(req_we) &
" V:" & std_ulogic'image(user_port0_cmd_ready);
" V:" & std_ulogic'image(user_port0_cmd_ready);
else
else
report "Store miss to:" &
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) &
" data:" & to_hstring(req_wdata) &
" we:" & to_hstring(req_we) &
" we:" & to_hstring(req_we) &
" V:" & std_ulogic'image(user_port0_cmd_ready);
" 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
if req_op = OP_STORE_HIT or req_op = OP_STORE_MISS then
-- For stores, forward signals directly. Only send command if
-- For stores, forward signals directly. Only send command if
-- the FIFO can accept a store.
-- 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_we <= '1';
user_port0_cmd_valid <= storeq_wr_ready;
user_port0_cmd_valid <= storeq_wr_ready;
else
else