Commit 72a0f7f0 authored by twlostow's avatar twlostow

bugfixes in FIFO generator, added read notifications

git-svn-id: http://svn.ohwr.org/wishbone-gen@22 4537843c-45c2-4d80-8546-c3283569414f
parent f8ead30c
......@@ -7,19 +7,24 @@ use altera_mf.all;
library wbgen2;
use wbgen2.all;
-- these two stupid wrappers (wbgen2_dpssram_wrapper_singleclock and
-- wbgen2_dpssram_wrapper_dualclock) are necessary to compile the same file
-- with Quartus and Modelsim:
-- - when "clock1" line is declared in the component, but not connected, Modelsim
-- will drop an error
-- - if "clock1" line is connected, but the altsyncram is declared as single-clock,
-- Quartus will drop an error.
entity wbgen2_dpssram is
entity wbgen2_dpssram_wrapper_singleclock is
generic (
g_data_width : natural;
g_size : natural;
g_addr_width : natural;
g_dual_clock : boolean := false;
g_use_bwsel : boolean := false);
port (
clk_a_i : in std_logic;
clk_b_i : in std_logic;
addr_a_i : in std_logic_vector(g_addr_width-1 downto 0);
addr_b_i : in std_logic_vector(g_addr_width-1 downto 0);
......@@ -40,10 +45,9 @@ entity wbgen2_dpssram is
wr_b_i : in std_logic
);
end wbgen2_dpssram;
end wbgen2_dpssram_wrapper_singleclock;
architecture syn of wbgen2_dpssram is
architecture syn of wbgen2_dpssram_wrapper_singleclock is
component altsyncram
generic (
......@@ -55,7 +59,7 @@ architecture syn of wbgen2_dpssram is
clock_enable_output_a : string;
clock_enable_output_b : string;
indata_reg_b : string;
-- intended_device_family : string;
intended_device_family : string;
lpm_type : string;
numwords_a : natural;
numwords_b : natural;
......@@ -77,8 +81,8 @@ architecture syn of wbgen2_dpssram is
port (
wren_a : in std_logic;
clock0 : in std_logic;
-- clock1: in std_logic;
wren_b : in std_logic;
clock1 : in std_logic;
byteena_a : in std_logic_vector ((g_data_width+7)/8-1 downto 0);
byteena_b : in std_logic_vector ((g_data_width+7)/8-1 downto 0);
address_a : in std_logic_vector ((g_addr_width-1) downto 0);
......@@ -91,26 +95,24 @@ architecture syn of wbgen2_dpssram is
data_b : in std_logic_vector ((g_data_width-1) downto 0));
end component;
signal clksel : string(1 to 6);
signal bwsel_int_a : std_logic_vector((g_data_width+7)/8-1 downto 0);
signal bwsel_int_b : std_logic_vector((g_data_width+7)/8-1 downto 0);
signal dummy : std_logic;
begin -- syn
genram1: if(g_dual_clock = true) generate
altsyncram_component : altsyncram
generic map (
address_reg_b => "CLOCK1",
byteena_reg_b => "CLOCK1",
address_reg_b => "CLOCK0",
byteena_reg_b => "CLOCK0",
byte_size => 8,
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_a => "BYPASS",
clock_enable_output_b => "BYPASS",
indata_reg_b => "CLOCK1",
-- intended_device_family => "Cyclone III",
indata_reg_b => "CLOCK0",
intended_device_family => "Cyclone III",
lpm_type => "altsyncram",
numwords_a => g_size,
numwords_b => g_size,
......@@ -128,13 +130,13 @@ begin -- syn
width_b => g_data_width,
width_byteena_a => (g_data_width+7)/8,
width_byteena_b => (g_data_width+7)/8,
wrcontrol_wraddress_reg_b => "CLOCK1"
wrcontrol_wraddress_reg_b => "CLOCK0"
)
port map (
wren_a => wr_a_i,
wren_b => wr_b_i,
clock0 => clk_a_i,
clock1 => clk_b_i,
-- clock1 => '0',
byteena_a => bwsel_int_a,
byteena_b => bwsel_int_b,
address_a => addr_a_i,
......@@ -147,21 +149,130 @@ begin -- syn
q_b => data_b_o
);
end generate genram1;
genram2: if(g_dual_clock = false) generate
genbwsel1: if(g_use_bwsel = true) generate
bwsel_int_a <= bwsel_a_i;
bwsel_int_b <= bwsel_b_i;
end generate genbwsel1;
genbwsel2: if(g_use_bwsel = false) generate
bwsel_int_a <= (others => '1');
bwsel_int_b <= (others => '1');
end generate genbwsel2;
end syn;
library ieee;
use ieee.std_logic_1164.all;
library altera_mf;
use altera_mf.all;
library wbgen2;
use wbgen2.all;
entity wbgen2_dpssram_wrapper_dualclock is
generic (
g_data_width : natural;
g_size : natural;
g_addr_width : natural;
g_use_bwsel : boolean := false);
port (
clk_a_i : in std_logic;
clk_b_i : in std_logic;
addr_a_i : in std_logic_vector(g_addr_width-1 downto 0);
addr_b_i : in std_logic_vector(g_addr_width-1 downto 0);
data_a_i : in std_logic_vector(g_data_width-1 downto 0);
data_b_i : in std_logic_vector(g_data_width-1 downto 0);
data_a_o : out std_logic_vector(g_data_width-1 downto 0);
data_b_o : out std_logic_vector(g_data_width-1 downto 0);
bwsel_a_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
bwsel_b_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
rd_a_i : in std_logic;
rd_b_i : in std_logic;
wr_a_i : in std_logic;
wr_b_i : in std_logic
);
end wbgen2_dpssram_wrapper_dualclock;
architecture syn of wbgen2_dpssram_wrapper_dualclock is
component altsyncram
generic (
address_reg_b : string;
byteena_reg_b : string;
byte_size : natural;
clock_enable_input_a : string;
clock_enable_input_b : string;
clock_enable_output_a : string;
clock_enable_output_b : string;
indata_reg_b : string;
intended_device_family : string;
lpm_type : string;
numwords_a : natural;
numwords_b : natural;
operation_mode : string;
outdata_aclr_a : string;
outdata_aclr_b : string;
outdata_reg_a : string;
outdata_reg_b : string;
power_up_uninitialized : string;
read_during_write_mode_port_a : string;
read_during_write_mode_port_b : string;
widthad_a : natural;
widthad_b : natural;
width_a : natural;
width_b : natural;
width_byteena_a : natural;
width_byteena_b : natural;
wrcontrol_wraddress_reg_b : string);
port (
wren_a : in std_logic;
clock0 : in std_logic;
wren_b : in std_logic;
clock1 : in std_logic;
byteena_a : in std_logic_vector ((g_data_width+7)/8-1 downto 0);
byteena_b : in std_logic_vector ((g_data_width+7)/8-1 downto 0);
address_a : in std_logic_vector ((g_addr_width-1) downto 0);
address_b : in std_logic_vector ((g_addr_width-1) downto 0);
rden_a : in std_logic;
q_a : out std_logic_vector ((g_data_width-1) downto 0);
rden_b : in std_logic;
q_b : out std_logic_vector ((g_data_width-1) downto 0);
data_a : in std_logic_vector ((g_data_width-1) downto 0);
data_b : in std_logic_vector ((g_data_width-1) downto 0));
end component;
signal bwsel_int_a : std_logic_vector((g_data_width+7)/8-1 downto 0);
signal bwsel_int_b : std_logic_vector((g_data_width+7)/8-1 downto 0);
signal dummy : std_logic;
begin -- syn
altsyncram_component : altsyncram
generic map (
address_reg_b => "CLOCK0",
byteena_reg_b => "CLOCK0",
address_reg_b => "CLOCK1",
byteena_reg_b => "CLOCK1",
byte_size => 8,
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_a => "BYPASS",
clock_enable_output_b => "BYPASS",
indata_reg_b => "CLOCK0",
-- intended_device_family => "Cyclone III",
indata_reg_b => "CLOCK1",
intended_device_family => "Cyclone III",
lpm_type => "altsyncram",
numwords_a => g_size,
numwords_b => g_size,
......@@ -179,13 +290,13 @@ begin -- syn
width_b => g_data_width,
width_byteena_a => (g_data_width+7)/8,
width_byteena_b => (g_data_width+7)/8,
wrcontrol_wraddress_reg_b => "CLOCK0"
wrcontrol_wraddress_reg_b => "CLOCK1"
)
port map (
wren_a => wr_a_i,
wren_b => wr_b_i,
clock0 => clk_a_i,
clock1 => '0',
clock1 => clk_b_i,
byteena_a => bwsel_int_a,
byteena_b => bwsel_int_b,
address_a => addr_a_i,
......@@ -198,9 +309,6 @@ begin -- syn
q_b => data_b_o
);
end generate genram2;
-- clksel <= ;
genbwsel1: if(g_use_bwsel = true) generate
bwsel_int_a <= bwsel_a_i;
......@@ -212,10 +320,151 @@ begin -- syn
bwsel_int_b <= (others => '1');
end generate genbwsel2;
end syn;
library ieee;
use ieee.std_logic_1164.all;
library altera_mf;
use altera_mf.all;
library wbgen2;
use wbgen2.all;
entity wbgen2_dpssram is
generic (
g_data_width : natural;
g_size : natural;
g_addr_width : natural;
g_dual_clock : boolean := false;
g_use_bwsel : boolean := false);
port (
clk_a_i : in std_logic;
clk_b_i : in std_logic;
addr_a_i : in std_logic_vector(g_addr_width-1 downto 0);
addr_b_i : in std_logic_vector(g_addr_width-1 downto 0);
data_a_i : in std_logic_vector(g_data_width-1 downto 0);
data_b_i : in std_logic_vector(g_data_width-1 downto 0);
data_a_o : out std_logic_vector(g_data_width-1 downto 0);
data_b_o : out std_logic_vector(g_data_width-1 downto 0);
bwsel_a_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
bwsel_b_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
rd_a_i : in std_logic;
rd_b_i : in std_logic;
wr_a_i : in std_logic;
wr_b_i : in std_logic
);
end wbgen2_dpssram;
architecture syn of wbgen2_dpssram is
component wbgen2_dpssram_wrapper_singleclock
generic (
g_data_width : natural;
g_size : natural;
g_addr_width : natural;
g_use_bwsel : boolean);
port (
clk_a_i : in std_logic;
addr_a_i : in std_logic_vector(g_addr_width-1 downto 0);
addr_b_i : in std_logic_vector(g_addr_width-1 downto 0);
data_a_i : in std_logic_vector(g_data_width-1 downto 0);
data_b_i : in std_logic_vector(g_data_width-1 downto 0);
data_a_o : out std_logic_vector(g_data_width-1 downto 0);
data_b_o : out std_logic_vector(g_data_width-1 downto 0);
bwsel_a_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
bwsel_b_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
rd_a_i : in std_logic;
rd_b_i : in std_logic;
wr_a_i : in std_logic;
wr_b_i : in std_logic);
end component;
component wbgen2_dpssram_wrapper_dualclock
generic (
g_data_width : natural;
g_size : natural;
g_addr_width : natural;
g_use_bwsel : boolean);
port (
clk_a_i : in std_logic;
clk_b_i : in std_logic;
addr_a_i : in std_logic_vector(g_addr_width-1 downto 0);
addr_b_i : in std_logic_vector(g_addr_width-1 downto 0);
data_a_i : in std_logic_vector(g_data_width-1 downto 0);
data_b_i : in std_logic_vector(g_data_width-1 downto 0);
data_a_o : out std_logic_vector(g_data_width-1 downto 0);
data_b_o : out std_logic_vector(g_data_width-1 downto 0);
bwsel_a_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
bwsel_b_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
rd_a_i : in std_logic;
rd_b_i : in std_logic;
wr_a_i : in std_logic;
wr_b_i : in std_logic);
end component;
begin -- syn
genram1: if(g_dual_clock = true) generate
U_dc_wrapper_inst: wbgen2_dpssram_wrapper_dualclock
generic map (
g_data_width => g_data_width,
g_size => g_size,
g_addr_width => g_addr_width,
g_use_bwsel => g_use_bwsel)
port map (
clk_a_i => clk_a_i,
clk_b_i => clk_b_i,
addr_a_i => addr_a_i,
addr_b_i => addr_b_i,
data_a_i => data_a_i,
data_b_i => data_b_i,
data_a_o => data_a_o,
data_b_o => data_b_o,
bwsel_a_i => bwsel_a_i,
bwsel_b_i => bwsel_b_i,
rd_a_i => rd_a_i,
rd_b_i => rd_b_i,
wr_a_i => wr_a_i,
wr_b_i => wr_b_i);
end generate genram1;
genram2: if(g_dual_clock = false) generate
U_sc_wrapper_inst: wbgen2_dpssram_wrapper_singleclock
generic map (
g_data_width => g_data_width,
g_size => g_size,
g_addr_width => g_addr_width,
g_use_bwsel => g_use_bwsel)
port map (
clk_a_i => clk_a_i,
addr_a_i => addr_a_i,
addr_b_i => addr_b_i,
data_a_i => data_a_i,
data_b_i => data_b_i,
data_a_o => data_a_o,
data_b_o => data_b_o,
bwsel_a_i => bwsel_a_i,
bwsel_b_i => bwsel_b_i,
rd_a_i => rd_a_i,
rd_b_i => rd_b_i,
wr_a_i => wr_a_i,
wr_b_i => wr_b_i);
end generate genram2;
end syn;
#!/usr/bin/env lua
package.preload['alt_getopt']=(function(...)
local i,s,u,a,o=type,pairs,ipairs,io,os
local i,r,u,o,a=type,pairs,ipairs,io,os
module("alt_getopt")
local function r(e)
local function c(e)
local t=1
local t=#e
local t={}
for e,a in e:gmatch("(%w)(:?)")do
t[e]=#a
for a,e in e:gmatch("(%w)(:?)")do
t[a]=#e
end
return t
end
local function d(t,e)
a.stderr:write(t)
o.exit(e)
o.stderr:write(t)
a.exit(e)
end
local function a(e)
d("Unknown option `-"..
......@@ -31,14 +31,14 @@ end
end
return e
end
function get_ordered_opts(n,o,a)
function get_ordered_opts(n,a,h)
local t=1
local e=1
local i={}
local h={}
local o=r(o)
for t,e in s(a)do
o[t]=e
local s={}
local o=c(a)
for e,t in r(h)do
o[e]=t
end
while t<=#n do
local a=n[t]
......@@ -48,49 +48,49 @@ break
elseif a=="-"then
break
elseif a:sub(1,2)=="--"then
local s=a:find("=",1,true)
if s then
local t=a:sub(3,s-1)
local h=a:find("=",1,true)
if h then
local t=a:sub(3,h-1)
t=l(o,t)
if o[t]==0 then
d("Bad usage of option `"..a.."'\n",1)
end
h[e]=a:sub(s+1)
s[e]=a:sub(h+1)
i[e]=t
else
local s=a:sub(3)
s=l(o,s)
if o[s]==0 then
i[e]=s
local h=a:sub(3)
h=l(o,h)
if o[h]==0 then
i[e]=h
else
if t==#n then
d("Missed value for option `"..a.."'\n",1)
end
h[e]=n[t+1]
i[e]=s
s[e]=n[t+1]
i[e]=h
t=t+1
end
end
e=e+1
elseif a:sub(1,1)=="-"then
local s
local h
for r=2,a:len()do
local s=l(o,a:sub(r,r))
if o[s]==0 then
i[e]=s
local h=l(o,a:sub(r,r))
if o[h]==0 then
i[e]=h
e=e+1
elseif a:len()==r then
if t==#n then
d("Missed value for option `-"..s.."'\n",1)
d("Missed value for option `-"..h.."'\n",1)
end
h[e]=n[t+1]
i[e]=s
s[e]=n[t+1]
i[e]=h
t=t+1
e=e+1
break
else
h[e]=a:sub(r+1)
i[e]=s
s[e]=a:sub(r+1)
i[e]=h
e=e+1
break
end
......@@ -100,14 +100,14 @@ break
end
t=t+1
end
return i,t,h
return i,t,s
end
function get_opts(a,t,o)
local e={}
local t,i,o=get_ordered_opts(a,t,o)
for t,a in u(t)do
if o[t]then
e[a]=o[t]
local a,i,t=get_ordered_opts(a,t,o)
for o,a in u(a)do
if t[o]then
e[a]=t[o]
else
e[a]=1
end
......@@ -176,20 +176,20 @@ die(t.." expected.");
end
return e;
end
function range2bits(t)
local e=t[1];
local a=t[2];
local t;
if(math.abs(e)>math.abs(a))then
t=math.abs(e);
function range2bits(e)
local t=e[1];
local a=e[2];
local e;
if(math.abs(t)>math.abs(a))then
e=math.abs(t);
else
t=math.abs(a);
e=math.abs(a);
end
local t=math.ceil(math.log(t)/math.log(2));
if(e<0)then
t=t+1;
local e=math.ceil(math.log(e)/math.log(2));
if(t<0)then
e=e+1;
end
return t;
return e;
end
function calc_size(e,t)
if(e.type==MONOSTABLE or e.type==BIT)then
......@@ -214,8 +214,11 @@ die("ENUM-type fields are not yet supported. Sorry :(");
end
t.total_size=t.total_size+e.size;
end
function foreach_reg(t,a)
for o,e in ipairs(periph)do
function foreach_reg(t,a,e)
if(e==nil)then
e=periph;
end
for o,e in ipairs(e)do
if(type(e)=='table')then
if(e.__type~=nil and(match(e.__type,t)))then
a(e);
......@@ -276,22 +279,22 @@ function die(e)
print("Error: "..e);
os.exit(-1);
end
function match(e,t)
function match(t,e)
local a,a;
for a,t in pairs(t)do
if(e==t)then return true;end
for a,e in pairs(e)do
if(t==e)then return true;end
end
return false;
end
function inset(e,t)
for a,t in ipairs(t)do if(e==t)then return true;end end
function inset(t,e)
for a,e in ipairs(e)do if(t==e)then return true;end end
return false;
end
function csel(t,a,e)
if(t)then
function csel(e,a,t)
if(e)then
return a;
else
return e;
return t;
end
end
function fix_prefix(e)
......@@ -356,9 +359,9 @@ end
function log2up(e)
return math.ceil(math.log(e)/math.log(2));
end
function is_power_of_2(t)
for e=1,24 do
if(t==math.pow(2,e))then return true;end
function is_power_of_2(e)
for t=1,24 do
if(e==math.pow(2,t))then return true;end
end
return false;
end
......@@ -385,19 +388,19 @@ end
function assign_addresses()
local o=math.max(max_ram_addr_bits,log2up(all_regs_size));
local e=num_rams;
local t=0;
local a=0;
if(all_regs_size>0)then
e=e+1;
end
local a=log2up(e);
local t=log2up(e);
foreach_reg({TYPE_REG,TYPE_FIFO},function(e)
if(e.__type==TYPE_REG)then
e.base=align(e,t);
t=e.base+1;
e.base=align(e,a);
a=e.base+1;
end
end);
address_bus_width=o+a;
address_bus_select_bits=a;
address_bus_width=o+t;
address_bus_select_bits=t;
end
function find_max(e,a)
local t=0;
......@@ -413,26 +416,26 @@ table.insert(t,e);
end
end
function tree_2_table(e)
local t={};
foreach_reg({TYPE_REG,TYPE_RAM,TYPE_FIFO,TYPE_IRQ},function(a)
if(a[e]~=nil)then
if(type(a[e])=='table')then
table_join(t,a[e]);
local a={};
foreach_reg({TYPE_REG,TYPE_RAM,TYPE_FIFO,TYPE_IRQ},function(t)
if(t[e]~=nil)then
if(type(t[e])=='table')then
table_join(a,t[e]);
else
table.insert(t,a[e]);
table.insert(a,t[e]);
end
end
foreach_subfield(a,function(a,o)
if(a[e]~=nil)then
if(type(a[e])=='table')then
table_join(t,a[e]);
foreach_subfield(t,function(t,o)
if(t[e]~=nil)then
if(type(t[e])=='table')then
table_join(a,t[e]);
else
table.insert(t,a[e]);
table.insert(a,t[e]);
end
end
end);
end);
return t;
return a;
end
function remove_duplicates(o)
function count_entries(t,a)
......@@ -451,67 +454,67 @@ end
return e;
end
function wbgen_count_subblocks()
local e=0;
local o=0;
local t=0;
local a=0;
local o=0;
foreach_reg({TYPE_RAM},function(t)e=e+1;end);
local e=0;
foreach_reg({TYPE_RAM},function(e)o=o+1;end);
foreach_reg({TYPE_REG},function(e)a=a+1;end);
foreach_reg({TYPE_FIFO},function(e)t=t+1;end);
foreach_reg({TYPE_IRQ},function(e)o=o+