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