Make wishbone addresses be in units of doublewords or words

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>
icbi-issue
Paul Mackerras 3 years ago
parent bb5f356386
commit ca4eb46aea

@ -456,7 +456,7 @@ architecture rtl of dcache is
-- Returns whether this is the last row of a line -- 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 function is_last_row_addr(addr: wishbone_addr_type; last: row_in_line_t) return boolean is
begin 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; end;


-- Returns whether this is the last row of a line -- Returns whether this is the last row of a line
@ -471,10 +471,10 @@ architecture rtl of dcache is
variable result : wishbone_addr_type; variable result : wishbone_addr_type;
begin begin
-- Is there no simpler way in VHDL to generate that 3 bits adder ? -- 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); row_idx := std_ulogic_vector(unsigned(row_idx) + 1);
result := addr; result := addr;
result(LINE_OFF_BITS-1 downto ROW_OFF_BITS) := row_idx; result(ROW_LINEBITS - 1 downto 0) := row_idx;
return result; return result;
end; end;


@ -807,7 +807,7 @@ begin
begin begin
if rising_edge(clk) then if rising_edge(clk) then
addr := (others => '0'); 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_tag_set <= cache_tags(get_index(addr));
snoop_wrtag <= get_tag(addr); snoop_wrtag <= get_tag(addr);
snoop_index <= get_index(addr); snoop_index <= get_index(addr);
@ -1383,7 +1383,7 @@ begin
-- Main state machine -- Main state machine
case r1.state is case r1.state is
when IDLE => 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.sel <= req.byte_sel;
r1.wb.dat <= req.data; r1.wb.dat <= req.data;
r1.dcbz <= req.dcbz; r1.dcbz <= req.dcbz;
@ -1532,8 +1532,8 @@ begin
-- See if there is another store waiting to be done -- See if there is another store waiting to be done
-- which is in the same real page. -- which is in the same real page.
if req.valid = '1' then if req.valid = '1' then
r1.wb.adr(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 0); req.real_addr(SET_SIZE_BITS - 1 downto ROW_OFF_BITS);
r1.wb.dat <= req.data; r1.wb.dat <= req.data;
r1.wb.sel <= req.byte_sel; r1.wb.sel <= req.byte_sel;
end if; end if;
@ -1598,7 +1598,7 @@ begin
dcache_log: process(clk) dcache_log: process(clk)
begin begin
if rising_edge(clk) then 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.stall &
wishbone_in.ack & wishbone_in.ack &
r1.wb.stb & r1.wb.cyc & r1.wb.stb & r1.wb.cyc &

