mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
commit
af6bc48d36
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;
|
||||
|
||||
@ -552,7 +552,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;
|
||||
@ -642,7 +642,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;
|
||||
|
||||
|
||||
@ -446,7 +446,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;
|
||||
@ -535,7 +535,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
@ -249,10 +249,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;
|
||||
@ -407,7 +407,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;
|
||||
@ -493,7 +493,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";
|
||||
@ -517,7 +517,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;
|
||||
@ -545,7 +545,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
|
||||
@ -603,7 +603,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
|
||||
@ -640,11 +640,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;
|
||||
@ -669,22 +669,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;
|
||||
@ -711,7 +711,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';
|
||||
@ -769,7 +769,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,
|
||||
@ -786,7 +786,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,
|
||||
@ -828,7 +828,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