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; ...@@ -7,19 +7,24 @@ use altera_mf.all;
library wbgen2; library wbgen2;
use wbgen2.all; 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 ( generic (
g_data_width : natural; g_data_width : natural;
g_size : natural; g_size : natural;
g_addr_width : natural; g_addr_width : natural;
g_dual_clock : boolean := false;
g_use_bwsel : boolean := false); g_use_bwsel : boolean := false);
port ( port (
clk_a_i : in std_logic; 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_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); addr_b_i : in std_logic_vector(g_addr_width-1 downto 0);
...@@ -40,10 +45,9 @@ entity wbgen2_dpssram is ...@@ -40,10 +45,9 @@ entity wbgen2_dpssram is
wr_b_i : in std_logic 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 component altsyncram
generic ( generic (
...@@ -55,7 +59,7 @@ architecture syn of wbgen2_dpssram is ...@@ -55,7 +59,7 @@ architecture syn of wbgen2_dpssram is
clock_enable_output_a : string; clock_enable_output_a : string;
clock_enable_output_b : string; clock_enable_output_b : string;
indata_reg_b : string; indata_reg_b : string;
-- intended_device_family : string; intended_device_family : string;
lpm_type : string; lpm_type : string;
numwords_a : natural; numwords_a : natural;
numwords_b : natural; numwords_b : natural;
...@@ -77,8 +81,8 @@ architecture syn of wbgen2_dpssram is ...@@ -77,8 +81,8 @@ architecture syn of wbgen2_dpssram is
port ( port (
wren_a : in std_logic; wren_a : in std_logic;
clock0 : in std_logic; clock0 : in std_logic;
-- clock1: in std_logic;
wren_b : 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_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); 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_a : in std_logic_vector ((g_addr_width-1) downto 0);
...@@ -91,26 +95,24 @@ architecture syn of wbgen2_dpssram is ...@@ -91,26 +95,24 @@ architecture syn of wbgen2_dpssram is
data_b : in std_logic_vector ((g_data_width-1) downto 0)); data_b : in std_logic_vector ((g_data_width-1) downto 0));
end component; 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_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 bwsel_int_b : std_logic_vector((g_data_width+7)/8-1 downto 0);
signal dummy : std_logic;
begin -- syn begin -- syn
genram1: if(g_dual_clock = true) generate
altsyncram_component : altsyncram altsyncram_component : altsyncram
generic map ( generic map (
address_reg_b => "CLOCK1", address_reg_b => "CLOCK0",
byteena_reg_b => "CLOCK1", byteena_reg_b => "CLOCK0",
byte_size => 8, byte_size => 8,
clock_enable_input_a => "BYPASS", clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS", clock_enable_input_b => "BYPASS",
clock_enable_output_a => "BYPASS", clock_enable_output_a => "BYPASS",
clock_enable_output_b => "BYPASS", clock_enable_output_b => "BYPASS",
indata_reg_b => "CLOCK1", indata_reg_b => "CLOCK0",
-- intended_device_family => "Cyclone III", intended_device_family => "Cyclone III",
lpm_type => "altsyncram", lpm_type => "altsyncram",
numwords_a => g_size, numwords_a => g_size,
numwords_b => g_size, numwords_b => g_size,
...@@ -128,13 +130,13 @@ begin -- syn ...@@ -128,13 +130,13 @@ begin -- syn
width_b => g_data_width, width_b => g_data_width,
width_byteena_a => (g_data_width+7)/8, width_byteena_a => (g_data_width+7)/8,
width_byteena_b => (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 ( port map (
wren_a => wr_a_i, wren_a => wr_a_i,
wren_b => wr_b_i, wren_b => wr_b_i,
clock0 => clk_a_i, clock0 => clk_a_i,
clock1 => clk_b_i, -- clock1 => '0',
byteena_a => bwsel_int_a, byteena_a => bwsel_int_a,
byteena_b => bwsel_int_b, byteena_b => bwsel_int_b,
address_a => addr_a_i, address_a => addr_a_i,
...@@ -147,21 +149,130 @@ begin -- syn ...@@ -147,21 +149,130 @@ begin -- syn
q_b => data_b_o 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 altsyncram_component : altsyncram
generic map ( generic map (
address_reg_b => "CLOCK0", address_reg_b => "CLOCK1",
byteena_reg_b => "CLOCK0", byteena_reg_b => "CLOCK1",
byte_size => 8, byte_size => 8,
clock_enable_input_a => "BYPASS", clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS", clock_enable_input_b => "BYPASS",
clock_enable_output_a => "BYPASS", clock_enable_output_a => "BYPASS",
clock_enable_output_b => "BYPASS", clock_enable_output_b => "BYPASS",
indata_reg_b => "CLOCK0", indata_reg_b => "CLOCK1",
-- intended_device_family => "Cyclone III", intended_device_family => "Cyclone III",
lpm_type => "altsyncram", lpm_type => "altsyncram",
numwords_a => g_size, numwords_a => g_size,
numwords_b => g_size, numwords_b => g_size,
...@@ -179,13 +290,13 @@ begin -- syn ...@@ -179,13 +290,13 @@ begin -- syn
width_b => g_data_width, width_b => g_data_width,
width_byteena_a => (g_data_width+7)/8, width_byteena_a => (g_data_width+7)/8,
width_byteena_b => (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 ( port map (
wren_a => wr_a_i, wren_a => wr_a_i,
wren_b => wr_b_i, wren_b => wr_b_i,
clock0 => clk_a_i, clock0 => clk_a_i,
clock1 => '0', clock1 => clk_b_i,
byteena_a => bwsel_int_a, byteena_a => bwsel_int_a,
byteena_b => bwsel_int_b, byteena_b => bwsel_int_b,
address_a => addr_a_i, address_a => addr_a_i,
...@@ -198,9 +309,6 @@ begin -- syn ...@@ -198,9 +309,6 @@ begin -- syn
q_b => data_b_o q_b => data_b_o
); );
end generate genram2;
-- clksel <= ;
genbwsel1: if(g_use_bwsel = true) generate genbwsel1: if(g_use_bwsel = true) generate
bwsel_int_a <= bwsel_a_i; bwsel_int_a <= bwsel_a_i;
...@@ -212,10 +320,151 @@ begin -- syn ...@@ -212,10 +320,151 @@ begin -- syn
bwsel_int_b <= (others => '1'); bwsel_int_b <= (others => '1');
end generate genbwsel2; 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; end syn;
#!/usr/bin/env lua #!/usr/bin/env lua
package.preload['alt_getopt']=(function(...) 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") module("alt_getopt")
local function r(e) local function c(e)
local t=1 local t=1
local t=#e local t=#e
local t={} local t={}
for e,a in e:gmatch("(%w)(:?)")do for a,e in e:gmatch("(%w)(:?)")do
t[e]=#a t[a]=#e
end end
return t return t
end end
local function d(t,e) local function d(t,e)
a.stderr:write(t) o.stderr:write(t)
o.exit(e) a.exit(e)
end end
local function a(e) local function a(e)
d("Unknown option `-".. d("Unknown option `-"..
...@@ -31,14 +31,14 @@ end ...@@ -31,14 +31,14 @@ end
end end
return e return e
end end
function get_ordered_opts(n,o,a) function get_ordered_opts(n,a,h)
local t=1 local t=1
local e=1 local e=1
local i={} local i={}
local h={} local s={}
local o=r(o) local o=c(a)
for t,e in s(a)do for e,t in r(h)do
o[t]=e o[e]=t
end end
while t<=#n do while t<=#n do
local a=n[t] local a=n[t]
...@@ -48,49 +48,49 @@ break ...@@ -48,49 +48,49 @@ break
elseif a=="-"then elseif a=="-"then
break break
elseif a:sub(1,2)=="--"then elseif a:sub(1,2)=="--"then
local s=a:find("=",1,true) local h=a:find("=",1,true)
if s then if h then
local t=a:sub(3,s-1) local t=a:sub(3,h-1)
t=l(o,t) t=l(o,t)
if o[t]==0 then if o[t]==0 then
d("Bad usage of option `"..a.."'\n",1) d("Bad usage of option `"..a.."'\n",1)
end end
h[e]=a:sub(s+1) s[e]=a:sub(h+1)
i[e]=t i[e]=t
else else
local s=a:sub(3) local h=a:sub(3)
s=l(o,s) h=l(o,h)
if o[s]==0 then if o[h]==0 then
i[e]=s i[e]=h
else else
if t==#n then if t==#n then
d("Missed value for option `"..a.."'\n",1) d("Missed value for option `"..a.."'\n",1)
end end
h[e]=n[t+1] s[e]=n[t+1]
i[e]=s i[e]=h
t=t+1 t=t+1
end end
end end
e=e+1 e=e+1
elseif a:sub(1,1)=="-"then elseif a:sub(1,1)=="-"then
local s local h
for r=2,a:len()do for r=2,a:len()do
local s=l(o,a:sub(r,r)) local h=l(o,a:sub(r,r))
if o[s]==0 then if o[h]==0 then
i[e]=s i[e]=h
e=e+1 e=e+1
elseif a:len()==r then elseif a:len()==r then
if t==#n then if t==#n then
d("Missed value for option `-"..s.."'\n",1) d("Missed value for option `-"..h.."'\n",1)
end end
h[e]=n[t+1] s[e]=n[t+1]
i[e]=s i[e]=h
t=t+1 t=t+1
e=e+1 e=e+1
break break
else else
h[e]=a:sub(r+1) s[e]=a:sub(r+1)
i[e]=s i[e]=h
e=e+1 e=e+1
break break
end end
...@@ -100,14 +100,14 @@ break ...@@ -100,14 +100,14 @@ break
end end
t=t+1 t=t+1
end end
return i,t,h return i,t,s
end end
function get_opts(a,t,o) function get_opts(a,t,o)
local e={} local e={}
local t,i,o=get_ordered_opts(a,t,o) local a,i,t=get_ordered_opts(a,t,o)
for t,a in u(t)do for o,a in u(a)do
if o[t]then if t[o]then
e[a]=o[t] e[a]=t[o]
else else
e[a]=1 e[a]=1
end end
...@@ -176,20 +176,20 @@ die(t.." expected."); ...@@ -176,20 +176,20 @@ die(t.." expected.");
end end
return e; return e;
end end
function range2bits(t) function range2bits(e)
local e=t[1]; local t=e[1];
local a=t[2]; local a=e[2];
local t; local e;
if(math.abs(e)>math.abs(a))then if(math.abs(t)>math.abs(a))then
t=math.abs(e); e=math.abs(t);
else else
t=math.abs(a); e=math.abs(a);
end end
local t=math.ceil(math.log(t)/math.log(2)); local e=math.ceil(math.log(e)/math.log(2));
if(e<0)then if(t<0)then
t=t+1; e=e+1;
end end
return t; return e;
end end
function calc_size(e,t) function calc_size(e,t)
if(e.type==MONOSTABLE or e.type==BIT)then if(e.type==MONOSTABLE or e.type==BIT)then
...@@ -214,8 +214,11 @@ die("ENUM-type fields are not yet supported. Sorry :("); ...@@ -214,8 +214,11 @@ die("ENUM-type fields are not yet supported. Sorry :(");
end end
t.total_size=t.total_size+e.size; t.total_size=t.total_size+e.size;
end end
function foreach_reg(t,a) function foreach_reg(t,a,e)
for o,e in ipairs(periph)do if(e==nil)then
e=periph;
end
for o,e in ipairs(e)do
if(type(e)=='table')then if(type(e)=='table')then
if(e.__type~=nil and(match(e.__type,t)))then if(e.__type~=nil and(match(e.__type,t)))then
a(e); a(e);
...@@ -276,22 +279,22 @@ function die(e) ...@@ -276,22 +279,22 @@ function die(e)
print("Error: "..e); print("Error: "..e);
os.exit(-1); os.exit(-1);
end end
function match(e,t) function match(t,e)
local a,a; local a,a;
for a,t in pairs(t)do for a,e in pairs(e)do
if(e==t)then return true;end if(t==e)then return true;end
end end
return false; return false;
end end
function inset(e,t) function inset(t,e)
for a,t in ipairs(t)do if(e==t)then return true;end end for a,e in ipairs(e)do if(t==e)then return true;end end
return false; return false;
end end
function csel(t,a,e) function csel(e,a,t)
if(t)then if(e)then
return a; return a;
else else
return e; return t;
end end
end end
function fix_prefix(e) function fix_prefix(e)
...@@ -356,9 +359,9 @@ end ...@@ -356,9 +359,9 @@ end
function log2up(e) function log2up(e)
return math.ceil(math.log(e)/math.log(2)); return math.ceil(math.log(e)/math.log(2));
end end
function is_power_of_2(t) function is_power_of_2(e)
for e=1,24 do for t=1,24 do
if(t==math.pow(2,e))then return true;end if(e==math.pow(2,t))then return true;end
end end
return false; return false;
end end
...@@ -385,19 +388,19 @@ end ...@@ -385,19 +388,19 @@ end
function assign_addresses() function assign_addresses()
local o=math.max(max_ram_addr_bits,log2up(all_regs_size)); local o=math.max(max_ram_addr_bits,log2up(all_regs_size));
local e=num_rams; local e=num_rams;
local t=0; local a=0;
if(all_regs_size>0)then if(all_regs_size>0)then
e=e+1; e=e+1;
end end
local a=log2up(e); local t=log2up(e);
foreach_reg({TYPE_REG,TYPE_FIFO},function(e) foreach_reg({TYPE_REG,TYPE_FIFO},function(e)
if(e.__type==TYPE_REG)then if(e.__type==TYPE_REG)then
e.base=align(e,t); e.base=align(e,a);
t=e.base+1; a=e.base+1;
end end
end); end);
address_bus_width=o+a; address_bus_width=o+t;
address_bus_select_bits=a; address_bus_select_bits=t;
end end
function find_max(e,a) function find_max(e,a)
local t=0; local t=0;
...@@ -413,26 +416,26 @@ table.insert(t,e); ...@@ -413,26 +416,26 @@ table.insert(t,e);
end end
end end
function tree_2_table(e) function tree_2_table(e)
local t={}; local a={};
foreach_reg({TYPE_REG,TYPE_RAM,TYPE_FIFO,TYPE_IRQ},function(a) foreach_reg({TYPE_REG,TYPE_RAM,TYPE_FIFO,TYPE_IRQ},function(t)
if(a[e]~=nil)then if(t[e]~=nil)then
if(type(a[e])=='table')then if(type(t[e])=='table')then
table_join(t,a[e]); table_join(a,t[e]);
else else
table.insert(t,a[e]); table.insert(a,t[e]);
end end
end end
foreach_subfield(a,function(a,o) foreach_subfield(t,function(t,o)
if(a[e]~=nil)then if(t[e]~=nil)then
if(type(a[e])=='table')then if(type(t[e])=='table')then
table_join(t,a[e]); table_join(a,t[e]);
else else
table.insert(t,a[e]); table.insert(a,t[e]);
end end
end end
end); end);
end); end);
return t; return a;
end end
function remove_duplicates(o) function remove_duplicates(o)
function count_entries(t,a) function count_entries(t,a)
...@@ -451,67 +454,67 @@ end ...@@ -451,67 +454,67 @@ end
return e; return e;
end end
function wbgen_count_subblocks() function wbgen_count_subblocks()
local e=0; local o=0;
local t=0; local t=0;
local a=0; local a=0;
local o=0; local e=0;
foreach_reg({TYPE_RAM},function(t)e=e+1;end); foreach_reg({TYPE_RAM},function(e)o=o+1;end);
foreach_reg({TYPE_REG},function(e)a=a+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_FIFO},function(e)t=t+1;end);
foreach_reg({TYPE_IRQ},function(e)o=o+1;end); foreach_reg({TYPE_IRQ},function(t)e=e+1;end);
periph.ramcount=e; periph.ramcount=o;
periph.fifocount=t; periph.fifocount=t;
periph.regcount=a; periph.regcount=a;
periph.irqcount=o; periph.irqcount=e;
if(e+t+a+o==0)then if(o+t+a+e==0)then
die("Can't generate an empty peripheral. Define some regs, RAMs, FIFOs or IRQs, please..."); die("Can't generate an empty peripheral. Define some regs, RAMs, FIFOs or IRQs, please...");
end end
end end
function deepcopy(i) function deepcopy(i)
local o={} local t={}
local function a(e) local function o(e)
if type(e)~="table"then if type(e)~="table"then
return e return e
elseif o[e]then elseif t[e]then
return o[e] return t[e]
end end
local t={} local a={}
o[e]=t t[e]=a
for o,e in pairs(e)do for t,e in pairs(e)do
t[a(o)]=a(e) a[o(t)]=o(e)
end end
return setmetatable(t,getmetatable(e)) return setmetatable(a,getmetatable(e))
end end
return a(i) return o(i)
end end
function va(a,t) function va(t,a)
local e={}; local e={};
e.t="assign"; e.t="assign";
e.dst=a; e.dst=t;
e.src=t; e.src=a;
return e; return e;
end end
function vi(a,o,t) function vi(o,t,a)
local e={}; local e={};
e.t="index"; e.t="index";
e.name=a; e.name=o;
e.h=o; e.h=t;
e.l=t; e.l=a;
return e; return e;
end end
function vinstance(o,a,t) function vinstance(t,a,o)
local e={}; local e={};
e.t="instance"; e.t="instance";
e.name=o; e.name=t;
e.component=a; e.component=a;
e.maps=t; e.maps=o;
return e; return e;
end end
function vpm(t,a) function vpm(a,t)
local e={}; local e={};
e.t="portmap"; e.t="portmap";
e.to=t; e.to=a;
e.from=a; e.from=t;
return e; return e;
end end
function vgm(t,a) function vgm(t,a)
...@@ -528,12 +531,12 @@ e.slist=t; ...@@ -528,12 +531,12 @@ e.slist=t;
e.code=a; e.code=a;
return e; return e;
end end
function vsyncprocess(t,a,o) function vsyncprocess(o,a,t)
local e={}; local e={};
e.t="syncprocess"; e.t="syncprocess";
e.clk=t; e.clk=o;
e.rst=a; e.rst=a;
e.code=o; e.code=t;
return e; return e;
end end
function vreset(a,t) function vreset(a,t)
...@@ -549,26 +552,26 @@ e.t="posedge"; ...@@ -549,26 +552,26 @@ e.t="posedge";
e.code=t; e.code=t;
return e; return e;
end end
function vif(a,t,o) function vif(t,a,o)
local e={}; local e={};
e.t="if"; e.t="if";
e.cond={a}; e.cond={t};
e.code=t; e.code=a;
e.code_else=o; e.code_else=o;
return e; return e;
end end
function vequal(t,a) function vequal(a,t)
local e={}; local e={};
e.t="eq"; e.t="eq";
e.a=t; e.a=a;
e.b=a; e.b=t;
return e; return e;
end end
function vand(t,a) function vand(a,t)
local e={}; local e={};
e.t="and"; e.t="and";
e.a=t; e.a=a;
e.b=a; e.b=t;
return e; return e;
end end
function vnot(t) function vnot(t)
...@@ -603,11 +606,11 @@ e.t="comment"; ...@@ -603,11 +606,11 @@ e.t="comment";
e.str=t; e.str=t;
return e; return e;
end end
function vsub(t,a) function vsub(a,t)
local e={}; local e={};
e.t="sub"; e.t="sub";
e.a=t; e.a=a;
e.b=a; e.b=t;
return e; return e;
end end
function vothers(t) function vothers(t)
...@@ -626,21 +629,21 @@ local e={} ...@@ -626,21 +629,21 @@ local e={}
e.t="undefined"; e.t="undefined";
return e; return e;
end end
function signal(t,o,a,i) function signal(i,a,o,t)
local e={} local e={}
e.comment=i; e.comment=t;
e.type=t; e.type=i;
e.range=o; e.range=a;
e.name=a; e.name=o;
return e; return e;
end end
function port(a,i,o,n,s,t) function port(n,i,a,o,s,t)
local e={} local e={}
e.comment=s; e.comment=s;
e.type=a; e.type=n;
e.range=i; e.range=i;
e.name=n; e.name=o;
e.dir=o; e.dir=a;
if(t~=nil and t)then if(t~=nil and t)then
e.is_wb=true; e.is_wb=true;
else else
...@@ -766,21 +769,21 @@ fieldtype_2_vhdl[SIGNED]="signed"; ...@@ -766,21 +769,21 @@ fieldtype_2_vhdl[SIGNED]="signed";
fieldtype_2_vhdl[UNSIGNED]="unsigned"; fieldtype_2_vhdl[UNSIGNED]="unsigned";
fieldtype_2_vhdl[ENUM]="std_logic_vector"; fieldtype_2_vhdl[ENUM]="std_logic_vector";
fieldtype_2_vhdl[SLV]="std_logic_vector"; fieldtype_2_vhdl[SLV]="std_logic_vector";
function gen_vhdl_bin_literal(n,o) function gen_vhdl_bin_literal(i,a)
if(o==1)then if(a==1)then
return string.format("'%d'",csel(n==0,0,1)); return string.format("'%d'",csel(i==0,0,1));
end end
local a='\"'; local o='\"';
local s,t,i,e; local s,t,n,e;
t=n; t=i;
e=math.pow(2,o-1); e=math.pow(2,a-1);
for o=1,o do for a=1,a do
i=math.floor(t/e); n=math.floor(t/e);
a=a..csel(i>0,"1","0"); o=o..csel(n>0,"1","0");
t=t%e; t=t%e;
e=e/2; e=e/2;
end end
return a..'\"'; return o..'\"';
end end
function cgen_vhdl_header() function cgen_vhdl_header()
emit("---------------------------------------------------------------------------------------"); emit("---------------------------------------------------------------------------------------");
...@@ -1048,22 +1051,22 @@ else ...@@ -1048,22 +1051,22 @@ else
emitx(gen_subrange(t)); emitx(gen_subrange(t));
end end
end end
function cgen_vhdl_binary_op(e) function cgen_vhdl_binary_op(t)
local a=node_typesize(e.a); local a=node_typesize(t.a);
local o=node_typesize(e.b); local o=node_typesize(t.b);
local t=e.t; local e=t.t;
if(a.type==EXPRESSION)then if(a.type==EXPRESSION)then
emitx("(");recurse({e.a});emitx(")"); emitx("(");recurse({t.a});emitx(")");
else else
emitx(gen_subrange(a)); emitx(gen_subrange(a));
end end
if(t=="eq")then emitx(" = ");end if(e=="eq")then emitx(" = ");end
if(t=="and")then emitx(" and ");end if(e=="and")then emitx(" and ");end
if(t=="or")then emitx(" or ");end if(e=="or")then emitx(" or ");end
if(t=="sub")then emitx(" - ");end if(e=="sub")then emitx(" - ");end
if(t=="add")then emitx(" + ");end if(e=="add")then emitx(" + ");end
if(o.type==EXPRESSION)then if(o.type==EXPRESSION)then
emitx("(");recurse({e.b});emitx(")"); emitx("(");recurse({t.b});emitx(")");
else else
emitx(gen_vhdl_typecvt(a,o)); emitx(gen_vhdl_typecvt(a,o));
end end
...@@ -1098,25 +1101,25 @@ end ...@@ -1098,25 +1101,25 @@ end
emit("end case;"); emit("end case;");
end end
function cgen_vhdl_instance(t) function cgen_vhdl_instance(t)
local o=0;
local a=0; local a=0;
local o=0;
local e; local e;
emit(t.name.." : "..t.component); emit(t.name.." : "..t.component);
for t,e in pairs(t.maps)do for t,e in pairs(t.maps)do
if(e.t=="genmap")then if(e.t=="genmap")then
a=a+1;
elseif(e.t=="portmap")then
o=o+1; o=o+1;
elseif(e.t=="portmap")then
a=a+1;
end end
end end
if(a>0)then if(o>0)then
indent_right(); indent_right();
emit("generic map ("); emit("generic map (");
indent_right(); indent_right();
e=1; e=1;
for o,t in pairs(t.maps)do for a,t in pairs(t.maps)do
if(t.t=="genmap")then if(t.t=="genmap")then
emit(string.format("%-20s => %s",t.to,t.from)..csel(e==a,"",",")); emit(string.format("%-20s => %s",t.to,t.from)..csel(e==o,"",","));
e=e+1; e=e+1;
end end
end end
...@@ -1124,15 +1127,15 @@ indent_left(); ...@@ -1124,15 +1127,15 @@ indent_left();
emit(")"); emit(")");
indent_left(); indent_left();
end end
if(o>0)then if(a>0)then
indent_right(); indent_right();
emit("port map ("); emit("port map (");
indent_right(); indent_right();
e=1; e=1;
for a,t in pairs(t.maps)do for o,t in pairs(t.maps)do
if(t.t=="portmap")then if(t.t=="portmap")then
local a=node_typesize(t.from); local o=node_typesize(t.from);
emit(string.format("%-20s => %s",t.to,gen_subrange(a))..csel(e==o,"",",")); emit(string.format("%-20s => %s",t.to,gen_subrange(o))..csel(e==a,"",","));
e=e+1; e=e+1;
end end
end end
...@@ -1254,7 +1257,7 @@ function cgen_verilog_ending() ...@@ -1254,7 +1257,7 @@ function cgen_verilog_ending()
indent_left(); indent_left();
emit("endmodule"); emit("endmodule");
end end
function cgen_generate_verilog_code(i) function cgen_generate_verilog_code(n)
local a=false; local a=false;
function find_code(e,t) function find_code(e,t)
for a,e in ipairs(e)do if((e.t~=nil)and(e.t==t))then return e;end end for a,e in ipairs(e)do if((e.t~=nil)and(e.t==t))then return e;end end
...@@ -1401,13 +1404,13 @@ indent_left(); ...@@ -1401,13 +1404,13 @@ indent_left();
emit("end"); emit("end");
end end
end end
function cgen_verilog_not(t) function cgen_verilog_not(e)
local e=node_typesize(t.a); local t=node_typesize(e.a);
emitx("! "); emitx("! ");
if(e.type==EXPRESSION)then if(t.type==EXPRESSION)then
emitx("(");recurse({t.a});emitx(")"); emitx("(");recurse({e.a});emitx(")");
else else
emitx(gen_subrange(e)); emitx(gen_subrange(t));
end end
end end
function cgen_verilog_binary_op(t) function cgen_verilog_binary_op(t)
...@@ -1459,29 +1462,29 @@ end ...@@ -1459,29 +1462,29 @@ end
end end
emit("endcase"); emit("endcase");
end end
function cgen_verilog_instance(t) function cgen_verilog_instance(a)
local a=0;
local o=0; local o=0;
local i=0;
local e; local e;
emitx(t.component.." "); emitx(a.component.." ");
for t,e in pairs(t.maps)do for t,e in pairs(a.maps)do
if(e.t=="genmap")then if(e.t=="genmap")then
o=o+1; i=i+1;
elseif(e.t=="portmap")then elseif(e.t=="portmap")then
a=a+1; o=o+1;
end end
end end
if(o>0)then if(i>0)then
indent_right(); indent_right();
emit("# ("); emit("# (");
indent_right(); indent_right();
e=1; e=1;
for t,a in pairs(t.maps)do for t,a in pairs(a.maps)do
if(a.t=="genmap")then if(a.t=="genmap")then
local t=a.from; local t=a.from;
if(t=="true")then t=1; if(t=="true")then t=1;
elseif(t=="false")then t=0;end elseif(t=="false")then t=0;end
emit(string.format(".%-20s(%s)",a.to,t)..csel(e==o,"",",")); emit(string.format(".%-20s(%s)",a.to,t)..csel(e==i,"",","));
e=e+1; e=e+1;
end end
end end
...@@ -1489,15 +1492,15 @@ indent_left(); ...@@ -1489,15 +1492,15 @@ indent_left();
emit(")"); emit(")");
indent_left(); indent_left();
end end
if(a>0)then if(o>0)then
indent_right(); indent_right();
emit(t.name.." ( "); emit(a.name.." ( ");
indent_right(); indent_right();
e=1; e=1;
for o,t in pairs(t.maps)do for a,t in pairs(a.maps)do
if(t.t=="portmap")then if(t.t=="portmap")then
local o=node_typesize(t.from); local a=node_typesize(t.from);
emit(string.format(".%-20s(%s)",t.to,gen_subrange(o))..csel(e==a,"",",")); emit(string.format(".%-20s(%s)",t.to,gen_subrange(a))..csel(e==o,"",","));
e=e+1; e=e+1;
end end
end end
...@@ -1564,17 +1567,17 @@ end ...@@ -1564,17 +1567,17 @@ end
end end
cgen_new_snippet(); cgen_new_snippet();
cgen_verilog_header(); cgen_verilog_header();
local e=cgen_get_snippet(); local a=cgen_get_snippet();
cgen_new_snippet(); cgen_new_snippet();
recurse(i); recurse(n);
cgen_verilog_ending(); cgen_verilog_ending();
local a=cgen_get_snippet(); local e=cgen_get_snippet();
cgen_new_snippet(); cgen_new_snippet();
cgen_verilog_module(); cgen_verilog_module();
local t=cgen_get_snippet(); local t=cgen_get_snippet();
cgen_write_snippet(e);
cgen_write_snippet(t);
cgen_write_snippet(a); cgen_write_snippet(a);
cgen_write_snippet(t);
cgen_write_snippet(e);
end end
function cgen_c_field_define(e,a) function cgen_c_field_define(e,a)
local t; local t;
...@@ -1610,7 +1613,7 @@ dbg("DOCREG: ",e.name,e.num_fields); ...@@ -1610,7 +1613,7 @@ dbg("DOCREG: ",e.name,e.num_fields);
if(e.num_fields~=nil and e.num_fields>0)then if(e.num_fields~=nil and e.num_fields>0)then
emit(""); emit("");
emit("/* definitions for register: "..e.name.." */"); emit("/* definitions for register: "..e.name.." */");
foreach_subfield(e,function(t,e)cgen_c_field_define(t,e)end); foreach_subfield(e,function(e,t)cgen_c_field_define(e,t)end);
end end
end); end);
foreach_reg({TYPE_RAM},function(e) foreach_reg({TYPE_RAM},function(e)
...@@ -1746,21 +1749,21 @@ end ...@@ -1746,21 +1749,21 @@ end
end end
return e; return e;
end end
function htable_tdstyle(a,t,e) function htable_tdstyle(e,t,a)
tbl.data[a][t].style=e; tbl.data[e][t].style=a;
end end
function htable_trstyle(t,a,e) function htable_trstyle(e,a,t)
tbl.data[t].style=e; tbl.data[e].style=t;
end end
function htable_frame(o,t,a,e) function htable_frame(e,o,a,t)
if(e==nil)then if(t==nil)then
o.data[t][a].extra='style="border: solid 1px black;"'; e.data[o][a].extra='style="border: solid 1px black;"';
else else
o.data[t][a].extra='style="border-left: solid 1px black; border-top: solid 1px black; border-bottom: solid 1px black;'; e.data[o][a].extra='style="border-left: solid 1px black; border-top: solid 1px black; border-bottom: solid 1px black;';
o.data[t][e].extra='style="border-right: solid 1px black; border-top: solid 1px black; border-bottom: solid 1px black;'; e.data[o][t].extra='style="border-right: solid 1px black; border-top: solid 1px black; border-bottom: solid 1px black;';
if(e>a+1)then if(t>a+1)then
for e=a+1,e-1 do for t=a+1,t-1 do
o.data[t][e].extra='border-top: solid 1px black; border-bottom: solid 1px black;'; e.data[o][t].extra='border-top: solid 1px black; border-bottom: solid 1px black;';
end end
end end
end end
...@@ -1798,26 +1801,26 @@ emit("</tr>"); ...@@ -1798,26 +1801,26 @@ emit("</tr>");
end end
emit("</table>"); emit("</table>");
end end
function has_any_ports(t) function has_any_ports(e)
local e=false; local t=false;
if(t.ports~=nil)then return true;end if(e.ports~=nil)then return true;end
foreach_subfield(t,function(t)if(t.ports~=nil)then e=true;end end); foreach_subfield(e,function(e)if(e.ports~=nil)then t=true;end end);
return e; return t;
end end
function htable_add_row(e,a) function htable_add_row(e,t)
if(a>e.rows)then if(t>e.rows)then
for t=e.rows+1,a do for t=e.rows+1,t do
e.data[t]={}; e.data[t]={};
for a=1,e.cols do for a=1,e.cols do
e.data[t][a]={}; e.data[t][a]={};
e.data[t][a].text=""; e.data[t][a].text="";
end end
end end
e.rows=a; e.rows=t;
end end
end end
function hlink(e,t) function hlink(t,e)
return'<A href="'..e..'">'..t..'</a>'; return'<A href="'..t..'">'..e..'</a>';
end end
function hitem(e) function hitem(e)
return'<li>'..e..'</li>'; return'<li>'..e..'</li>';
...@@ -1965,11 +1968,11 @@ emit('<span style="margin-left: '..((e.level-1)*20)..'px; ">'..e.id.." "..hlink( ...@@ -1965,11 +1968,11 @@ emit('<span style="margin-left: '..((e.level-1)*20)..'px; ">'..e.id.." "..hlink(
end end
end end
function cgen_doc_memmap() function cgen_doc_memmap()
local o=0; local i=0;
local a=2; local a=2;
emit(hsection(1,0,"Memory map summary")); emit(hsection(1,0,"Memory map summary"));
local i=htable_new(1,5); local o=htable_new(1,5);
local e=i.data[1]; local e=o.data[1];
e.is_header=true; e.is_header=true;
e[1].text="H/W Address" e[1].text="H/W Address"
e[2].text="Type"; e[2].text="Type";
...@@ -1978,9 +1981,9 @@ e[4].text="VHDL/Verilog prefix"; ...@@ -1978,9 +1981,9 @@ e[4].text="VHDL/Verilog prefix";
e[5].text="C prefix"; e[5].text="C prefix";
foreach_reg({TYPE_REG},function(t) foreach_reg({TYPE_REG},function(t)
if(t.full_hdl_prefix~=nil)then if(t.full_hdl_prefix~=nil)then
htable_add_row(i,a); htable_add_row(o,a);
local e=i.data[a];a=a+1; local e=o.data[a];a=a+1;
e.style=csel(o,"tr_odd","tr_even"); e.style=csel(i,"tr_odd","tr_even");
e[1].style="td_code"; e[1].style="td_code";
e[1].text=string.format("0x%x",t.base); e[1].text=string.format("0x%x",t.base);
if(t.doc_is_fiforeg==nil)then if(t.doc_is_fiforeg==nil)then
...@@ -1993,14 +1996,14 @@ e[4].style="td_code"; ...@@ -1993,14 +1996,14 @@ e[4].style="td_code";
e[4].text=t.full_hdl_prefix; e[4].text=t.full_hdl_prefix;
e[5].style="td_code"; e[5].style="td_code";
e[5].text=string.upper(t.c_prefix); e[5].text=string.upper(t.c_prefix);
o=not o; i=not i;
end end
end); end);
foreach_reg({TYPE_RAM},function(e) foreach_reg({TYPE_RAM},function(e)
if(e.full_hdl_prefix~=nil)then if(e.full_hdl_prefix~=nil)then
htable_add_row(i,a); htable_add_row(o,a);
local t=i.data[a];a=a+1; local t=o.data[a];a=a+1;
t.style=csel(o,"tr_odd","tr_even"); t.style=csel(i,"tr_odd","tr_even");
t[1].style="td_code"; t[1].style="td_code";
t[1].text=string.format("0x%x - 0x%x",e.base,e.base+math.pow(2,e.wrap_bits)*e.size-1); t[1].text=string.format("0x%x - 0x%x",e.base,e.base+math.pow(2,e.wrap_bits)*e.size-1);
t[2].text="MEM"; t[2].text="MEM";
...@@ -2009,10 +2012,10 @@ t[4].style="td_code"; ...@@ -2009,10 +2012,10 @@ t[4].style="td_code";
t[4].text=e.full_hdl_prefix; t[4].text=e.full_hdl_prefix;
t[5].style="td_code"; t[5].style="td_code";
t[5].text=string.upper(e.c_prefix); t[5].text=string.upper(e.c_prefix);
o=not o; i=not i;
end end
end); end);
htable_emit(i); htable_emit(o);
end end
function find_field_by_offset(e,t) function find_field_by_offset(e,t)
local a=nil; local a=nil;
...@@ -2021,20 +2024,20 @@ return a; ...@@ -2021,20 +2024,20 @@ return a;
end end
function cgen_doc_fieldtable(h,i) function cgen_doc_fieldtable(h,i)
local e=70; local e=70;
local e; local t;
local t=1; local e=1;
e=htable_new(2,8); t=htable_new(2,8);
for t=1,8 do for e=1,8 do
e.data[1][t].style="td_bit"; t.data[1][e].style="td_bit";
e.data[1][t].text=string.format("%d",i+8-t); t.data[1][e].text=string.format("%d",i+8-e);
end end
local a=i+7; local a=i+7;
while(a>=i)do while(a>=i)do
local o=find_field_by_offset(h,a); local o=find_field_by_offset(h,a);
if(o==nil)then if(o==nil)then
e.data[2][t].style="td_unused"; t.data[2][e].style="td_unused";
e.data[2][t].text="-"; t.data[2][e].text="-";
t=t+1; e=e+1;
a=a-1; a=a-1;
else else
local n; local n;
...@@ -2045,18 +2048,18 @@ n=o.offset; ...@@ -2045,18 +2048,18 @@ n=o.offset;
end end
local s=(a-n)+1; local s=(a-n)+1;
dbg("ncells: ",s,"bit: ",a,"name: ",o.prefix); dbg("ncells: ",s,"bit: ",a,"name: ",o.prefix);
e.data[2][t].colspan=s; t.data[2][e].colspan=s;
local i; local i;
i=o.c_prefix; i=o.c_prefix;
if(i==nil)then i=h.c_prefix;end if(i==nil)then i=h.c_prefix;end
e.data[2][t].style="td_field"; t.data[2][e].style="td_field";
e.data[2][t].text=csel(o.size>1,string.format("%s[%d:%d]",string.upper(i),a-o.offset,n-o.offset),string.upper(i)); t.data[2][e].text=csel(o.size>1,string.format("%s[%d:%d]",string.upper(i),a-o.offset,n-o.offset),string.upper(i));
htable_frame(e,2,t); htable_frame(t,2,e);
a=a-s; a=a-s;
t=t+1; e=e+1;
end end
end end
htable_emit(e); htable_emit(t);
end end
function cgen_doc_access(e) function cgen_doc_access(e)
if(e==READ_ONLY)then if(e==READ_ONLY)then
...@@ -2179,11 +2182,11 @@ emit("<p>"..string.gsub(e.description,"\n","<br>").."</p>"); ...@@ -2179,11 +2182,11 @@ emit("<p>"..string.gsub(e.description,"\n","<br>").."</p>");
end end
end end
function cgen_generate_documentation() function cgen_generate_documentation()
cgen_new_snippet();cgen_doc_hdl_symbol();local i=cgen_get_snippet(); cgen_new_snippet();cgen_doc_hdl_symbol();local o=cgen_get_snippet();
cgen_new_snippet(); cgen_new_snippet();
emit(hsection(3,0,"Register description")); emit(hsection(3,0,"Register description"));
foreach_reg({TYPE_REG},function(e)if(e.no_docu==nil or e.no_docu==false)then cgen_doc_reg(e);end end); foreach_reg({TYPE_REG},function(e)if(e.no_docu==nil or e.no_docu==false)then cgen_doc_reg(e);end end);
local o=cgen_get_snippet(); local i=cgen_get_snippet();
local t=""; local t="";
if(periph.ramcount>0)then if(periph.ramcount>0)then
emit(hsection(4,0,"Memory blocks")); emit(hsection(4,0,"Memory blocks"));
...@@ -2204,8 +2207,8 @@ local e=cgen_get_snippet(); ...@@ -2204,8 +2207,8 @@ local e=cgen_get_snippet();
cgen_new_snippet(); cgen_new_snippet();
cgen_doc_header_and_toc(); cgen_doc_header_and_toc();
emit(e); emit(e);
emit(i);
emit(o); emit(o);
emit(i);
emit(t); emit(t);
emit(a); emit(a);
emit('</BODY>'); emit('</BODY>');
...@@ -2743,7 +2746,7 @@ end ...@@ -2743,7 +2746,7 @@ end
if(e.__type==TYPE_RAM)then if(e.__type==TYPE_RAM)then
gen_code_ram(e); gen_code_ram(e);
else else
foreach_subfield(e,function(e,t)gen_hdl_code_reg_field(e,t);end); foreach_subfield(e,function(t,e)gen_hdl_code_reg_field(t,e);end);
end end
end end
function gen_hdl_block_select_bits() function gen_hdl_block_select_bits()
...@@ -2831,8 +2834,8 @@ end ...@@ -2831,8 +2834,8 @@ end
function wbgen_generate_eic() function wbgen_generate_eic()
if(periph.irqcount==0)then return;end if(periph.irqcount==0)then return;end
local t=0; local t=0;
local n={}; local o={};
local s={["__type"]=TYPE_REG; local a={["__type"]=TYPE_REG;
["__blockindex"]=1e6; ["__blockindex"]=1e6;
["align"]=8; ["align"]=8;
["name"]="Interrupt disable register"; ["name"]="Interrupt disable register";
...@@ -2864,7 +2867,7 @@ signal(BIT,0,"eic_ier_write_int");}; ...@@ -2864,7 +2867,7 @@ signal(BIT,0,"eic_ier_write_int");};
["extra_code"]={va(vi("eic_ier_int",periph.irqcount-1,0),vi("wrdata_reg",periph.irqcount-1,0));}; ["extra_code"]={va(vi("eic_ier_int",periph.irqcount-1,0),vi("wrdata_reg",periph.irqcount-1,0));};
["no_std_regbank"]=true; ["no_std_regbank"]=true;
}; };
local o={["__type"]=TYPE_REG; local s={["__type"]=TYPE_REG;
["__blockindex"]=1000002; ["__blockindex"]=1000002;
["align"]=1; ["align"]=1;
["name"]="Interrupt status register"; ["name"]="Interrupt status register";
...@@ -2883,7 +2886,7 @@ signal(BIT,0,"eic_isr_write_int");}; ...@@ -2883,7 +2886,7 @@ signal(BIT,0,"eic_isr_write_int");};
["extra_code"]={va(vi("eic_isr_clear_int",periph.irqcount-1,0),vi("wrdata_reg",periph.irqcount-1,0));}; ["extra_code"]={va(vi("eic_isr_clear_int",periph.irqcount-1,0),vi("wrdata_reg",periph.irqcount-1,0));};
["no_std_regbank"]=true; ["no_std_regbank"]=true;
}; };
local a={["__type"]=TYPE_REG; local n={["__type"]=TYPE_REG;
["__blockindex"]=1000003; ["__blockindex"]=1000003;
["align"]=1; ["align"]=1;
["name"]="Interrupt mask register"; ["name"]="Interrupt mask register";
...@@ -2898,9 +2901,9 @@ local a={["__type"]=TYPE_REG; ...@@ -2898,9 +2901,9 @@ local a={["__type"]=TYPE_REG;
foreach_reg({TYPE_IRQ},function(e) foreach_reg({TYPE_IRQ},function(e)
e.index=t; e.index=t;
t=t+1; t=t+1;
table.insert(n,{["index"]=e.index;["trigger"]=e.trigger;}); table.insert(o,{["index"]=e.index;["trigger"]=e.trigger;});
fix_prefix(e); fix_prefix(e);
local n={ local t={
["__blockindex"]=e.index; ["__blockindex"]=e.index;
["__type"]=TYPE_FIELD; ["__type"]=TYPE_FIELD;
["type"]=BIT; ["type"]=BIT;
...@@ -2911,7 +2914,7 @@ local n={ ...@@ -2911,7 +2914,7 @@ local n={
["access_bus"]=READ_WRITE; ["access_bus"]=READ_WRITE;
["access_dev"]=READ_WRITE; ["access_dev"]=READ_WRITE;
}; };
local t={ local o={
["__blockindex"]=e.index; ["__blockindex"]=e.index;
["__type"]=TYPE_FIELD; ["__type"]=TYPE_FIELD;
["type"]=BIT; ["type"]=BIT;
...@@ -2953,18 +2956,18 @@ end ...@@ -2953,18 +2956,18 @@ end
if(e.mask_line==true)then if(e.mask_line==true)then
table_join(e.ports,{port(BIT,0,"out",e.full_prefix.."_mask_o");}); table_join(e.ports,{port(BIT,0,"out",e.full_prefix.."_mask_o");});
end end
table.insert(s,h); table.insert(a,h);
table.insert(o,n); table.insert(s,t);
table.insert(a,r); table.insert(n,r);
table.insert(i,t); table.insert(i,o);
end); end);
add_global_signals({ add_global_signals({
signal(SLV,periph.irqcount,"irq_inputs_vector_int"); signal(SLV,periph.irqcount,"irq_inputs_vector_int");
}); });
table.insert(periph,s);
table.insert(periph,i);
table.insert(periph,a); table.insert(periph,a);
table.insert(periph,o); table.insert(periph,i);
table.insert(periph,n);
table.insert(periph,s);
local e={vgm("g_num_interrupts",periph.irqcount); local e={vgm("g_num_interrupts",periph.irqcount);
vpm("clk_i","bus_clock_int"); vpm("clk_i","bus_clock_int");
vpm("rst_n_i","rst_n_i"); vpm("rst_n_i","rst_n_i");
...@@ -2981,7 +2984,7 @@ vpm("reg_isr_wr_stb_i","eic_isr_write_int"); ...@@ -2981,7 +2984,7 @@ vpm("reg_isr_wr_stb_i","eic_isr_write_int");
vpm("wb_irq_o","wb_irq_o"); vpm("wb_irq_o","wb_irq_o");
}; };
local t; local t;
for o,a in ipairs(n)do for o,a in ipairs(o)do
table_join(e,{vgm(string.format("g_irq%02x_mode",a.index),a.trigger)}); table_join(e,{vgm(string.format("g_irq%02x_mode",a.index),a.trigger)});
t=o; t=o;
end end
...@@ -3161,12 +3164,15 @@ local s={ ...@@ -3161,12 +3164,15 @@ local s={
["hdl_prefix"]=e.hdl_prefix.."_CSR"; ["hdl_prefix"]=e.hdl_prefix.."_CSR";
["no_std_regbank"]=true; ["no_std_regbank"]=true;
}; };
function gen_fifo_csr_field(h,a,r,o,n,i,t) function gen_fifo_csr_field(r,a,o,h,n,i,t)
if inset(h,e.flags_bus)then if(e.flags_bus==nil)then
return;
end
if inset(r,e.flags_bus)then
local t={ local t={
["__type"]=TYPE_FIELD; ["__type"]=TYPE_FIELD;
["name"]=r; ["name"]=o;
["description"]=o; ["description"]=h;
["access_bus"]=READ_ONLY; ["access_bus"]=READ_ONLY;
["access_dev"]=WRITE_ONLY; ["access_dev"]=WRITE_ONLY;
["type"]=i; ["type"]=i;
...@@ -3311,22 +3317,22 @@ gen_wishbone_signals(); ...@@ -3311,22 +3317,22 @@ gen_wishbone_signals();
foreach_reg(ALL_REG_TYPES,function(e) foreach_reg(ALL_REG_TYPES,function(e)
gen_abstract_code(e); gen_abstract_code(e);
end); end);
local n={};
local o={}; local o={};
local i={}; local i={};
local n={};
foreach_field(function(e,t) foreach_field(function(e,t)
table_join(n,e.reset_code_main); table_join(o,e.reset_code_main);
end); end);
foreach_reg(ALL_REG_TYPES,function(e) foreach_reg(ALL_REG_TYPES,function(e)
table_join(n,e.reset_code_main); table_join(o,e.reset_code_main);
end); end);
foreach_reg({TYPE_REG},function(e) foreach_reg({TYPE_REG},function(e)
foreach_subfield(e,function(e,t) foreach_subfield(e,function(e,t)
table_join(o,e.ackgen_code); table_join(i,e.ackgen_code);
table_join(i,e.ackgen_code_pre); table_join(n,e.ackgen_code_pre);
end); end);
table_join(o,e.ackgen_code); table_join(i,e.ackgen_code);
table_join(i,e.ackgen_code_pre); table_join(n,e.ackgen_code_pre);
end); end);
local e={}; local e={};
foreach_reg({TYPE_REG},function(t) foreach_reg({TYPE_REG},function(t)
...@@ -3367,13 +3373,13 @@ local t={}; ...@@ -3367,13 +3373,13 @@ local t={};
if(periph.fifocount+periph.regcount>0)then if(periph.fifocount+periph.regcount>0)then
t={vcase(0,e);}; t={vcase(0,e);};
end end
foreach_reg({TYPE_RAM},function(a) foreach_reg({TYPE_RAM},function(e)
local e=csel(options.register_data_output,1,0); local a=csel(options.register_data_output,1,0);
table_join(t,{vcase(a.select_bits,{ table_join(t,{vcase(e.select_bits,{
vif(vequal("rd_int",1),{ vif(vequal("rd_int",1),{
va(vi("ack_sreg",0),1); va(vi("ack_sreg",0),1);
},{ },{
va(vi("ack_sreg",e),1); va(vi("ack_sreg",a),1);
}); });
va("ack_in_progress",1); va("ack_in_progress",1);
});}); });});
...@@ -3404,14 +3410,14 @@ vreset(0,{ ...@@ -3404,14 +3410,14 @@ vreset(0,{
va("ack_sreg",0); va("ack_sreg",0);
va("ack_in_progress",0); va("ack_in_progress",0);
va("rddata_reg",0); va("rddata_reg",0);
n o
}); });
vposedge({ vposedge({
vcomment("advance the ACK generator shift register"); vcomment("advance the ACK generator shift register");
va(vi("ack_sreg",MAX_ACK_LENGTH-2,0),vi("ack_sreg",MAX_ACK_LENGTH-1,1)); va(vi("ack_sreg",MAX_ACK_LENGTH-2,0),vi("ack_sreg",MAX_ACK_LENGTH-1,1));
va(vi("ack_sreg",MAX_ACK_LENGTH-1),0); va(vi("ack_sreg",MAX_ACK_LENGTH-1),0);
vif(vequal("ack_in_progress",1),{ vif(vequal("ack_in_progress",1),{
vif(vequal(vi("ack_sreg",0),1),{o;va("ack_in_progress",0);},i); vif(vequal(vi("ack_sreg",0),1),{i;va("ack_in_progress",0);},n);
},{ },{
e e
}); });
...@@ -3420,20 +3426,20 @@ e ...@@ -3420,20 +3426,20 @@ e
}; };
if(periph.ramcount>0)then if(periph.ramcount>0)then
if(not options.register_data_output)then if(not options.register_data_output)then
local t={"rddata_reg","rwaddr_reg"}; local a={"rddata_reg","rwaddr_reg"};
local a={}; local t={};
local o={vswitch(vi("rwaddr_reg",address_bus_width-1,address_bus_width-address_bus_select_bits),a);}; local o={vswitch(vi("rwaddr_reg",address_bus_width-1,address_bus_width-address_bus_select_bits),t);};
local o={vcomment("Data output multiplexer process");vcombprocess(t,o);}; local o={vcomment("Data output multiplexer process");vcombprocess(a,o);};
foreach_reg({TYPE_RAM},function(e) foreach_reg({TYPE_RAM},function(e)
table.insert(t,e.full_prefix.."_rddata_int"); table.insert(a,e.full_prefix.."_rddata_int");
local t={va(vi("wb_data_o",e.width-1,0),e.full_prefix.."_rddata_int");}; local a={va(vi("wb_data_o",e.width-1,0),e.full_prefix.."_rddata_int");};
if(e.width<DATA_BUS_WIDTH)then if(e.width<DATA_BUS_WIDTH)then
table_join(t,{va(vi("wb_data_o",DATA_BUS_WIDTH-1,e.width),0);}); table_join(a,{va(vi("wb_data_o",DATA_BUS_WIDTH-1,e.width),0);});
end end
table_join(a,{vcase(e.select_bits,t);}); table_join(t,{vcase(e.select_bits,a);});
end); end);
table.insert(t,"wb_addr_i"); table.insert(a,"wb_addr_i");
table_join(a,{vcasedefault(va("wb_data_o","rddata_reg"));}); table_join(t,{vcasedefault(va("wb_data_o","rddata_reg"));});
table_join(e,o); table_join(e,o);
end end
local a={"wb_addr_i","rd_int","wr_int"}; local a={"wb_addr_i","rd_int","wr_int"};
......
...@@ -150,8 +150,12 @@ function calc_size(field, reg) ...@@ -150,8 +150,12 @@ function calc_size(field, reg)
end end
-- iterates for all registers which type is in "accecepted_types", executing function "func" for each register -- iterates for all registers which type is in "accecepted_types", executing function "func" for each register
function foreach_reg(accepted_types, func) function foreach_reg(accepted_types, func, p)
for i,v in ipairs(periph) do if(p == nil) then
p = periph;
end
for i,v in ipairs(p) do
if(type(v) == 'table') then if(type(v) == 'table') then
if(v.__type ~= nil and (match(v.__type, accepted_types))) then if(v.__type ~= nil and (match(v.__type, accepted_types))) then
func(v); func(v);
......
...@@ -228,6 +228,10 @@ function fifo_wire_bus_ports(fifo) ...@@ -228,6 +228,10 @@ function fifo_wire_bus_ports(fifo)
}; };
function gen_fifo_csr_field(flag, field_prefix, field_name, field_desc, size, type, offset) function gen_fifo_csr_field(flag, field_prefix, field_name, field_desc, size, type, offset)
if(fifo.flags_bus == nil) then
return;
end
if inset(flag, fifo.flags_bus) then if inset(flag, fifo.flags_bus) then
local f = { local f = {
["__type"] = TYPE_FIELD; ["__type"] = TYPE_FIELD;
......
...@@ -692,8 +692,6 @@ function gen_hdl_code_reg_field(field, reg) ...@@ -692,8 +692,6 @@ function gen_hdl_code_reg_field(field, reg)
if(field.ackgen_code == nil) then field.ackgen_code= {}; end if(field.ackgen_code == nil) then field.ackgen_code= {}; end
table_join(field.ackgen_code, { va(field.ack_read, 0) }); table_join(field.ackgen_code, { va(field.ack_read, 0) });
end end
end end
-- generates VHDL for single register -- generates VHDL for single register
......
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