@ -250,10 +250,10 @@ begin
report "Back to back 4 stores 4 reads on hit..."; report "Back to back 4 stores 4 reads on hit...";
clr_acks; clr_acks;
for i in 0 to 3 loop 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; end loop;
for i in 0 to 3 loop for i in 0 to 3 loop
wb_read(add_off(a, i*8)); wb_read(add_off(a, i));
end loop; end loop;
wait_acks(8); wait_acks(8);
for i in 0 to 7 loop for i in 0 to 7 loop
@ -268,10 +268,10 @@ begin
a(10) := '1'; a(10) := '1';
clr_acks; clr_acks;
for i in 0 to 3 loop 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; end loop;
for i in 0 to 3 loop for i in 0 to 3 loop
wb_read(add_off(a, i*8)); wb_read(add_off(a, i));
end loop; end loop;
wait_acks(8); wait_acks(8);
for i in 0 to 7 loop for i in 0 to 7 loop
@ -286,8 +286,8 @@ begin
a(10) := '1'; a(10) := '1';
clr_acks; clr_acks;
for i in 0 to 3 loop 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");
wb_read(add_off(a, i*8)); wb_read(add_off(a, i));
end loop; end loop;
wait_acks(8); wait_acks(8);
for i in 0 to 3 loop for i in 0 to 3 loop
@ -299,29 +299,29 @@ begin
a(11) := '1'; a(11) := '1';
clr_acks; clr_acks;
wb_write(add_off(a, 0), x"1111111100000000", x"ff"); 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, 1), x"3333333322222222", x"ff");
wb_write(add_off(a, 16), x"5555555544444444", x"ff"); wb_write(add_off(a, 2), x"5555555544444444", x"ff");
wb_write(add_off(a, 24), x"7777777766666666", x"ff"); wb_write(add_off(a, 3), x"7777777766666666", x"ff");
wb_write(add_off(a, 32), x"9999999988888888", x"ff"); wb_write(add_off(a, 4), x"9999999988888888", x"ff");
wb_write(add_off(a, 40), x"bbbbbbbbaaaaaaaa", x"ff"); wb_write(add_off(a, 5), x"bbbbbbbbaaaaaaaa", x"ff");
wb_write(add_off(a, 48), x"ddddddddcccccccc", x"ff"); wb_write(add_off(a, 6), x"ddddddddcccccccc", x"ff");
wb_write(add_off(a, 56), x"ffffffffeeeeeeee", x"ff"); wb_write(add_off(a, 7), x"ffffffffeeeeeeee", x"ff");
wb_write(add_off(a, 64), x"1111111100000000", x"ff"); wb_write(add_off(a, 8), x"1111111100000000", x"ff");
wb_write(add_off(a, 72), x"3333333322222222", x"ff"); wb_write(add_off(a, 9), x"3333333322222222", x"ff");
wb_write(add_off(a, 80), x"5555555544444444", x"ff"); wb_write(add_off(a, 10), x"5555555544444444", x"ff");
wb_write(add_off(a, 88), x"7777777766666666", x"ff"); wb_write(add_off(a, 11), x"7777777766666666", x"ff");
wb_write(add_off(a, 96), x"9999999988888888", x"ff"); wb_write(add_off(a, 12), x"9999999988888888", x"ff");
wb_write(add_off(a,104), x"bbbbbbbbaaaaaaaa", x"ff"); wb_write(add_off(a, 13), x"bbbbbbbbaaaaaaaa", x"ff");
wb_write(add_off(a,112), x"ddddddddcccccccc", x"ff"); wb_write(add_off(a, 14), x"ddddddddcccccccc", x"ff");
wb_write(add_off(a,120), x"ffffffffeeeeeeee", x"ff"); wb_write(add_off(a, 15), x"ffffffffeeeeeeee", x"ff");
wait_acks(16); wait_acks(16);


report "Scattered from middle of line..."; report "Scattered from middle of line...";
clr_acks; clr_acks;
wb_read(add_off(a,24)); wb_read(add_off(a, 3));
wb_read(add_off(a,32)); wb_read(add_off(a, 4));
wb_read(add_off(a, 0)); wb_read(add_off(a, 0));
wb_read(add_off(a,16)); wb_read(add_off(a, 2));
wait_acks(4); wait_acks(4);
read_data(d); read_data(d);
assert d = x"7777777766666666" report "bad data (24), got " & to_hstring(d) severity failure; assert d = x"7777777766666666" report "bad data (24), got " & to_hstring(d) severity failure;

@ -550,7 +550,7 @@ begin
wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth; 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 -- 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 -- LiteETH isn't pipelined
wb_eth_out.stall <= not wb_eth_out.ack; wb_eth_out.stall <= not wb_eth_out.ack;
@ -640,7 +640,7 @@ begin
-- Gate cyc with chip select from SoC -- Gate cyc with chip select from SoC
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard; 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_sdcard_out.stall <= not wb_sdcard_out.ack;



@ -444,7 +444,7 @@ begin
wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth; 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 -- 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 -- LiteETH isn't pipelined
wb_eth_out.stall <= not wb_eth_out.ack; wb_eth_out.stall <= not wb_eth_out.ack;
@ -533,7 +533,7 @@ begin
-- Gate cyc with chip select from SoC -- Gate cyc with chip select from SoC
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard; 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_sdcard_out.stall <= not wb_sdcard_out.ack;



