Commit ab1ee585 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

Merge branch 'greg-vivado' into proposed_master

parents 47b5fcb2 6016433a
......@@ -71,6 +71,12 @@ architecture behavioral of gc_sync_ffs is
attribute keep of sync0 : signal is "true";
attribute keep of sync1 : signal is "true";
-- synchronizer attribute for Vivado
attribute ASYNC_REG : string;
attribute ASYNC_REG of sync0 : signal is "true";
attribute ASYNC_REG of sync1 : signal is "true";
attribute ASYNC_REG of sync2 : signal is "true";
begin
......
......@@ -48,6 +48,9 @@ package genram_pkg is
function f_check_bounds(x : integer; minx : integer; maxx : integer) return integer;
type t_generic_ram_init is array (integer range <>, integer range <>) of std_logic;
type t_ram8_type is array (integer range <>) of std_logic_vector(7 downto 0);
type t_ram16_type is array (integer range <>) of std_logic_vector(15 downto 0);
type t_ram32_type is array (integer range <>) of std_logic_vector(31 downto 0);
-- Single-port synchronous RAM
component generic_spram
......
......@@ -12,18 +12,35 @@ package memory_loader_pkg is
subtype t_meminit_array is t_generic_ram_init;
function f_load_mem_from_file
impure function f_load_mem_from_file
(file_name : string;
mem_size : integer;
mem_width : integer;
fail_if_notfound : boolean)
return t_meminit_array;
impure function f_load_mem32_from_file
(file_name : string; mem_size : integer; fail_if_notfound : boolean)
return t_ram32_type;
impure function f_load_mem16_from_file
(file_name : string; mem_size : integer; fail_if_notfound : boolean)
return t_ram16_type;
impure function f_load_mem8_from_file
(file_name : string; mem_size : integer; fail_if_notfound : boolean)
return t_ram8_type;
impure function f_load_mem32_from_file_split
(file_name : in string; mem_size : in integer;
fail_if_notfound : boolean; byte_idx : in integer)
return t_ram8_type;
end memory_loader_pkg;
package body memory_loader_pkg is
function f_load_mem_from_file
impure function f_load_mem_from_file
(file_name : in string;
mem_size : in integer;
mem_width : in integer;
......@@ -66,4 +83,169 @@ package body memory_loader_pkg is
return mem;
end f_load_mem_from_file;
-------------------------------------------------------------------
-- RAM initialization for most common sizes to speed-up synthesis
-------------------------------------------------------------------
impure function f_load_mem32_from_file
(file_name : in string;
mem_size : in integer;
fail_if_notfound : boolean)
return t_ram32_type is
FILE f_in : text;
variable l : line;
variable tmp_bv : bit_vector(31 downto 0);
variable mem: t_ram32_type(0 to mem_size-1);
variable status : file_open_status;
begin
if(file_name = "" or file_name = "none") then
mem:= (others => (others => '0'));
return mem;
end if;
file_open(status, f_in, file_name, read_mode);
if(status /= open_ok) then
if(fail_if_notfound) then
report "f_load_mem_from_file(): can't open file '"&file_name&"'" severity failure;
else
report "f_load_mem_from_file(): can't open file '"&file_name&"'" severity warning;
end if;
end if;
for I in 0 to mem_size-1 loop
readline (f_in, l);
-- read function gives us bit_vector
read (l, tmp_bv);
mem(I) := to_stdlogicvector(tmp_bv);
end loop;
file_close(f_in);
return mem;
end f_load_mem32_from_file;
-------------------------------------------------------------------
impure function f_load_mem16_from_file
(file_name : in string;
mem_size : in integer;
fail_if_notfound : boolean)
return t_ram16_type is
FILE f_in : text;
variable l : line;
variable tmp_bv : bit_vector(15 downto 0);
variable mem: t_ram16_type(0 to mem_size-1);
variable status : file_open_status;
begin
if(file_name = "" or file_name = "none") then
mem:= (others => (others => '0'));
return mem;
end if;
file_open(status, f_in, file_name, read_mode);
if(status /= open_ok) then
if(fail_if_notfound) then
report "f_load_mem_from_file(): can't open file '"&file_name&"'" severity failure;
else
report "f_load_mem_from_file(): can't open file '"&file_name&"'" severity warning;
end if;
end if;
for I in 0 to mem_size-1 loop
readline (f_in, l);
-- read function gives us bit_vector
read (l, tmp_bv);
mem(I) := to_stdlogicvector(tmp_bv);
end loop;
file_close(f_in);
return mem;
end f_load_mem16_from_file;
-------------------------------------------------------------------
impure function f_load_mem8_from_file
(file_name : in string;
mem_size : in integer;
fail_if_notfound : boolean)
return t_ram8_type is
FILE f_in : text;
variable l : line;
variable tmp_bv : bit_vector(7 downto 0);
variable mem: t_ram8_type(0 to mem_size-1);
variable status : file_open_status;
begin
if(file_name = "" or file_name = "none") then
mem:= (others => (others => '0'));
return mem;
end if;
file_open(status, f_in, file_name, read_mode);
if(status /= open_ok) then
if(fail_if_notfound) then
report "f_load_mem_from_file(): can't open file '"&file_name&"'" severity failure;
else
report "f_load_mem_from_file(): can't open file '"&file_name&"'" severity warning;
end if;
end if;
for I in 0 to mem_size-1 loop
readline (f_in, l);
-- read function gives us bit_vector
read (l, tmp_bv);
mem(I) := to_stdlogicvector(tmp_bv);
end loop;
file_close(f_in);
return mem;
end f_load_mem8_from_file;
-------------------------------------------------------------------
-- initialization for 32-bit RAM split into 4x 8-bit BRAM
-------------------------------------------------------------------
impure function f_load_mem32_from_file_split
(file_name : in string;
mem_size : in integer;
fail_if_notfound : boolean;
byte_idx : in integer)
return t_ram8_type is
FILE f_in : text;
variable l : line;
variable tmp_bv : bit_vector(31 downto 0);
variable mem: t_ram8_type(0 to mem_size-1);
variable status : file_open_status;
begin
if(file_name = "" or file_name = "none") then
mem:= (others => (others => '0'));
return mem;
end if;
file_open(status, f_in, file_name, read_mode);
if(status /= open_ok) then
if(fail_if_notfound) then
report "f_load_mem_from_file(): can't open file '"&file_name&"'" severity failure;
else
report "f_load_mem_from_file(): can't open file '"&file_name&"'" severity warning;
end if;
end if;
for I in 0 to mem_size-1 loop
readline (f_in, l);
-- read function gives us bit_vector
read (l, tmp_bv);
mem(I) := to_stdlogicvector( tmp_bv((byte_idx+1)*8-1 downto byte_idx*8) );
end loop;
file_close(f_in);
return mem;
end f_load_mem32_from_file_split;
end memory_loader_pkg;
......@@ -79,10 +79,39 @@ architecture syn of generic_dpram_dualclock is
type t_ram_type is array(0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
function f_memarray_to_ramtype(arr : t_meminit_array) return t_ram_type is
impure function f_file_to_ramtype return t_ram_type is
variable tmp : t_ram_type;
variable n, pos : integer;
variable mem32 : t_ram32_type(0 to g_size-1);
variable mem16 : t_ram16_type(0 to g_size-1);
variable mem8 : t_ram8_type(0 to g_size-1);
variable arr : t_meminit_array(0 to g_size-1, g_data_width-1 downto 0);
begin
-- If no file was given, there is nothing to convert, just return
if (g_init_file = "" or g_init_file = "none") then
tmp := (others=>(others=>'0'));
return tmp;
end if;
-- To speed-up most common cases, use dedicated functions
-- 32-bit width
if (g_data_width = 32) then
mem32 := f_load_mem32_from_file(g_init_file, g_size, g_fail_if_file_not_found);
return t_ram_type(mem32);
end if;
-- 16-bit width
if (g_data_width = 16) then
mem16 := f_load_mem16_from_file(g_init_file, g_size, g_fail_if_file_not_found);
return t_ram_type(mem16);
end if;
-- 8-bit width
if (g_data_width = 8) then
mem8 := f_load_mem8_from_file(g_init_file, g_size, g_fail_if_file_not_found);
return t_ram_type(mem8);
end if;
-- Only for "exotic" sizes do the lengthly (in Vivado 2016.4) copying
arr := f_load_mem_from_file(g_init_file, g_size, g_data_width, g_fail_if_file_not_found);
pos := 0;
while(pos < g_size)loop
n := 0;
......@@ -91,17 +120,12 @@ architecture syn of generic_dpram_dualclock is
for i in 0 to g_data_width-1 loop
tmp(pos)(i) := arr(pos, i);
end loop; -- i
n := n+1;
n := n+1;
pos := pos + 1;
end loop;
end loop;
return tmp;
end f_memarray_to_ramtype;
function f_file_contents return t_meminit_array is
begin
return f_load_mem_from_file(g_init_file, g_size, g_data_width, g_fail_if_file_not_found);
end f_file_contents;
end f_file_to_ramtype;
function f_is_synthesis return boolean is
begin
......@@ -111,7 +135,7 @@ architecture syn of generic_dpram_dualclock is
return true;
end f_is_synthesis;
shared variable ram : t_ram_type := f_memarray_to_ramtype(f_file_contents);
shared variable ram : t_ram_type := f_file_to_ramtype;
signal s_we_a : std_logic_vector(c_num_bytes-1 downto 0);
signal s_ram_in_a : std_logic_vector(g_data_width-1 downto 0);
......
......@@ -73,15 +73,44 @@ end generic_dpram_sameclock;
architecture syn of generic_dpram_sameclock is
constant c_num_bytes : integer := (g_data_width+7)/8;
constant c_num_bytes : integer := (g_data_width + 7)/8;
type t_ram_type is array(0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
function f_memarray_to_ramtype(arr : t_meminit_array) return t_ram_type is
impure function f_file_to_ramtype return t_ram_type is
variable tmp : t_ram_type;
variable n, pos : integer;
variable mem32 : t_ram32_type(0 to g_size-1);
variable mem16 : t_ram16_type(0 to g_size-1);
variable mem8 : t_ram8_type(0 to g_size-1);
variable arr : t_meminit_array(0 to g_size-1, g_data_width-1 downto 0);
begin
-- If no file was given, there is nothing to convert, just return
if (g_init_file = "" or g_init_file = "none") then
tmp := (others=>(others=>'0'));
return tmp;
end if;
-- To speed-up most common cases, use dedicated functions
-- 32-bit width
if (g_data_width = 32) then
mem32 := f_load_mem32_from_file(g_init_file, g_size, g_fail_if_file_not_found);
return t_ram_type(mem32);
end if;
-- 16-bit width
if (g_data_width = 16) then
mem16 := f_load_mem16_from_file(g_init_file, g_size, g_fail_if_file_not_found);
return t_ram_type(mem16);
end if;
-- 8-bit width
if (g_data_width = 8) then
mem8 := f_load_mem8_from_file(g_init_file, g_size, g_fail_if_file_not_found);
return t_ram_type(mem8);
end if;
-- Only for "exotic" sizes do the lengthly (in Vivado 2016.4) copying
arr := f_load_mem_from_file(g_init_file, g_size, g_data_width, g_fail_if_file_not_found);
pos := 0;
while(pos < g_size)loop
n := 0;
......@@ -95,12 +124,28 @@ architecture syn of generic_dpram_sameclock is
end loop;
end loop;
return tmp;
end f_memarray_to_ramtype;
function f_file_contents return t_meminit_array is
begin
return f_load_mem_from_file(g_init_file, g_size, g_data_width, g_fail_if_file_not_found);
end f_file_contents;
end f_file_to_ramtype;
--impure function InitRamFromFile(fname : in string) return t_ram_type is
-- FILE RamFile : text;
-- variable fline : line;
-- variable RAM : t_ram_type;
-- variable tmp_bv : bit_vector(g_data_width-1 downto 0);
-- variable status : file_open_status;
--begin
-- if(fname = "" or fname = "none") then
-- RAM := (others=>(others=>'0'));
-- return RAM;
-- end if;
-- file_open(status, RamFile, fname, read_mode);
-- for I in t_ram_type'range loop
-- readline(RamFile, fline);
-- read(fline, tmp_bv);
-- RAM(I) := to_stdlogicvector(tmp_bv);
-- end loop;
-- return RAM;
--end function;
function f_is_synthesis return boolean is
begin
......@@ -110,7 +155,7 @@ architecture syn of generic_dpram_sameclock is
return true;
end f_is_synthesis;
shared variable ram : t_ram_type := f_memarray_to_ramtype(f_file_contents);
shared variable ram : t_ram_type := f_file_to_ramtype;
signal s_we_a : std_logic_vector(c_num_bytes-1 downto 0);
signal s_ram_in_a : std_logic_vector(g_data_width-1 downto 0);
......@@ -130,15 +175,23 @@ begin
gen_with_byte_enable_readfirst : if(g_with_byte_enable = true and (g_addr_conflict_resolution = "read_first" or
g_addr_conflict_resolution = "dont_care")) generate
process (clk_i)
Port_A: process (clk_i)
begin
if rising_edge(clk_i) then
qa_o <= ram(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1));
qb_o <= ram(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1));
for i in 0 to c_num_bytes-1 loop
if s_we_a(i) = '1' then
ram(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1))((i+1)*8-1 downto i*8) := da_i((i+1)*8-1 downto i*8);
end if;
end loop;
end if;
end process;
Port_B: process (clk_i)
begin
if rising_edge(clk_i) then
qb_o <= ram(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1));
for i in 0 to c_num_bytes-1 loop
if(s_we_b(i) = '1') then
ram(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1))((i+1)*8-1 downto i*8) := db_i((i+1)*8-1 downto i*8);
end if;
......@@ -153,19 +206,28 @@ begin
gen_without_byte_enable_readfirst : if(g_with_byte_enable = false and (g_addr_conflict_resolution = "read_first" or
g_addr_conflict_resolution = "dont_care")) generate
process(clk_i)
Port_A: process(clk_i)
begin
if rising_edge(clk_i) then
if f_is_synthesis then
qa_o <= ram(to_integer(unsigned(aa_i)));
qb_o <= ram(to_integer(unsigned(ab_i)));
else
qa_o <= ram(to_integer(unsigned(aa_i)) mod g_size);
qb_o <= ram(to_integer(unsigned(ab_i)) mod g_size);
end if;
if(wea_i = '1') then
ram(to_integer(unsigned(aa_i))) := da_i;
end if;
end if;
end process;
Port_B: process(clk_i)
begin
if rising_edge(clk_i) then
if f_is_synthesis then
qb_o <= ram(to_integer(unsigned(ab_i)));
else
qb_o <= ram(to_integer(unsigned(ab_i)) mod g_size);
end if;
if(web_i = '1') then
ram(to_integer(unsigned(ab_i))) := db_i;
end if;
......@@ -175,7 +237,7 @@ begin
gen_without_byte_enable_writefirst : if(g_with_byte_enable = false and g_addr_conflict_resolution = "write_first") generate
process(clk_i)
Port_A: process(clk_i)
begin
if rising_edge(clk_i) then
if(wea_i = '1') then
......@@ -188,6 +250,12 @@ begin
qa_o <= ram(to_integer(unsigned(aa_i)) mod g_size);
end if;
end if;
end if;
end process;
Port_B: process(clk_i)
begin
if rising_edge(clk_i) then
if(web_i = '1') then
ram(to_integer(unsigned(ab_i))) := db_i;
qb_o <= db_i;
......@@ -199,14 +267,14 @@ begin
end if;
end if;
end if;
end process;
end generate gen_without_byte_enable_writefirst;
gen_without_byte_enable_nochange : if(g_with_byte_enable = false and g_addr_conflict_resolution = "no_change") generate
process(clk_i)
Port_A: process(clk_i)
begin
if rising_edge(clk_i) then
if(wea_i = '1') then
......@@ -218,6 +286,12 @@ begin
qa_o <= ram(to_integer(unsigned(aa_i)) mod g_size);
end if;
end if;
end if;
end process;
Port_B: process(clk_i)
begin
if rising_edge(clk_i) then
if(web_i = '1') then
ram(to_integer(unsigned(ab_i))) := db_i;
else
......@@ -230,13 +304,12 @@ begin
end if;
end process;
end generate gen_without_byte_enable_nochange;
gen_with_byte_enable_writefirst : if(g_with_byte_enable = true and (g_addr_conflict_resolution = "write_first")) generate
process (clk_i)
Port_A: process (clk_i)
begin
if rising_edge(clk_i) then
for i in 0 to c_num_bytes-1 loop
......@@ -246,13 +319,19 @@ begin
else
qa_o((i+1)*8-1 downto i*8) <= ram(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1))((i+1)*8-1 downto i*8);
end if;
end loop;
end if;
end process;
Port_B: process (clk_i)
begin
if rising_edge(clk_i) then
for i in 0 to c_num_bytes-1 loop
if s_we_b(i) = '1' then
ram(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1))((i+1)*8-1 downto i*8) := db_i((i+1)*8-1 downto i*8);
qb_o((i+1)*8-1 downto i*8) <= db_i((i+1)*8-1 downto i*8);
else
qb_o((i+1)*8-1 downto i*8) <= ram(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1))((i+1)*8-1 downto i*8);
end if;
end loop;
end if;
......
......@@ -23,16 +23,16 @@
-- However, it looks that ISE is not able to initialize 3-d array that would be
-- needed in this case.
-- I.e. this works:
-- shared variable ram0 : t_split_ram := f_memarray_to_ramtype(f_file_contents, 0);
-- shared variable ram1 : t_split_ram := f_memarray_to_ramtype(f_file_contents, 1);
-- shared variable ram2 : t_split_ram := f_memarray_to_ramtype(f_file_contents, 2);
-- shared variable ram3 : t_split_ram := f_memarray_to_ramtype(f_file_contents, 3);
-- shared variable ram0 : t_split_ram := f_file_to_ramtype(0);
-- shared variable ram1 : t_split_ram := f_file_to_ramtype(1);
-- shared variable ram2 : t_split_ram := f_file_to_ramtype(2);
-- shared variable ram3 : t_split_ram := f_file_to_ramtype(3);
--
-- but this doesn't:
-- type t_split_ram_array is array(0 to 3) of t_split_ram;
-- shared variable ram : t_split_ram_array := (f_memarray_to_ramtype(f_file_contents, 0),
-- f_memarray_to_ramtype(f_file_contents, 1),f_memarray_to_ramtype(f_file_contents, 2),
-- f_memarray_to_ramtype(f_file_contents, 3));
-- shared variable ram : t_split_ram_array := (f_file_to_ramtype(0),
-- f_file_to_ramtype(1),f_file_to_ramtype(2),
-- f_file_to_ramtype(3));
--
-- By "doesn't work" I mean that ISE does not fail during the synthesis, but RAM
-- does not get initialized.
......@@ -98,34 +98,29 @@ architecture syn of generic_dpram_split is
type t_split_ram is array(0 to g_size-1) of std_logic_vector(7 downto 0);
function f_memarray_to_ramtype(arr : t_meminit_array; idx : integer) return t_split_ram is
impure function f_file_to_ramtype(idx : integer) return t_split_ram is
variable tmp : t_split_ram;
variable n, pos : integer;
variable mem8 : t_ram8_type(0 to g_size-1);
begin
pos := 0;
while(pos < g_size)loop
n := 0;
-- avoid ISE loop iteration limit
while (pos < g_size and n<4096) loop
for i in 0 to 7 loop
tmp(pos)(i) := arr(pos, i+idx*8);
end loop;
n := n+1;
pos := pos + 1;
end loop;
end loop;
return tmp;
end f_memarray_to_ramtype;
function f_file_contents return t_meminit_array is
-- If no file was given, there is nothing to convert, just return
if (g_init_file = "" or g_init_file = "none") then
tmp := (others=>(others=>'0'));
return tmp;
end if;
mem8 := f_load_mem32_from_file_split(g_init_file, g_size, g_fail_if_file_not_found, idx);
return t_split_ram(mem8);
end f_file_to_ramtype;
impure function f_file_contents return t_meminit_array is
begin
return f_load_mem_from_file(g_init_file, g_size, c_data_width, g_fail_if_file_not_found);
end f_file_contents;
shared variable ram0 : t_split_ram := f_memarray_to_ramtype(f_file_contents, 0);
shared variable ram1 : t_split_ram := f_memarray_to_ramtype(f_file_contents, 1);
shared variable ram2 : t_split_ram := f_memarray_to_ramtype(f_file_contents, 2);
shared variable ram3 : t_split_ram := f_memarray_to_ramtype(f_file_contents, 3);
shared variable ram0 : t_split_ram := f_file_to_ramtype(0);
shared variable ram1 : t_split_ram := f_file_to_ramtype(1);
shared variable ram2 : t_split_ram := f_file_to_ramtype(2);
shared variable ram3 : t_split_ram := f_file_to_ramtype(3);
signal s_we_a : std_logic_vector(c_num_bytes-1 downto 0);
signal s_we_b : std_logic_vector(c_num_bytes-1 downto 0);
......@@ -147,60 +142,92 @@ begin
-- yes, I know this is 4 times exactly the same code for ram0,1,2,3,
-- but ISE fails to initialize BRAM when ram is an array (check Note
-- in the header of this file).
GEN_RAM0: process (clk_i)
GEN_RAM0_Port_A: process (clk_i)
begin
if rising_edge(clk_i) then
qa_o(7 downto 0) <= ram0(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1));
qb_o(7 downto 0) <= ram0(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1));
if s_we_a(0) = '1' then
ram0(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1)) := da_i(7 downto 0);
end if;
end if;
end process;
GEN_RAM0_Port_B: process (clk_i)
begin
if rising_edge(clk_i) then
qb_o(7 downto 0) <= ram0(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1));
if s_we_b(0) = '1' then
ram0(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1)) := db_i(7 downto 0);
end if;
end if;
end process;
GEN_RAM1: process (clk_i)
--------------------------------------------------
GEN_RAM1_Port_A: process (clk_i)
begin
if rising_edge(clk_i) then
qa_o(15 downto 8) <= ram1(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1));
qb_o(15 downto 8) <= ram1(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1));
if s_we_a(1) = '1' then
ram1(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1)) := da_i(15 downto 8);
end if;
end if;
end process;
GEN_RAM1_Port_B: process (clk_i)
begin
if rising_edge(clk_i) then
qb_o(15 downto 8) <= ram1(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1));
if s_we_b(1) = '1' then
ram1(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1)) := db_i(15 downto 8);
end if;
end if;
end process;
GEN_RAM2: process (clk_i)
--------------------------------------------------
GEN_RAM2_Port_A: process (clk_i)
begin
if rising_edge(clk_i) then
qa_o(23 downto 16) <= ram2(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1));
qb_o(23 downto 16) <= ram2(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1));
if s_we_a(2) = '1' then
ram2(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1)) := da_i(23 downto 16);
end if;
end if;
end process;
GEN_RAM2_Port_B: process (clk_i)
begin
if rising_edge(clk_i) then
qb_o(23 downto 16) <= ram2(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1));
if s_we_b(2) = '1' then
ram2(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1)) := db_i(23 downto 16);
end if;
end if;
end process;
GEN_RAM3: process (clk_i)
--------------------------------------------------
GEN_RAM3_Port_A: process (clk_i)
begin
if rising_edge(clk_i) then
qa_o(31 downto 24) <= ram3(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1));
qb_o(31 downto 24) <= ram3(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1));
if s_we_a(3) = '1' then
ram3(f_check_bounds(to_integer(unsigned(aa_i)), 0, g_size-1)) := da_i(31 downto 24);
end if;
end if;
end process;
GEN_RAM3_Port_B: process (clk_i)
begin
if rising_edge(clk_i) then
qb_o(31 downto 24) <= ram3(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1));
if s_we_b(3) = '1' then
ram3(f_check_bounds(to_integer(unsigned(ab_i)), 0, g_size-1)) := db_i(31 downto 24);
end if;
end if;
end process;
--------------------------------------------------
end syn;
modules = { "local" : [
"wb_async_bridge",
"wb_axi4lite_bridge",
"wb_onewire_master",
"wb_i2c_master",
"wb_bus_fanout",
......@@ -18,7 +19,7 @@ modules = { "local" : [
"wb_dma",
"wb_serial_lcd",
"wb_spi_flash",
"wb_simple_pwm",
"wb_simple_pwm",
"wb_i2c_bridge",
"wbgen2",
"wbgenplus",
......
files = [
"axi4_pkg.vhd",
"wb_axi4lite_bridge.vhd",
"xwb_axi4lite_bridge.vhd"
]
library ieee;
use ieee.std_logic_1164.all;
use work.wishbone_pkg.all;
package axi4_pkg is
-- AXI4-Full interface, master output ports, 32 bits
type t_axi4_full_master_out_32 is record
ARVALID : std_logic;
AWVALID : std_logic;
BREADY : std_logic;
RREADY : std_logic;
WLAST : std_logic;
WVALID : std_logic;
ARID : std_logic_vector (11 downto 0);
AWID : std_logic_vector (11 downto 0);
WID : std_logic_vector (11 downto 0);
ARBURST : std_logic_vector (1 downto 0);
ARLOCK : std_logic_vector (1 downto 0);
ARSIZE : std_logic_vector (2 downto 0);
AWBURST : std_logic_vector (1 downto 0);
AWLOCK : std_logic_vector (1 downto 0);
AWSIZE : std_logic_vector (2 downto 0);
ARPROT : std_logic_vector (2 downto 0);
AWPROT : std_logic_vector (2 downto 0);
ARADDR : std_logic_vector (31 downto 0);
AWADDR : std_logic_vector (31 downto 0);
WDATA : std_logic_vector (31 downto 0);
ARCACHE : std_logic_vector (3 downto 0);
ARLEN : std_logic_vector (3 downto 0);
ARQOS : std_logic_vector (3 downto 0);
AWCACHE : std_logic_vector (3 downto 0);
AWLEN : std_logic_vector (3 downto 0);
AWQOS : std_logic_vector (3 downto 0);
WSTRB : std_logic_vector (3 downto 0);
end record;
-- AXI4-Full interface, master input ports, 32 bits
type t_axi4_full_master_in_32 is record
ARREADY : std_logic;
AWREADY : std_logic;
BVALID : std_logic;
RLAST : std_logic;
RVALID : std_logic;
WREADY : std_logic;
BID : std_logic_vector (11 downto 0);
RID : std_logic_vector (11 downto 0);
BRESP : std_logic_vector (1 downto 0);
RRESP : std_logic_vector (1 downto 0);
RDATA : std_logic_vector (31 downto 0);
end record;
-- AXI4-Lite interface, master output ports, 32 bits
type t_axi4_lite_master_out_32 is record
ARVALID : std_logic;
AWVALID : std_logic;
BREADY : std_logic;
RREADY : std_logic;
WLAST : std_logic;
WVALID : std_logic;
ARADDR : std_logic_vector (31 downto 0);
AWADDR : std_logic_vector (31 downto 0);
WDATA : std_logic_vector (31 downto 0);
WSTRB : std_logic_vector (3 downto 0);
end record;
-- AXI4-Lite interface, master input ports, 32 bits
type t_axi4_lite_master_in_32 is record
ARREADY : std_logic;
AWREADY : std_logic;
BVALID : std_logic;
RLAST : std_logic;
RVALID : std_logic;
WREADY : std_logic;
BRESP : std_logic_vector (1 downto 0);
RRESP : std_logic_vector (1 downto 0);
RDATA : std_logic_vector (31 downto 0);
end record;
constant c_axi4_lite_default_master_in_32 : t_axi4_lite_master_in_32 :=
(
AWREADY => '0',
ARREADY => '0',
BVALID => '0',
RLAST => '0',
RVALID => '0',
WREADY => '0',
BRESP => "00",
RRESP => "00",
RDATA => (others => '0')
);
constant c_axi4_lite_default_master_out_32 : t_axi4_lite_master_out_32 :=
(
ARVALID => '0',
AWVALID => '0',
BREADY => '0',
RREADY => '0',
WLAST => '0',
WVALID => '0',
ARADDR => (others => '0'),
AWADDR => (others => '0'),
WDATA => (others => '0'),
WSTRB => (others => '0')
);
subtype t_axi4_lite_slave_in_32 is t_axi4_lite_master_out_32;
subtype t_axi4_lite_slave_out_32 is t_axi4_lite_master_in_32;
constant c_AXI4_RESP_OKAY : std_logic_vector(1 downto 0) := "00";
constant c_AXI4_RESP_EXOKAY : std_logic_vector(1 downto 0) := "01";
constant c_AXI4_RESP_SLVERR : std_logic_vector(1 downto 0) := "10";
constant c_AXI4_RESP_DECERR : std_logic_vector(1 downto 0) := "11";
function f_axi4_full_to_lite (
f : t_axi4_full_master_out_32
) return t_axi4_lite_master_out_32;
function f_axi4_lite_to_full (
l : t_axi4_lite_master_in_32
) return t_axi4_full_master_in_32;
component xwb_axi4lite_bridge is
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
axi4_slave_i : in t_axi4_lite_slave_in_32;
axi4_slave_o : out t_axi4_lite_slave_out_32;
wb_master_o : out t_wishbone_master_out;
wb_master_i : in t_wishbone_master_in);
end component xwb_axi4lite_bridge;
component wb_axi4lite_bridge is
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
ARVALID : in std_logic;
AWVALID : in std_logic;
BREADY : in std_logic;
RREADY : in std_logic;
WLAST : in std_logic;
WVALID : in std_logic;
ARADDR : in std_logic_vector (31 downto 0);
AWADDR : in std_logic_vector (31 downto 0);
WDATA : in std_logic_vector (31 downto 0);
WSTRB : in std_logic_vector (3 downto 0);
ARREADY : out std_logic;
AWREADY : out std_logic;
BVALID : out std_logic;
RLAST : out std_logic;
RVALID : out std_logic;
WREADY : out std_logic;
BRESP : out std_logic_vector (1 downto 0);
RRESP : out std_logic_vector (1 downto 0);
RDATA : out std_logic_vector (31 downto 0);
wb_adr : out std_logic_vector(c_wishbone_address_width-1 downto 0);
wb_dat_m2s : out std_logic_vector(c_wishbone_data_width-1 downto 0);
wb_sel : out std_logic_vector(c_wishbone_data_width/8-1 downto 0);
wb_cyc : out std_logic;
wb_stb : out std_logic;
wb_we : out std_logic;
wb_dat_s2m : in std_logic_vector(c_wishbone_data_width-1 downto 0);
wb_err : in std_logic := '0';
wb_rty : in std_logic := '0';
wb_ack : in std_logic;
wb_stall : in std_logic
);
end component;
end package;
package body axi4_pkg is
function f_axi4_full_to_lite (
f : t_axi4_full_master_out_32
) return t_axi4_lite_master_out_32 is
variable l : t_axi4_lite_master_out_32;
begin
l.ARVALID := f.ARVALID;
l.AWVALID := f.AWVALID;
l.BREADY := f.BREADY;
l.RREADY := f.RREADY;
l.WLAST := f.WLAST;
l.WVALID := f.WVALID;
l.ARADDR := f.ARADDR;
l.AWADDR := f.AWADDR;
l.WDATA := f.WDATA;
l.WSTRB := f.WSTRB;
return l;
end f_axi4_full_to_lite;
function f_axi4_lite_to_full (
l : t_axi4_lite_master_in_32
) return t_axi4_full_master_in_32 is
variable f : t_axi4_full_master_in_32;
begin
f.ARREADY := l.ARREADY;
f.AWREADY := l.AWREADY;
f.BVALID := l.BVALID;
f.RLAST := l.RLAST;
f.RVALID := l.RVALID;
f.WREADY := l.WREADY;
f.BID := (others => '0');
f.RID := (others => '0');
f.BRESP := l.BRESP;
f.RRESP := l.RRESP;
f.RDATA := l.RDATA;
return f;
end f_axi4_lite_to_full;
end package body;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axi4_pkg.all;
use work.wishbone_pkg.all;
entity wb_axi4lite_bridge is
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
ARVALID : in std_logic;
AWVALID : in std_logic;
BREADY : in std_logic;
RREADY : in std_logic;
WLAST : in std_logic;
WVALID : in std_logic;
ARADDR : in std_logic_vector (31 downto 0);
AWADDR : in std_logic_vector (31 downto 0);
WDATA : in std_logic_vector (31 downto 0);
WSTRB : in std_logic_vector (3 downto 0);
ARREADY : out std_logic;
AWREADY : out std_logic;
BVALID : out std_logic;
RLAST : out std_logic;
RVALID : out std_logic;
WREADY : out std_logic;
BRESP : out std_logic_vector (1 downto 0);
RRESP : out std_logic_vector (1 downto 0);
RDATA : out std_logic_vector (31 downto 0);
wb_adr : out std_logic_vector(c_wishbone_address_width-1 downto 0);
wb_dat_m2s : out std_logic_vector(c_wishbone_data_width-1 downto 0);
wb_sel : out std_logic_vector(c_wishbone_data_width/8-1 downto 0);
wb_cyc : out std_logic;
wb_stb : out std_logic;
wb_we : out std_logic;
wb_dat_s2m : in std_logic_vector(c_wishbone_data_width-1 downto 0);
wb_err : in std_logic := '0';
wb_rty : in std_logic := '0';
wb_ack : in std_logic;
wb_stall : in std_logic
);
end wb_axi4lite_bridge;
architecture rtl of wb_axi4lite_bridge is
signal axi_in : t_axi4_lite_master_out_32;
signal axi_out : t_axi4_lite_master_in_32;
signal wb_in : t_wishbone_master_in;
signal wb_out : t_wishbone_master_out;
begin
axi_in.ARVALID <= ARVALID;
axi_in.AWVALID <= AWVALID;
axi_in.BREADY <= BREADY;
axi_in.RREADY <= RREADY;
axi_in.WLAST <= WLAST;
axi_in.WVALID <= WVALID;
axi_in.ARADDR <= ARADDR;
axi_in.AWADDR <= AWADDR;
axi_in.WDATA <= WDATA;
axi_in.WSTRB <= WSTRB;
ARREADY <= axi_out.ARREADY;
AWREADY <= axi_out.AWREADY;
BVALID <= axi_out.BVALID;
RLAST <= axi_out.RLAST;
RVALID <= axi_out.RVALID;
WREADY <= axi_out.WREADY;
BRESP <= axi_out.BRESP;
RRESP <= axi_out.RRESP;
RDATA <= axi_out.RDATA;
wb_adr <= wb_out.adr;
wb_dat_m2s <= wb_out.dat;
wb_stb <= wb_out.stb;
wb_sel <= wb_out.sel;
wb_cyc <= wb_out.cyc;
wb_we <= wb_out.we;
wb_in.err <= wb_err;
wb_in.rty <= wb_rty;
wb_in.ack <= wb_ack;
wb_in.int <= '0';
wb_in.stall <= wb_stall;
wb_in.dat <= wb_dat_s2m;
U_Wrapped_Bridge : xwb_axi4lite_bridge
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
axi4_slave_i => axi_in,
axi4_slave_o => axi_out,
wb_master_o => wb_out,
wb_master_i => wb_in);
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axi4_pkg.all;
use work.wishbone_pkg.all;
entity xwb_axi4lite_bridge is
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
axi4_slave_i : in t_axi4_lite_slave_in_32;
axi4_slave_o : out t_axi4_lite_slave_out_32;
wb_master_o : out t_wishbone_master_out;
wb_master_i : in t_wishbone_master_in
);
end xwb_axi4lite_bridge;
architecture rtl of xwb_axi4lite_bridge is
constant c_timeout : integer := 256;
type t_state is
(IDLE, ISSUE_WRITE, ISSUE_READ, COMPLETE_WRITE, COMPLETE_READ, WAIT_ACK_READ, WAIT_ACK_WRITE, RESPONSE_READ, RESPONSE_WRITE);
signal state : t_state;
signal count : unsigned(10 downto 0);
begin
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
axi4_slave_o <= c_axi4_lite_default_master_in_32;
wb_master_o.cyc <= '0';
state <= IDLE;
else
case state is
when IDLE =>
wb_master_o.cyc <= '0';
axi4_slave_o.ARREADY <= '1';
axi4_slave_o.AWREADY <= '1';
axi4_slave_o.WREADY <= '0';
axi4_slave_o.BVALID <= '0';
axi4_slave_o.BRESP <= (others => 'X');
axi4_slave_o.RDATA <= (others => 'X');
axi4_slave_o.RRESP <= (others => 'X');
axi4_slave_o.RVALID <= '0';
axi4_slave_o.RLAST <= '0';
if(axi4_slave_i.AWVALID = '1') then
state <= ISSUE_WRITE;
wb_master_o.adr <= axi4_slave_i.AWADDR;
elsif (axi4_slave_i.ARVALID = '1') then
state <= ISSUE_READ;
wb_master_o.adr <= axi4_slave_i.ARADDR;
end if;
when ISSUE_WRITE =>
axi4_slave_o.WREADY <= '1';
wb_master_o.cyc <= '1';
wb_master_o.we <= '1';
if(axi4_slave_i.WVALID = '1') then
wb_master_o.stb <= '1';
wb_master_o.sel <= axi4_slave_i.WSTRB;
wb_master_o.dat <= axi4_slave_i.WDATA;
state <= COMPLETE_WRITE;
end if;
when ISSUE_READ =>
wb_master_o.cyc <= '1';
wb_master_o.stb <= '1';
wb_master_o.we <= '0';
axi4_slave_o.RVALID <= '0';
axi4_slave_o.RLAST <= '0';
state <= COMPLETE_READ;
when COMPLETE_READ =>
if(wb_master_i.stall = '0') then
wb_master_o.stb <= '0';
if(wb_master_i.ack = '1') then
state <= IDLE;
axi4_slave_o.RRESP <= c_AXI4_RESP_EXOKAY;
axi4_slave_o.RDATA <= wb_master_i.dat;
axi4_slave_o.RVALID <= '1';
axi4_slave_o.RLAST <= '1';
wb_master_o.cyc <= '0';
else
state <= WAIT_ACK_READ;
count <= (others => '0');
end if;
end if;
when COMPLETE_WRITE =>
if(wb_master_i.stall = '0') then
wb_master_o.stb <= '0';
if(wb_master_i.ack = '1') then
state <= RESPONSE_WRITE;
axi4_slave_o.BRESP <= c_AXI4_RESP_EXOKAY;
wb_master_o.cyc <= '0';
else
state <= WAIT_ACK_WRITE;
count <= (others => '0');
end if;
end if;
when WAIT_ACK_WRITE =>
if(wb_master_i.ack = '1') then
state <= RESPONSE_WRITE;
axi4_slave_o.BRESP <= c_AXI4_RESP_EXOKAY;
wb_master_o.cyc <= '0';
elsif count = c_timeout then
state <= RESPONSE_WRITE;
axi4_slave_o.BRESP <= c_AXI4_RESP_SLVERR;
wb_master_o.cyc <= '0';
end if;
count <= count + 1;
when WAIT_ACK_READ =>
if(wb_master_i.ack = '1') then
state <= IDLE;
axi4_slave_o.RRESP <= c_AXI4_RESP_EXOKAY;
axi4_slave_o.RVALID <= '1';
axi4_slave_o.RLAST <= '1';
axi4_slave_o.RDATA <= wb_master_i.dat;
wb_master_o.cyc <= '0';
elsif count = c_timeout then
state <= IDLE;
axi4_slave_o.RRESP <= c_AXI4_RESP_SLVERR;
axi4_slave_o.RVALID <= '1';
axi4_slave_o.RLAST <= '1';
axi4_slave_o.RDATA <= (others => 'X');
wb_master_o.cyc <= '0';
end if;
count <= count + 1;
when RESPONSE_WRITE =>
if (axi4_slave_i.BREADY = '1') then
axi4_slave_o.BVALID <= '1';
state <= IDLE;
end if;
when RESPONSE_READ => null;
end case;
end if;
end if;
end process;
end rtl;
......@@ -57,6 +57,20 @@ def mangle_names(string, profile_name):
for pattern in LM32_mods:
string = string.replace(pattern, pattern + "_"+profile_name)
return string;
def remove_unsynthetizable(code):
syn_on = True
r=""
for l in code.split("\n"):
if l.lstrip("\t ").startswith("// synthesis translate_off"):
syn_on = False
elif l.lstrip("\t ").startswith("// synthesis translate_on"):
syn_on = True
if syn_on:
r=r+l+"\n"
return r
def gen_customized_version(profile_name, feats):
print("GenCfg ", profile_name);
......@@ -110,7 +124,8 @@ def gen_customized_version(profile_name, feats):
f = open(fname, "r");
contents = f.read();
mangled = mangle_names(contents, profile_name)
ftmp.write(mangled);
code = remove_unsynthetizable(mangled)
ftmp.write(code);
f.close();
ftmp.close();
......@@ -226,10 +241,10 @@ architecture rtl of xwb_lm32 is \n""");
variable tmp : std_logic_vector(x'left downto 0);
begin
for i in 0 to x'left loop
if(x(i)='X' or x(i)='U' or x(i)='Z') then
tmp(i) := '0';
if(x(i)='1') then
tmp(i) := '1';
else
tmp(i) := x(i);
tmp(i) := '0';
end if;
end loop; -- i
return tmp;
......
......@@ -348,10 +348,10 @@ end component;
variable tmp : std_logic_vector(x'left downto 0);
begin
for i in 0 to x'left loop
if(x(i)='X' or x(i)='U' or x(i)='Z') then
tmp(i) := '0';
if(x(i)='1') then
tmp(i) := '1';
else
tmp(i) := x(i);
tmp(i) := '0';
end if;
end loop; -- i
return tmp;
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : simple_uart_pkg.vhd
-- Author : auto-generated by wbgen2 from simple_uart_wb.wb
-- Created : Thu Feb 14 10:36:11 2013
-- Created : Tue Aug 15 10:16:30 2017
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
......@@ -66,20 +66,20 @@ end package;
package body uart_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if(x = 'X' or x = 'U') then
return '0';
if x = '1' then
return '1';
else
return x;
end if;
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
if x(i) = '1' then
tmp(i):= '1';
else
tmp(i):=x(i);
tmp(i):= '0';
end if;
end loop;
return tmp;
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : simple_uart_wb.vhd
-- Author : auto-generated by wbgen2 from simple_uart_wb.wb
-- Created : Thu Feb 14 10:36:11 2013
-- Created : Tue Aug 15 10:16:30 2017
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
......@@ -42,22 +42,12 @@ architecture syn of simple_uart_wb is
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(2 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
-- Some internal signals assignments
wrdata_reg <= wb_dat_i;
bwsel_reg <= wb_sel_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
......
Markdown is supported
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