Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
Wishbone slave generator
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
24
Issues
24
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Wishbone slave generator
Commits
50e10c5b
Commit
50e10c5b
authored
Jan 28, 2013
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
TexInfo doc: use macro to define sections/subsections/chapters
parent
2113b3eb
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
581 additions
and
391 deletions
+581
-391
cgen_doc_texinfo.lua
cgen_doc_texinfo.lua
+2
-3
wbgen2
wbgen2
+579
-388
No files found.
cgen_doc_texinfo.lua
View file @
50e10c5b
...
...
@@ -32,8 +32,7 @@ end
function
cgen_tex_memmap
()
local
evenodd
=
0
;
local
n
=
2
;
emit
(
"@subsubsection Memory map summary"
);
emit
(
"@regsection Memory map summary"
);
emit
(
"@multitable @columnfractions .10 .15 .15 .55"
)
emit
(
"@headitem Address @tab Type @tab Prefix @tab Name"
)
...
...
@@ -80,7 +79,7 @@ end
function
cgen_texinfo_reg
(
reg
)
emit
(
"@
subsub
section @code{"
..
reg
.
c_prefix
..
"} - "
..
reg
.
name
);
emit
(
"@
reg
section @code{"
..
reg
.
c_prefix
..
"} - "
..
reg
.
name
);
cur_reg_no
=
cur_reg_no
+
1
;
...
...
wbgen2
View file @
50e10c5b
#!/usr/bin/env lua
package.preload
[
'alt_getopt'
]
=
(
function
(
...
)
local
o
,
r
,
u
,
i
,
a
=
type
,
pairs
,
ipairs
,
io
,
os
local
i
,
h
,
u
,
o
,
a
=
type
,
pairs
,
ipairs
,
io
,
os
module
(
"alt_getopt"
)
local
function
c
(
e
)
local
function
r
(
e
)
local
t
=
1
local
t
=#
e
local
t
=
{}
for
a
,
e
in
e
:
gmatch
(
"(%w)(:?)"
)
do
t
[
a
]
=#
e
for
e
,
a
in
e
:
gmatch
(
"(%w)(:?)"
)
do
t
[
e
]
=#
a
end
return
t
end
local
function
d
(
t
,
e
)
i
.
stderr
:
write
(
t
)
a
.
exit
(
e
)
local
function
d
(
e
,
t
)
o
.
stderr
:
write
(
e
)
a
.
exit
(
t
)
end
local
function
a
(
e
)
d
(
"Unknown option `-"
..
...
...
@@ -23,7 +23,7 @@ local function l(t,e)
if
not
t
[
e
]
then
a
(
e
)
end
while
o
(
t
[
e
])
==
"string"
do
while
i
(
t
[
e
])
==
"string"
do
e
=
t
[
e
]
if
not
t
[
e
]
then
a
(
e
)
...
...
@@ -31,13 +31,13 @@ end
end
return
e
end
function
get_ordered_opts
(
n
,
a
,
s
)
function
get_ordered_opts
(
n
,
o
,
a
)
local
t
=
1
local
e
=
1
local
i
=
{}
local
h
=
{}
local
o
=
c
(
a
)
for
e
,
t
in
r
(
s
)
do
local
s
=
{}
local
o
=
r
(
o
)
for
e
,
t
in
h
(
a
)
do
o
[
e
]
=
t
end
while
t
<=#
n
do
...
...
@@ -48,49 +48,49 @@ break
elseif
a
==
"-"
then
break
elseif
a
:
sub
(
1
,
2
)
==
"--"
then
local
s
=
a
:
find
(
"="
,
1
,
true
)
if
s
then
local
t
=
a
:
sub
(
3
,
s
-
1
)
local
h
=
a
:
find
(
"="
,
1
,
true
)
if
h
then
local
t
=
a
:
sub
(
3
,
h
-
1
)
t
=
l
(
o
,
t
)
if
o
[
t
]
==
0
then
d
(
"Bad usage of option `"
..
a
..
"'\n"
,
1
)
end
h
[
e
]
=
a
:
sub
(
s
+
1
)
s
[
e
]
=
a
:
sub
(
h
+
1
)
i
[
e
]
=
t
else
local
s
=
a
:
sub
(
3
)
s
=
l
(
o
,
s
)
if
o
[
s
]
==
0
then
i
[
e
]
=
s
local
h
=
a
:
sub
(
3
)
h
=
l
(
o
,
h
)
if
o
[
h
]
==
0
then
i
[
e
]
=
h
else
if
t
==#
n
then
d
(
"Missed value for option `"
..
a
..
"'\n"
,
1
)
end
h
[
e
]
=
n
[
t
+
1
]
i
[
e
]
=
s
s
[
e
]
=
n
[
t
+
1
]
i
[
e
]
=
h
t
=
t
+
1
end
end
e
=
e
+
1
elseif
a
:
sub
(
1
,
1
)
==
"-"
then
local
s
local
h
for
r
=
2
,
a
:
len
()
do
local
s
=
l
(
o
,
a
:
sub
(
r
,
r
))
if
o
[
s
]
==
0
then
i
[
e
]
=
s
local
h
=
l
(
o
,
a
:
sub
(
r
,
r
))
if
o
[
h
]
==
0
then
i
[
e
]
=
h
e
=
e
+
1
elseif
a
:
len
()
==
r
then
if
t
==#
n
then
d
(
"Missed value for option `-"
..
s
..
"'\n"
,
1
)
d
(
"Missed value for option `-"
..
h
..
"'\n"
,
1
)
end
h
[
e
]
=
n
[
t
+
1
]
i
[
e
]
=
s
s
[
e
]
=
n
[
t
+
1
]
i
[
e
]
=
h
t
=
t
+
1
e
=
e
+
1
break
else
h
[
e
]
=
a
:
sub
(
r
+
1
)
i
[
e
]
=
s
s
[
e
]
=
a
:
sub
(
r
+
1
)
i
[
e
]
=
h
e
=
e
+
1
break
end
...
...
@@ -100,14 +100,14 @@ break
end
t
=
t
+
1
end
return
i
,
t
,
h
return
i
,
t
,
s
end
function
get_opts
(
a
,
t
,
o
)
function
get_opts
(
t
,
a
,
o
)
local
e
=
{}
local
t
,
i
,
o
=
get_ordered_opts
(
a
,
t
,
o
)
for
a
,
t
in
u
(
t
)
do
if
o
[
a
]
then
e
[
t
]
=
o
[
a
]
local
t
,
i
,
a
=
get_ordered_opts
(
t
,
a
,
o
)
for
o
,
t
in
u
(
t
)
do
if
a
[
o
]
then
e
[
t
]
=
a
[
o
]
else
e
[
t
]
=
1
end
...
...
@@ -191,10 +191,10 @@ e=e+1;
end
return
e
;
end
function
calc_size
(
e
,
a
)
function
calc_size
(
e
,
t
)
if
(
e
.
type
==
MONOSTABLE
or
e
.
type
==
BIT
)
then
e
.
size
=
1
;
elseif
(
e
.
type
==
SLV
)
then
elseif
(
e
.
type
==
SLV
or
e
.
type
==
PASS_THROUGH
)
then
if
(
e
.
size
==
nil
)
then
die
(
"no size declared for SLV-type field '"
..
e
.
name
..
"'"
);
end
...
...
@@ -212,7 +212,7 @@ end
elseif
(
e
.
type
==
ENUM
)
then
die
(
"ENUM-type fields are not yet supported. Sorry :("
);
end
a
.
total_size
=
a
.
total_size
+
e
.
size
;
t
.
total_size
=
t
.
total_size
+
e
.
size
;
end
function
foreach_reg
(
a
,
t
,
e
)
if
(
e
==
nil
)
then
...
...
@@ -290,11 +290,21 @@ function inset(t,e)
for
a
,
e
in
ipairs
(
e
)
do
if
(
t
==
e
)
then
return
true
;
end
end
return
false
;
end
function
csel
(
e
,
t
,
a
)
if
(
e
)
then
return
t
;
else
function
csel
(
t
,
a
,
e
)
if
(
t
)
then
return
a
;
else
return
e
;
end
end
function
check_field_types
(
e
)
if
(
e
.
type
==
nil
)
then
die
(
"no type declared for field: "
..
e
.
name
);
end
end
function
check_obj_names_prefixes
(
e
)
if
(
e
.
name
==
nil
)
then
die
(
"no name declared for object: "
..
e
.
size
);
end
end
function
fix_prefix
(
e
)
...
...
@@ -308,13 +318,13 @@ return e;
end
return
e
;
end
function
default_access
(
e
,
o
,
a
,
t
)
if
(
e
.
type
==
o
)
then
function
default_access
(
e
,
t
,
a
,
o
)
if
(
e
.
type
==
t
)
then
if
(
e
.
access_bus
==
nil
)
then
e
.
access_bus
=
a
;
end
if
(
e
.
access_dev
==
nil
)
then
e
.
access_dev
=
t
;
e
.
access_dev
=
o
;
end
end
end
...
...
@@ -346,7 +356,7 @@ end
end
function
check_max_size
(
e
)
if
(
e
.
total_size
>
DATA_BUS_WIDTH
and
e
.
__type
==
TYPE_REG
)
then
die
(
"register "
,
e
.
name
,
" size exceeds data bus witdh ("
,
DATA_BUS_WIDTH
,
" bits)"
);
die
(
"register "
..
e
.
name
..
" size exceeds data bus witdh ("
..
DATA_BUS_WIDTH
..
" bits)"
);
end
end
all_regs_size
=
0
;
...
...
@@ -359,9 +369,9 @@ end
function
log2up
(
e
)
return
math.ceil
(
math.log
(
e
)
/
math.log
(
2
));
end
function
is_power_of_2
(
e
)
for
t
=
1
,
24
do
if
(
e
==
math.pow
(
2
,
t
))
then
return
true
;
end
function
is_power_of_2
(
t
)
for
e
=
1
,
24
do
if
(
t
==
math.pow
(
2
,
e
))
then
return
true
;
end
end
return
false
;
end
...
...
@@ -388,25 +398,25 @@ end
function
assign_addresses
()
local
o
=
math.max
(
max_ram_addr_bits
,
log2up
(
all_regs_size
));
local
e
=
num_rams
;
local
a
=
0
;
local
t
=
0
;
if
(
all_regs_size
>
0
)
then
e
=
e
+
1
;
end
local
t
=
log2up
(
e
);
local
a
=
log2up
(
e
);
foreach_reg
({
TYPE_REG
,
TYPE_FIFO
},
function
(
e
)
if
(
e
.
__type
==
TYPE_REG
)
then
e
.
base
=
align
(
e
,
a
);
a
=
e
.
base
+
1
;
e
.
base
=
align
(
e
,
t
);
t
=
e
.
base
+
1
;
end
end
);
address_bus_width
=
o
+
t
;
address_bus_select_bits
=
t
;
address_bus_width
=
o
+
a
;
address_bus_select_bits
=
a
;
end
function
find_max
(
e
,
t
)
local
a
=
0
;
function
find_max
(
e
,
a
)
local
t
=
0
;
local
o
,
o
;
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
a
;
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
return
t
;
end
function
table_join
(
t
,
e
)
local
a
,
a
;
...
...
@@ -438,10 +448,10 @@ end);
return
a
;
end
function
remove_duplicates
(
o
)
function
count_entries
(
a
,
t
)
function
count_entries
(
t
,
a
)
local
o
,
o
,
e
;
e
=
0
;
for
o
,
a
in
ipairs
(
a
)
do
if
(
a
==
t
)
then
e
=
e
+
1
;
end
end
for
o
,
t
in
ipairs
(
t
)
do
if
(
t
==
a
)
then
e
=
e
+
1
;
end
end
return
e
;
end
local
e
=
{};
...
...
@@ -455,37 +465,37 @@ return e;
end
function
wbgen_count_subblocks
()
local
t
=
0
;
local
o
=
0
;
local
a
=
0
;
local
e
=
0
;
local
o
=
0
;
foreach_reg
({
TYPE_RAM
},
function
(
e
)
t
=
t
+
1
;
end
);
foreach_reg
({
TYPE_REG
},
function
(
t
)
e
=
e
+
1
;
end
);
foreach_reg
({
TYPE_FIFO
},
function
(
e
)
a
=
a
+
1
;
end
);
foreach_reg
({
TYPE_IRQ
},
function
(
e
)
o
=
o
+
1
;
end
);
foreach_reg
({
TYPE_REG
},
function
(
e
)
a
=
a
+
1
;
end
);
foreach_reg
({
TYPE_FIFO
},
function
(
e
)
o
=
o
+
1
;
end
);
foreach_reg
({
TYPE_IRQ
},
function
(
t
)
e
=
e
+
1
;
end
);
periph
.
ramcount
=
t
;
periph
.
fifocount
=
a
;
periph
.
regcount
=
e
;
periph
.
irqcount
=
o
;
if
(
t
+
a
+
e
+
o
==
0
)
then
periph
.
fifocount
=
o
;
periph
.
regcount
=
a
;
periph
.
irqcount
=
e
;
if
(
t
+
o
+
a
+
e
==
0
)
then
die
(
"Can't generate an empty peripheral. Define some regs, RAMs, FIFOs or IRQs, please..."
);
end
end
function
deepcopy
(
i
)
local
t
=
{}
local
function
o
(
e
)
local
function
a
(
e
)
if
type
(
e
)
~=
"table"
then
return
e
elseif
t
[
e
]
then
return
t
[
e
]
end
local
a
=
{}
t
[
e
]
=
a
local
o
=
{}
t
[
e
]
=
o
for
t
,
e
in
pairs
(
e
)
do
a
[
o
(
t
)]
=
o
(
e
)
o
[
a
(
t
)]
=
a
(
e
)
end
return
setmetatable
(
a
,
getmetatable
(
e
))
return
setmetatable
(
o
,
getmetatable
(
e
))
end
return
o
(
i
)
return
a
(
i
)
end
function
va
(
t
,
a
)
local
e
=
{};
...
...
@@ -502,12 +512,12 @@ e.h=a;
e
.
l
=
o
;
return
e
;
end
function
vinstance
(
a
,
o
,
t
)
function
vinstance
(
a
,
t
,
o
)
local
e
=
{};
e
.
t
=
"instance"
;
e
.
name
=
a
;
e
.
component
=
o
;
e
.
maps
=
t
;
e
.
component
=
t
;
e
.
maps
=
o
;
return
e
;
end
function
vpm
(
t
,
a
)
...
...
@@ -524,26 +534,26 @@ e.to=t;
e
.
from
=
a
;
return
e
;
end
function
vcombprocess
(
t
,
a
)
function
vcombprocess
(
a
,
t
)
local
e
=
{};
e
.
t
=
"combprocess"
;
e
.
slist
=
t
;
e
.
code
=
a
;
e
.
slist
=
a
;
e
.
code
=
t
;
return
e
;
end
function
vsyncprocess
(
t
,
o
,
a
)
function
vsyncprocess
(
o
,
a
,
t
)
local
e
=
{};
e
.
t
=
"syncprocess"
;
e
.
clk
=
t
;
e
.
rst
=
o
;
e
.
code
=
a
;
e
.
clk
=
o
;
e
.
rst
=
a
;
e
.
code
=
t
;
return
e
;
end
function
vreset
(
a
,
t
)
function
vreset
(
t
,
a
)
local
e
=
{};
e
.
t
=
"reset"
;
e
.
level
=
a
;
e
.
code
=
t
;
e
.
level
=
t
;
e
.
code
=
a
;
return
e
;
end
function
vposedge
(
t
)
...
...
@@ -574,24 +584,31 @@ e.a=t;
e
.
b
=
a
;
return
e
;
end
function
vor
(
a
,
t
)
local
e
=
{};
e
.
t
=
"or"
;
e
.
a
=
a
;
e
.
b
=
t
;
return
e
;
end
function
vnot
(
t
)
local
e
=
{};
e
.
t
=
"not"
;
e
.
a
=
t
;
return
e
;
end
function
vswitch
(
a
,
t
)
function
vswitch
(
t
,
a
)
local
e
=
{};
e
.
t
=
"switch"
;
e
.
a
=
a
;
e
.
code
=
t
;
e
.
a
=
t
;
e
.
code
=
a
;
return
e
;
end
function
vcase
(
a
,
t
)
function
vcase
(
t
,
a
)
local
e
=
{};
e
.
t
=
"case"
;
e
.
a
=
a
;
e
.
code
=
t
;
e
.
a
=
t
;
e
.
code
=
a
;
return
e
;
end
function
vcasedefault
(
t
)
...
...
@@ -606,11 +623,11 @@ e.t="comment";
e
.
str
=
t
;
return
e
;
end
function
vsub
(
a
,
t
)
function
vsub
(
t
,
a
)
local
e
=
{};
e
.
t
=
"sub"
;
e
.
a
=
a
;
e
.
b
=
t
;
e
.
a
=
t
;
e
.
b
=
a
;
return
e
;
end
function
vothers
(
t
)
...
...
@@ -629,26 +646,23 @@ local e={}
e
.
t
=
"undefined"
;
return
e
;
end
function
signal
(
t
,
o
,
a
,
i
)
function
signal
(
a
,
o
,
i
,
t
)
local
e
=
{}
e
.
comment
=
i
;
e
.
type
=
t
;
e
.
comment
=
t
;
e
.
type
=
a
;
e
.
range
=
o
;
e
.
name
=
a
;
e
.
name
=
i
;
return
e
;
end
VPORT_WB
=
1
;
VPORT_REG
=
2
;
function
port
(
s
,
a
,
n
,
i
,
o
,
t
)
function
port
(
s
,
o
,
i
,
a
,
n
,
t
)
local
e
=
{}
e
.
comment
=
o
;
e
.
comment
=
n
;
e
.
type
=
s
;
if
(
e
.
type
==
SLV
and
a
==
1
)
then
e
.
type
=
BIT
;
end
e
.
range
=
a
;
e
.
name
=
i
;
e
.
dir
=
n
;
e
.
range
=
o
;
e
.
name
=
a
;
e
.
dir
=
i
;
if
(
t
~=
nil
)
then
if
(
t
==
VPORT_WB
)
then
e
.
is_wb
=
true
;
...
...
@@ -758,7 +772,7 @@ if(e==nil)then
die
(
"can't open "
..
t
..
" for writing."
);
end
foreach_reg
({
TYPE_REG
},
function
(
a
)
e
.
write
(
e
,
string.format
(
"`define %-30s %d'h%x\n"
,
"ADDR_"
..
string.upper
(
periph
.
hdl_prefix
..
"_"
..
a
.
hdl
_prefix
),
address_bus_width
+
2
,(
DATA_BUS_WIDTH
/
8
)
*
a
.
base
));
e
.
write
(
e
,
string.format
(
"`define %-30s %d'h%x\n"
,
"ADDR_"
..
string.upper
(
periph
.
c_prefix
..
"_"
..
a
.
c
_prefix
),
address_bus_width
+
2
,(
DATA_BUS_WIDTH
/
8
)
*
a
.
base
));
foreach_subfield
(
a
,
function
(
t
)
if
(
t
.
c_prefix
~=
nil
)
then
e
.
write
(
e
,
string.format
(
"`define %s_%s_%s_OFFSET %d\n"
,
string.upper
(
periph
.
c_prefix
),
string.upper
(
a
.
c_prefix
),
string.upper
(
t
.
c_prefix
),
t
.
offset
));
...
...
@@ -769,8 +783,8 @@ end);
foreach_reg
({
TYPE_RAM
},
function
(
t
)
local
a
=
t
.
select_bits
*
math.pow
(
2
,
address_bus_width
-
address_bus_select_bits
);
e
.
write
(
e
,
string.format
(
"`define %-30s %d'h%x\n"
,
"BASE_"
..
string.upper
(
periph
.
hdl_prefix
..
"_"
..
t
.
hdl
_prefix
),
address_bus_width
+
2
,(
DATA_BUS_WIDTH
/
8
)
*
a
));
e
.
write
(
e
,
string.format
(
"`define %-30s 32'h%x\n"
,
"SIZE_"
..
string.upper
(
periph
.
hdl_prefix
..
"_"
..
t
.
hdl
_prefix
),
t
.
size
));
e
.
write
(
e
,
string.format
(
"`define %-30s %d'h%x\n"
,
"BASE_"
..
string.upper
(
periph
.
c_prefix
..
"_"
..
t
.
c
_prefix
),
address_bus_width
+
2
,(
DATA_BUS_WIDTH
/
8
)
*
a
));
e
.
write
(
e
,
string.format
(
"`define %-30s 32'h%x\n"
,
"SIZE_"
..
string.upper
(
periph
.
c_prefix
..
"_"
..
t
.
c
_prefix
),
t
.
size
));
end
);
io.close
(
e
);
end
...
...
@@ -781,23 +795,23 @@ fieldtype_2_vhdl[SIGNED]="signed";
fieldtype_2_vhdl
[
UNSIGNED
]
=
"unsigned"
;
fieldtype_2_vhdl
[
ENUM
]
=
"std_logic_vector"
;
fieldtype_2_vhdl
[
SLV
]
=
"std_logic_vector"
;
function
gen_vhdl_bin_literal
(
i
,
a
)
if
(
a
==
1
)
then
function
gen_vhdl_bin_literal
(
i
,
o
)
if
(
o
==
1
)
then
return
string.format
(
"'%d'"
,
csel
(
i
==
0
,
0
,
1
));
end
local
t
=
'
\"
'
;
local
s
,
o
,
n
,
e
;
o
=
i
;
e
=
math.pow
(
2
,
a
-
1
);
local
s
,
a
,
n
,
e
;
a
=
i
;
e
=
math.pow
(
2
,
o
-
1
);
if
(
i
==
nil
)
then
for
e
=
1
,
a
do
for
e
=
1
,
o
do
t
=
t
..
"X"
;
end
else
for
a
=
1
,
a
do
n
=
math.floor
(
o
/
e
);
for
o
=
1
,
o
do
n
=
math.floor
(
a
/
e
);
t
=
t
..
csel
(
n
>
0
,
"1"
,
"0"
);
o
=
o
%
e
;
a
=
a
%
e
;
e
=
e
/
2
;
end
end
...
...
@@ -834,6 +848,7 @@ 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;"
);
emit
(
"function f_x_to_zero (x:std_logic_vector) return std_logic_vector;"
);
indent_left
();
indent_left
();
emit
(
"end package;"
);
...
...
@@ -847,6 +862,18 @@ emit("else");
emit
(
"return x;"
);
emit
(
"end if; "
);
emit
(
"end function;"
);
emit
(
"function f_x_to_zero (x:std_logic_vector) return std_logic_vector is"
);
emit
(
"variable tmp: std_logic_vector(x'length-1 downto 0);"
);
emit
(
"begin"
);
emit
(
"for i in 0 to x'length-1 loop"
);
emit
(
"if(x(i) = 'X' or x(i) = 'U') then"
);
emit
(
"tmp(i):= '0';"
);
emit
(
"else"
);
emit
(
"tmp(i):=x(i);"
);
emit
(
"end if; "
);
emit
(
"end loop; "
);
emit
(
"return tmp;"
);
emit
(
"end function;"
);
emit
(
"function \"
or
\
" (left, right: "
..
e
..
") return "
..
e
..
" is"
);
emit
(
"variable tmp: "
..
e
..
";"
);
emit
(
"begin"
);
...
...
@@ -854,45 +881,46 @@ 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
..
"
;"
);
emit
(
"tmp."
..
e
..
" :=
f_x_to_zero(left."
..
e
..
") or f_x_to_zero(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"
);
function
cgen_vhdl_port_struct
(
o
)
emit
(
"type t_"
..
periph
.
hdl_prefix
..
"_"
..
o
..
"_registers is record"
);
indent_right
();
local
e
=
{};
for
a
=
1
,
table
.
getn
(
g_portlist
)
do
local
a
=
g_portlist
[
a
];
if
(
a
.
is_reg_port
==
true
and
a
.
dir
==
t
)
then
table.insert
(
e
,
a
);
local
a
=
{};
for
e
=
1
,
table
.
getn
(
g_portlist
)
do
local
e
=
g_portlist
[
e
];
if
(
e
.
is_reg_port
==
true
and
e
.
dir
==
o
)
then
table.insert
(
a
,
e
);
end
end
for
e
,
t
in
ipairs
(
e
)
do
local
e
=
string.format
(
"%-40s : %s"
,
strip_periph_prefix
(
t
.
name
),
fieldtype_2_vhdl
[
t
.
type
]);
if
(
t
.
range
>
1
)
then
e
=
e
..
"("
..
(
t
.
range
-
1
)
..
" downto 0)"
;
for
t
,
e
in
ipairs
(
a
)
do
local
t
=
csel
(
e
.
type
==
SLV
and
e
.
range
==
1
,
"std_logic"
,
fieldtype_2_vhdl
[
e
.
type
]);
local
t
=
string.format
(
"%-40s : %s"
,
strip_periph_prefix
(
e
.
name
),
t
);
if
(
e
.
range
>
1
)
then
t
=
t
..
"("
..
(
e
.
range
-
1
)
..
" downto 0)"
;
end
e
=
e
..
";"
;
emit
(
e
);
t
=
t
..
";"
;
emit
(
t
);
end
emit
(
"end record;"
);
indent_left
();
emit
(
""
);
emit
(
"constant c_"
..
periph
.
hdl_prefix
..
"_"
..
t
..
"_registers_init_value: t_"
..
periph
.
hdl_prefix
..
"_"
..
t
..
"_registers := ("
);
emit
(
"constant c_"
..
periph
.
hdl_prefix
..
"_"
..
o
..
"_registers_init_value: t_"
..
periph
.
hdl_prefix
..
"_"
..
o
..
"_registers := ("
);
indent_right
();
for
t
=
1
,
table
.
getn
(
e
)
do
local
a
=
e
[
t
];
line
=
strip_periph_prefix
(
a
.
name
)
..
" => "
;
if
(
a
.
range
>
1
)
then
for
t
=
1
,
table
.
getn
(
a
)
do
local
e
=
a
[
t
];
line
=
strip_periph_prefix
(
e
.
name
)
..
" => "
;
if
(
e
.
range
>
1
)
then
line
=
line
..
"(others => '0')"
else
line
=
line
..
"'0'"
end
if
(
t
~=
table
.
getn
(
e
))
then
if
(
t
~=
table
.
getn
(
a
))
then
line
=
line
..
","
;
end
emit
(
line
);
...
...
@@ -936,8 +964,9 @@ if(options.hdl_reg_style=="signals"or not e.is_reg_port)then
if
(
e
.
comment
~=
nil
and
e
.
comment
~=
""
)
then
emitx
(
"-- "
..
e
.
comment
..
"
\n
"
);
end
print
(
e
.
name
..
" "
..
e
.
type
)
local
t
=
string.format
(
"%-40s : %-6s %s"
,
e
.
name
,
e
.
dir
,
fieldtype_2_vhdl
[
e
.
type
]);
if
(
e
.
range
>
1
)
then
if
(
e
.
range
>
1
or
e
.
type
==
SLV
)
then
t
=
t
..
"("
..
(
e
.
range
-
1
)
..
" downto 0)"
;
end
t
=
t
..
csel
((
a
==
table
.
getn
(
g_portlist
))
and
not
(
options
.
hdl_reg_style
==
"record"
),
""
,
";"
);
...
...
@@ -1165,13 +1194,13 @@ indent_right();recurse(e.code);indent_left();
emit
(
"end if;"
);
end
end
function
cgen_vhdl_not
(
e
)
local
t
=
node_typesize
(
e
.
a
);
function
cgen_vhdl_not
(
t
)
local
e
=
node_typesize
(
t
.
a
);
emitx
(
"not "
);
if
(
t
.
type
==
EXPRESSION
)
then
emitx
(
"("
);
recurse
({
e
.
a
});
emitx
(
")"
);
if
(
e
.
type
==
EXPRESSION
)
then
emitx
(
"("
);
recurse
({
t
.
a
});
emitx
(
")"
);
else
emitx
(
gen_subrange
(
t
));
emitx
(
gen_subrange
(
e
));
end
end
function
cgen_vhdl_binary_op
(
t
)
...
...
@@ -1390,7 +1419,7 @@ function cgen_verilog_ending()
indent_left
();
emit
(
"endmodule"
);
end
function
cgen_generate_verilog_code
(
i
)
function
cgen_generate_verilog_code
(
n
)
local
a
=
false
;
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
...
...
@@ -1547,23 +1576,23 @@ emitx(gen_subrange(e));
end
end
function
cgen_verilog_binary_op
(
e
)
local
a
=
node_typesize
(
e
.
a
);
local
o
=
node_typesize
(
e
.
b
);
local
o
=
node_typesize
(
e
.
a
);
local
a
=
node_typesize
(
e
.
b
);
local
t
=
e
.
t
;
if
(
a
.
type
==
EXPRESSION
)
then
if
(
o
.
type
==
EXPRESSION
)
then
emitx
(
"("
);
recurse
({
e
.
a
});
emitx
(
")"
);
else
emitx
(
gen_subrange
(
a
));
emitx
(
gen_subrange
(
o
));
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
if
(
a
.
type
==
EXPRESSION
)
then
emitx
(
"("
);
recurse
({
e
.
b
});
emitx
(
")"
);
else
emitx
(
gen_subrange
(
o
));
emitx
(
gen_subrange
(
a
));
end
end
function
cgen_verilog_comment
(
e
)
...
...
@@ -1595,29 +1624,29 @@ end
end
emit
(
"endcase"
);
end
function
cgen_verilog_instance
(
t
)
local
a
=
0
;
function
cgen_verilog_instance
(
a
)
local
o
=
0
;
local
i
=
0
;
local
e
;
emitx
(
t
.
component
..
" "
);
for
t
,
e
in
pairs
(
t
.
maps
)
do
emitx
(
a
.
component
..
" "
);
for
t
,
e
in
pairs
(
a
.
maps
)
do
if
(
e
.
t
==
"genmap"
)
then
o
=
o
+
1
;
i
=
i
+
1
;
elseif
(
e
.
t
==
"portmap"
)
then
a
=
a
+
1
;
o
=
o
+
1
;
end
end
if
(
o
>
0
)
then
if
(
i
>
0
)
then
indent_right
();
emit
(
"# ("
);
indent_right
();
e
=
1
;
for
t
,
a
in
pairs
(
t
.
maps
)
do
for
t
,
a
in
pairs
(
a
.
maps
)
do
if
(
a
.
t
==
"genmap"
)
then
local
t
=
a
.
from
;
if
(
t
==
"true"
)
then
t
=
1
;
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
;
end
end
...
...
@@ -1625,15 +1654,15 @@ indent_left();
emit
(
")"
);
indent_left
();
end
if
(
a
>
0
)
then
if
(
o
>
0
)
then
indent_right
();
emit
(
t
.
name
..
" ( "
);
emit
(
a
.
name
..
" ( "
);
indent_right
();
e
=
1
;
for
o
,
t
in
pairs
(
t
.
maps
)
do
for
a
,
t
in
pairs
(
a
.
maps
)
do
if
(
t
.
t
==
"portmap"
)
then
local
o
=
node_typesize
(
t
.
from
);
emit
(
string.format
(
".%-20s(%s)"
,
t
.
to
,
gen_subrange
(
o
))
..
csel
(
e
==
a
,
""
,
","
));
local
a
=
node_typesize
(
t
.
from
);
emit
(
string.format
(
".%-20s(%s)"
,
t
.
to
,
gen_subrange
(
a
))
..
csel
(
e
==
o
,
""
,
","
));
e
=
e
+
1
;
end
end
...
...
@@ -1700,17 +1729,17 @@ end
end
cgen_new_snippet
();
cgen_verilog_header
();
local
t
=
cgen_get_snippet
();
local
a
=
cgen_get_snippet
();
cgen_new_snippet
();
recurse
(
i
);
recurse
(
n
);
cgen_verilog_ending
();
local
e
=
cgen_get_snippet
();
local
t
=
cgen_get_snippet
();
cgen_new_snippet
();
cgen_verilog_module
();
local
a
=
cgen_get_snippet
();
cgen_write_snippet
(
t
);
local
e
=
cgen_get_snippet
();
cgen_write_snippet
(
a
);
cgen_write_snippet
(
e
);
cgen_write_snippet
(
t
);
end
function
cgen_c_field_define
(
e
,
a
)
local
t
;
...
...
@@ -1737,6 +1766,7 @@ end
function
cgen_c_ramdefs
(
e
)
local
t
=
string.upper
(
periph
.
c_prefix
)
..
"_"
..
string.upper
(
e
.
c_prefix
);
emit
(
"/* definitions for RAM: "
..
e
.
name
..
" */"
);
emit
(
string.format
(
"#define "
..
t
..
"_BASE 0x%08x %-50s"
,
e
.
base
*
DATA_BUS_WIDTH
/
8
,
"/* base address */"
));
emit
(
string.format
(
"#define "
..
t
..
"_BYTES 0x%08x %-50s"
,
e
.
size
*
e
.
width
/
8
,
"/* size in bytes */"
));
emit
(
string.format
(
"#define "
..
t
..
"_WORDS 0x%08x %-50s"
,
e
.
size
,
"/* size in "
..
e
.
width
..
"-bit words, 32-bit aligned */"
));
end
...
...
@@ -1882,21 +1912,21 @@ end
end
return
e
;
end
function
htable_tdstyle
(
a
,
t
,
e
)
tbl
.
data
[
a
][
t
].
style
=
e
;
function
htable_tdstyle
(
e
,
a
,
t
)
tbl
.
data
[
e
][
a
].
style
=
t
;
end
function
htable_trstyle
(
t
,
a
,
e
)
tbl
.
data
[
t
].
style
=
e
;
function
htable_trstyle
(
e
,
a
,
t
)
tbl
.
data
[
e
].
style
=
t
;
end
function
htable_frame
(
e
,
t
,
a
,
o
)
if
(
o
==
nil
)
then
e
.
data
[
t
][
a
].
extra
=
'style="border: solid 1px black;"'
;
function
htable_frame
(
a
,
o
,
t
,
e
)
if
(
e
==
nil
)
then
a
.
data
[
o
][
t
].
extra
=
'style="border: solid 1px black;"'
;
else
e
.
data
[
t
][
a
].
extra
=
'style="border-left: 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
(
o
>
a
+
1
)
then
for
a
=
a
+
1
,
o
-
1
do
e
.
data
[
t
][
a
].
extra
=
'border-top: solid 1px black; border-bottom: solid 1px black;'
;
a
.
data
[
o
][
t
].
extra
=
'style="border-left: solid 1px black; border-top: solid 1px black; border-bottom: solid 1px black;'
;
a
.
data
[
o
][
e
].
extra
=
'style="border-right: solid 1px black; border-top: solid 1px black; border-bottom: solid 1px black;'
;
if
(
e
>
t
+
1
)
then
for
e
=
t
+
1
,
e
-
1
do
a
.
data
[
o
][
e
].
extra
=
'border-top: solid 1px black; border-bottom: solid 1px black;'
;
end
end
end
...
...
@@ -1952,27 +1982,27 @@ end
e
.
rows
=
a
;
end
end
function
hlink
(
e
,
t
)
return
'<A href="'
..
e
..
'">'
..
t
..
'</a>'
;
function
hlink
(
t
,
e
)
return
'<A href="'
..
t
..
'">'
..
e
..
'</a>'
;
end
function
hitem
(
e
)
return
'<li>'
..
e
..
'</li>'
;
end
function
hanchor
(
t
,
e
)
return
'<a name="'
..
t
..
'">'
..
e
..
'</a>'
;
function
hanchor
(
e
,
t
)
return
'<a name="'
..
e
..
'">'
..
t
..
'</a>'
;
end
doc_toc
=
{};
function
hsection
(
a
,
t
,
o
)
function
hsection
(
t
,
a
,
o
)
local
e
=
{};
local
i
=
0
;
e
.
id_mangled
=
"sect_"
..
a
..
"_"
..
t
;
e
.
key
=
a
*
1e3
+
t
;
if
(
t
~=
0
)
then
e
.
id_mangled
=
"sect_"
..
t
..
"_"
..
a
;
e
.
key
=
t
*
1e3
+
a
;
if
(
a
~=
0
)
then
e
.
level
=
2
;
e
.
id
=
a
..
"."
..
t
..
"."
;
e
.
id
=
t
..
"."
..
a
..
"."
;
else
e
.
level
=
1
;
e
.
id
=
a
..
"."
;
e
.
id
=
t
..
"."
;
end
e
.
name
=
o
;
table.insert
(
doc_toc
,
e
);
...
...
@@ -2021,23 +2051,23 @@ end
end
);
cgen_doc_symbol
(
t
);
end
function
cgen_doc_mem_symbol
(
t
)
local
e
=
{};
for
t
,
a
in
pairs
(
t
.
ports
)
do
local
t
=
a
;
function
cgen_doc_mem_symbol
(
e
)
local
t
=
{};
for
e
,
a
in
pairs
(
e
.
ports
)
do
local
e
=
a
;
if
(
string.find
(
a
.
name
,
"_i"
)
~=
nil
)
then
t
.
is_wb
=
true
;
e
.
is_wb
=
true
;
else
t
.
is_wb
=
false
;
e
.
is_wb
=
false
;
end
table.insert
(
e
,
t
);
table.insert
(
t
,
e
);
end
if
(
t
.
clock
~=
nil
)
then
local
t
=
port
(
BIT
,
0
,
"in"
,
t
.
clock
);
t
.
is_wb
=
true
;
table.insert
(
e
,
t
);
if
(
e
.
clock
~=
nil
)
then
local
e
=
port
(
BIT
,
0
,
"in"
,
e
.
clock
);
e
.
is_wb
=
true
;
table.insert
(
t
,
e
);
end
cgen_doc_symbol
(
e
);
cgen_doc_symbol
(
t
);
end
function
cgen_doc_symbol
(
o
)
local
t
=
htable_new
(
3
,
5
);
...
...
@@ -2101,11 +2131,11 @@ emit('<span style="margin-left: '..((e.level-1)*20)..'px; ">'..e.id.." "..hlink(
end
end
function
cgen_doc_memmap
()
local
o
=
0
;
local
i
=
0
;
local
a
=
2
;
emit
(
hsection
(
1
,
0
,
"Memory map summary"
));
local
i
=
htable_new
(
1
,
5
);
local
e
=
i
.
data
[
1
];
local
o
=
htable_new
(
1
,
5
);
local
e
=
o
.
data
[
1
];
e
.
is_header
=
true
;
e
[
1
].
text
=
"H/W Address"
e
[
2
].
text
=
"Type"
;
...
...
@@ -2114,9 +2144,9 @@ e[4].text="VHDL/Verilog prefix";
e
[
5
].
text
=
"C prefix"
;
foreach_reg
({
TYPE_REG
},
function
(
t
)
if
(
t
.
full_hdl_prefix
~=
nil
)
then
htable_add_row
(
i
,
a
);
local
e
=
i
.
data
[
a
];
a
=
a
+
1
;
e
.
style
=
csel
(
o
,
"tr_odd"
,
"tr_even"
);
htable_add_row
(
o
,
a
);
local
e
=
o
.
data
[
a
];
a
=
a
+
1
;
e
.
style
=
csel
(
i
,
"tr_odd"
,
"tr_even"
);
e
[
1
].
style
=
"td_code"
;
e
[
1
].
text
=
string.format
(
"0x%x"
,
t
.
base
);
if
(
t
.
doc_is_fiforeg
==
nil
)
then
...
...
@@ -2129,48 +2159,48 @@ e[4].style="td_code";
e
[
4
].
text
=
t
.
full_hdl_prefix
;
e
[
5
].
style
=
"td_code"
;
e
[
5
].
text
=
string.upper
(
t
.
c_prefix
);
o
=
not
o
;
i
=
not
i
;
end
end
);
foreach_reg
({
TYPE_RAM
},
function
(
t
)
if
(
t
.
full_hdl_prefix
~=
nil
)
then
htable_add_row
(
i
,
a
);
local
e
=
i
.
data
[
a
];
a
=
a
+
1
;
e
.
style
=
csel
(
o
,
"tr_odd"
,
"tr_even"
);
e
[
1
].
style
=
"td_code"
;
e
[
1
].
text
=
string.format
(
"0x%x - 0x%x"
,
t
.
base
,
t
.
base
+
math.pow
(
2
,
t
.
wrap_bits
)
*
t
.
size
-
1
);
e
[
2
].
text
=
"MEM"
;
e
[
3
].
text
=
hlink
(
"#"
..
string.upper
(
t
.
c_prefix
),
t
.
name
);
e
[
4
].
style
=
"td_code"
;
e
[
4
].
text
=
t
.
full_hdl_prefix
;
e
[
5
].
style
=
"td_code"
;
e
[
5
].
text
=
string.upper
(
t
.
c_prefix
);
o
=
not
o
;
foreach_reg
({
TYPE_RAM
},
function
(
e
)
if
(
e
.
full_hdl_prefix
~=
nil
)
then
htable_add_row
(
o
,
a
);
local
t
=
o
.
data
[
a
];
a
=
a
+
1
;
t
.
style
=
csel
(
i
,
"tr_odd"
,
"tr_even"
);
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
[
2
].
text
=
"MEM"
;
t
[
3
].
text
=
hlink
(
"#"
..
string.upper
(
e
.
c_prefix
),
e
.
name
);
t
[
4
].
style
=
"td_code"
;
t
[
4
].
text
=
e
.
full_hdl_prefix
;
t
[
5
].
style
=
"td_code"
;
t
[
5
].
text
=
string.upper
(
e
.
c_prefix
);
i
=
not
i
;
end
end
);
htable_emit
(
i
);
htable_emit
(
o
);
end
function
find_field_by_offset
(
e
,
a
)
local
t
=
nil
;
foreach_subfield
(
e
,
function
(
e
)
if
(
a
>=
e
.
offset
and
a
<=
(
e
.
offset
+
e
.
size
-
1
))
then
t
=
e
;
end
end
);
return
t
;
function
find_field_by_offset
(
e
,
t
)
local
a
=
nil
;
foreach_subfield
(
e
,
function
(
e
)
if
(
t
>=
e
.
offset
and
t
<=
(
e
.
offset
+
e
.
size
-
1
))
then
a
=
e
;
end
end
);
return
a
;
end
function
cgen_doc_fieldtable
(
h
,
i
)
local
e
=
70
;
local
e
;
local
t
=
1
;
e
=
htable_new
(
2
,
8
);
for
t
=
1
,
8
do
e
.
data
[
1
][
t
].
style
=
"td_bit"
;
e
.
data
[
1
][
t
].
text
=
string.format
(
"%d"
,
i
+
8
-
t
);
local
t
;
local
e
=
1
;
t
=
htable_new
(
2
,
8
);
for
e
=
1
,
8
do
t
.
data
[
1
][
e
].
style
=
"td_bit"
;
t
.
data
[
1
][
e
].
text
=
string.format
(
"%d"
,
i
+
8
-
e
);
end
local
a
=
i
+
7
;
while
(
a
>=
i
)
do
local
o
=
find_field_by_offset
(
h
,
a
);
if
(
o
==
nil
)
then
e
.
data
[
2
][
t
].
style
=
"td_unused"
;
e
.
data
[
2
][
t
].
text
=
"-"
;
t
=
t
+
1
;
t
.
data
[
2
][
e
].
style
=
"td_unused"
;
t
.
data
[
2
][
e
].
text
=
"-"
;
e
=
e
+
1
;
a
=
a
-
1
;
else
local
n
;
...
...
@@ -2181,18 +2211,18 @@ n=o.offset;
end
local
s
=
(
a
-
n
)
+
1
;
dbg
(
"ncells: "
,
s
,
"bit: "
,
a
,
"name: "
,
o
.
prefix
);
e
.
data
[
2
][
t
].
colspan
=
s
;
t
.
data
[
2
][
e
].
colspan
=
s
;
local
i
;
i
=
o
.
c_prefix
;
if
(
i
==
nil
)
then
i
=
h
.
c_prefix
;
end
e
.
data
[
2
][
t
].
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
));
htable_frame
(
e
,
2
,
t
);
t
.
data
[
2
][
e
].
style
=
"td_field"
;
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
(
t
,
2
,
e
);
a
=
a
-
s
;
t
=
t
+
1
;
e
=
e
+
1
;
end
end
htable_emit
(
e
);
htable_emit
(
t
);
end
function
cgen_doc_access
(
e
)
if
(
e
==
READ_ONLY
)
then
...
...
@@ -2292,47 +2322,47 @@ emit("<p>"..string.gsub(t.description,"\n","<br>").."</p>");
end
end
cur_irq_no
=
1
;
function
cgen_doc_irq
(
t
)
emit
(
hanchor
(
string.upper
(
t
.
c_prefix
),
""
));
emit
(
hsection
(
5
,
cur_irq_no
,
t
.
name
));
function
cgen_doc_irq
(
e
)
emit
(
hanchor
(
string.upper
(
e
.
c_prefix
),
""
));
emit
(
hsection
(
5
,
cur_irq_no
,
e
.
name
));
cur_irq_no
=
cur_irq_no
+
1
;
local
e
=
htable_new
(
3
,
2
);
e
.
data
[
1
][
1
].
text
=
"<b>HW prefix: </b>"
;
e
.
data
[
2
][
1
].
text
=
"<b>C prefix: </b>"
;
e
.
data
[
3
][
1
].
text
=
"<b>Trigger: </b>"
;
e
.
data
[
1
][
2
].
text
=
string.lower
(
periph
.
hdl_prefix
..
"_"
..
t
.
hdl_prefix
);
e
.
data
[
2
][
2
].
text
=
string.upper
(
t
.
c_prefix
);
local
t
=
htable_new
(
3
,
2
);
t
.
data
[
1
][
1
].
text
=
"<b>HW prefix: </b>"
;
t
.
data
[
2
][
1
].
text
=
"<b>C prefix: </b>"
;
t
.
data
[
3
][
1
].
text
=
"<b>Trigger: </b>"
;
t
.
data
[
1
][
2
].
text
=
string.lower
(
periph
.
hdl_prefix
..
"_"
..
e
.
hdl_prefix
);
t
.
data
[
2
][
2
].
text
=
string.upper
(
e
.
c_prefix
);
local
a
=
{
[
EDGE_RISING
]
=
"rising edge"
;
[
EDGE_FALLING
]
=
"falling edge"
;
[
LEVEL_0
]
=
"low level"
;
[
LEVEL_1
]
=
"high level"
;
};
e
.
data
[
3
][
2
].
text
=
a
[
t
.
trigger
];
htable_emit
(
e
);
if
(
t
.
description
~=
nil
)
then
emit
(
"<p>"
..
string.gsub
(
t
.
description
,
"
\n
"
,
"<br>"
)
..
"</p>"
);
t
.
data
[
3
][
2
].
text
=
a
[
e
.
trigger
];
htable_emit
(
t
);
if
(
e
.
description
~=
nil
)
then
emit
(
"<p>"
..
string.gsub
(
e
.
description
,
"
\n
"
,
"<br>"
)
..
"</p>"
);
end
end
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
();
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
);
local
o
=
cgen_get_snippet
();
local
t
=
""
;
local
i
=
cgen_get_snippet
();
local
a
=
""
;
if
(
periph
.
ramcount
>
0
)
then
emit
(
hsection
(
4
,
0
,
"Memory blocks"
));
cgen_new_snippet
();
foreach_reg
({
TYPE_RAM
},
function
(
e
)
if
(
e
.
no_docu
==
nil
or
e
.
no_docu
==
false
)
then
cgen_doc_ram
(
e
);
end
end
);
t
=
cgen_get_snippet
();
a
=
cgen_get_snippet
();
end
local
a
=
""
;
local
t
=
""
;
if
(
periph
.
irqcount
>
0
)
then
cgen_new_snippet
();
emit
(
hsection
(
5
,
0
,
"Interrupts"
));
foreach_reg
({
TYPE_IRQ
},
function
(
e
)
if
(
e
.
no_docu
==
nil
or
e
.
no_docu
==
false
)
then
cgen_doc_irq
(
e
);
end
end
);
a
=
cgen_get_snippet
();
t
=
cgen_get_snippet
();
end
cgen_new_snippet
();
cgen_doc_memmap
();
...
...
@@ -2340,14 +2370,104 @@ local e=cgen_get_snippet();
cgen_new_snippet
();
cgen_doc_header_and_toc
();
emit
(
e
);
emit
(
i
);
emit
(
o
);
emit
(
t
);
emit
(
i
);
emit
(
a
);
emit
(
t
);
emit
(
'</BODY>'
);
emit
(
'</HTML>'
);
cgen_write_current_snippet
();
end
function
format_tex_string
(
e
)
e
=
string.gsub
(
e
,
" +"
,
" "
);
e
=
string.gsub
(
e
,
"^%-"
,
"@bullet{} "
);
e
=
string.gsub
(
e
,
"
\n
%-"
,
"@*@bullet{} "
);
e
=
string.gsub
(
e
,
"
\n
"
,
"@*"
);
e
=
string.gsub
(
e
,
"<b>"
,
"@b{"
);
e
=
string.gsub
(
e
,
"</b>"
,
"}"
);
e
=
string.gsub
(
e
,
"<i>"
,
"@b{"
);
e
=
string.gsub
(
e
,
"</i>"
,
"}"
);
e
=
string.gsub
(
e
,
"<code>"
,
"@code{"
);
e
=
string.gsub
(
e
,
"</code>"
,
"}"
);
return
e
end
function
cgen_tex_memmap
()
local
e
=
0
;
local
e
=
2
;
emit
(
"@regsection Memory map summary"
);
emit
(
"@multitable @columnfractions .10 .15 .15 .55"
)
emit
(
"@headitem Address @tab Type @tab Prefix @tab Name"
)
foreach_reg
({
TYPE_REG
},
function
(
e
)
if
(
e
.
full_hdl_prefix
~=
nil
)
then
emit
(
string.format
(
"@item @code{0x%x} @tab"
,
e
.
base
*
4
));
if
(
e
.
doc_is_fiforeg
==
nil
)
then
emit
(
"REG @tab"
);
else
emit
(
"FIFOREG @tab"
);
end
emit
(
"@code{"
..
e
.
c_prefix
..
"} @tab"
);
emit
(
e
.
name
);
end
end
);
foreach_reg
({
TYPE_RAM
},
function
(
e
)
if
(
e
.
full_hdl_prefix
~=
nil
)
then
emit
(
string.format
(
"@item @code{0x%x - 0x%x}"
,
e
.
base
,
e
.
base
+
math.pow
(
2
,
e
.
wrap_bits
)
*
e
.
size
-
1
));
emit
(
"@tab MEM @tab @code{"
..
e
.
c_prefix
..
"} @tab "
..
e
.
name
);
end
end
);
emit
(
"@end multitable "
)
end
function
cgen_tex_access
(
e
)
if
(
e
==
READ_ONLY
)
then
return
"R/O"
;
elseif
(
e
==
READ_WRITE
)
then
return
"R/W"
;
elseif
(
e
==
WRITE_ONLY
)
then
return
"W/O"
;
else
return
"FIXME!"
;
end
end
function
cgen_texinfo_reg
(
t
)
emit
(
"@regsection @code{"
..
t
.
c_prefix
..
"} - "
..
t
.
name
);
cur_reg_no
=
cur_reg_no
+
1
;
local
e
=
htable_new
(
4
,
2
);
if
(
t
.
description
~=
nil
)
then
emit
(
t
.
description
);
end
emit
(
"@multitable @columnfractions .10 .10 .15 .10 .55"
)
emit
(
"@headitem Bits @tab Access @tab Prefix @tab Default @tab Name"
)
foreach_subfield
(
t
,
function
(
e
)
if
(
e
.
size
==
1
)
then
emit
(
string.format
(
"@item @code{%d}"
,
e
.
offset
));
else
emit
(
string.format
(
"@item @code{%d...%d}"
,
e
.
offset
+
e
.
size
-
1
,
e
.
offset
));
end
emit
(
"@tab "
..
cgen_tex_access
(
e
.
access_bus
)
..
" @tab"
);
if
(
e
.
c_prefix
==
nil
)
then
emit
(
"@code{"
..
string.upper
(
t
.
c_prefix
)
..
"}"
);
else
emit
(
"@code{"
..
string.upper
(
e
.
c_prefix
)
..
"}"
);
end
emit
(
"@tab @code{X} @tab "
);
emit
(
e
.
name
);
end
);
emit
(
"@end multitable"
);
emit
(
"@multitable @columnfractions 0.15 0.85"
)
emit
(
"@headitem Field @tab Description"
)
foreach_subfield
(
t
,
function
(
e
)
if
(
e
.
description
~=
nil
)
then
pfx
=
csel
(
e
.
c_prefix
==
nil
,
t
.
c_prefix
,
e
.
c_prefix
)
emit
(
"@item @code{"
..
pfx
..
"} @tab "
..
format_tex_string
(
e
.
description
));
end
end
);
emit
(
"@end multitable"
);
end
function
cgen_generate_texinfo_documentation
()
cgen_new_snippet
();
cgen_tex_memmap
();
foreach_reg
({
TYPE_REG
},
function
(
e
)
if
(
e
.
no_docu
==
nil
or
e
.
no_docu
==
false
)
then
cgen_texinfo_reg
(
e
);
end
end
);
cgen_write_current_snippet
();
end
function
gen_hdl_field_prefix
(
a
,
e
)
local
t
;
if
(
e
.
hdl_prefix
==
nil
)
then
...
...
@@ -2374,7 +2494,7 @@ t.signals={signal(BIT,0,e.."_dly0"),
signal
(
BIT
,
0
,
e
..
"_int"
)};
t
.
ports
=
{
port
(
BIT
,
0
,
"out"
,
e
..
"_o"
,
"Port for MONOSTABLE field: '"
..
t
.
name
..
"' in reg: '"
..
a
.
name
..
"'"
,
VPORT_REG
)};
t
.
acklen
=
3
;
t
.
extra_code
=
vsyncprocess
(
"
bus_clock_int
"
,
"rst_n_i"
,{
t
.
extra_code
=
vsyncprocess
(
"
clk_sys_i
"
,
"rst_n_i"
,{
vreset
(
0
,{
va
(
e
..
"_dly0"
,
0
);
va
(
e
..
"_o"
,
0
);
...
...
@@ -2385,8 +2505,7 @@ va(e.."_o",vand(e.."_int",vnot(e.."_dly0")));
};
});
t
.
reset_code_main
=
{
va
(
e
..
"_int"
,
0
)};
t
.
write_code
=
{
va
(
e
..
"_int"
,
vi
(
"wrdata_reg"
,
t
.
offset
)),
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
())};
t
.
write_code
=
{
va
(
e
..
"_int"
,
vi
(
"wrdata_reg"
,
t
.
offset
))};
t
.
read_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
())};
t
.
ackgen_code
=
{
va
(
e
..
"_int"
,
0
)};
else
...
...
@@ -2415,7 +2534,7 @@ va(e.."_o",vand(e.."_sync2",vnot(e.."_sync1")));
});};
t
.
reset_code_main
=
{
va
(
e
..
"_int"
,
0
);
va
(
e
..
"_int_delay"
,
0
);};
t
.
write_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
()),
t
.
write_code
=
{
va
(
e
..
"_int"
,
vi
(
"wrdata_reg"
,
t
.
offset
));
va
(
e
..
"_int_delay"
,
vi
(
"wrdata_reg"
,
t
.
offset
));};
t
.
read_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
())};
...
...
@@ -2431,16 +2550,17 @@ 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
.
signals
=
{
signal
(
BIT
,
0
,
e
..
"_int"
)};
t
.
acklen
=
1
;
t
.
write_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
()),
t
.
write_code
=
{
va
(
e
..
"_int"
,
vi
(
"wrdata_reg"
,
t
.
offset
))};
t
.
read_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
e
..
"_int"
)};
t
.
reset_code_main
=
{
va
(
e
..
"_int"
,
0
)};
print
(
"RV: "
,
t
.
reset_value
)
t
.
reset_code_main
=
{
va
(
e
..
"_int"
,
csel
(
t
.
reset_value
==
nil
,
0
,
t
.
reset_value
))};
t
.
extra_code
=
{
va
(
e
..
"_o"
,
e
..
"_int"
)};
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
.
signals
=
{};
t
.
acklen
=
1
;
t
.
write_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
())
};
t
.
write_code
=
{};
t
.
read_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
e
..
"_i"
)};
t
.
reset_code_main
=
{};
t
.
extra_code
=
{};
...
...
@@ -2453,7 +2573,7 @@ port(BIT,0,"in",e.."_i",nil,VPORT_REG),
port
(
BIT
,
0
,
"out"
,
e
..
"_load_o"
,
nil
,
VPORT_REG
)};
t
.
acklen
=
1
;
t
.
read_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
e
..
"_i"
)};
t
.
write_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
()),
t
.
write_code
=
{
va
(
e
..
"_load_o"
,
1
)};
t
.
extra_code
=
{
va
(
e
..
"_o"
,
vi
(
"wrdata_reg"
,
t
.
offset
))};
t
.
ackgen_code_pre
=
{
va
(
e
..
"_load_o"
,
0
)};
...
...
@@ -2470,11 +2590,10 @@ t.signals={signal(BIT,0,e.."_int"),
signal
(
BIT
,
0
,
e
..
"_sync0"
),
signal
(
BIT
,
0
,
e
..
"_sync1"
)};
t
.
acklen
=
4
;
t
.
write_code
=
{
va
(
e
..
"_int"
,
vi
(
"wrdata_reg"
,
t
.
offset
)),
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
())};
t
.
write_code
=
{
va
(
e
..
"_int"
,
vi
(
"wrdata_reg"
,
t
.
offset
))};
t
.
read_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
e
..
"_int"
)};
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,
clk_sys_i
<-> "
..
t
.
clock
..
")"
);
vsyncprocess
(
t
.
clock
,
"rst_n_i"
,{
vreset
(
0
,{
va
(
e
..
"_o"
,
0
);
...
...
@@ -2493,10 +2612,10 @@ t.ports={port(BIT,0,"in",e.."_i","Port for asynchronous (clock: "..t.clock..") B
t
.
signals
=
{
signal
(
BIT
,
0
,
e
..
"_sync0"
),
signal
(
BIT
,
0
,
e
..
"_sync1"
)};
t
.
acklen
=
1
;
t
.
write_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
())
};
t
.
write_code
=
{};
t
.
read_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
e
..
"_sync1"
)};
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
..
" ->
clk_sys_i
)"
);
vsyncprocess
(
t
.
clock
,
"rst_n_i"
,{
vreset
(
0
,{
va
(
e
..
"_sync0"
,
0
);
...
...
@@ -2526,17 +2645,18 @@ signal(BIT,0,e.."_lw_s1"),
signal
(
BIT
,
0
,
e
..
"_lw_s2"
),
signal
(
BIT
,
0
,
e
..
"_rwsel"
)};
t
.
acklen
=
6
;
t
.
write_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
());
t
.
write_code
=
{
va
(
e
..
"_int_write"
,
vi
(
"wrdata_reg"
,
t
.
offset
));
va
(
e
..
"_lw"
,
1
);
va
(
e
..
"_lw_delay"
,
1
);
va
(
e
..
"_lw_read_in_progress"
,
0
);
va
(
e
..
"_rwsel"
,
1
);};
t
.
read_code
=
{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
());
t
.
read_code
=
{
vif
(
vequal
(
"wb_we_i"
,
0
),{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
vundefined
());
va
(
e
..
"_lw"
,
1
);
va
(
e
..
"_lw_delay"
,
1
);
va
(
e
..
"_lw_read_in_progress"
,
1
);
va
(
e
..
"_rwsel"
,
0
);};
va
(
e
..
"_rwsel"
,
0
);}
);}
;
t
.
reset_code_main
=
{
va
(
e
..
"_lw"
,
0
);
va
(
e
..
"_lw_delay"
,
0
);
va
(
e
..
"_lw_read_in_progress"
,
0
);
...
...
@@ -2550,7 +2670,7 @@ va(vi("rddata_reg",t.offset),e.."_int_read");
va
(
e
..
"_lw_read_in_progress"
,
0
);
});
};
t
.
extra_code
=
{
vcomment
(
"asynchronous BIT register : "
..
t
.
name
..
" (type RW/WO, "
..
t
.
clock
..
" <->
bus_clock_int
)"
);
t
.
extra_code
=
{
vcomment
(
"asynchronous BIT register : "
..
t
.
name
..
" (type RW/WO, "
..
t
.
clock
..
" <->
clk_sys_i
)"
);
vsyncprocess
(
t
.
clock
,
"rst_n_i"
,{
vreset
(
0
,{
va
(
e
..
"_lw_s0"
,
0
);
...
...
@@ -2646,7 +2766,7 @@ va(e.."_swb",0);
va
(
e
..
"_swb_delay"
,
0
);};
t
.
ackgen_code_pre
=
{
va
(
e
..
"_swb"
,
e
..
"_swb_delay"
);
va
(
e
..
"_swb_delay"
,
0
);};
t
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
t
.
type
]
..
" register : "
..
t
.
name
..
" (type RW/RO, "
..
t
.
clock
..
" <->
bus_clock_int
)"
);
t
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
t
.
type
]
..
" register : "
..
t
.
name
..
" (type RW/RO, "
..
t
.
clock
..
" <->
clk_sys_i
)"
);
vsyncprocess
(
t
.
clock
,
"rst_n_i"
,{
vreset
(
0
,{
va
(
e
..
"_swb_s0"
,
0
);
...
...
@@ -2676,9 +2796,10 @@ signal(BIT,0,e.."_lwb_s1"),
signal
(
BIT
,
0
,
e
..
"_lwb_s2"
)};
t
.
acklen
=
6
;
t
.
write_code
=
{};
t
.
read_code
=
{
va
(
e
..
"_lwb"
,
1
);
t
.
read_code
=
{
vif
(
vequal
(
"wb_we_i"
,
0
),{
va
(
e
..
"_lwb"
,
1
);
va
(
e
..
"_lwb_delay"
,
1
);
va
(
e
..
"_lwb_in_progress"
,
1
);};
va
(
e
..
"_lwb_in_progress"
,
1
);}
);}
;
t
.
reset_code_main
=
{
va
(
e
..
"_lwb"
,
0
);
va
(
e
..
"_lwb_delay"
,
0
);
va
(
e
..
"_lwb_in_progress"
,
0
);};
...
...
@@ -2689,7 +2810,7 @@ va(vir("rddata_reg",t),e.."_int");
va
(
e
..
"_lwb_in_progress"
,
0
);
});
};
t
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
t
.
type
]
..
" register : "
..
t
.
name
..
" (type RO/WO, "
..
t
.
clock
..
" <->
bus_clock_int
)"
),
t
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
t
.
type
]
..
" register : "
..
t
.
name
..
" (type RO/WO, "
..
t
.
clock
..
" <->
clk_sys_i
)"
),
vsyncprocess
(
t
.
clock
,
"rst_n_i"
,{
vreset
(
0
,{
va
(
e
..
"_lwb_s0"
,
0
);
...
...
@@ -2730,10 +2851,12 @@ va(e.."_lw",1);
va
(
e
..
"_lw_delay"
,
1
);
va
(
e
..
"_lw_read_in_progress"
,
0
);
va
(
e
..
"_rwsel"
,
1
);};
t
.
read_code
=
{
va
(
e
..
"_lw"
,
1
);
t
.
read_code
=
{
vif
(
vequal
(
"wb_we_i"
,
0
),{
va
(
e
..
"_lw"
,
1
);
va
(
e
..
"_lw_delay"
,
1
);
va
(
e
..
"_lw_read_in_progress"
,
1
);
va
(
e
..
"_rwsel"
,
0
);};
va
(
e
..
"_rwsel"
,
0
);});
};
t
.
reset_code_main
=
{
va
(
e
..
"_lw"
,
0
);
va
(
e
..
"_lw_delay"
,
0
);
va
(
e
..
"_lw_read_in_progress"
,
0
);
...
...
@@ -2747,7 +2870,7 @@ va(vir("rddata_reg",t),e.."_int_read");
va
(
e
..
"_lw_read_in_progress"
,
0
);
});
};
t
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
t
.
type
]
..
" register : "
..
t
.
name
..
" (type RW/WO, "
..
t
.
clock
..
" <->
bus_clock_int
)"
);
t
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
t
.
type
]
..
" register : "
..
t
.
name
..
" (type RW/WO, "
..
t
.
clock
..
" <->
clk_sys_i
)"
);
vsyncprocess
(
t
.
clock
,
"rst_n_i"
,{
vreset
(
0
,{
va
(
e
..
"_lw_s0"
,
0
);
...
...
@@ -2836,27 +2959,27 @@ e.ports={};
e
.
acklen
=
1
;
e
.
read_code
=
{
va
(
vir
(
"rddata_reg"
,
e
),
e
.
value
);};
end
function
fill_unused_bits
(
i
,
e
)
function
fill_unused_bits
(
o
,
e
)
local
a
=
{};
local
t
=
{};
local
o
=
true
;
local
i
=
true
;
foreach_subfield
(
e
,
function
(
e
,
t
)
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
elseif
(
e
.
type
==
BIT
or
e
.
type
==
MONOSTABLE
)
then
a
[
e
.
offset
]
=
1
;
end
if
(
e
.
access_bus
~=
WRITE_ONLY
)
then
o
=
false
;
end
if
(
e
.
access_bus
~=
WRITE_ONLY
)
then
i
=
false
;
end
end
);
if
(
o
)
then
if
(
i
)
then
for
e
=
0
,
DATA_BUS_WIDTH
-
1
do
table_join
(
t
,{
va
(
vi
(
i
,
e
),
vundefined
());});
table_join
(
t
,{
va
(
vi
(
o
,
e
),
vundefined
());});
end
return
t
;
end
for
e
=
0
,
DATA_BUS_WIDTH
-
1
do
if
(
a
[
e
]
==
nil
)
then
table_join
(
t
,{
va
(
vi
(
i
,
e
),
vundefined
());});
table_join
(
t
,{
va
(
vi
(
o
,
e
),
vundefined
());});
end
end
return
t
;
...
...
@@ -2891,7 +3014,7 @@ end
if
(
e
.
__type
==
TYPE_RAM
)
then
gen_code_ram
(
e
);
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
function
gen_hdl_block_select_bits
()
...
...
@@ -2958,8 +3081,8 @@ e.signals={};
e
.
maps
=
{};
e
.
ports
=
{
port
(
SLV
,
e
.
addr_bits
-
e
.
wrap_bits
,
"in"
,
t
..
"_addr_i"
,
"Ports for RAM: "
..
e
.
name
)};
e
.
reset_code_main
=
{};
table_join
(
e
.
maps
,{
vpm
(
"clk_a_i"
,
"
bus_clock_int
"
);
vpm
(
"clk_b_i"
,
csel
(
e
.
clock
~=
nil
,
e
.
clock
,
"
bus_clock_int
"
));
table_join
(
e
.
maps
,{
vpm
(
"clk_a_i"
,
"
clk_sys_i
"
);
vpm
(
"clk_b_i"
,
csel
(
e
.
clock
~=
nil
,
e
.
clock
,
"
clk_sys_i
"
));
vpm
(
"addr_b_i"
,
t
..
"_addr_i"
);
vpm
(
"addr_a_i"
,
vi
(
"rwaddr_reg"
,
log2up
(
e
.
size
)
-
1
,
0
));
});
...
...
@@ -3012,7 +3135,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
));};
[
"no_std_regbank"
]
=
true
;
};
local
n
=
{[
"__type"
]
=
TYPE_REG
;
local
s
=
{[
"__type"
]
=
TYPE_REG
;
[
"__blockindex"
]
=
1000002
;
[
"align"
]
=
1
;
[
"name"
]
=
"Interrupt status register"
;
...
...
@@ -3031,7 +3154,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
));};
[
"no_std_regbank"
]
=
true
;
};
local
s
=
{[
"__type"
]
=
TYPE_REG
;
local
n
=
{[
"__type"
]
=
TYPE_REG
;
[
"__blockindex"
]
=
1000003
;
[
"align"
]
=
1
;
[
"name"
]
=
"Interrupt mask register"
;
...
...
@@ -3048,7 +3171,7 @@ e.index=t;
t
=
t
+
1
;
table.insert
(
o
,{[
"index"
]
=
e
.
index
;[
"trigger"
]
=
e
.
trigger
;});
fix_prefix
(
e
);
local
o
=
{
local
t
=
{
[
"__blockindex"
]
=
e
.
index
;
[
"__type"
]
=
TYPE_FIELD
;
[
"type"
]
=
BIT
;
...
...
@@ -3059,7 +3182,7 @@ local o={
[
"access_bus"
]
=
READ_WRITE
;
[
"access_dev"
]
=
READ_WRITE
;
};
local
r
=
{
local
o
=
{
[
"__blockindex"
]
=
e
.
index
;
[
"__type"
]
=
TYPE_FIELD
;
[
"type"
]
=
BIT
;
...
...
@@ -3070,7 +3193,7 @@ local r={
[
"access_bus"
]
=
WRITE_ONLY
;
[
"access_dev"
]
=
READ_ONLY
;
};
local
h
=
{
local
r
=
{
[
"__blockindex"
]
=
e
.
index
;
[
"__type"
]
=
TYPE_FIELD
;
[
"type"
]
=
BIT
;
...
...
@@ -3081,7 +3204,7 @@ local h={
[
"access_bus"
]
=
WRITE_ONLY
;
[
"access_dev"
]
=
READ_ONLY
;
};
local
t
=
{
local
h
=
{
[
"__blockindex"
]
=
e
.
index
;
[
"__type"
]
=
TYPE_FIELD
;
[
"type"
]
=
BIT
;
...
...
@@ -3101,20 +3224,20 @@ end
if
(
e
.
mask_line
==
true
)
then
table_join
(
e
.
ports
,{
port
(
BIT
,
0
,
"out"
,
e
.
full_prefix
..
"_mask_o"
);});
end
table.insert
(
a
,
h
);
table.insert
(
n
,
o
);
table.insert
(
a
,
r
);
table.insert
(
s
,
t
);
table.insert
(
i
,
r
);
table.insert
(
n
,
h
);
table.insert
(
i
,
o
);
end
);
add_global_signals
({
signal
(
SLV
,
periph
.
irqcount
,
"irq_inputs_vector_int"
);
});
table.insert
(
periph
,
a
);
table.insert
(
periph
,
i
);
table.insert
(
periph
,
s
);
table.insert
(
periph
,
n
);
table.insert
(
periph
,
s
);
local
e
=
{
vgm
(
"g_num_interrupts"
,
periph
.
irqcount
);
vpm
(
"clk_i"
,
"
bus_clock_int
"
);
vpm
(
"clk_i"
,
"
clk_sys_i
"
);
vpm
(
"rst_n_i"
,
"rst_n_i"
);
vpm
(
"irq_i"
,
"irq_inputs_vector_int"
);
vpm
(
"irq_ack_o"
,
"eic_irq_ack_int"
);
...
...
@@ -3126,7 +3249,7 @@ vpm("reg_idr_wr_stb_i","eic_idr_write_int");
vpm
(
"reg_isr_o"
,
"eic_isr_status_int"
);
vpm
(
"reg_isr_i"
,
"eic_isr_clear_int"
);
vpm
(
"reg_isr_wr_stb_i"
,
"eic_isr_write_int"
);
vpm
(
"wb_irq_o"
,
"wb_i
rq
_o"
);
vpm
(
"wb_irq_o"
,
"wb_i
nt
_o"
);
};
local
a
;
for
o
,
t
in
ipairs
(
o
)
do
...
...
@@ -3276,7 +3399,7 @@ table_join(t.ackgen_code,{va(e.full_prefix.."_wrreq_int",0)});
table_join
(
t
.
reset_code_main
,{
va
(
e
.
full_prefix
..
"_wrreq_int"
,
0
)});
else
local
t
=
o
[
0
];
table_join
(
t
.
extra_code
,{
vsyncprocess
(
"
bus_clock_int
"
,
"rst_n_i"
,{
table_join
(
t
.
extra_code
,{
vsyncprocess
(
"
clk_sys_i
"
,
"rst_n_i"
,{
vreset
(
0
,{
va
(
e
.
full_prefix
..
"_rdreq_int_d0"
,
0
)
});
...
...
@@ -3302,44 +3425,58 @@ va(vi("ack_sreg",0),1);
};
t
.
dont_emit_ack_code
=
true
;
end
local
n
=
{
local
s
=
{
[
"__type"
]
=
TYPE_REG
;
[
"name"
]
=
"FIFO '"
..
e
.
name
..
"' control/status register"
;
[
"c_prefix"
]
=
e
.
c_prefix
..
"_CSR"
;
[
"hdl_prefix"
]
=
e
.
hdl_prefix
..
"_CSR"
;
[
"no_std_regbank"
]
=
true
;
};
function
gen_fifo_csr_field
(
h
,
a
,
r
,
o
,
s
,
i
,
t
)
function
gen_fifo_csr_field
(
d
,
n
,
t
,
r
,
h
,
o
,
a
,
i
)
print
(
"GenCSR Field "
..
t
);
if
(
e
.
flags_bus
==
nil
)
then
return
;
end
if
inset
(
h
,
e
.
flags_bus
)
then
if
inset
(
d
,
e
.
flags_bus
)
then
local
t
=
{
[
"__type"
]
=
TYPE_FIELD
;
[
"name"
]
=
r
;
[
"description"
]
=
o
;
[
"name"
]
=
t
;
[
"description"
]
=
r
;
[
"access_bus"
]
=
READ_ONLY
;
[
"access_dev"
]
=
WRITE_ONLY
;
[
"type"
]
=
i
;
[
"size"
]
=
s
;
[
"offset"
]
=
t
;
[
"c_prefix"
]
=
a
;
[
"hdl_prefix"
]
=
a
;
[
"type"
]
=
o
;
[
"size"
]
=
h
;
[
"offset"
]
=
a
;
[
"c_prefix"
]
=
n
;
[
"hdl_prefix"
]
=
n
;
[
"signals"
]
=
{};
[
"read_code"
]
=
{};
[
"ack_len"
]
=
2
;
};
local
o
=
e
.
full_prefix
..
"_"
..
a
..
"_int"
;
table_join
(
e
.
maps
,{
vpm
(
e
.
nrdwr
..
"_"
..
a
..
"_o"
,
o
)});
table_join
(
t
.
signals
,{
signal
(
i
,
s
,
o
)});
if
(
i
==
BIT
)
then
table_join
(
t
.
read_code
,{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
o
)});
local
a
=
e
.
full_prefix
..
"_"
..
n
..
"_int"
;
if
(
i
==
nil
)
then
i
=
true
else
table_join
(
t
.
read_code
,{
va
(
vi
(
"rddata_reg"
,
t
.
offset
+
t
.
size
-
1
,
t
.
offset
),
o
)});
i
=
false
end
table.insert
(
n
,
t
);
else
table_join
(
e
.
maps
,{
vpm
(
e
.
nrdwr
..
"_"
..
a
..
"_o"
,
vopenpin
())});
if
(
i
)
then
table_join
(
e
.
maps
,{
vpm
(
e
.
nrdwr
..
"_"
..
n
..
"_o"
,
a
)});
end
table_join
(
t
.
signals
,{
signal
(
csel
(
o
==
MONOSTABLE
,
BIT
,
o
),
h
,
a
)});
if
(
o
==
BIT
)
then
table_join
(
t
.
read_code
,{
va
(
vi
(
"rddata_reg"
,
t
.
offset
),
a
)});
elseif
(
o
==
SLV
)
then
table_join
(
t
.
read_code
,{
va
(
vi
(
"rddata_reg"
,
t
.
offset
+
t
.
size
-
1
,
t
.
offset
),
a
)});
elseif
(
o
==
MONOSTABLE
)
then
t
.
access_bus
=
WRITE_ONLY
;
t
.
access_dev
=
READ_ONLY
;
t
.
reset_code_main
=
{
va
(
a
,
0
)};
t
.
write_code
=
{
vif
(
vequal
(
vi
(
"rddata_reg"
,
t
.
offset
),
1
),{
va
(
a
,
1
)})};
t
.
ackgen_code
=
{
va
(
a
,
0
)}
end
table.insert
(
s
,
t
);
elseif
(
i
)
then
table_join
(
e
.
maps
,{
vpm
(
e
.
nrdwr
..
"_"
..
n
..
"_o"
,
vopenpin
())});
end
end
gen_fifo_csr_field
(
FIFO_FULL
,
...
...
@@ -3356,6 +3493,14 @@ gen_fifo_csr_field(FIFO_EMPTY,
1
,
BIT
,
17
);
gen_fifo_csr_field
(
FIFO_CLEAR
,
"clear_bus"
,
"FIFO clear"
,
"write 1: clears FIFO '"
..
e
.
name
..
"
\n
write 0: no effect"
,
1
,
MONOSTABLE
,
18
,
false
);
gen_fifo_csr_field
(
FIFO_COUNT
,
"usedw"
,
"FIFO counter"
,
...
...
@@ -3364,10 +3509,38 @@ e.usedw_size,
SLV
,
0
);
if
(
type
(
e
.
flags_bus
)
==
"table"
)
then
table.insert
(
periph
,
n
);
table.insert
(
periph
,
s
);
end
table_join
(
e
.
maps
,{
vpm
(
e
.
nrdwr
..
"_req_i"
,
e
.
full_prefix
..
"_"
..
e
.
nrdwr
..
"req_int"
)});
end
function
fifo_wire_clear_ports
(
e
)
c_dev
=
inset
(
FIFO_CLEAR
,
e
.
flags_dev
);
c_bus
=
inset
(
FIFO_CLEAR
,
e
.
flags_bus
);
table_join
(
e
.
signals
,{
signal
(
BIT
,
0
,
e
.
full_prefix
..
"_rst_n"
)
});
table_join
(
e
.
maps
,{
vpm
(
"rst_n_i"
,
e
.
full_prefix
..
"_rst_n"
)});
if
(
c_dev
)
then
table_join
(
e
.
ports
,{
port
(
BIT
,
0
,
"in"
,
e
.
full_prefix
..
"_clear_i"
,
"FIFO clear"
)});
end
if
(
c_dev
and
c_bus
)
then
table_join
(
e
.
extra_code
,{
va
(
e
.
full_prefix
..
"_rst_n"
,
vand
(
"rst_n_i"
,
vnot
(
vor
(
e
.
full_prefix
..
"_clear_i"
,
e
.
full_prefix
..
"_clear_bus_int"
))));
});
elseif
(
c_dev
)
then
table_join
(
e
.
extra_code
,{
va
(
e
.
full_prefix
..
"_rst_n"
,
vand
(
"rst_n_i"
,
vnot
(
e
.
full_prefix
..
"_clear_i"
)));
});
elseif
(
c_bus
)
then
table_join
(
e
.
extra_code
,{
va
(
e
.
full_prefix
..
"_rst_n"
,
vand
(
"rst_n_i"
,
vnot
(
e
.
full_prefix
..
"_clear_bus_int"
)));
});
else
table_join
(
e
.
extra_code
,{
va
(
e
.
full_prefix
..
"_rst_n"
,
"rst_n_i"
);
});
end
end
function
gen_code_fifo
(
e
)
local
t
=
string.lower
(
periph
.
hdl_prefix
..
"_"
..
e
.
hdl_prefix
);
dbg
(
"GenCodeFIFO"
);
...
...
@@ -3385,9 +3558,11 @@ e.nrdwr="rd";
end
fifo_wire_core_ports
(
e
);
fifo_wire_bus_ports
(
e
);
fifo_wire_clear_ports
(
e
);
table_join
(
e
.
signals
,{
signal
(
SLV
,
e
.
total_size
,
e
.
full_prefix
..
"_in_int"
),
signal
(
SLV
,
e
.
total_size
,
e
.
full_prefix
..
"_out_int"
)});
signal
(
SLV
,
e
.
total_size
,
e
.
full_prefix
..
"_out_int"
)
});
if
(
e
.
direction
==
BUS_TO_CORE
)
then
table_join
(
e
.
signals
,{
signal
(
BIT
,
0
,
e
.
full_prefix
..
"_wrreq_int"
)});
else
...
...
@@ -3395,14 +3570,14 @@ table_join(e.signals,{signal(BIT,0,e.full_prefix.."_rdreq_int")});
table_join
(
e
.
signals
,{
signal
(
BIT
,
0
,
e
.
full_prefix
..
"_rdreq_int_d0"
)});
end
if
(
e
.
clock
==
nil
)
then
table_join
(
e
.
maps
,{
vpm
(
"clk_i"
,
"
bus_clock_int
"
);});
table_join
(
e
.
maps
,{
vpm
(
"clk_i"
,
"
clk_sys_i
"
);});
else
if
(
e
.
direction
==
BUS_TO_CORE
)
then
table_join
(
e
.
maps
,{
vpm
(
"rd_clk_i"
,
e
.
clock
);
vpm
(
"wr_clk_i"
,
"
bus_clock_int
"
)});
vpm
(
"wr_clk_i"
,
"
clk_sys_i
"
)});
elseif
(
e
.
direction
==
CORE_TO_BUS
)
then
table_join
(
e
.
maps
,{
vpm
(
"wr_clk_i"
,
e
.
clock
);
vpm
(
"rd_clk_i"
,
"
bus_clock_int
"
)});
vpm
(
"rd_clk_i"
,
"
clk_sys_i
"
)});
end
end
table_join
(
e
.
maps
,{
...
...
@@ -3417,29 +3592,34 @@ vinstance(e.full_prefix.."_INST",csel(e.clock==nil,"wbgen2_fifo_sync","wbgen2_fi
});
end
MAX_ACK_LENGTH
=
10
;
function
gen_wishbone_ports
()
MODE_CLASSIC
=
1
MODE_PIPELINED
=
2
function
gen_pipelined_wb_ports
(
t
)
local
e
=
{
port
(
BIT
,
0
,
"in"
,
"rst_n_i"
,
""
,
VPORT_WB
),
port
(
BIT
,
0
,
"in"
,
"
wb_clk
_i"
,
""
,
VPORT_WB
),
port
(
BIT
,
0
,
"in"
,
"
clk_sys
_i"
,
""
,
VPORT_WB
),
};
if
(
address_bus_width
>
0
)
then
table_join
(
e
,{
port
(
SLV
,
address_bus_width
,
"in"
,
"wb_ad
dr_i"
,
""
,
VPORT_WB
)});
table_join
(
e
,{
port
(
SLV
,
address_bus_width
,
"in"
,
"wb_ad
r_i"
,
""
,
VPORT_WB
)})
end
table_join
(
e
,{
port
(
SLV
,
DATA_BUS_WIDTH
,
"in"
,
"wb_dat
a
_i"
,
""
,
VPORT_WB
),
port
(
SLV
,
DATA_BUS_WIDTH
,
"out"
,
"wb_dat
a
_o"
,
""
,
VPORT_WB
),
port
(
SLV
,
DATA_BUS_WIDTH
,
"in"
,
"wb_dat_i"
,
""
,
VPORT_WB
),
port
(
SLV
,
DATA_BUS_WIDTH
,
"out"
,
"wb_dat_o"
,
""
,
VPORT_WB
),
port
(
BIT
,
0
,
"in"
,
"wb_cyc_i"
,
""
,
VPORT_WB
),
port
(
SLV
,
math.floor
((
DATA_BUS_WIDTH
+
7
)
/
8
),
"in"
,
"wb_sel_i"
,
""
,
VPORT_WB
),
port
(
BIT
,
0
,
"in"
,
"wb_stb_i"
,
""
,
VPORT_WB
),
port
(
BIT
,
0
,
"in"
,
"wb_we_i"
,
""
,
VPORT_WB
),
port
(
BIT
,
0
,
"out"
,
"wb_ack_o"
,
""
,
VPORT_WB
)
});
if
(
t
==
MODE_PIPELINED
)
then
table_join
(
e
,{
port
(
BIT
,
0
,
"out"
,
"wb_stall_o"
,
""
,
VPORT_WB
)});
end
if
(
periph
.
irqcount
>
0
)
then
table_join
(
e
,{
port
(
BIT
,
0
,
"out"
,
"wb_i
rq
_o"
,
""
,
VPORT_WB
);});
table_join
(
e
,{
port
(
BIT
,
0
,
"out"
,
"wb_i
nt
_o"
,
""
,
VPORT_WB
);});
end
add_global_ports
(
e
);
end
function
gen_
wishbone_signals
(
)
function
gen_
pipelined_wb_signals
(
e
)
local
e
=
math.max
(
1
,
address_bus_width
);
local
e
=
{
signal
(
SLV
,
MAX_ACK_LENGTH
,
"ack_sreg"
),
signal
(
SLV
,
DATA_BUS_WIDTH
,
"rddata_reg"
),
...
...
@@ -3449,53 +3629,52 @@ signal(SLV,e,"rwaddr_reg"),
signal
(
BIT
,
0
,
"ack_in_progress"
),
signal
(
BIT
,
0
,
"wr_int"
),
signal
(
BIT
,
0
,
"rd_int"
),
signal
(
BIT
,
0
,
"bus_clock_int"
),
signal
(
SLV
,
DATA_BUS_WIDTH
,
"allones"
),
signal
(
SLV
,
DATA_BUS_WIDTH
,
"allzeros"
)
};
add_global_signals
(
e
);
end
function
gen_bus_logic_
wishbone
(
)
local
e
;
gen_
wishbone_ports
(
);
gen_
wishbone_signals
(
);
function
gen_bus_logic_
pipelined_wb
(
e
)
local
t
;
gen_
pipelined_wb_ports
(
e
);
gen_
pipelined_wb_signals
(
e
);
foreach_reg
(
ALL_REG_TYPES
,
function
(
e
)
gen_abstract_code
(
e
);
end
);
local
i
=
{};
local
o
=
{};
local
i
=
{};
local
n
=
{};
foreach_field
(
function
(
e
,
t
)
table_join
(
i
,
e
.
reset_code_main
);
table_join
(
o
,
e
.
reset_code_main
);
end
);
foreach_reg
(
ALL_REG_TYPES
,
function
(
e
)
table_join
(
i
,
e
.
reset_code_main
);
table_join
(
o
,
e
.
reset_code_main
);
end
);
foreach_reg
({
TYPE_REG
},
function
(
e
)
foreach_subfield
(
e
,
function
(
e
,
t
)
table_join
(
o
,
e
.
ackgen_code
);
table_join
(
i
,
e
.
ackgen_code
);
table_join
(
n
,
e
.
ackgen_code_pre
);
end
);
table_join
(
o
,
e
.
ackgen_code
);
table_join
(
i
,
e
.
ackgen_code
);
table_join
(
n
,
e
.
ackgen_code_pre
);
end
);
local
e
=
{};
foreach_reg
({
TYPE_REG
},
function
(
t
)
local
n
=
find_max
(
t
,
"acklen"
);
local
o
=
{};
local
a
=
{};
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
o
=
{};
foreach_subfield
(
t
,
function
(
e
,
t
)
table_join
(
o
,
e
.
write_code
);
end
);
foreach_subfield
(
t
,
function
(
e
,
t
)
table_join
(
a
,
e
.
read_code
);
end
);
local
i
=
fill_unused_bits
(
"rddata_reg"
,
t
);
table_join
(
a
,
t
.
write_code
);
table_join
(
o
,
t
.
read_code
);
table_join
(
o
,
t
.
write_code
);
table_join
(
a
,
t
.
read_code
);
local
a
=
{
vif
(
vequal
(
"wb_we_i"
,
1
),{
a
,
},{
o
,
});
a
,
i
}
);}
;
};
if
(
not
(
t
.
dont_emit_ack_code
==
true
))
then
table_join
(
a
,{
va
(
vi
(
"ack_sreg"
,
math.max
(
n
-
1
,
0
)),
1
);});
table_join
(
a
,{
va
(
"ack_in_progress"
,
1
);});
...
...
@@ -3541,28 +3720,27 @@ end
e
=
{
vif
(
vand
(
vequal
(
"wb_cyc_i"
,
1
),
vequal
(
"wb_stb_i"
,
1
)),{
e
});};
local
e
=
{
vcomment
(
"Some internal signals assignments. For (foreseen) compatibility with other bus standards."
);
va
(
"wrdata_reg"
,
"wb_dat
a
_i"
);
va
(
"wrdata_reg"
,
"wb_dat_i"
);
va
(
"bwsel_reg"
,
"wb_sel_i"
);
va
(
"bus_clock_int"
,
"wb_clk_i"
);
va
(
"rd_int"
,
vand
(
"wb_cyc_i"
,
vand
(
"wb_stb_i"
,
vnot
(
"wb_we_i"
))));
va
(
"wr_int"
,
vand
(
"wb_cyc_i"
,
vand
(
"wb_stb_i"
,
"wb_we_i"
)));
va
(
"allones"
,
vothers
(
1
));
va
(
"allzeros"
,
vothers
(
0
));
vcomment
(
""
);
vcomment
(
"Main register bank access process."
);
vsyncprocess
(
"
bus_clock_int
"
,
"rst_n_i"
,{
vsyncprocess
(
"
clk_sys_i
"
,
"rst_n_i"
,{
vreset
(
0
,{
va
(
"ack_sreg"
,
0
);
va
(
"ack_in_progress"
,
0
);
va
(
"rddata_reg"
,
0
);
i
o
});
vposedge
({
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
-
1
),
0
);
vif
(
vequal
(
"ack_in_progress"
,
1
),{
vif
(
vequal
(
vi
(
"ack_sreg"
,
0
),
1
),{
o
;
va
(
"ack_in_progress"
,
0
);},
n
);
vif
(
vequal
(
vi
(
"ack_sreg"
,
0
),
1
),{
i
;
va
(
"ack_in_progress"
,
0
);},
n
);
},{
e
});
...
...
@@ -3577,20 +3755,20 @@ local o={vswitch(vi("rwaddr_reg",address_bus_width-1,address_bus_width-address_b
local
o
=
{
vcomment
(
"Data output multiplexer process"
);
vcombprocess
(
a
,
o
);};
foreach_reg
({
TYPE_RAM
},
function
(
e
)
table.insert
(
a
,
e
.
full_prefix
..
"_rddata_int"
);
local
a
=
{
va
(
vi
(
"wb_dat
a
_o"
,
e
.
width
-
1
,
0
),
e
.
full_prefix
..
"_rddata_int"
);};
local
a
=
{
va
(
vi
(
"wb_dat_o"
,
e
.
width
-
1
,
0
),
e
.
full_prefix
..
"_rddata_int"
);};
if
(
e
.
width
<
DATA_BUS_WIDTH
)
then
table_join
(
a
,{
va
(
vi
(
"wb_dat
a
_o"
,
DATA_BUS_WIDTH
-
1
,
e
.
width
),
0
);});
table_join
(
a
,{
va
(
vi
(
"wb_dat_o"
,
DATA_BUS_WIDTH
-
1
,
e
.
width
),
0
);});
end
table_join
(
t
,{
vcase
(
e
.
select_bits
,
a
);});
end
);
table.insert
(
a
,
"wb_ad
d
r_i"
);
table_join
(
t
,{
vcasedefault
(
va
(
"wb_dat
a
_o"
,
"rddata_reg"
));});
table.insert
(
a
,
"wb_adr_i"
);
table_join
(
t
,{
vcasedefault
(
va
(
"wb_dat_o"
,
"rddata_reg"
));});
table_join
(
e
,
o
);
end
local
a
=
{
"wb_ad
d
r_i"
,
"rd_int"
,
"wr_int"
};
local
a
=
{
"wb_adr_i"
,
"rd_int"
,
"wr_int"
};
local
t
=
{};
foreach_reg
({
TYPE_RAM
},
function
(
e
)
table_join
(
t
,{
vif
(
vequal
(
vi
(
"wb_ad
d
r_i"
,
address_bus_width
-
1
,
address_bus_width
-
address_bus_select_bits
),
e
.
select_bits
),{
table_join
(
t
,{
vif
(
vequal
(
vi
(
"wb_adr_i"
,
address_bus_width
-
1
,
address_bus_width
-
address_bus_select_bits
),
e
.
select_bits
),{
va
(
e
.
full_prefix
..
"_rd_int"
,
"rd_int"
);
va
(
e
.
full_prefix
..
"_wr_int"
,
"wr_int"
);
},{
...
...
@@ -3600,7 +3778,7 @@ va(e.full_prefix.."_rd_int",0);
end
);
table_join
(
e
,{
vcomment
(
"Read & write lines decoder for RAMs"
);
vcombprocess
(
a
,
t
);});
else
table_join
(
e
,{
vcomment
(
"Drive the data output bus"
);
va
(
"wb_dat
a
_o"
,
"rddata_reg"
)});
table_join
(
e
,{
vcomment
(
"Drive the data output bus"
);
va
(
"wb_dat_o"
,
"rddata_reg"
)});
end
foreach_reg
(
ALL_REG_TYPES
,
function
(
t
)
if
(
t
.
extra_code
~=
nil
)
then
...
...
@@ -3614,10 +3792,11 @@ end
end
);
end
);
if
(
address_bus_width
>
0
)
then
table_join
(
e
,{
va
(
"rwaddr_reg"
,
"wb_ad
d
r_i"
);});
table_join
(
e
,{
va
(
"rwaddr_reg"
,
"wb_adr_i"
);});
else
table_join
(
e
,{
va
(
"rwaddr_reg"
,
vothers
(
0
));});
end
table_join
(
e
,{
va
(
"wb_stall_o"
,
vand
(
vnot
(
vi
(
"ack_sreg"
,
0
)),
vand
(
"wb_stb_i"
,
"wb_cyc_i"
)))});
table_join
(
e
,{
vcomment
(
"ACK signal generation. Just pass the LSB of ACK counter."
);
va
(
"wb_ack_o"
,
vi
(
"ack_sreg"
,
0
));
});
...
...
@@ -3631,12 +3810,14 @@ options.register_data_output=false;
options
.
lang
=
"vhdl"
;
options
.
c_reg_style
=
"struct"
;
options
.
hdl_reg_style
=
"signals"
;
options
.
doc_format
=
"html"
require
"alt_getopt"
local
e
=
[[slave Wishbone generator
wbgen2 [options] input_file.wb]]
local
t
=
[[options:
-C, --co=FILE Write the slave's generated C header file to FILE
-D, --doco=FILE Write the slave's generated HTML documentation to FILE
-f, --docformat=FORMAT Write documentation for texinfo or HTML (defaults to HTML)
-D, --doco=FILE Write the slave's generated documentation to FILE
-h, --help Show this help text
-l, --lang=LANG Set the output Hardware Description Language (HDL) to LANG
Valid values for LANG: {vhdl,verilog}
...
...
@@ -3650,7 +3831,7 @@ local t=[[options:
-p, --vpo=FILE Generate a VHDL package for slave's generated VHDL
(necessary with --hstyle=record)
wbgen2 (c) Tomasz Wlostowski/CERN BE-CO-HT 2010]]
wbgen2 (c) Tomasz Wlostowski/CERN BE-CO-HT 2010
-2012
]]
function
usage
()
print
(
e
)
print
(
"Try `wbgen2 -h' for more information"
)
...
...
@@ -3659,11 +3840,12 @@ function usage_complete()
print
(
e
)
print
(
t
)
end
function
parse_args
(
o
)
function
parse_args
(
a
)
local
t
=
{
help
=
"h"
,
version
=
"v"
,
co
=
"C"
,
docformat
=
"f"
,
doco
=
"D"
,
constco
=
"K"
,
lang
=
"l"
,
...
...
@@ -3673,8 +3855,8 @@ cstyle="s",
hstyle
=
"H"
}
local
e
local
a
e
,
a
=
alt_getopt
.
get_opts
(
o
,
"hvC:D:K:l:V:s
:H:p:"
,
t
)
local
o
e
,
o
=
alt_getopt
.
get_opts
(
a
,
"hvC:D:K:l:V:s:f
:H:p:"
,
t
)
for
t
,
e
in
pairs
(
e
)
do
if
t
==
"h"
then
usage_complete
()
...
...
@@ -3688,6 +3870,8 @@ elseif t=="D"then
options
.
output_doc_file
=
e
elseif
t
==
"K"
then
options
.
output_vlog_constants_file
=
e
elseif
t
==
"f"
then
options
.
doc_format
=
e
elseif
t
==
"l"
then
options
.
lang
=
e
if
(
options
.
lang
~=
"vhdl"
and
options
.
lang
~=
"verilog"
)
then
...
...
@@ -3709,18 +3893,21 @@ end
options
.
hdl_reg_style
=
e
end
end
if
(
o
[
a
]
==
nil
)
then
if
(
a
[
o
]
==
nil
)
then
usage
()
os.exit
(
0
)
end
input_wb_file
=
o
[
a
];
input_wb_file
=
a
[
o
];
end
parse_args
(
arg
);
dofile
(
input_wb_file
);
if
(
periph
==
nil
)
then
die
(
"missing peripheral declaration"
);
end
foreach_field
(
fix_prefix
);
foreach_field
(
fix_access
);
foreach_field
(
check_field_types
);
foreach_reg
(
ALL_REG_TYPES
,
fix_prefix
);
foreach_reg
(
ALL_REG_TYPES
,
check_obj_names_prefixes
);
foreach_field
(
check_obj_names_prefixes
);
periph
=
fix_prefix
(
periph
);
wbgen_count_subblocks
();
wbgen_generate_eic
();
...
...
@@ -3737,7 +3924,7 @@ foreach_reg({TYPE_FIFO},gen_code_fifo);
foreach_field
(
calc_num_fields
);
foreach_reg
({
TYPE_REG
,
TYPE_RAM
,
TYPE_FIFO
},
calc_address_sizes
);
assign_addresses
();
tree
=
gen_bus_logic_
wishbone
(
);
tree
=
gen_bus_logic_
pipelined_wb
(
MODE_PIPELINED
);
cgen_build_signals_ports
();
if
(
options
.
output_hdl_file
~=
nil
)
then
if
(
options
.
lang
==
"vhdl"
)
then
...
...
@@ -3755,6 +3942,10 @@ cgen_gen_vlog_constants(options.output_vlog_constants_file);
end
if
(
options
.
output_doc_file
~=
nil
)
then
cgen_generate_init
(
options
.
output_doc_file
);
cgen_generate_documentation
();
if
(
options
.
doc_format
==
"html"
)
then
cgen_generate_html_documentation
();
else
cgen_generate_texinfo_documentation
();
end
cgen_generate_done
();
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment