Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
H
HDL Core Lib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
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
HDL Core Lib
Commits
7cc2ac4a
Commit
7cc2ac4a
authored
Mar 10, 2010
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new code generator (vlog/vhdl)
parent
dee54890
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
3280 additions
and
438 deletions
+3280
-438
cgen_common.lua
trunk/software/wbgen2/cgen_common.lua
+286
-0
cgen_verilog.lua
trunk/software/wbgen2/cgen_verilog.lua
+420
-0
cgen_vhdl.lua
trunk/software/wbgen2/cgen_vhdl.lua
+442
-0
wbgen2_doc.kilepr
trunk/software/wbgen2/doc-src/wbgen2_doc.kilepr
+85
-0
target_simpcon.lua
trunk/software/wbgen2/target_simpcon.lua
+803
-0
target_wishbone.lua
trunk/software/wbgen2/target_wishbone.lua
+803
-0
wbgen2.lua
trunk/software/wbgen2/wbgen2.lua
+16
-7
wbgen_common.lua
trunk/software/wbgen2/wbgen_common.lua
+3
-1
wbgen_regbank.lua
trunk/software/wbgen2/wbgen_regbank.lua
+422
-430
No files found.
trunk/software/wbgen2/cgen_common.lua
0 → 100644
View file @
7cc2ac4a
#!/usr/bin/lua
-- wbgen2, (c) 2010 Tomasz Wlostowski
-- CERN BE-Co-HT
-- LICENSED UNDER GPL v2
------------------------------
-- HDL syntax tree constructors
------------------------------
-- assignment: dst <= src;
function
va
(
dst
,
src
)
local
s
=
{};
s
.
t
=
"assign"
;
s
.
dst
=
dst
;
s
.
src
=
src
;
return
s
;
end
-- index: name(h downto l)
function
vi
(
name
,
h
,
l
)
local
s
=
{};
s
.
t
=
"index"
;
s
.
name
=
name
;
s
.
h
=
h
;
s
.
l
=
l
;
return
s
;
end
-- synchronous process: process(clk, rst) begin {code} end process;
function
vsyncprocess
(
clk
,
rst
,
code
)
local
s
=
{};
s
.
t
=
"syncprocess"
;
s
.
clk
=
clk
;
s
.
rst
=
rst
;
s
.
code
=
code
;
return
s
;
end
-- reset in process
function
vreset
(
level
,
code
)
local
s
=
{};
s
.
t
=
"reset"
;
s
.
level
=
level
;
s
.
code
=
code
;
return
s
;
end
function
vposedge
(
code
)
local
s
=
{};
s
.
t
=
"posedge"
;
s
.
code
=
code
;
return
s
;
end
function
vif
(
cond
,
code
,
code_else
)
local
s
=
{};
s
.
t
=
"if"
;
s
.
cond
=
{
cond
};
s
.
code
=
code
;
s
.
code_else
=
code_else
;
return
s
;
end
function
vequal
(
a
,
b
)
local
s
=
{};
s
.
t
=
"eq"
;
s
.
a
=
a
;
s
.
b
=
b
;
return
s
;
end
function
vand
(
a
,
b
)
local
s
=
{};
s
.
t
=
"and"
;
s
.
a
=
a
;
s
.
b
=
b
;
return
s
;
end
function
vnot
(
a
)
local
s
=
{};
s
.
t
=
"not"
;
s
.
a
=
a
;
return
s
;
end
function
vswitch
(
a
,
code
)
local
s
=
{};
s
.
t
=
"switch"
;
s
.
a
=
a
;
s
.
code
=
code
;
return
s
;
end
function
vcase
(
a
,
code
)
local
s
=
{};
s
.
t
=
"case"
;
s
.
a
=
a
;
s
.
code
=
code
;
return
s
;
end
function
vcasedefault
(
code
)
local
s
=
{};
s
.
t
=
"casedefault"
;
s
.
code
=
code
;
return
s
;
end
function
vcomment
(
str
)
local
s
=
{};
s
.
t
=
"comment"
;
s
.
str
=
str
;
return
s
;
end
function
vsub
(
a
,
b
)
local
s
=
{};
s
.
t
=
"sub"
;
s
.
a
=
a
;
s
.
b
=
b
;
return
s
;
end
-- constructor for a HDL signal
function
signal
(
type
,
nbits
,
name
,
comment
)
local
t
=
{}
t
.
comment
=
comment
;
t
.
type
=
type
;
t
.
range
=
nbits
;
t
.
name
=
name
;
return
t
;
end
-- constructor for a HDL port
function
port
(
type
,
nbits
,
dir
,
name
,
comment
)
local
t
=
{}
t
.
comment
=
comment
;
t
.
type
=
type
;
t
.
range
=
nbits
;
t
.
name
=
name
;
t
.
dir
=
dir
;
return
t
;
end
function
cgen_build_wishbone_ports
()
local
ports
=
{
port
(
BIT
,
0
,
"in"
,
"rst_n_i"
),
port
(
BIT
,
0
,
"in"
,
"wb_clk_i"
),
};
if
(
address_bus_width
>
0
)
then
table_join
(
ports
,
{
port
(
SLV
,
address_bus_width
,
"in"
,
"wb_addr_i"
)
});
end
table_join
(
ports
,
{
port
(
SLV
,
DATA_BUS_WIDTH
,
"in"
,
"wb_data_i"
),
port
(
SLV
,
DATA_BUS_WIDTH
,
"out"
,
"wb_data_o"
),
port
(
BIT
,
0
,
"in"
,
"wb_cyc_i"
),
port
(
BIT
,
0
,
"in"
,
"wb_sel_i"
),
port
(
BIT
,
0
,
"in"
,
"wb_stb_i"
),
port
(
BIT
,
0
,
"in"
,
"wb_we_i"
),
port
(
BIT
,
0
,
"out"
,
"wb_ack_o"
)
});
return
ports
;
end
function
cgen_build_clock_list
()
local
allclocks
=
tree_2_table
(
"clock"
);
local
i
,
v
;
local
clockports
=
{};
remove_duplicates
(
allclocks
);
for
i
,
v
in
pairs
(
allclocks
)
do
table.insert
(
clockports
,
port
(
BIT
,
0
,
"in"
,
v
));
end
return
clockports
;
end
function
cgen_build_siglist
()
local
siglist
=
{};
local
i
,
v
;
local
s
;
siglist
=
tree_2_table
(
"signals"
);
wb_sigs
=
{
signal
(
BIT
,
0
,
"wb_ack_regbank"
),
signal
(
UNSIGNED
,
4
,
"ack_cntr"
),
signal
(
BIT
,
0
,
"ack_in_progress"
),
signal
(
BIT
,
0
,
"tmpbit"
),
signal
(
SLV
,
DATA_BUS_WIDTH
,
"rddata_reg"
),
signal
(
SLV
,
DATA_BUS_WIDTH
,
"wrdata_reg"
),
signal
(
SLV
,
address_bus_width
,
"rwaddr_reg"
)
};
table_join
(
siglist
,
wb_sigs
);
return
siglist
;
end
function
cgen_build_portlist
()
local
portlist
=
{};
table_join
(
portlist
,
cgen_build_wishbone_ports
());
table_join
(
portlist
,
cgen_build_clock_list
());
table_join
(
portlist
,
tree_2_table
(
"ports"
));
return
portlist
;
end
function
cgen_find_sigport
(
name
)
for
i
,
v
in
pairs
(
g_portlist
)
do
if
(
name
==
v
.
name
)
then
return
v
;
end
end
for
i
,
v
in
pairs
(
g_siglist
)
do
if
(
name
==
v
.
name
)
then
return
v
;
end
end
return
nil
;
end
function
cgen_build_signals_ports
()
g_portlist
=
cgen_build_portlist
();
g_siglist
=
cgen_build_siglist
();
end
cur_indent
=
0
;
function
indent_zero
()
cur_indent
=
0
;
end
function
indent_left
()
cur_indent
=
cur_indent
-
1
;
end
function
indent_right
()
cur_indent
=
cur_indent
+
1
;
end
function
cgen_new_snippet
()
emit_code
=
""
;
end
function
emiti
()
local
i
;
for
i
=
1
,
cur_indent
do
emit_code
=
emit_code
..
" "
;
end
end
function
emit
(
s
)
local
i
;
for
i
=
1
,
cur_indent
do
emit_code
=
emit_code
..
" "
;
end
emit_code
=
emit_code
..
s
..
"
\n
"
;
end
function
emitx
(
s
)
emit_code
=
emit_code
..
s
;
end
function
cgen_get_snippet
()
return
emit_code
;
end
function
cgen_write_current_snippet
()
hdl_file
.
write
(
hdl_file
,
emit_code
);
end
function
cgen_write_snippet
(
s
)
hdl_file
.
write
(
hdl_file
,
s
);
end
function
cgen_generate_hdl_init
(
filename
)
hdl_file
=
io.open
(
filename
,
"w"
);
end
function
cgen_generate_hdl_done
()
hdl_file
.
close
(
hdl_file
);
end
trunk/software/wbgen2/cgen_verilog.lua
0 → 100644
View file @
7cc2ac4a
#!/usr/bin/lua
-- wbgen2, (c) 2010 Tomasz Wlostowski/CERN BE-Co-HT
-- LICENSED UNDER GPL v2
-- File: cgen_vhdl.lua
-- The Verilog code generator
VLOG_WIRE
=
1
;
VLOG_REG
=
2
;
function
cgen_verilog_header
()
emit
(
"//////////////////////////////////////////////////////////////////////////////////////"
);
emit
(
"// Title : Wishbone slave core for "
..
periph
.
name
);
emit
(
"//////////////////////////////////////////////////////////////////////////////////////"
);
emit
(
"// File : "
..
options
.
output_hdl_file
);
emit
(
"// Author : auto-generated by wbgen2 from "
..
input_wb_file
);
emit
(
"// Created : "
..
os.date
());
emit
(
"// Standard : Verilog 2001"
);
emit
(
"//////////////////////////////////////////////////////////////////////////////////////"
);
emit
(
"// THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE "
..
input_wb_file
);
emit
(
"// DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!"
);
emit
(
"//////////////////////////////////////////////////////////////////////////////////////"
);
emit
(
""
);
end
function
cgen_verilog_module
()
local
last
;
indent_zero
();
emit
(
"module "
..
periph
.
hdl_entity
..
" ("
);
indent_right
();
for
i
=
1
,
table
.
getn
(
g_portlist
)
do
local
port
=
g_portlist
[
i
];
if
(
i
==
table
.
getn
(
g_portlist
))
then
last
=
true
;
else
last
=
false
;
end
if
(
port
.
comment
~=
nil
)
then
emitx
(
"// "
..
port
.
comment
..
"
\n
"
);
end
local
dirstr
;
if
(
port
.
dir
==
"in"
)
then
dirstr
=
"input"
;
elseif
(
port
.
dir
==
"out"
)
then
dirstr
=
"output"
;
elseif
(
port
.
dir
==
"inout"
)
then
dirst
=
"inout"
;
end
print
(
"Port: "
,
port
.
name
,
"type "
,
port
.
vlog_type
);
if
(
port
.
vlog_type
==
VLOG_REG
)
then
dirstr
=
dirstr
..
" reg"
;
end
local
rangestr
=
""
;
if
(
port
.
range
>
0
)
then
rangestr
=
"["
..
(
port
.
range
-
1
)
..
":0]"
;
end
local
line
=
string.format
(
"%-11s %-6s %s"
,
dirstr
,
rangestr
,
port
.
name
);
line
=
line
..
csel
(
last
,
""
,
","
);
emit
(
line
);
end
indent_left
();
emit
(
");"
);
indent_left
();
emit
(
""
);
for
i
,
v
in
pairs
(
g_siglist
)
do
local
rwire
=
csel
(
v
.
vlog_type
==
VLOG_REG
,
"reg"
,
"wire"
);
local
rangestr
=
""
;
if
(
v
.
range
>
0
)
then
rangestr
=
string.format
(
"[%d:0] "
,
v
.
range
-
1
);
end
emit
(
string.format
(
"%-5s %-7s %s;"
,
rwire
,
rangestr
,
v
.
name
));
end
emit
(
""
);
indent_right
();
end
function
cgen_verilog_ending
()
indent_left
();
emit
(
"endmodule"
);
end
-- Generates the vlog code from syntax tree <tree>, writing it into previously chosen file.
function
cgen_generate_verilog_code
(
tree
)
local
inside_process
=
false
;
function
find_code
(
node
,
t
)
for
i
,
v
in
ipairs
(
node
)
do
if
((
v
.
t
~=
nil
)
and
(
v
.
t
==
t
))
then
return
v
;
end
end
return
nil
;
end
function
cgen_verilog_syncprocess
(
node
)
local
vrst
=
find_code
(
node
.
code
,
"reset"
);
if
(
vrst
~=
nil
and
options
.
reset_type
==
"asynchronous"
)
then
emit
(
"always @(posedge "
..
node
.
clk
..
" or "
..
csel
(
vrst
.
level
==
0
,
"negedge"
,
"posedge"
)
..
" rst_n_i) begin"
)
else
emit
(
"always @(posedge "
..
node
.
clk
..
") begin"
);
end
indent_right
();
inside_process
=
true
;
local
vpe
=
find_code
(
node
.
code
,
"posedge"
);
if
(
vpe
==
nil
)
then
die
(
"verilog code generation error: no vposedge defined for vsyncprocess"
);
end
if
(
vrst
~=
nil
)
then
emit
(
"if ("
..
node
.
rst
..
" == 1'b"
..
vrst
.
level
..
") begin "
);
indent_right
();
recurse
(
vrst
.
code
);
indent_left
();
emit
(
"end else begin"
);
indent_right
();
end
recurse
(
vpe
.
code
);
if
(
vrst
~=
nil
)
then
indent_left
();
emit
(
"end"
);
end
indent_left
();
emit
(
"end"
);
emit
(
""
);
inside_process
=
false
;
end
function
node_typesize
(
node
)
local
ts
=
{};
local
sig
;
print
(
node
);
if
(
type
(
node
)
==
"table"
)
then
print
(
"table!"
);
if
(
node
.
t
~=
nil
and
node
.
t
==
"index"
)
then
sig
=
cgen_find_sigport
(
node
.
name
);
ts
.
h
=
node
.
h
;
ts
.
l
=
node
.
l
;
ts
.
sig
=
sig
;
ts
.
name
=
sig
.
name
;
ts
.
type
=
sig
.
type
;
ts
.
size
=
csel
(
ts
.
l
==
nil
,
1
,
ts
.
h
-
ts
.
l
+
1
);
return
ts
;
else
print
(
"expr2: "
,
node
.
t
);
ts
.
type
=
EXPRESSION
;
ts
.
code
=
node
;
return
ts
;
end
elseif
(
type
(
node
)
==
"string"
)
then
print
(
"string-type node: "
..
node
);
sig
=
cgen_find_sigport
(
node
);
ts
.
sig
=
sig
;
ts
.
size
=
sig
.
range
;
ts
.
type
=
sig
.
type
;
ts
.
name
=
node
;
return
ts
;
elseif
(
type
(
node
)
==
"number"
)
then
ts
.
type
=
INTEGER
;
ts
.
name
=
node
;
ts
.
size
=
0
;
return
ts
;
else
print
(
"Unknown node?"
);
end
end
function
gen_subrange
(
t
)
if
(
t
.
h
~=
nil
and
t
.
l
==
nil
)
then
return
t
.
name
..
"["
..
t
.
h
..
"]"
;
elseif
(
t
.
h
~=
nil
and
t
.
l
~=
nil
)
then
return
t
.
name
..
"["
..
t
.
h
..
":"
..
t
.
l
..
"]"
;
else
return
t
.
name
;
end
end
function
calc_size
(
t
)
if
(
t
.
h
~=
nil
and
t
.
l
==
nil
)
then
return
1
;
elseif
(
t
.
h
~=
nil
and
t
.
l
~=
nil
)
then
return
t
.
h
-
t
.
l
+
1
;
else
local
sig
=
cgen_find_sigport
(
t
.
name
);
return
sig
.
range
;
end
end
function
cgen_verilog_assign
(
node
)
local
tsd
=
node_typesize
(
node
.
dst
);
local
tss
=
node_typesize
(
node
.
src
);
-- for i,v in pairs(tsd) do
-- print(i,v);
-- end
-- vlog synchronous assignment
if
(
inside_process
)
then
if
(
tss
.
type
==
EXPRESSION
)
then
print
(
"EXPR!"
);
emiti
();
emitx
(
gen_subrange
(
tsd
)
..
" <= "
);
tsd
.
sig
.
vlog_type
=
VLOG_REG
;
recurse
({
tss
.
code
});
emitx
(
";\n"
);
else
emit
(
gen_subrange
(
tsd
)
..
" <= "
..
gen_subrange
(
tss
)
..
";"
);
tsd
.
sig
.
vlog_type
=
VLOG_REG
;
end
else
-- vlog combinatorial assignment
emit
(
"assign "
..
gen_subrange
(
tsd
)
..
" = "
..
gen_subrange
(
tss
)
..
";"
);
tsd
.
sig
.
vlog_type
=
VLOG_WIRE
;
end
end
function
cgen_verilog_if
(
node
)
emiti
();
emitx
(
"if ("
);
-- print("EMIT IF:", node.cond);
for
i
,
v
in
pairs
(
node
.
cond
)
do
print
(
i
,
v
);
end
recurse
(
node
.
cond
);
emitx
(
") begin\n"
);
if
(
node
.
code_else
~=
nil
)
then
indent_right
();
recurse
(
node
.
code
);
indent_left
();
emit
(
"end else begin"
);
indent_right
();
recurse
(
node
.
code_else
);
indent_left
();
emit
(
"end"
);
else
indent_right
();
recurse
(
node
.
code
);
indent_left
();
emit
(
"end"
);
end
end
function
cgen_verilog_not
(
node
)
local
tsa
=
node_typesize
(
node
.
a
);
emitx
(
"! "
);
if
(
tsa
.
type
==
EXPRESSION
)
then
emitx
(
"("
);
recurse
({
node
.
a
});
emitx
(
")"
);
else
emitx
(
gen_subrange
(
tsa
));
end
end
function
cgen_verilog_op
(
node
,
op
)
local
tsa
=
node_typesize
(
node
.
a
);
local
tsb
=
node_typesize
(
node
.
b
);
if
(
tsa
.
type
==
EXPRESSION
)
then
emitx
(
"("
);
recurse
({
node
.
a
});
emitx
(
")"
);
else
emitx
(
gen_subrange
(
tsa
));
end
if
(
op
==
"eq"
)
then
emitx
(
" == "
);
end
if
(
op
==
"and"
)
then
emitx
(
" && "
);
end
if
(
op
==
"or"
)
then
emitx
(
" || "
);
end
if
(
op
==
"sub"
)
then
emitx
(
" - "
);
end
if
(
op
==
"add"
)
then
emitx
(
" + "
);
end
if
(
tsb
.
type
==
EXPRESSION
)
then
emitx
(
"("
);
recurse
({
node
.
b
});
emitx
(
")"
);
else
emitx
(
gen_subrange
(
tsb
));
end
end
function
cgen_verilog_comment
(
node
)
emitx
(
"// "
..
node
.
str
..
"
\n
"
);
end
-- switch/case statement --
function
cgen_verilog_switch
(
node
)
local
tsa
=
node_typesize
(
node
.
a
);
emiti
();
emitx
(
"case "
);
if
(
tsa
.
type
==
EXPRESSION
)
then
emitx
(
"("
);
recurse
({
node
.
a
});
emitx
(
")"
);
else
emitx
(
"("
..
gen_subrange
(
tsa
)
..
")"
);
end
emit
(
""
);
for
i
,
v
in
pairs
(
node
.
code
)
do
print
(
"CA: "
,
v
.
t
);
if
(
v
.
t
==
"case"
)
then
emit
(
string.format
(
"%d'h%x: begin"
,
tsa
.
size
,
v
.
a
));
indent_right
();
recurse
({
v
.
code
});
indent_left
();
emit
(
"end"
);
elseif
(
v
.
t
==
"casedefault"
)
then
emit
(
"default: begin"
);
indent_right
();
recurse
({
v
.
code
});
indent_left
();
emit
(
"end"
);
end
end
emit
(
"endcase"
);
end
function
recurse
(
t
)
print
(
"recurse: "
,
t
);
for
i
,
v
in
pairs
(
t
)
do
print
(
"-> i "
,
i
,
"v "
,
v
,
"vt "
,
v
.
t
);
if
(
v
.
t
==
nil
)
then
recurse
(
v
);
elseif
(
v
.
t
==
"comment"
)
then
cgen_verilog_comment
(
v
);
elseif
(
v
.
t
==
"syncprocess"
)
then
cgen_verilog_syncprocess
(
v
);
elseif
(
v
.
t
==
"assign"
)
then
cgen_verilog_assign
(
v
);
elseif
(
v
.
t
==
"if"
)
then
cgen_verilog_if
(
v
);
elseif
(
v
.
t
==
"eq"
or
v
.
t
==
"sub"
or
v
.
t
==
"add"
or
v
.
t
==
"or"
or
v
.
t
==
"and"
)
then
cgen_verilog_op
(
v
,
v
.
t
);
elseif
(
v
.
t
==
"switch"
)
then
cgen_verilog_switch
(
v
);
elseif
(
v
.
t
==
"not"
)
then
cgen_verilog_not
(
v
);
else
print
(
"unimpl: "
..
v
.
t
);
os.exit
(
-
1
);
end
end
print
(
"end recurse"
);
end
cgen_new_snippet
();
cgen_verilog_header
();
local
c_header
=
cgen_get_snippet
();
cgen_new_snippet
();
recurse
(
tree
);
cgen_verilog_ending
();
local
c_body
=
cgen_get_snippet
();
-- generate the module definions and signals - this must done after the module body has been generated in order to determine whether to declare things
-- as regs or wires.
cgen_new_snippet
();
cgen_verilog_module
();
local
c_mod
=
cgen_get_snippet
();
cgen_write_snippet
(
c_header
);
cgen_write_snippet
(
c_mod
);
cgen_write_snippet
(
c_body
);
--cgen_write_snippet();
end
trunk/software/wbgen2/cgen_vhdl.lua
0 → 100644
View file @
7cc2ac4a
This diff is collapsed.
Click to expand it.
trunk/software/wbgen2/doc-src/wbgen2_doc.kilepr
View file @
7cc2ac4a
[General]
def_graphic_ext=eps
img_extIsRegExp=false
img_extensions=.eps .jpg .jpeg .png .pdf .ps .fig .gif
kileprversion=2
kileversion=2.0.84
lastDocument=regs.tex
masterDocument=
name=wbgen2_doc
pkg_extIsRegExp=false
pkg_extensions=.cls .sty .bbx .cbx .lbx