Merge pull request #329 from paulusmack/wb-fix

Wishbone addressing fix
pull/332/head
Anton Blanchard 3 years ago committed by GitHub
commit af6bc48d36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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

@ -552,7 +552,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;
@ -642,7 +642,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;



@ -446,7 +446,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;
@ -535,7 +535,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

@ -249,10 +249,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;
@ -407,7 +407,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;
@ -493,7 +493,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";
@ -517,7 +517,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;
@ -545,7 +545,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
@ -603,7 +603,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
@ -640,11 +640,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;
@ -669,22 +669,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;
@ -711,7 +711,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';
@ -769,7 +769,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,
@ -786,7 +786,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,
@ -828,7 +828,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