@ -58,7 +58,7 @@ begin


-- Wishbone response -- Wishbone response
wb_rsp.ack <= wb_in.cyc and wb_in.stb; 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_data when GPIO_REG_DATA_OUT,
reg_in2 when GPIO_REG_DATA_IN, reg_in2 when GPIO_REG_DATA_IN,
reg_dirn when GPIO_REG_DIR, reg_dirn when GPIO_REG_DIR,
@ -79,7 +79,7 @@ begin
wb_out.ack <= '0'; wb_out.ack <= '0';
else else
if wb_in.cyc = '1' and wb_in.stb = '1' and wb_in.we = '1' then 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 => when GPIO_REG_DATA_OUT =>
reg_data <= wb_in.dat(NGPIO - 1 downto 0); reg_data <= wb_in.dat(NGPIO - 1 downto 0);
when GPIO_REG_DIR => when GPIO_REG_DIR =>

@ -237,7 +237,7 @@ architecture rtl of icache is
end; end;


-- Return the cache row index (data memory) for an address -- 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 begin
return to_integer(unsigned(addr(SET_SIZE_BITS - 1 downto ROW_OFF_BITS))); return to_integer(unsigned(addr(SET_SIZE_BITS - 1 downto ROW_OFF_BITS)));
end; end;
@ -253,7 +253,7 @@ architecture rtl of icache is
-- Returns whether this is the last row of a line -- 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 function is_last_row_addr(addr: wishbone_addr_type; last: row_in_line_t) return boolean is
begin 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; end;


-- Returns whether this is the last row of a line -- Returns whether this is the last row of a line
@ -269,10 +269,10 @@ architecture rtl of icache is
variable result : wishbone_addr_type; variable result : wishbone_addr_type;
begin begin
-- Is there no simpler way in VHDL to generate that 3 bits adder ? -- 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); row_idx := std_ulogic_vector(unsigned(row_idx) + 1);
result := addr; result := addr;
result(LINE_OFF_BITS-1 downto ROW_OFF_BITS) := row_idx; result(ROW_LINEBITS - 1 downto 0) := row_idx;
return result; return result;
end; end;


@ -658,7 +658,7 @@ begin
-- Since we never write, any write should be snooped -- 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_valid <= wb_snoop_in.cyc and wb_snoop_in.stb and wb_snoop_in.we;
snoop_addr := (others => '0'); 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_index <= get_index(snoop_addr);
snoop_cache_tags := cache_tags(get_index(snoop_addr)); snoop_cache_tags := cache_tags(get_index(snoop_addr));
snoop_tag := get_tag(snoop_addr, '0'); snoop_tag := get_tag(snoop_addr, '0');
@ -717,7 +717,7 @@ begin
-- Prep for first wishbone read. We calculate the address of -- Prep for first wishbone read. We calculate the address of
-- the start of the cache line and start the WB cycle. -- 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.cyc <= '1';
r.wb.stb <= '1'; r.wb.stb <= '1';


@ -804,7 +804,7 @@ begin
log_data <= i_out.valid & log_data <= i_out.valid &
i_out.insn & i_out.insn &
wishbone_in.ack & wishbone_in.ack &
r.wb.adr(5 downto 3) & r.wb.adr(2 downto 0) &
r.wb.stb & r.wb.cyc & r.wb.stb & r.wb.cyc &
wishbone_in.stall & wishbone_in.stall &
stall_out & stall_out &

@ -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

@ -100,7 +100,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
oack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then 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 if wb_in.we = '0' then
obuf <= init_ram(adr); obuf <= init_ram(adr);
else else

@ -100,7 +100,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
oack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then 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 if wb_in.we = '0' then
obuf <= init_ram(adr); obuf <= init_ram(adr);
else else

@ -100,7 +100,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
oack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then 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 if wb_in.we = '0' then
obuf <= init_ram(adr); obuf <= init_ram(adr);
else else

