Skip to content
Snippets Groups Projects
Commit 219b2ad2 authored by Wesley W. Terpstra's avatar Wesley W. Terpstra
Browse files

sdb: new master-describing SDB record

parent 3bf64433
No related merge requests found
......@@ -5,19 +5,22 @@ use work.wishbone_pkg.all;
entity sdb_rom is
generic(
g_layout : t_sdb_record_array;
g_slaves : t_sdb_record_array;
g_masters : t_sdb_record_array;
g_bus_end : unsigned(63 downto 0));
port(
clk_sys_i : in std_logic;
master_i : in std_logic_vector(g_masters'length-1 downto 0);
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out);
end sdb_rom;
architecture rtl of sdb_rom is
alias c_layout : t_sdb_record_array(g_layout'length downto 1) is g_layout;
alias c_masters : t_sdb_record_array(g_masters'length downto 1) is g_masters;
alias c_slaves : t_sdb_record_array(g_slaves'length+c_masters'high downto c_masters'high+1) is g_slaves;
-- The ROM must describe all slaves, the crossbar itself and the optional information records
constant c_used_entries : natural := c_layout'length + 1;
constant c_used_entries : natural := c_slaves'high + 1;
constant c_rom_entries : natural := 2**f_ceil_log2(c_used_entries); -- next power of 2
constant c_sdb_words : natural := c_sdb_device_length / c_wishbone_data_width;
constant c_rom_words : natural := c_rom_entries * c_sdb_words;
......@@ -42,10 +45,17 @@ architecture rtl of sdb_rom is
sdb_component.addr_first := (others => '0');
sdb_component.addr_last := std_logic_vector(g_bus_end);
sdb_component.product.vendor_id := x"0000000000000651"; -- GSI
sdb_component.product.device_id := x"e6a542c9";
sdb_component.product.version := x"00000002";
sdb_component.product.date := x"20120511";
sdb_component.product.name := "WB4-Crossbar-GSI ";
if g_masters'length > 0 then
sdb_component.product.device_id := x"2b6e61b3";
sdb_component.product.version := x"00000001";
sdb_component.product.date := x"20160421";
sdb_component.product.name := "MSI-Crossbar-GSI ";
else
sdb_component.product.device_id := x"e6a542c9";
sdb_component.product.version := x"00000002";
sdb_component.product.date := x"20120511";
sdb_component.product.name := "WB4-Crossbar-GSI ";
end if;
sdb_device(447 downto 8) := f_sdb_embed_component(sdb_component, (others => '0'));
for i in 0 to c_sdb_words-1 loop
......@@ -53,8 +63,17 @@ architecture rtl of sdb_rom is
sdb_device((i+1)*c_wishbone_data_width-1 downto i*c_wishbone_data_width);
end loop;
for slave in 1 to c_used_entries-1 loop
sdb_device(511 downto 0) := c_layout(slave);
for master in c_masters'range loop
sdb_device(511 downto 0) := c_masters(master);
for i in 0 to c_sdb_words-1 loop
res((master+1)*c_sdb_words-1-i) :=
sdb_device((i+1)*c_wishbone_data_width-1 downto i*c_wishbone_data_width);
end loop;
end loop;
for slave in c_slaves'range loop
sdb_device(511 downto 0) := c_slaves(slave);
for i in 0 to c_sdb_words-1 loop
res((slave+1)*c_sdb_words-1-i) :=
......@@ -64,23 +83,50 @@ architecture rtl of sdb_rom is
return res;
end f_build_rom;
signal rom : t_rom := f_build_rom;
function f_msi_flag_index(y : std_logic_vector) return std_logic_vector is
-- Bump the indexes to start from 1 (0 is the SDB table header)
alias x : std_logic_vector(y'length downto 1) is y;
-- Result is the full width of the SDB word address
variable result : std_logic_vector(c_rom_depth-1 downto 0) := (others => '0');
variable step : natural := 1;
begin
-- Leave bits 0-3 as '0' (16 words per SDB record)
for i in 4 to result'high loop
for j in x'range loop
if (j / step) mod 2 = 1 then
result(i) := result(i) or x(j);
end if;
end loop;
step := step + step;
end loop;
return result;
end f_msi_flag_index;
constant rom : t_rom := f_build_rom;
signal adr_reg : unsigned(c_rom_depth-1 downto 0);
signal sel_reg : unsigned(c_rom_depth-1 downto 0);
signal s_rom : t_wishbone_data;
signal s_flag : t_wishbone_data := (others => '0');
begin
-- Simple ROM; ignore we/sel/dat
slave_o.err <= '0';
slave_o.rty <= '0';
slave_o.stall <= '0';
slave_o.int <= '0'; -- Tom sucks! This should not be here.
slave_o.dat <= rom(to_integer(adr_reg));
s_rom <= rom(to_integer(adr_reg));
s_flag(s_flag'high) <= '1' when adr_reg = sel_reg and g_masters'length > 0 else '0';
slave_o.dat <= s_rom or s_flag;
slave_clk : process(clk_sys_i)
begin
if (rising_edge(clk_sys_i)) then
adr_reg <= unsigned(slave_i.adr(c_rom_depth+c_rom_lowbits-1 downto c_rom_lowbits));
sel_reg <= unsigned(f_msi_flag_index(master_i));
slave_o.ack <= slave_i.cyc and slave_i.stb;
end if;
end process;
......
......@@ -154,10 +154,10 @@ architecture rtl of xwb_sdb_crossbar is
constant c_sdb_mask : t_wishbone_address :=
std_logic_vector(c_rom_mask(c_wishbone_address_width-1 downto 0));
constant c_address : t_wishbone_address_array(g_num_slaves downto 0) :=
g_sdb_addr & f_addresses;
constant c_mask : t_wishbone_address_array(g_num_slaves downto 0) :=
c_sdb_mask & f_masks;
constant c_null : t_sdb_record_array(0 downto 1) := (others => (others => '0'));
signal master_i_1 : t_wishbone_master_in_array(g_num_slaves downto 0);
signal master_o_1 : t_wishbone_master_out_array(g_num_slaves downto 0);
......@@ -167,10 +167,12 @@ begin
rom : sdb_rom
generic map(
g_layout => c_layout,
g_slaves => c_layout,
g_masters => c_null,
g_bus_end => c_bus_end)
port map(
clk_sys_i => clk_sys_i,
master_i => (others => '0'),
slave_i => master_o_1(g_num_slaves),
slave_o => master_i_1(g_num_slaves));
......
......@@ -124,6 +124,12 @@ package wishbone_pkg is
sdb_component : t_sdb_component;
end record t_sdb_device;
type t_sdb_msi is record
wbd_endian : std_logic; -- 0 = big, 1 = little
wbd_width : std_logic_vector(3 downto 0); -- 3=64-bit, 2=32-bit, 1=16-bit, 0=8-bit
sdb_component : t_sdb_component;
end record t_sdb_msi;
type t_sdb_bridge is record
sdb_child : std_logic_vector(63 downto 0);
sdb_component : t_sdb_component;
......@@ -165,12 +171,14 @@ package wishbone_pkg is
-- Used to configure a device at a certain address
function f_sdb_embed_device(device : t_sdb_device; address : t_wishbone_address) return t_sdb_record;
function f_sdb_embed_bridge(bridge : t_sdb_bridge; address : t_wishbone_address) return t_sdb_record;
function f_sdb_embed_msi(msi : t_sdb_msi; address : t_wishbone_address) return t_sdb_record;
function f_sdb_embed_integration(integr : t_sdb_integration) return t_sdb_record;
function f_sdb_embed_repo_url(url : t_sdb_repo_url) return t_sdb_record;
function f_sdb_embed_synthesis(syn : t_sdb_synthesis) return t_sdb_record;
function f_sdb_extract_device(sdb_record : t_sdb_record) return t_sdb_device;
function f_sdb_extract_bridge(sdb_record : t_sdb_record) return t_sdb_bridge;
function f_sdb_extract_msi(sdb_record : t_sdb_record) return t_sdb_msi;
function f_sdb_extract_integration(sdb_record : t_sdb_record) return t_sdb_integration;
function f_sdb_extract_repo_url(sdb_record : t_sdb_record) return t_sdb_repo_url;
function f_sdb_extract_synthesis(sdb_record : t_sdb_record) return t_sdb_synthesis;
......@@ -178,6 +186,7 @@ package wishbone_pkg is
-- Automatic crossbar mapping functions
function f_sdb_auto_device(device : t_sdb_device; enable : boolean := true) return t_sdb_record;
function f_sdb_auto_bridge(bridge : t_sdb_bridge; enable : boolean := true) return t_sdb_record;
function f_sdb_auto_msi (msi : t_sdb_msi; enable : boolean := true) return t_sdb_record;
function f_sdb_auto_layout(records : t_sdb_record_array) return t_sdb_record_array;
function f_sdb_auto_sdb (records : t_sdb_record_array) return t_wishbone_address;
......@@ -349,10 +358,12 @@ package wishbone_pkg is
component sdb_rom is
generic(
g_layout : t_sdb_record_array;
g_slaves : t_sdb_record_array;
g_masters : t_sdb_record_array;
g_bus_end : unsigned(63 downto 0));
port(
clk_sys_i : in std_logic;
master_i : in std_logic_vector(g_masters'length-1 downto 0);
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out);
end component;
......@@ -1196,6 +1207,36 @@ package body wishbone_pkg is
return result;
end;
function f_sdb_embed_msi(msi : t_sdb_msi; address : t_wishbone_address)
return t_sdb_record
is
variable result : t_sdb_record;
begin
result(511 downto 456) := (others => '0');
result(455) := msi.wbd_endian;
result(454 downto 452) := (others => '0');
result(451 downto 448) := msi.wbd_width;
result(447 downto 8) := f_sdb_embed_component(msi.sdb_component, address);
result(7 downto 0) := x"03"; -- msi
return result;
end;
function f_sdb_extract_msi(sdb_record : t_sdb_record)
return t_sdb_msi
is
variable result : t_sdb_msi;
begin
result.wbd_endian := sdb_record(452);
result.wbd_width := sdb_record(451 downto 448);
result.sdb_component := f_sdb_extract_component(sdb_record(447 downto 8));
assert sdb_record(7 downto 0) = x"03"
report "Cannot extract t_sdb_msi from record of type " & integer'image(to_integer(unsigned(sdb_record(7 downto 0)))) & "."
severity failure;
return result;
end;
function f_sdb_embed_integration(integr : t_sdb_integration)
return t_sdb_record
is
......@@ -1339,6 +1380,20 @@ package body wishbone_pkg is
end if;
end f_sdb_auto_bridge;
function f_sdb_auto_msi(msi : t_sdb_msi; enable : boolean := true)
return t_sdb_record
is
constant c_zero : t_wishbone_address := (others => '0');
variable v_empty : t_sdb_record := (others => '0');
begin
v_empty(7 downto 0) := (others => '1');
if enable then
return f_sdb_embed_msi(msi, c_zero);
else
return v_empty;
end if;
end f_sdb_auto_msi;
subtype t_usdb_address is unsigned(63 downto 0);
type t_usdb_address_array is array(natural range <>) of t_usdb_address;
......@@ -1843,6 +1898,7 @@ package body wishbone_pkg is
return ret_v;
end f_string_fix_len;
-- do not synthesize
function f_hot_to_bin(x : std_logic_vector) return natural is
variable rv : natural;
begin
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment