Commit 04a79f31 authored by twlostow's avatar twlostow

added dummy read register assignment during read of MONOSTABLE fields

git-svn-id: http://svn.ohwr.org/wishbone-gen@27 4537843c-45c2-4d80-8546-c3283569414f
parent 15081e0b
#!/usr/bin/env lua #!/usr/bin/env lua
package.preload['alt_getopt']=(function(...) package.preload['alt_getopt']=(function(...)
local n,s,u,o,i=type,pairs,ipairs,io,os local o,r,u,i,a=type,pairs,ipairs,io,os
module("alt_getopt") module("alt_getopt")
local function d(t) local function c(e)
local e=1 local t=1
local e=#t local t=#e
local e={} local t={}
for a,t in t:gmatch("(%w)(:?)")do for a,e in e:gmatch("(%w)(:?)")do
e[a]=#t t[a]=#e
end end
return e return t
end end
local function r(e,t) local function d(t,e)
o.stderr:write(e) i.stderr:write(t)
i.exit(t) a.exit(e)
end end
local function a(e) local function a(e)
r("Unknown option `-".. d("Unknown option `-"..
(#e>1 and"-"or"")..e.."'\n",1) (#e>1 and"-"or"")..e.."'\n",1)
end end
local function l(t,e) local function l(t,e)
if not t[e]then if not t[e]then
a(e) a(e)
end end
while n(t[e])=="string"do while o(t[e])=="string"do
e=t[e] e=t[e]
if not t[e]then if not t[e]then
a(e) a(e)
...@@ -31,13 +31,13 @@ end ...@@ -31,13 +31,13 @@ end
end end
return e return e
end end
function get_ordered_opts(n,a,u) function get_ordered_opts(n,a,s)
local t=1 local t=1
local e=1 local e=1
local i={} local i={}
local h={} local h={}
local o=d(a) local o=c(a)
for e,t in s(u)do for e,t in r(s)do
o[e]=t o[e]=t
end end
while t<=#n do while t<=#n do
...@@ -53,7 +53,7 @@ if s then ...@@ -53,7 +53,7 @@ if s then
local t=a:sub(3,s-1) local t=a:sub(3,s-1)
t=l(o,t) t=l(o,t)
if o[t]==0 then if o[t]==0 then
r("Bad usage of option `"..a.."'\n",1) d("Bad usage of option `"..a.."'\n",1)
end end
h[e]=a:sub(s+1) h[e]=a:sub(s+1)
i[e]=t i[e]=t
...@@ -64,7 +64,7 @@ if o[s]==0 then ...@@ -64,7 +64,7 @@ if o[s]==0 then
i[e]=s i[e]=s
else else
if t==#n then if t==#n then
r("Missed value for option `"..a.."'\n",1) d("Missed value for option `"..a.."'\n",1)
end end
h[e]=n[t+1] h[e]=n[t+1]
i[e]=s i[e]=s
...@@ -74,14 +74,14 @@ end ...@@ -74,14 +74,14 @@ end
e=e+1 e=e+1
elseif a:sub(1,1)=="-"then elseif a:sub(1,1)=="-"then
local s local s
for d=2,a:len()do for r=2,a:len()do
local s=l(o,a:sub(d,d)) local s=l(o,a:sub(r,r))
if o[s]==0 then if o[s]==0 then
i[e]=s i[e]=s
e=e+1 e=e+1
elseif a:len()==d then elseif a:len()==r then
if t==#n then if t==#n then
r("Missed value for option `-"..s.."'\n",1) d("Missed value for option `-"..s.."'\n",1)
end end
h[e]=n[t+1] h[e]=n[t+1]
i[e]=s i[e]=s
...@@ -89,7 +89,7 @@ t=t+1 ...@@ -89,7 +89,7 @@ t=t+1
e=e+1 e=e+1
break break
else else
h[e]=a:sub(d+1) h[e]=a:sub(r+1)
i[e]=s i[e]=s
e=e+1 e=e+1
break break
...@@ -102,12 +102,12 @@ t=t+1 ...@@ -102,12 +102,12 @@ t=t+1
end end
return i,t,h return i,t,h
end end
function get_opts(a,o,t) function get_opts(a,t,o)
local e={} local e={}
local t,i,a=get_ordered_opts(a,o,t) local t,i,o=get_ordered_opts(a,t,o)
for o,t in u(t)do for a,t in u(t)do
if a[o]then if o[a]then
e[t]=a[o] e[t]=o[a]
else else
e[t]=1 e[t]=1
end end
...@@ -176,22 +176,22 @@ die(t.." expected."); ...@@ -176,22 +176,22 @@ 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,a)
if(e.type==MONOSTABLE or e.type==BIT)then if(e.type==MONOSTABLE or e.type==BIT)then
e.size=1; e.size=1;
elseif(e.type==SLV)then elseif(e.type==SLV)then
...@@ -212,7 +212,7 @@ end ...@@ -212,7 +212,7 @@ end
elseif(e.type==ENUM)then elseif(e.type==ENUM)then
die("ENUM-type fields are not yet supported. Sorry :("); die("ENUM-type fields are not yet supported. Sorry :(");
end end
t.total_size=t.total_size+e.size; a.total_size=a.total_size+e.size;
end end
function foreach_reg(a,t,e) function foreach_reg(a,t,e)
if(e==nil)then if(e==nil)then
...@@ -248,27 +248,27 @@ if(t.align==nil)then e=1;else e=t.align;end ...@@ -248,27 +248,27 @@ if(t.align==nil)then e=1;else e=t.align;end
local e=e*math.floor((a+e-1)/e); local e=e*math.floor((a+e-1)/e);
return e; return e;
end end
function calc_field_offset(e,t) function calc_field_offset(t,e)
local a=t.current_offset; local a=e.current_offset;
if(t.__type==TYPE_FIFO)then if(e.__type==TYPE_FIFO)then
local o=align(e,a); local o=align(t,a);
if((o%DATA_BUS_WIDTH)+e.size>DATA_BUS_WIDTH)then if((o%DATA_BUS_WIDTH)+t.size>DATA_BUS_WIDTH)then
e.align=DATA_BUS_WIDTH; t.align=DATA_BUS_WIDTH;
a=align(e,a); a=align(t,a);
else else
a=o; a=o;
end end
t.current_offset=a+e.size; e.current_offset=a+t.size;
e.offset=a; t.offset=a;
else else
a=align(e,a); a=align(t,a);
t.current_offset=a+e.size; e.current_offset=a+t.size;
e.offset=a; t.offset=a;
end end
e.offset_unaligned=t.current_offset_unaligned; t.offset_unaligned=e.current_offset_unaligned;
t.current_offset_unaligned=t.current_offset_unaligned+e.size; e.current_offset_unaligned=e.current_offset_unaligned+t.size;
if(t.__type==TYPE_REG and t.current_offset>DATA_BUS_WIDTH)then if(e.__type==TYPE_REG and e.current_offset>DATA_BUS_WIDTH)then
die("Total size of register '"..t.name.."' ("..t.current_offset..") exceeds data bus width ("..DATA_BUS_WIDTH..")"); die("Total size of register '"..e.name.."' ("..e.current_offset..") exceeds data bus width ("..DATA_BUS_WIDTH..")");
end end
end end
function calc_num_fields(t,e) function calc_num_fields(t,e)
...@@ -290,11 +290,11 @@ function inset(t,e) ...@@ -290,11 +290,11 @@ function inset(t,e)
for a,e in ipairs(e)do if(t==e)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,t,a)
if(t)then if(e)then
return a; return t;
else else
return e; return a;
end end
end end
function fix_prefix(e) function fix_prefix(e)
...@@ -308,13 +308,13 @@ return e; ...@@ -308,13 +308,13 @@ return e;
end end
return e; return e;
end end
function default_access(e,t,a,o) function default_access(e,o,a,t)
if(e.type==t)then if(e.type==o)then
if(e.access_bus==nil)then if(e.access_bus==nil)then
e.access_bus=a; e.access_bus=a;
end end
if(e.access_dev==nil)then if(e.access_dev==nil)then
e.access_dev=o; e.access_dev=t;
end end
end end
end end
...@@ -388,25 +388,25 @@ end ...@@ -388,25 +388,25 @@ 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,t)
local t=0; local a=0;
local o,o; local o,o;
for o,e in pairs(e)do if(type(e)=='table'and e[a]~=nil and e[a]>t)then t=e[a];end end for o,e in pairs(e)do if(type(e)=='table'and e[t]~=nil and e[t]>a)then a=e[t];end end
return t; return a;
end end
function table_join(t,e) function table_join(t,e)
local a,a; local a,a;
...@@ -438,10 +438,10 @@ end); ...@@ -438,10 +438,10 @@ end);
return a; return a;
end end
function remove_duplicates(o) function remove_duplicates(o)
function count_entries(t,a) function count_entries(a,t)
local o,o,e; local o,o,e;
e=0; e=0;
for o,t in ipairs(t)do if(t==a)then e=e+1;end end for o,a in ipairs(a)do if(a==t)then e=e+1;end end
return e; return e;
end end
local e={}; local e={};
...@@ -454,19 +454,19 @@ end ...@@ -454,19 +454,19 @@ end
return e; return e;
end end
function wbgen_count_subblocks() function wbgen_count_subblocks()
local e=0;
local t=0; local t=0;
local o=0;
local a=0; local a=0;
foreach_reg({TYPE_RAM},function(t)e=e+1;end); local e=0;
foreach_reg({TYPE_REG},function(e)o=o+1;end); local o=0;
foreach_reg({TYPE_FIFO},function(e)t=t+1;end); foreach_reg({TYPE_RAM},function(e)t=t+1;end);
foreach_reg({TYPE_IRQ},function(e)a=a+1;end); foreach_reg({TYPE_REG},function(t)e=e+1;end);
periph.ramcount=e; foreach_reg({TYPE_FIFO},function(e)a=a+1;end);
periph.fifocount=t; foreach_reg({TYPE_IRQ},function(e)o=o+1;end);
periph.regcount=o; periph.ramcount=t;
periph.irqcount=a; periph.fifocount=a;
if(e+t+o+a==0)then periph.regcount=e;
periph.irqcount=o;
if(t+a+e+o==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
...@@ -494,34 +494,34 @@ e.dst=t; ...@@ -494,34 +494,34 @@ e.dst=t;
e.src=a; e.src=a;
return e; return e;
end end
function vi(o,t,a) function vi(t,a,o)
local e={}; local e={};
e.t="index"; e.t="index";
e.name=o; e.name=t;
e.h=t; e.h=a;
e.l=a; e.l=o;
return e; return e;
end end
function vinstance(o,t,a) function vinstance(a,o,t)
local e={}; local e={};
e.t="instance"; e.t="instance";
e.name=o; e.name=a;
e.component=t; e.component=o;
e.maps=a; e.maps=t;
return e; return e;
end end
function vpm(a,t) function vpm(t,a)
local e={}; local e={};
e.t="portmap"; e.t="portmap";
e.to=a; e.to=t;
e.from=t; e.from=a;
return e; return e;
end end
function vgm(a,t) function vgm(t,a)
local e={}; local e={};
e.t="genmap"; e.t="genmap";
e.to=a; e.to=t;
e.from=t; e.from=a;
return e; return e;
end end
function vcombprocess(t,a) function vcombprocess(t,a)
...@@ -531,19 +531,19 @@ e.slist=t; ...@@ -531,19 +531,19 @@ e.slist=t;
e.code=a; e.code=a;
return e; return e;
end end
function vsyncprocess(a,t,o) function vsyncprocess(t,o,a)
local e={}; local e={};
e.t="syncprocess"; e.t="syncprocess";
e.clk=a; e.clk=t;
e.rst=t; e.rst=o;
e.code=o; e.code=a;
return e; return e;
end end
function vreset(t,a) function vreset(a,t)
local e={}; local e={};
e.t="reset"; e.t="reset";
e.level=t; e.level=a;
e.code=a; e.code=t;
return e; return e;
end end
function vposedge(t) function vposedge(t)
...@@ -552,19 +552,19 @@ e.t="posedge"; ...@@ -552,19 +552,19 @@ e.t="posedge";
e.code=t; e.code=t;
return e; return e;
end end
function vif(o,t,a) function vif(o,a,t)
local e={}; local e={};
e.t="if"; e.t="if";
e.cond={o}; e.cond={o};
e.code=t; e.code=a;
e.code_else=a; e.code_else=t;
return e; return e;
end end
function vequal(a,t) function vequal(t,a)
local e={}; local e={};
e.t="eq"; e.t="eq";
e.a=a; e.a=t;
e.b=t; e.b=a;
return e; return e;
end end
function vand(t,a) function vand(t,a)
...@@ -580,18 +580,18 @@ e.t="not"; ...@@ -580,18 +580,18 @@ e.t="not";
e.a=t; e.a=t;
return e; return e;
end end
function vswitch(t,a) function vswitch(a,t)
local e={}; local e={};
e.t="switch"; e.t="switch";
e.a=t; e.a=a;
e.code=a; e.code=t;
return e; return e;
end end
function vcase(t,a) function vcase(a,t)
local e={}; local e={};
e.t="case"; e.t="case";
e.a=t; e.a=a;
e.code=a; e.code=t;
return e; return e;
end end
function vcasedefault(t) function vcasedefault(t)
...@@ -629,26 +629,26 @@ local e={} ...@@ -629,26 +629,26 @@ local e={}
e.t="undefined"; e.t="undefined";
return e; return e;
end end
function signal(t,i,o,a) function signal(t,o,a,i)
local e={} local e={}
e.comment=a; e.comment=i;
e.type=t; e.type=t;
e.range=i; e.range=o;
e.name=o; e.name=a;
return e; return e;
end end
VPORT_WB=1; VPORT_WB=1;
VPORT_REG=2; VPORT_REG=2;
function port(i,a,o,n,s,t) function port(s,a,n,i,o,t)
local e={} local e={}
e.comment=s; e.comment=o;
e.type=i; e.type=s;
if(e.type==SLV and a==1)then if(e.type==SLV and a==1)then
e.type=BIT; e.type=BIT;
end end
e.range=a; e.range=a;
e.name=n; e.name=i;
e.dir=o; e.dir=n;
if(t~=nil)then if(t~=nil)then
if(t==VPORT_WB)then if(t==VPORT_WB)then
e.is_wb=true; e.is_wb=true;
...@@ -781,21 +781,27 @@ fieldtype_2_vhdl[SIGNED]="signed"; ...@@ -781,21 +781,27 @@ 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 t='\"';
local s,t,i,e; local s,o,n,e;
t=n; o=i;
e=math.pow(2,o-1); e=math.pow(2,a-1);
for o=1,o do if(i==nil)then
i=math.floor(t/e); for e=1,a do
a=a..csel(i>0,"1","0"); t=t.."X";
t=t%e; end
else
for a=1,a do
n=math.floor(o/e);
t=t..csel(n>0,"1","0");
o=o%e;
e=e/2; e=e/2;
end end
return a..'\"'; end
return t..'\"';
end end
function strip_periph_prefix(e) function strip_periph_prefix(e)
return string.gsub(e,"^"..periph.hdl_prefix.."\_","") return string.gsub(e,"^"..periph.hdl_prefix.."\_","")
...@@ -806,21 +812,63 @@ return e ...@@ -806,21 +812,63 @@ return e
end end
for a,t in ipairs(g_portlist)do for a,t in ipairs(g_portlist)do
if(t.name==e and t.is_reg_port)then if(t.name==e and t.is_reg_port)then
return"regs_b."..strip_periph_prefix(e) return csel(t.dir=="in","regs_i.","regs_o.")..strip_periph_prefix(e)
end end
end end
return e return e
end end
function cgen_vhdl_package() function cgen_vhdl_package()
emit("package "..periph.hdl_prefix.."_wbgen2_pkg is") local t=periph.hdl_prefix.."_wbgen2_pkg";
emit("package "..t.." is")
indent_right(); indent_right();
emit("type t_"..periph.hdl_prefix.."_registers is record"); emit("");
emit("");
emit("-- Input registers (user design -> WB slave)");
emit("");
cgen_vhdl_port_struct("in");
emit("");
emit("-- Output registers (WB slave -> user design)");
emit("");
cgen_vhdl_port_struct("out");
indent_left();
local e="t_"..periph.hdl_prefix.."_in_registers";
emit("function \"or\" (left, right: "..e..") return "..e..";");
emit("function f_x_to_zero (x:std_logic) return std_logic;");
indent_left();
indent_left();
emit("end package;");
emit("");
emit("package body "..t.." is");
emit("function f_x_to_zero (x:std_logic) return std_logic is");
emit("begin");
emit("if(x = 'X' or x = 'U') then");
emit("return '0';");
emit("else");
emit("return x;");
emit("end if; ");
emit("end function;");
emit("function \"or\" (left, right: "..e..") return "..e.." is");
emit("variable tmp: "..e..";");
emit("begin");
for e=1,table.getn(g_portlist)do
local e=g_portlist[e];
if(e.is_reg_port==true and e.dir=="in")then
local e=strip_periph_prefix(e.name);
emit("tmp."..e.." := left."..e.." or right."..e..";");
end
end
emit("return tmp;");
emit("end function;");
emit("end package body;");
end
function cgen_vhdl_port_struct(t)
emit("type t_"..periph.hdl_prefix.."_"..t.."_registers is record");
indent_right(); indent_right();
local e={}; local e={};
for t=1,table.getn(g_portlist)do for a=1,table.getn(g_portlist)do
local t=g_portlist[t]; local a=g_portlist[a];
if(t.is_reg_port==true)then if(a.is_reg_port==true and a.dir==t)then
table.insert(e,t); table.insert(e,a);
end end
end end
for e,t in ipairs(e)do for e,t in ipairs(e)do
...@@ -834,26 +882,22 @@ end ...@@ -834,26 +882,22 @@ end
emit("end record;"); emit("end record;");
indent_left(); indent_left();
emit(""); emit("");
emit("constant c_"..periph.hdl_prefix.."_registers_init_value: t_"..periph.hdl_prefix.."_registers := ("); emit("constant c_"..periph.hdl_prefix.."_"..t.."_registers_init_value: t_"..periph.hdl_prefix.."_"..t.."_registers := (");
indent_right(); indent_right();
for t=1,table.getn(e)do for t=1,table.getn(e)do
local a=e[t]; local a=e[t];
line=strip_periph_prefix(a.name).." => "; line=strip_periph_prefix(a.name).." => ";
if(a.range>1)then if(a.range>1)then
line=line.."(others => 'Z')" line=line.."(others => '0')"
else else
line=line.."'Z'" line=line.."'0'"
end end
if(t~=table.getn(e))then if(t~=table.getn(e))then
line=line..","; line=line..",";
end end
emit(line); emit(line);
end end
indent_left();
emit(");"); emit(");");
indent_left();
indent_left();
emit("end package;");
end end
function cgen_vhdl_header(e) function cgen_vhdl_header(e)
emit("---------------------------------------------------------------------------------------"); emit("---------------------------------------------------------------------------------------");
...@@ -901,7 +945,8 @@ emit(t); ...@@ -901,7 +945,8 @@ emit(t);
end end
end end
if(options.hdl_reg_style=="record")then if(options.hdl_reg_style=="record")then
emit(string.format("%-40s : %-6s %s","regs_b","inout","t_"..periph.hdl_prefix.."_registers")); emit(string.format("%-40s : %-6s %s","regs_i","in","t_"..periph.hdl_prefix.."_in_registers;"));
emit(string.format("%-40s : %-6s %s","regs_o","out","t_"..periph.hdl_prefix.."_out_registers"));
end end
indent_left(); indent_left();
emit(");"); emit(");");
...@@ -921,9 +966,6 @@ end ...@@ -921,9 +966,6 @@ end
emit(""); emit("");
emit("begin"); emit("begin");
indent_right(); indent_right();
if(options.hdl_reg_style=="record")then
emit("regs_b <= c_"..periph.hdl_prefix.."_registers_init_value;");
end
end end
function cgen_vhdl_ending() function cgen_vhdl_ending()
indent_left(); indent_left();
...@@ -1097,16 +1139,16 @@ else ...@@ -1097,16 +1139,16 @@ else
die("unsupported assignment: "..t.name.." "..e.name);end die("unsupported assignment: "..t.name.." "..e.name);end
else die("unsupported assignment: "..t.name.." "..e.name);end else die("unsupported assignment: "..t.name.." "..e.name);end
end end
function cgen_vhdl_assign(t) function cgen_vhdl_assign(e)
local e=node_typesize(t.dst); local t=node_typesize(e.dst);
local t=node_typesize(t.src); local e=node_typesize(e.src);
if(t.type==EXPRESSION)then if(e.type==EXPRESSION)then
emiti(); emiti();
emitx(gen_subrange(e).." <= "); emitx(gen_subrange(t).." <= ");
recurse({t.code}); recurse({e.code});
emitx(";\n"); emitx(";\n");
else else
emit(gen_subrange(e).." <= "..gen_vhdl_typecvt(e,t)..";"); emit(gen_subrange(t).." <= "..gen_vhdl_typecvt(t,e)..";");
end end
end end
function cgen_vhdl_if(e) function cgen_vhdl_if(e)
...@@ -1123,13 +1165,13 @@ indent_right();recurse(e.code);indent_left(); ...@@ -1123,13 +1165,13 @@ indent_right();recurse(e.code);indent_left();
emit("end if;"); emit("end if;");
end end
end end
function cgen_vhdl_not(t) function cgen_vhdl_not(e)
local e=node_typesize(t.a); local t=node_typesize(e.a);
emitx("not "); emitx("not ");
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_vhdl_binary_op(t) function cgen_vhdl_binary_op(t)
...@@ -1495,34 +1537,34 @@ indent_left(); ...@@ -1495,34 +1537,34 @@ indent_left();
emit("end"); emit("end");
end end
end end
function cgen_verilog_not(e) function cgen_verilog_not(t)
local t=node_typesize(e.a); local e=node_typesize(t.a);
emitx("! "); emitx("! ");
if(t.type==EXPRESSION)then if(e.type==EXPRESSION)then
emitx("(");recurse({e.a});emitx(")");
else
emitx(gen_subrange(t));
end
end
function cgen_verilog_binary_op(t)
local o=node_typesize(t.a);
local a=node_typesize(t.b);
local e=t.t;
if(o.type==EXPRESSION)then
emitx("(");recurse({t.a});emitx(")"); emitx("(");recurse({t.a});emitx(")");
else else
emitx(gen_subrange(o)); emitx(gen_subrange(e));
end end
if(e=="eq")then emitx(" == ");end end
if(e=="and")then emitx(" && ");end function cgen_verilog_binary_op(e)
if(e=="or")then emitx(" || ");end local a=node_typesize(e.a);
if(e=="sub")then emitx(" - ");end local o=node_typesize(e.b);
if(e=="add")then emitx(" + ");end local t=e.t;
if(a.type==EXPRESSION)then if(a.type==EXPRESSION)then
emitx("(");recurse({t.b});emitx(")"); emitx("(");recurse({e.a});emitx(")");
else else
emitx(gen_subrange(a)); emitx(gen_subrange(a));
end end
if(t=="eq")then emitx(" == ");end
if(t=="and")then emitx(" && ");end
if(t=="or")then emitx(" || ");end
if(t=="sub")then emitx(" - ");end
if(t=="add")then emitx(" + ");end
if(o.type==EXPRESSION)then
emitx("(");recurse({e.b});emitx(")");
else
emitx(gen_subrange(o));
end
end end
function cgen_verilog_comment(e) function cgen_verilog_comment(e)
emitx("// "..e.str.."\n"); emitx("// "..e.str.."\n");
...@@ -1554,28 +1596,28 @@ end ...@@ -1554,28 +1596,28 @@ end
emit("endcase"); emit("endcase");
end end
function cgen_verilog_instance(t) function cgen_verilog_instance(t)
local o=0;
local a=0; local a=0;
local o=0;
local e; local e;
emitx(t.component.." "); emitx(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("# ("); emit("# (");
indent_right(); indent_right();
e=1; e=1;
for t,o in pairs(t.maps)do for t,a in pairs(t.maps)do
if(o.t=="genmap")then if(a.t=="genmap")then
local t=o.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)",o.to,t)..csel(e==a,"",",")); emit(string.format(".%-20s(%s)",a.to,t)..csel(e==o,"",","));
e=e+1; e=e+1;
end end
end end
...@@ -1583,15 +1625,15 @@ indent_left(); ...@@ -1583,15 +1625,15 @@ indent_left();
emit(")"); emit(")");
indent_left(); indent_left();
end end
if(o>0)then if(a>0)then
indent_right(); indent_right();
emit(t.name.." ( "); emit(t.name.." ( ");
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
...@@ -1604,23 +1646,23 @@ end ...@@ -1604,23 +1646,23 @@ end
function cgen_verilog_openpin(e) function cgen_verilog_openpin(e)
emitx(""); emitx("");
end end
function cgen_verilog_combprocess(e) function cgen_verilog_combprocess(t)
local t=true; local e=true;
emiti(); emiti();
emitx("always @("); emitx("always @(");
a=true; a=true;
for a,e in pairs(e.slist)do for a,t in pairs(t.slist)do
if(t)then if(e)then
t=false; e=false;
else else
emitx(" or "); emitx(" or ");
end end
emitx(e); emitx(t);
end end
emit(")"); emit(")");
emit("begin"); emit("begin");
indent_right(); indent_right();
recurse(e.code); recurse(t.code);
indent_left(); indent_left();
a=false; a=false;
emit("end"); emit("end");
...@@ -1662,13 +1704,13 @@ local t=cgen_get_snippet(); ...@@ -1662,13 +1704,13 @@ local t=cgen_get_snippet();
cgen_new_snippet(); cgen_new_snippet();
recurse(i); recurse(i);
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 e=cgen_get_snippet(); local a=cgen_get_snippet();
cgen_write_snippet(t); cgen_write_snippet(t);
cgen_write_snippet(e);
cgen_write_snippet(a); cgen_write_snippet(a);
cgen_write_snippet(e);
end end
function cgen_c_field_define(e,a) function cgen_c_field_define(e,a)
local t; local t;
...@@ -1840,21 +1882,21 @@ end ...@@ -1840,21 +1882,21 @@ end
end end
return e; return e;
end end
function htable_tdstyle(t,a,e) function htable_tdstyle(a,t,e)
tbl.data[t][a].style=e; tbl.data[a][t].style=e;
end end
function htable_trstyle(e,a,t) function htable_trstyle(t,a,e)
tbl.data[e].style=t; tbl.data[t].style=e;
end end
function htable_frame(o,a,e,t) function htable_frame(e,t,a,o)
if(t==nil)then if(o==nil)then
o.data[a][e].extra='style="border: solid 1px black;"'; e.data[t][a].extra='style="border: solid 1px black;"';
else else
o.data[a][e].extra='style="border-left: solid 1px black; border-top: solid 1px black; border-bottom: solid 1px black;'; e.data[t][a].extra='style="border-left: solid 1px black; border-top: solid 1px black; border-bottom: solid 1px black;';
o.data[a][t].extra='style="border-right: solid 1px black; border-top: solid 1px black; border-bottom: solid 1px black;'; e.data[t][o].extra='style="border-right: solid 1px black; border-top: solid 1px black; border-bottom: solid 1px black;';
if(t>e+1)then if(o>a+1)then
for e=e+1,t-1 do for a=a+1,o-1 do
o.data[a][e].extra='border-top: solid 1px black; border-bottom: solid 1px black;'; e.data[t][a].extra='border-top: solid 1px black; border-bottom: solid 1px black;';
end end
end end
end end
...@@ -1892,11 +1934,11 @@ emit("</tr>"); ...@@ -1892,11 +1934,11 @@ 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,a)
if(a>e.rows)then if(a>e.rows)then
...@@ -1910,27 +1952,27 @@ end ...@@ -1910,27 +1952,27 @@ end
e.rows=a; e.rows=a;
end end
end end
function hlink(t,e) function hlink(e,t)
return'<A href="'..t..'">'..e..'</a>'; return'<A href="'..e..'">'..t..'</a>';
end end
function hitem(e) function hitem(e)
return'<li>'..e..'</li>'; return'<li>'..e..'</li>';
end end
function hanchor(e,t) function hanchor(t,e)
return'<a name="'..e..'">'..t..'</a>'; return'<a name="'..t..'">'..e..'</a>';
end end
doc_toc={}; doc_toc={};
function hsection(t,a,o) function hsection(a,t,o)
local e={}; local e={};
local i=0; local i=0;
e.id_mangled="sect_"..t.."_"..a; e.id_mangled="sect_"..a.."_"..t;
e.key=t*1e3+a; e.key=a*1e3+t;
if(a~=0)then if(t~=0)then
e.level=2; e.level=2;
e.id=t.."."..a.."."; e.id=a.."."..t..".";
else else
e.level=1; e.level=1;
e.id=t.."."; e.id=a..".";
end end
e.name=o; e.name=o;
table.insert(doc_toc,e); table.insert(doc_toc,e);
...@@ -1979,9 +2021,9 @@ end ...@@ -1979,9 +2021,9 @@ end
end); end);
cgen_doc_symbol(t); cgen_doc_symbol(t);
end end
function cgen_doc_mem_symbol(a) function cgen_doc_mem_symbol(t)
local e={}; local e={};
for t,a in pairs(a.ports)do for t,a in pairs(t.ports)do
local t=a; local t=a;
if(string.find(a.name,"_i")~=nil)then if(string.find(a.name,"_i")~=nil)then
t.is_wb=true; t.is_wb=true;
...@@ -1990,8 +2032,8 @@ t.is_wb=false; ...@@ -1990,8 +2032,8 @@ t.is_wb=false;
end end
table.insert(e,t); table.insert(e,t);
end end
if(a.clock~=nil)then if(t.clock~=nil)then
local t=port(BIT,0,"in",a.clock); local t=port(BIT,0,"in",t.clock);
t.is_wb=true; t.is_wb=true;
table.insert(e,t); table.insert(e,t);
end end
...@@ -2090,28 +2132,28 @@ e[5].text=string.upper(t.c_prefix); ...@@ -2090,28 +2132,28 @@ e[5].text=string.upper(t.c_prefix);
o=not o; o=not o;
end end
end); end);
foreach_reg({TYPE_RAM},function(e) foreach_reg({TYPE_RAM},function(t)
if(e.full_hdl_prefix~=nil)then if(t.full_hdl_prefix~=nil)then
htable_add_row(i,a); htable_add_row(i,a);
local t=i.data[a];a=a+1; local e=i.data[a];a=a+1;
t.style=csel(o,"tr_odd","tr_even"); e.style=csel(o,"tr_odd","tr_even");
t[1].style="td_code"; e[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); e[1].text=string.format("0x%x - 0x%x",t.base,t.base+math.pow(2,t.wrap_bits)*t.size-1);
t[2].text="MEM"; e[2].text="MEM";
t[3].text=hlink("#"..string.upper(e.c_prefix),e.name); e[3].text=hlink("#"..string.upper(t.c_prefix),t.name);
t[4].style="td_code"; e[4].style="td_code";
t[4].text=e.full_hdl_prefix; e[4].text=t.full_hdl_prefix;
t[5].style="td_code"; e[5].style="td_code";
t[5].text=string.upper(e.c_prefix); e[5].text=string.upper(t.c_prefix);
o=not o; o=not o;
end end
end); end);
htable_emit(i); htable_emit(i);
end end
function find_field_by_offset(e,t) function find_field_by_offset(e,a)
local a=nil; local t=nil;
foreach_subfield(e,function(e)if(t>=e.offset and t<=(e.offset+e.size-1))then a=e;end end); foreach_subfield(e,function(e)if(a>=e.offset and a<=(e.offset+e.size-1))then t=e;end end);
return a; return t;
end end
function cgen_doc_fieldtable(h,i) function cgen_doc_fieldtable(h,i)
local e=70; local e=70;
...@@ -2322,6 +2364,9 @@ return string.lower(periph.hdl_prefix.."_"..e.hdl_prefix); ...@@ -2322,6 +2364,9 @@ return string.lower(periph.hdl_prefix.."_"..e.hdl_prefix);
end end
return string.lower(periph.hdl_prefix.."_"..e.hdl_prefix.."_"..a.hdl_prefix); return string.lower(periph.hdl_prefix.."_"..e.hdl_prefix.."_"..a.hdl_prefix);
end end
function gen_reset_value(e)
return csel(e.reset_value==nil,'0',e.reset_value)
end
function gen_hdl_code_monostable(t,a) function gen_hdl_code_monostable(t,a)
local e=gen_hdl_field_prefix(t,a); local e=gen_hdl_field_prefix(t,a);
if(t.clock==nil)then if(t.clock==nil)then
...@@ -2340,8 +2385,9 @@ va(e.."_o",vand(e.."_int",vnot(e.."_dly0"))); ...@@ -2340,8 +2385,9 @@ va(e.."_o",vand(e.."_int",vnot(e.."_dly0")));
}; };
}); });
t.reset_code_main={va(e.."_int",0)}; t.reset_code_main={va(e.."_int",0)};
t.write_code={va(e.."_int",vi("wrdata_reg",t.offset))}; t.write_code={va(e.."_int",vi("wrdata_reg",t.offset)),
t.read_code={}; va(vi("rddata_reg",t.offset),vundefined())};
t.read_code={va(vi("rddata_reg",t.offset),vundefined())};
t.ackgen_code={va(e.."_int",0)}; t.ackgen_code={va(e.."_int",0)};
else else
t.signals={signal(BIT,0,e.."_int"), t.signals={signal(BIT,0,e.."_int"),
...@@ -2369,9 +2415,10 @@ va(e.."_o",vand(e.."_sync2",vnot(e.."_sync1"))); ...@@ -2369,9 +2415,10 @@ va(e.."_o",vand(e.."_sync2",vnot(e.."_sync1")));
});}; });};
t.reset_code_main={va(e.."_int",0); t.reset_code_main={va(e.."_int",0);
va(e.."_int_delay",0);}; va(e.."_int_delay",0);};
t.write_code={va(e.."_int",vi("wrdata_reg",t.offset)); t.write_code={va(vi("rddata_reg",t.offset),vundefined()),
va(e.."_int",vi("wrdata_reg",t.offset));
va(e.."_int_delay",vi("wrdata_reg",t.offset));}; va(e.."_int_delay",vi("wrdata_reg",t.offset));};
t.read_code={}; t.read_code={va(vi("rddata_reg",t.offset),vundefined())};
t.ackgen_code_pre={va(e.."_int",e.."_int_delay"); t.ackgen_code_pre={va(e.."_int",e.."_int_delay");
va(e.."_int_delay",0);}; va(e.."_int_delay",0);};
end end
...@@ -2384,7 +2431,8 @@ if(t.access==ACC_RW_RO)then ...@@ -2384,7 +2431,8 @@ if(t.access==ACC_RW_RO)then
t.ports={port(BIT,0,"out",e.."_o","Port for BIT field: '"..t.name.."' in reg: '"..a.name.."'",VPORT_REG)}; t.ports={port(BIT,0,"out",e.."_o","Port for BIT field: '"..t.name.."' in reg: '"..a.name.."'",VPORT_REG)};
t.signals={signal(BIT,0,e.."_int")}; t.signals={signal(BIT,0,e.."_int")};
t.acklen=1; t.acklen=1;
t.write_code={va(e.."_int",vi("wrdata_reg",t.offset))}; t.write_code={va(vi("rddata_reg",t.offset),vundefined()),
va(e.."_int",vi("wrdata_reg",t.offset))};
t.read_code={va(vi("rddata_reg",t.offset),e.."_int")}; t.read_code={va(vi("rddata_reg",t.offset),e.."_int")};
t.reset_code_main={va(e.."_int",0)}; t.reset_code_main={va(e.."_int",0)};
t.extra_code={va(e.."_o",e.."_int")}; t.extra_code={va(e.."_o",e.."_int")};
...@@ -2392,7 +2440,7 @@ elseif(t.access==ACC_RO_WO)then ...@@ -2392,7 +2440,7 @@ elseif(t.access==ACC_RO_WO)then
t.ports={port(BIT,0,"in",e.."_i","Port for BIT field: '"..t.name.."' in reg: '"..a.name.."'",VPORT_REG)}; t.ports={port(BIT,0,"in",e.."_i","Port for BIT field: '"..t.name.."' in reg: '"..a.name.."'",VPORT_REG)};
t.signals={}; t.signals={};
t.acklen=1; t.acklen=1;
t.write_code={}; t.write_code={va(vi("rddata_reg",t.offset),vundefined())};
t.read_code={va(vi("rddata_reg",t.offset),e.."_i")}; t.read_code={va(vi("rddata_reg",t.offset),e.."_i")};
t.reset_code_main={}; t.reset_code_main={};
t.extra_code={}; t.extra_code={};
...@@ -2405,7 +2453,8 @@ port(BIT,0,"in",e.."_i",nil,VPORT_REG), ...@@ -2405,7 +2453,8 @@ port(BIT,0,"in",e.."_i",nil,VPORT_REG),
port(BIT,0,"out",e.."_load_o",nil,VPORT_REG)}; port(BIT,0,"out",e.."_load_o",nil,VPORT_REG)};
t.acklen=1; t.acklen=1;
t.read_code={va(vi("rddata_reg",t.offset),e.."_i")}; t.read_code={va(vi("rddata_reg",t.offset),e.."_i")};
t.write_code={va(e.."_load_o",1)}; t.write_code={va(vi("rddata_reg",t.offset),vundefined()),
va(e.."_load_o",1)};
t.extra_code={va(e.."_o",vi("wrdata_reg",t.offset))}; t.extra_code={va(e.."_o",vi("wrdata_reg",t.offset))};
t.ackgen_code_pre={va(e.."_load_o",0)}; t.ackgen_code_pre={va(e.."_load_o",0)};
t.ackgen_code={va(e.."_load_o",0)}; t.ackgen_code={va(e.."_load_o",0)};
...@@ -2421,7 +2470,8 @@ t.signals={signal(BIT,0,e.."_int"), ...@@ -2421,7 +2470,8 @@ t.signals={signal(BIT,0,e.."_int"),
signal(BIT,0,e.."_sync0"), signal(BIT,0,e.."_sync0"),
signal(BIT,0,e.."_sync1")}; signal(BIT,0,e.."_sync1")};
t.acklen=4; t.acklen=4;
t.write_code={va(e.."_int",vi("wrdata_reg",t.offset))}; t.write_code={va(e.."_int",vi("wrdata_reg",t.offset)),
va(vi("rddata_reg",t.offset),vundefined())};
t.read_code={va(vi("rddata_reg",t.offset),e.."_int")}; t.read_code={va(vi("rddata_reg",t.offset),e.."_int")};
t.reset_code_main={va(e.."_int",0)}; t.reset_code_main={va(e.."_int",0)};
t.extra_code={vcomment("synchronizer chain for field : "..t.name.." (type RW/RO, bus_clock_int <-> "..t.clock..")"); t.extra_code={vcomment("synchronizer chain for field : "..t.name.." (type RW/RO, bus_clock_int <-> "..t.clock..")");
...@@ -2443,7 +2493,7 @@ t.ports={port(BIT,0,"in",e.."_i","Port for asynchronous (clock: "..t.clock..") B ...@@ -2443,7 +2493,7 @@ t.ports={port(BIT,0,"in",e.."_i","Port for asynchronous (clock: "..t.clock..") B
t.signals={signal(BIT,0,e.."_sync0"), t.signals={signal(BIT,0,e.."_sync0"),
signal(BIT,0,e.."_sync1")}; signal(BIT,0,e.."_sync1")};
t.acklen=1; t.acklen=1;
t.write_code={}; t.write_code={va(vi("rddata_reg",t.offset),vundefined())};
t.read_code={va(vi("rddata_reg",t.offset),e.."_sync1")}; t.read_code={va(vi("rddata_reg",t.offset),e.."_sync1")};
t.reset_code_main={}; t.reset_code_main={};
t.extra_code={vcomment("synchronizer chain for field : "..t.name.." (type RO/WO, "..t.clock.." -> bus_clock_int)"); t.extra_code={vcomment("synchronizer chain for field : "..t.name.." (type RO/WO, "..t.clock.." -> bus_clock_int)");
...@@ -2476,12 +2526,14 @@ signal(BIT,0,e.."_lw_s1"), ...@@ -2476,12 +2526,14 @@ signal(BIT,0,e.."_lw_s1"),
signal(BIT,0,e.."_lw_s2"), signal(BIT,0,e.."_lw_s2"),
signal(BIT,0,e.."_rwsel")}; signal(BIT,0,e.."_rwsel")};
t.acklen=6; t.acklen=6;
t.write_code={va(e.."_int_write",vi("wrdata_reg",t.offset)); t.write_code={va(vi("rddata_reg",t.offset),vundefined());
va(e.."_int_write",vi("wrdata_reg",t.offset));
va(e.."_lw",1); va(e.."_lw",1);
va(e.."_lw_delay",1); va(e.."_lw_delay",1);
va(e.."_lw_read_in_progress",0); va(e.."_lw_read_in_progress",0);
va(e.."_rwsel",1);}; va(e.."_rwsel",1);};
t.read_code={va(e.."_lw",1); t.read_code={va(vi("rddata_reg",t.offset),vundefined());
va(e.."_lw",1);
va(e.."_lw_delay",1); va(e.."_lw_delay",1);
va(e.."_lw_read_in_progress",1); va(e.."_lw_read_in_progress",1);
va(e.."_rwsel",0);}; va(e.."_rwsel",0);};
...@@ -2784,27 +2836,27 @@ e.ports={}; ...@@ -2784,27 +2836,27 @@ e.ports={};
e.acklen=1; e.acklen=1;
e.read_code={va(vir("rddata_reg",e),e.value);}; e.read_code={va(vir("rddata_reg",e),e.value);};
end end
function fill_unused_bits(o,e) function fill_unused_bits(i,e)
local a={}; local a={};
local t={}; local t={};
local i=true; local o=true;
foreach_subfield(e,function(e,t) foreach_subfield(e,function(e,t)
if(e.type==SLV or e.type==SIGNED or e.type==UNSIGNED or e.type==CONSTANT)then if(e.type==SLV or e.type==SIGNED or e.type==UNSIGNED or e.type==CONSTANT)then
for e=e.offset,(e.offset+e.size-1)do a[e]=1;end for e=e.offset,(e.offset+e.size-1)do a[e]=1;end
elseif(e.type==BIT or e.type==MONOSTABLE)then elseif(e.type==BIT or e.type==MONOSTABLE)then
a[e.offset]=1; a[e.offset]=1;
end end
if(e.access_bus~=WRITE_ONLY)then i=false;end if(e.access_bus~=WRITE_ONLY)then o=false;end
end); end);
if(i)then if(o)then
for e=0,DATA_BUS_WIDTH-1 do for e=0,DATA_BUS_WIDTH-1 do
table_join(t,{va(vi(o,e),vundefined());}); table_join(t,{va(vi(i,e),vundefined());});
end end
return t; return t;
end end
for e=0,DATA_BUS_WIDTH-1 do for e=0,DATA_BUS_WIDTH-1 do
if(a[e]==nil)then if(a[e]==nil)then
table_join(t,{va(vi(o,e),vundefined());}); table_join(t,{va(vi(i,e),vundefined());});
end end
end end
return t; return t;
...@@ -2928,7 +2980,7 @@ function wbgen_generate_eic() ...@@ -2928,7 +2980,7 @@ 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 o={}; local o={};
local i={["__type"]=TYPE_REG; local a={["__type"]=TYPE_REG;
["__blockindex"]=1e6; ["__blockindex"]=1e6;
["align"]=8; ["align"]=8;
["name"]="Interrupt disable register"; ["name"]="Interrupt disable register";
...@@ -2944,7 +2996,7 @@ signal(BIT,0,"eic_idr_write_int");}; ...@@ -2944,7 +2996,7 @@ signal(BIT,0,"eic_idr_write_int");};
["extra_code"]={va(vi("eic_idr_int",periph.irqcount-1,0),vi("wrdata_reg",periph.irqcount-1,0));}; ["extra_code"]={va(vi("eic_idr_int",periph.irqcount-1,0),vi("wrdata_reg",periph.irqcount-1,0));};
["no_std_regbank"]=true; ["no_std_regbank"]=true;
}; };
local n={["__type"]=TYPE_REG; local i={["__type"]=TYPE_REG;
["__blockindex"]=1000001; ["__blockindex"]=1000001;
["align"]=1; ["align"]=1;
["name"]="Interrupt enable register"; ["name"]="Interrupt enable register";
...@@ -2960,7 +3012,7 @@ signal(BIT,0,"eic_ier_write_int");}; ...@@ -2960,7 +3012,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 a={["__type"]=TYPE_REG; local n={["__type"]=TYPE_REG;
["__blockindex"]=1000002; ["__blockindex"]=1000002;
["align"]=1; ["align"]=1;
["name"]="Interrupt status register"; ["name"]="Interrupt status register";
...@@ -3049,18 +3101,18 @@ end ...@@ -3049,18 +3101,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(i,h); table.insert(a,h);
table.insert(a,o); table.insert(n,o);
table.insert(s,t); table.insert(s,t);
table.insert(n,r); table.insert(i,r);
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,a);
table.insert(periph,i); table.insert(periph,i);
table.insert(periph,n);
table.insert(periph,s); table.insert(periph,s);
table.insert(periph,a); table.insert(periph,n);
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");
...@@ -3076,12 +3128,12 @@ vpm("reg_isr_i","eic_isr_clear_int"); ...@@ -3076,12 +3128,12 @@ vpm("reg_isr_i","eic_isr_clear_int");
vpm("reg_isr_wr_stb_i","eic_isr_write_int"); 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 a;
for o,a in ipairs(o)do for o,t 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",t.index),t.trigger)});
t=o; a=o;
end end
for t=t,31 do for t=a,31 do
table_join(e,{vgm(string.format("g_irq%02x_mode",t),0)}); table_join(e,{vgm(string.format("g_irq%02x_mode",t),0)});
end end
local t={vinstance("eic_irq_controller_inst","wbgen2_eic",e);}; local t={vinstance("eic_irq_controller_inst","wbgen2_eic",e);};
...@@ -3410,38 +3462,38 @@ gen_wishbone_signals(); ...@@ -3410,38 +3462,38 @@ 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 o={};
local i={}; local i={};
local o={};
local n={}; local n={};
foreach_field(function(e,t) foreach_field(function(e,t)
table_join(o,e.reset_code_main); table_join(i,e.reset_code_main);
end); end);
foreach_reg(ALL_REG_TYPES,function(e) foreach_reg(ALL_REG_TYPES,function(e)
table_join(o,e.reset_code_main); table_join(i,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(i,e.ackgen_code); table_join(o,e.ackgen_code);
table_join(n,e.ackgen_code_pre); table_join(n,e.ackgen_code_pre);
end); end);
table_join(i,e.ackgen_code); table_join(o,e.ackgen_code);
table_join(n,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)
local n=find_max(t,"acklen"); local n=find_max(t,"acklen");
local a={};
local o={}; local o={};
foreach_subfield(t,function(e,t)table_join(o,e.write_code);end); local a={};
foreach_subfield(t,function(e,t)table_join(a,e.read_code);end); foreach_subfield(t,function(e,t)table_join(a,e.write_code);end);
foreach_subfield(t,function(e,t)table_join(o,e.read_code);end);
local i=fill_unused_bits("rddata_reg",t); local i=fill_unused_bits("rddata_reg",t);
table_join(o,t.write_code); table_join(a,t.write_code);
table_join(a,t.read_code); table_join(o,t.read_code);
local a={ local a={
vif(vequal("wb_we_i",1),{ vif(vequal("wb_we_i",1),{
o,
},{
a, a,
},{
o,
i i
});}; });};
if(not(t.dont_emit_ack_code==true))then if(not(t.dont_emit_ack_code==true))then
...@@ -3503,14 +3555,14 @@ vreset(0,{ ...@@ -3503,14 +3555,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);
o i
}); });
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),{i;va("ack_in_progress",0);},n); vif(vequal(vi("ack_sreg",0),1),{o;va("ack_in_progress",0);},n);
},{ },{
e e
}); });
......
...@@ -30,6 +30,9 @@ function gen_hdl_field_prefix(field, reg) ...@@ -30,6 +30,9 @@ function gen_hdl_field_prefix(field, reg)
end end
function gen_reset_value(field)
return csel(field.reset_value == nil, '0', field.reset_value)
end
-- generates VHDL for monostable-type field (both same-clock and other-clock) -- generates VHDL for monostable-type field (both same-clock and other-clock)
function gen_hdl_code_monostable(field, reg) function gen_hdl_code_monostable(field, reg)
local prefix = gen_hdl_field_prefix(field, reg); local prefix = gen_hdl_field_prefix(field, reg);
...@@ -57,8 +60,9 @@ function gen_hdl_code_monostable(field, reg) ...@@ -57,8 +60,9 @@ function gen_hdl_code_monostable(field, reg)
}); });
field.reset_code_main = { va(prefix.."_int", 0) }; field.reset_code_main = { va(prefix.."_int", 0) };
field.write_code = { va(prefix.."_int", vi("wrdata_reg", field.offset)) }; field.write_code = { va(prefix.."_int", vi("wrdata_reg", field.offset)),
field.read_code = { }; va(vi("rddata_reg", field.offset), vundefined()) };
field.read_code = { va(vi("rddata_reg", field.offset), vundefined()) };
field.ackgen_code = { va(prefix.."_int", 0) }; field.ackgen_code = { va(prefix.."_int", 0) };
else else
...@@ -96,10 +100,11 @@ function gen_hdl_code_monostable(field, reg) ...@@ -96,10 +100,11 @@ function gen_hdl_code_monostable(field, reg)
va(prefix.."_int_delay", 0); }; va(prefix.."_int_delay", 0); };
field.write_code = { va(prefix.."_int", vi("wrdata_reg", field.offset)); field.write_code = { va(vi("rddata_reg", field.offset), vundefined()),
va(prefix.."_int", vi("wrdata_reg", field.offset));
va(prefix.."_int_delay", vi("wrdata_reg", field.offset)); }; va(prefix.."_int_delay", vi("wrdata_reg", field.offset)); };
field.read_code = { }; field.read_code = { va(vi("rddata_reg", field.offset), vundefined())};
field.ackgen_code_pre = { va(prefix.."_int", prefix.."_int_delay"); field.ackgen_code_pre = { va(prefix.."_int", prefix.."_int_delay");
va(prefix.."_int_delay", 0); }; va(prefix.."_int_delay", 0); };
...@@ -121,7 +126,8 @@ function gen_hdl_code_bit(field, reg) ...@@ -121,7 +126,8 @@ function gen_hdl_code_bit(field, reg)
field.signals = { signal(BIT, 0, prefix.."_int") }; field.signals = { signal(BIT, 0, prefix.."_int") };
field.acklen = 1; field.acklen = 1;
field.write_code = { va(prefix.."_int", vi("wrdata_reg", field.offset)) }; field.write_code = { va(vi("rddata_reg", field.offset), vundefined()),
va(prefix.."_int", vi("wrdata_reg", field.offset)) };
field.read_code = { va(vi("rddata_reg", field.offset), prefix.."_int") }; field.read_code = { va(vi("rddata_reg", field.offset), prefix.."_int") };
field.reset_code_main = { va(prefix.."_int", 0) }; field.reset_code_main = { va(prefix.."_int", 0) };
field.extra_code = { va(prefix.."_o", prefix.."_int") }; field.extra_code = { va(prefix.."_o", prefix.."_int") };
...@@ -131,7 +137,7 @@ function gen_hdl_code_bit(field, reg) ...@@ -131,7 +137,7 @@ function gen_hdl_code_bit(field, reg)
field.ports = { port(BIT, 0, "in", prefix.."_i", "Port for BIT field: '"..field.name.."' in reg: '"..reg.name.."'", VPORT_REG) }; field.ports = { port(BIT, 0, "in", prefix.."_i", "Port for BIT field: '"..field.name.."' in reg: '"..reg.name.."'", VPORT_REG) };
field.signals = { }; field.signals = { };
field.acklen = 1; field.acklen = 1;
field.write_code = { }; field.write_code = { va(vi("rddata_reg", field.offset), vundefined()) };
field.read_code = { va(vi("rddata_reg", field.offset), prefix.."_i") }; field.read_code = { va(vi("rddata_reg", field.offset), prefix.."_i") };
field.reset_code_main = { }; field.reset_code_main = { };
field.extra_code = { }; field.extra_code = { };
...@@ -152,7 +158,8 @@ function gen_hdl_code_bit(field, reg) ...@@ -152,7 +158,8 @@ function gen_hdl_code_bit(field, reg)
field.acklen = 1; field.acklen = 1;
field.read_code = { va(vi("rddata_reg", field.offset), prefix.."_i") }; field.read_code = { va(vi("rddata_reg", field.offset), prefix.."_i") };
field.write_code = { va(prefix.."_load_o", 1) }; field.write_code = { va(vi("rddata_reg", field.offset), vundefined()),
va(prefix.."_load_o", 1) };
field.extra_code = { va(prefix.."_o", vi("wrdata_reg", field.offset)) }; field.extra_code = { va(prefix.."_o", vi("wrdata_reg", field.offset)) };
field.ackgen_code_pre = { va(prefix.."_load_o", 0) }; field.ackgen_code_pre = { va(prefix.."_load_o", 0) };
field.ackgen_code = { va(prefix.."_load_o", 0) }; field.ackgen_code = { va(prefix.."_load_o", 0) };
...@@ -173,7 +180,8 @@ function gen_hdl_code_bit(field, reg) ...@@ -173,7 +180,8 @@ function gen_hdl_code_bit(field, reg)
signal(BIT, 0, prefix.."_sync1") }; signal(BIT, 0, prefix.."_sync1") };
field.acklen = 4; field.acklen = 4;
field.write_code = { va(prefix.."_int", vi("wrdata_reg", field.offset)) }; field.write_code = { va(prefix.."_int", vi("wrdata_reg", field.offset)),
va(vi("rddata_reg", field.offset), vundefined()) };
field.read_code = { va(vi("rddata_reg", field.offset), prefix.."_int") }; field.read_code = { va(vi("rddata_reg", field.offset), prefix.."_int") };
field.reset_code_main = { va(prefix.."_int", 0) }; field.reset_code_main = { va(prefix.."_int", 0) };
...@@ -201,7 +209,7 @@ function gen_hdl_code_bit(field, reg) ...@@ -201,7 +209,7 @@ function gen_hdl_code_bit(field, reg)
signal(BIT, 0, prefix.."_sync1") }; signal(BIT, 0, prefix.."_sync1") };
field.acklen = 1; field.acklen = 1;
field.write_code = { }; field.write_code = { va(vi("rddata_reg", field.offset), vundefined()) };
field.read_code = { va(vi("rddata_reg", field.offset), prefix.."_sync1") }; field.read_code = { va(vi("rddata_reg", field.offset), prefix.."_sync1") };
field.reset_code_main = { }; field.reset_code_main = { };
...@@ -246,13 +254,15 @@ function gen_hdl_code_bit(field, reg) ...@@ -246,13 +254,15 @@ function gen_hdl_code_bit(field, reg)
field.acklen = 6; field.acklen = 6;
field.write_code = { va(prefix.."_int_write", vi("wrdata_reg", field.offset)); field.write_code = { va(vi("rddata_reg", field.offset), vundefined());
va(prefix.."_int_write", vi("wrdata_reg", field.offset));
va(prefix.."_lw", 1); va(prefix.."_lw", 1);
va(prefix.."_lw_delay", 1); va(prefix.."_lw_delay", 1);
va(prefix.."_lw_read_in_progress", 0); va(prefix.."_lw_read_in_progress", 0);
va(prefix.."_rwsel", 1); }; va(prefix.."_rwsel", 1); };
field.read_code = { va(prefix.."_lw", 1); field.read_code = { va(vi("rddata_reg", field.offset), vundefined());
va(prefix.."_lw", 1);
va(prefix.."_lw_delay", 1); va(prefix.."_lw_delay", 1);
va(prefix.."_lw_read_in_progress", 1); va(prefix.."_lw_read_in_progress", 1);
va(prefix.."_rwsel", 0); }; va(prefix.."_rwsel", 0); };
......
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