@ -100,7 +100,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
oack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then 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 if wb_in.we = '0' then
obuf <= init_ram(adr); obuf <= init_ram(adr);
else else

@ -100,7 +100,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
oack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then 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 if wb_in.we = '0' then
obuf <= init_ram(adr); obuf <= init_ram(adr);
else else

@ -100,7 +100,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
oack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then 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 if wb_in.we = '0' then
obuf <= init_ram(adr); obuf <= init_ram(adr);
else else

@ -248,10 +248,10 @@ architecture behaviour of soc is
function wishbone_widen_data(wb : wb_io_master_out) return wishbone_master_out is function wishbone_widen_data(wb : wb_io_master_out) return wishbone_master_out is
variable wwb : wishbone_master_out; variable wwb : wishbone_master_out;
begin 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.dat := wb.dat & wb.dat;
wwb.sel := x"00"; wwb.sel := x"00";
if wwb.adr(2) = '0' then if wb.adr(0) = '0' then
wwb.sel(3 downto 0) := wb.sel; wwb.sel(3 downto 0) := wb.sel;
else else
wwb.sel(7 downto 4) := wb.sel; wwb.sel(7 downto 4) := wb.sel;
@ -405,7 +405,7 @@ begin
variable top_decode : std_ulogic_vector(3 downto 0); variable top_decode : std_ulogic_vector(3 downto 0);
begin begin
-- Top-level address decoder -- 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; slave_top := SLAVE_TOP_BRAM;
if std_match(top_decode, "0000") then if std_match(top_decode, "0000") then
slave_top := SLAVE_TOP_BRAM; slave_top := SLAVE_TOP_BRAM;
@ -491,7 +491,7 @@ begin


-- Copy write enable to IO out, copy address as well -- Copy write enable to IO out, copy address as well
wb_sio_out.we <= wb_io_in.we; 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 ? -- Do we have a top word and/or a bottom word ?
has_top := wb_io_in.sel(7 downto 4) /= "0000"; 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); wb_sio_out.sel <= wb_io_in.sel(7 downto 4);


-- Bump address -- Bump address
wb_sio_out.adr(2) <= '1'; wb_sio_out.adr(0) <= '1';


-- Wait for ack -- Wait for ack
state := WAIT_ACK_TOP; state := WAIT_ACK_TOP;
@ -543,7 +543,7 @@ begin
wb_sio_out.sel <= wb_io_in.sel(7 downto 4); wb_sio_out.sel <= wb_io_in.sel(7 downto 4);


-- Bump address and set STB -- Bump address and set STB
wb_sio_out.adr(2) <= '1'; wb_sio_out.adr(0) <= '1';
wb_sio_out.stb <= '1'; wb_sio_out.stb <= '1';


-- Wait for new ack -- Wait for new ack
@ -601,7 +601,7 @@ begin


-- Simple address decoder. -- Simple address decoder.
slave_io := SLAVE_IO_NONE; 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 if std_match(match, x"FF---") and HAS_DRAM then
slave_io := SLAVE_IO_EXTERNAL; slave_io := SLAVE_IO_EXTERNAL;
elsif std_match(match, x"F----") then elsif std_match(match, x"F----") then
@ -638,11 +638,11 @@ begin
-- Only give xics 8 bits of wb addr (for now...) -- Only give xics 8 bits of wb addr (for now...)
wb_xics_icp_in <= wb_sio_out; wb_xics_icp_in <= wb_sio_out;
wb_xics_icp_in.adr <= (others => '0'); 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_icp_in.cyc <= '0';
wb_xics_ics_in <= wb_sio_out; wb_xics_ics_in <= wb_sio_out;
wb_xics_ics_in.adr <= (others => '0'); 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_xics_ics_in.cyc <= '0';


