-- 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
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;
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);
-- 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;
-- 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;
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 &
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
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
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
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;
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;
-- 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;
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;
-- 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;
-- 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,
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 =>
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;
-- 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
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;
-- 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
-- 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');
-- 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';
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 &
-- 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
-- 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
-- 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
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;
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;
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;
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;
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));
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;
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
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);
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
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
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
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
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
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
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
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;
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;
-- 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";
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;
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
-- 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
-- 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;
--
-- 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;
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';
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,
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,
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,
-- 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";
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';
-- 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);
-- 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,
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';
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;
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
);
-- 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';
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;
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);
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);
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;
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)