mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-24 11:11:47 +00:00
Merge pull request #115 from antonblanchard/reduce-wishbone
Reduce wishbone
This commit is contained in:
commit
9620a76281
16
dcache.vhdl
16
dcache.vhdl
@ -244,16 +244,16 @@ architecture rtl of dcache is
|
||||
end;
|
||||
|
||||
-- Returns whether this is the last row of a line
|
||||
function is_last_row(addr: std_ulogic_vector(63 downto 0)) return boolean is
|
||||
function is_last_row(addr: wishbone_addr_type) return boolean is
|
||||
constant ones : std_ulogic_vector(ROW_LINEBITS-1 downto 0) := (others => '1');
|
||||
begin
|
||||
return addr(LINE_OFF_BITS-1 downto ROW_OFF_BITS) = ones;
|
||||
end;
|
||||
|
||||
-- Return the address of the next row in the current cache line
|
||||
function next_row_addr(addr: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
function next_row_addr(addr: wishbone_addr_type) return std_ulogic_vector is
|
||||
variable row_idx : std_ulogic_vector(ROW_LINEBITS-1 downto 0);
|
||||
variable result : std_ulogic_vector(63 downto 0);
|
||||
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);
|
||||
@ -573,6 +573,7 @@ begin
|
||||
wr_data => wr_data
|
||||
);
|
||||
process(all)
|
||||
variable tmp_adr : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
-- Cache hit reads
|
||||
do_read <= '1';
|
||||
@ -595,7 +596,8 @@ begin
|
||||
-- Otherwise, we might be doing a reload
|
||||
wr_data <= wishbone_in.dat;
|
||||
wr_sel <= (others => '1');
|
||||
wr_addr <= std_ulogic_vector(to_unsigned(get_row(r1.wb.adr), ROW_BITS));
|
||||
tmp_adr := (r1.wb.adr'left downto 0 => r1.wb.adr, others => '0');
|
||||
wr_addr <= std_ulogic_vector(to_unsigned(get_row(tmp_adr), ROW_BITS));
|
||||
end if;
|
||||
|
||||
-- The two actual write cases here
|
||||
@ -733,7 +735,7 @@ begin
|
||||
-- Prep for first wishbone read. We calculate the address of
|
||||
-- the start of the cache line
|
||||
--
|
||||
r1.wb.adr <= d_in.addr(63 downto LINE_OFF_BITS) &
|
||||
r1.wb.adr <= d_in.addr(r1.wb.adr'left downto LINE_OFF_BITS) &
|
||||
(LINE_OFF_BITS-1 downto 0 => '0');
|
||||
r1.wb.sel <= (others => '1');
|
||||
r1.wb.we <= '0';
|
||||
@ -743,7 +745,7 @@ begin
|
||||
|
||||
when OP_LOAD_NC =>
|
||||
r1.wb.sel <= bus_sel;
|
||||
r1.wb.adr <= d_in.addr(63 downto 3) & "000";
|
||||
r1.wb.adr <= d_in.addr(r1.wb.adr'left downto 3) & "000";
|
||||
r1.wb.cyc <= '1';
|
||||
r1.wb.stb <= '1';
|
||||
r1.wb.we <= '0';
|
||||
@ -755,7 +757,7 @@ begin
|
||||
r1.update_valid <= '1';
|
||||
end if;
|
||||
r1.wb.sel <= bus_sel;
|
||||
r1.wb.adr <= d_in.addr(63 downto 3) & "000";
|
||||
r1.wb.adr <= d_in.addr(r1.wb.adr'left downto 3) & "000";
|
||||
r1.wb.dat <= store_data;
|
||||
r1.wb.cyc <= '1';
|
||||
r1.wb.stb <= '1';
|
||||
|
||||
13
icache.vhdl
13
icache.vhdl
@ -193,16 +193,17 @@ architecture rtl of icache is
|
||||
end;
|
||||
|
||||
-- Returns whether this is the last row of a line
|
||||
function is_last_row(addr: std_ulogic_vector(63 downto 0)) return boolean is
|
||||
function is_last_row(addr: wishbone_addr_type) return boolean is
|
||||
constant ones : std_ulogic_vector(ROW_LINEBITS-1 downto 0) := (others => '1');
|
||||
begin
|
||||
return addr(LINE_OFF_BITS-1 downto ROW_OFF_BITS) = ones;
|
||||
end;
|
||||
|
||||
-- Return the address of the next row in the current cache line
|
||||
function next_row_addr(addr: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
function next_row_addr(addr: wishbone_addr_type)
|
||||
return std_ulogic_vector is
|
||||
variable row_idx : std_ulogic_vector(ROW_LINEBITS-1 downto 0);
|
||||
variable result : std_ulogic_vector(63 downto 0);
|
||||
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);
|
||||
@ -297,6 +298,7 @@ begin
|
||||
wr_data => wishbone_in.dat
|
||||
);
|
||||
process(all)
|
||||
variable tmp_adr : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
do_read <= '1';
|
||||
do_write <= '0';
|
||||
@ -305,7 +307,8 @@ begin
|
||||
end if;
|
||||
cache_out(i) <= dout;
|
||||
rd_addr <= std_ulogic_vector(to_unsigned(req_row, ROW_BITS));
|
||||
wr_addr <= std_ulogic_vector(to_unsigned(get_row(r.wb.adr), ROW_BITS));
|
||||
tmp_adr := (r.wb.adr'left downto 0 => r.wb.adr, others => '0');
|
||||
wr_addr <= std_ulogic_vector(to_unsigned(get_row(tmp_adr), ROW_BITS));
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
@ -474,7 +477,7 @@ begin
|
||||
-- Prep for first wishbone read. We calculate the address of
|
||||
-- the start of the cache line
|
||||
--
|
||||
r.wb.adr <= i_in.nia(63 downto LINE_OFF_BITS) &
|
||||
r.wb.adr <= i_in.nia(r.wb.adr'left downto LINE_OFF_BITS) &
|
||||
(LINE_OFF_BITS-1 downto 0 => '0');
|
||||
r.wb.cyc <= '1';
|
||||
r.wb.stb <= '1';
|
||||
|
||||
@ -32,6 +32,7 @@ architecture behave of mw_soc_memory is
|
||||
begin
|
||||
wishbone_process: process(clk)
|
||||
variable ret_dat: std_ulogic_vector(63 downto 0) := (others => '0');
|
||||
variable adr: std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
wishbone_out.ack <= ret_ack and wishbone_in.cyc and wishbone_in.stb;
|
||||
wishbone_out.dat <= ret_dat;
|
||||
@ -49,15 +50,16 @@ begin
|
||||
when IDLE =>
|
||||
if wishbone_in.stb = '1' then
|
||||
-- write
|
||||
adr := (wishbone_in.adr'left downto 0 => wishbone_in.adr, others => '0');
|
||||
if wishbone_in.we = '1' then
|
||||
assert not(is_x(wishbone_in.dat)) and not(is_x(wishbone_in.adr)) severity failure;
|
||||
report "RAM writing " & to_hstring(wishbone_in.dat) & " to " & to_hstring(wishbone_in.adr);
|
||||
behavioural_write(wishbone_in.dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier);
|
||||
behavioural_write(wishbone_in.dat, adr, to_integer(unsigned(wishbone_in.sel)), identifier);
|
||||
reload <= reload + 1;
|
||||
ret_ack <= '1';
|
||||
state <= ACK;
|
||||
else
|
||||
behavioural_read(ret_dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier, reload);
|
||||
behavioural_read(ret_dat, adr, to_integer(unsigned(wishbone_in.sel)), identifier, reload);
|
||||
report "RAM reading from " & to_hstring(wishbone_in.adr) & " returns " & to_hstring(ret_dat);
|
||||
ret_ack <= '1';
|
||||
state <= ACK;
|
||||
|
||||
@ -16,6 +16,11 @@ architecture behave of simple_ram_behavioural_tb is
|
||||
|
||||
signal w_in : wishbone_slave_out;
|
||||
signal w_out : wishbone_master_out;
|
||||
|
||||
impure function to_adr(a: integer) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(to_unsigned(a, w_out.adr'length));
|
||||
end;
|
||||
begin
|
||||
simple_ram_0: entity work.mw_soc_memory
|
||||
generic map (
|
||||
@ -56,7 +61,7 @@ begin
|
||||
-- test various read lengths and alignments
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000001";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
w_out.adr <= to_adr(0);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -67,7 +72,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000001";
|
||||
w_out.adr <= x"0000000000000001";
|
||||
w_out.adr <= to_adr(1);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -78,7 +83,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000001";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
w_out.adr <= to_adr(7);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -89,7 +94,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000011";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
w_out.adr <= to_adr(0);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -100,7 +105,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000011";
|
||||
w_out.adr <= x"0000000000000001";
|
||||
w_out.adr <= to_adr(1);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -111,7 +116,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000011";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
w_out.adr <= to_adr(7);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -122,7 +127,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00001111";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
w_out.adr <= to_adr(0);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -133,7 +138,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00001111";
|
||||
w_out.adr <= x"0000000000000001";
|
||||
w_out.adr <= to_adr(1);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -144,7 +149,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00001111";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
w_out.adr <= to_adr(7);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -155,7 +160,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "11111111";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
w_out.adr <= to_adr(0);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -166,7 +171,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "11111111";
|
||||
w_out.adr <= x"0000000000000001";
|
||||
w_out.adr <= to_adr(1);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -177,7 +182,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "11111111";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
w_out.adr <= to_adr(7);
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
@ -189,7 +194,7 @@ begin
|
||||
-- test various write lengths and alignments
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000001";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
w_out.adr <= to_adr(0);
|
||||
w_out.we <= '1';
|
||||
w_out.dat(7 downto 0) <= x"0F";
|
||||
assert w_in.ack = '0';
|
||||
@ -201,7 +206,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000001";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
w_out.adr <= to_adr(0);
|
||||
w_out.we <= '0';
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
@ -213,7 +218,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "11111111";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
w_out.adr <= to_adr(7);
|
||||
w_out.we <= '1';
|
||||
w_out.dat <= x"BADC0FFEBADC0FFE";
|
||||
assert w_in.ack = '0';
|
||||
@ -225,7 +230,7 @@ begin
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "11111111";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
w_out.adr <= to_adr(7);
|
||||
w_out.we <= '0';
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
|
||||
6
soc.vhdl
6
soc.vhdl
@ -111,11 +111,11 @@ begin
|
||||
SLAVE_NONE);
|
||||
variable slave : slave_type;
|
||||
begin
|
||||
-- Simple address decoder
|
||||
-- Simple address decoder.
|
||||
slave := SLAVE_NONE;
|
||||
if wb_master_out.adr(63 downto 24) = x"0000000000" then
|
||||
if wb_master_out.adr(31 downto 24) = x"00" then
|
||||
slave := SLAVE_MEMORY;
|
||||
elsif wb_master_out.adr(63 downto 24) = x"00000000c0" then
|
||||
elsif wb_master_out.adr(31 downto 24) = x"c0" then
|
||||
if wb_master_out.adr(23 downto 12) = x"002" then
|
||||
slave := SLAVE_UART_0;
|
||||
end if;
|
||||
|
||||
@ -117,7 +117,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 <= reg_addr(wb_out.adr'left downto 0);
|
||||
wb_out.dat <= dmi_din;
|
||||
wb_out.sel <= reg_ctrl(7 downto 0);
|
||||
wb_out.we <= dmi_wr;
|
||||
|
||||
@ -2,7 +2,7 @@ library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package wishbone_types is
|
||||
constant wishbone_addr_bits : integer := 64;
|
||||
constant wishbone_addr_bits : integer := 32;
|
||||
constant wishbone_data_bits : integer := 64;
|
||||
constant wishbone_sel_bits : integer := wishbone_data_bits/8;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user