wb_ext_io_in <= wb_sio_out; wb_ext_io_in <= wb_sio_out;
@ -667,22 +667,22 @@ begin
-- --
-- DRAM init is special at 0xFF* so we just test the top -- DRAM init is special at 0xFF* so we just test the top
-- bit. Everything else is at 0xC8* so we test only bits -- 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; 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'; wb_ext_is_dram_init <= '1';
ext_valid := true; 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'; wb_ext_is_dram_csr <= '1';
ext_valid := true; 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'; wb_ext_is_eth <= '1';
ext_valid := true; 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'; wb_ext_is_eth <= '1';
ext_valid := true; 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'; wb_ext_is_sdcard <= '1';
ext_valid := true; ext_valid := true;
end if; end if;
@ -709,7 +709,7 @@ begin
when SLAVE_IO_SPI_FLASH_MAP => when SLAVE_IO_SPI_FLASH_MAP =>
-- Clear top bits so they don't make their way to the -- Clear top bits so they don't make their way to the
-- fash chip. -- 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_spiflash_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_spiflash_out; wb_sio_in <= wb_spiflash_out;
wb_spiflash_is_map <= '1'; wb_spiflash_is_map <= '1';
@ -767,7 +767,7 @@ begin
txd => uart0_txd, txd => uart0_txd,
rxd => uart0_rxd, rxd => uart0_rxd,
irq => uart0_irq, 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_in => wb_uart0_in.dat(7 downto 0),
wb_dat_out => uart0_dat8, wb_dat_out => uart0_dat8,
wb_cyc_in => wb_uart0_in.cyc, wb_cyc_in => wb_uart0_in.cyc,
@ -784,7 +784,7 @@ begin
port map ( port map (
wb_clk_i => system_clk, wb_clk_i => system_clk,
wb_rst_i => rst_uart, 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_i => wb_uart0_in.dat(7 downto 0),
wb_dat_o => uart0_dat8, wb_dat_o => uart0_dat8,
wb_we_i => wb_uart0_in.we, wb_we_i => wb_uart0_in.we,
@ -826,7 +826,7 @@ begin
port map ( port map (
wb_clk_i => system_clk, wb_clk_i => system_clk,
wb_rst_i => rst_uart, 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_i => wb_uart1_in.dat(7 downto 0),
wb_dat_o => uart1_dat8, wb_dat_o => uart1_dat8,
wb_we_i => wb_uart1_in.we, wb_we_i => wb_uart1_in.we,

@ -43,7 +43,7 @@ architecture rtl of spi_flash_ctrl is
-- Register indices -- Register indices
constant SPI_REG_BITS : positive := 3; 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_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_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"; 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; wb_map_valid <= wb_valid and wb_sel_map;


-- Register decode. For map accesses, make it look like "invalid" -- 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 -- Shortcut because we test that a lot: data register access
wb_reg_dat_v <= '1' when wb_reg = SPI_REG_DATA else '0'; 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 -- Convert wishbone address into a flash address. We mask
-- off the 4 top address bits to get rid of the "f" there. -- 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 -- Calculate the next address for store & compare later
auto_lad_next <= std_ulogic_vector(unsigned(addr) + 4); auto_lad_next <= std_ulogic_vector(unsigned(addr) + 4);

@ -171,7 +171,7 @@ begin


-- Wishbone response -- Wishbone response
wb_rsp.ack <= wishbone_in.cyc and wishbone_in.stb; 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, SIG_VALUE when SYS_REG_SIG,
reg_info when SYS_REG_INFO, reg_info when SYS_REG_INFO,
reg_braminfo when SYS_REG_BRAMINFO, reg_braminfo when SYS_REG_BRAMINFO,
@ -183,7 +183,7 @@ begin
reg_uart0info when SYS_REG_UART0_INFO, reg_uart0info when SYS_REG_UART0_INFO,
reg_uart1info when SYS_REG_UART1_INFO, reg_uart1info when SYS_REG_UART1_INFO,
(others => '0') when others; (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); reg_out(31 downto 0);
wb_rsp.stall <= '0'; wb_rsp.stall <= '0';


@ -205,8 +205,8 @@ begin
else else
if wishbone_in.cyc and wishbone_in.stb and wishbone_in.we then if wishbone_in.cyc and wishbone_in.stb and wishbone_in.we then
-- Change this if CTRL ever has more than 32 bits -- Change this if CTRL ever has more than 32 bits
if wishbone_in.adr(SYS_REG_BITS+2 downto 3) = SYS_REG_CTRL and if wishbone_in.adr(SYS_REG_BITS downto 1) = SYS_REG_CTRL and
wishbone_in.adr(2) = '0' then wishbone_in.adr(0) = '0' then
reg_ctrl(SYS_REG_CTRL_BITS-1 downto 0) <= reg_ctrl(SYS_REG_CTRL_BITS-1 downto 0) <=
wishbone_in.dat(SYS_REG_CTRL_BITS-1 downto 0); wishbone_in.dat(SYS_REG_CTRL_BITS-1 downto 0);
end if; end if;

@ -19,7 +19,7 @@ architecture behave of wishbone_bram_tb is


impure function to_adr(a: integer) return std_ulogic_vector is impure function to_adr(a: integer) return std_ulogic_vector is
begin 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; end;
begin begin
simple_ram_0: entity work.wishbone_bram_wrapper simple_ram_0: entity work.wishbone_bram_wrapper

@ -54,7 +54,7 @@ begin
); );


-- Wishbone interface -- 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_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; ram_re <= wishbone_in.stb and wishbone_in.cyc and not wishbone_in.we;
wishbone_out.stall <= '0'; wishbone_out.stall <= '0';

@ -118,7 +118,7 @@ begin
dmi_ack <= dmi_req when (dmi_addr /= DBG_WB_DATA or state = DMI_WAIT) else '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 -- 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.dat <= dmi_din;
wb_out.sel <= reg_ctrl(7 downto 0); wb_out.sel <= reg_ctrl(7 downto 0);
wb_out.we <= dmi_wr; wb_out.we <= dmi_wr;

@ -3,11 +3,13 @@ use ieee.std_logic_1164.all;


package wishbone_types is 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_data_bits : integer := 64;
constant wishbone_sel_bits : integer := wishbone_data_bits/8; 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_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); subtype wishbone_data_type is std_ulogic_vector(wishbone_data_bits-1 downto 0);

@ -111,7 +111,7 @@ begin
v.wb_ack := '1'; -- always ack v.wb_ack := '1'; -- always ack
if wb_in.we = '1' then -- write if wb_in.we = '1' then -- write
-- writes to both XIRR are the same -- 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 => when XIRR_POLL =>
report "ICP XIRR_POLL write"; report "ICP XIRR_POLL write";
v.cppr := be_in(31 downto 24); v.cppr := be_in(31 downto 24);
@ -138,7 +138,7 @@ begin


else -- read else -- read


case wb_in.adr(7 downto 0) is case wb_in.adr(5 downto 0) & "00" is
when XIRR_POLL => when XIRR_POLL =>
report "ICP XIRR_POLL read"; report "ICP XIRR_POLL read";
be_out := r.cppr & r.xisr; be_out := r.cppr & r.xisr;
@ -308,12 +308,12 @@ begin


assert SRC_NUM = 16 report "Fixup address decode with log2"; assert SRC_NUM = 16 report "Fixup address decode with log2";


reg_is_xive <= wb_in.adr(11); reg_is_xive <= wb_in.adr(9);
reg_is_config <= '1' when wb_in.adr(11 downto 0) = x"000" else '0'; reg_is_config <= '1' when wb_in.adr(9 downto 0) = 10x"000" else '0';
reg_is_debug <= '1' when wb_in.adr(11 downto 0) = x"004" 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 -- 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 -- Latch interrupt inputs for timing
int_latch: process(clk) int_latch: process(clk)

Loading…
Cancel
Save