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
cc54a8c2
Commit
cc54a8c2
authored
Mar 17, 2010
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
--no commit message
--no commit message
parent
879b5725
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
739 additions
and
232 deletions
+739
-232
cgen_c_headers.lua
trunk/software/wbgen2/cgen_c_headers.lua
+176
-0
cgen_common.lua
trunk/software/wbgen2/cgen_common.lua
+22
-7
cgen_vhdl.lua
trunk/software/wbgen2/cgen_vhdl.lua
+63
-6
gpio_port.vhdl
trunk/software/wbgen2/examples/gpio_port/gpio_port.vhdl
+3
-3
testbench.v
trunk/software/wbgen2/examples/gpio_port/testbench.v
+3
-1
gpio_port_async.vhdl
...ware/wbgen2/examples/gpio_port_async/gpio_port_async.vhdl
+3
-3
testbench.v
trunk/software/wbgen2/examples/gpio_port_async/testbench.v
+5
-1
wbgen2_pkg.vhd
trunk/software/wbgen2/lib/wbgen2_pkg.vhd
+23
-25
maketest.sh
trunk/software/wbgen2/maketest.sh
+8
-0
regs_with_fields.wb
trunk/software/wbgen2/regs_with_fields.wb
+143
-0
target_wishbone.lua
trunk/software/wbgen2/target_wishbone.lua
+165
-131
wbgen2.lua
trunk/software/wbgen2/wbgen2.lua
+17
-4
wbgen_common.lua
trunk/software/wbgen2/wbgen_common.lua
+30
-1
wbgen_rams.lua
trunk/software/wbgen2/wbgen_rams.lua
+68
-40
wbgen_regbank.lua
trunk/software/wbgen2/wbgen_regbank.lua
+10
-10
No files found.
trunk/software/wbgen2/cgen_c_headers.lua
0 → 100644
View file @
cc54a8c2
#!/usr/bin/lua
-- wbgen2, (c) 2010 Tomasz Wlostowski/CERN BE-Co-HT
-- LICENSED UNDER GPL v2
-- File: cgen_c_headers.lua
--
-- The C header code generator.
--
function
cgen_c_field_define
(
field
,
reg
)
local
prefix
=
string.upper
(
periph
.
c_prefix
)
..
"_"
..
string.upper
(
reg
.
c_prefix
)
..
"_"
..
string.upper
(
field
.
c_prefix
);
emit
(
""
);
emit
(
"/* definitions for field: "
..
field
.
name
..
" in reg: "
..
reg
.
name
..
" */"
);
if
(
field
.
type
==
BIT
or
field
.
type
==
MONOSTABLE
)
then
emit
(
"#define "
..
prefix
..
" (1<<"
..
field
.
offset
..
")"
);
else
print
(
field
.
offset
,
field
.
size
);
emit
(
"#define "
..
prefix
..
"_MASK "
..
string.format
(
"0x%08x"
,
(
math.pow
(
2
,
field
.
size
)
-
1
)
*
math.pow
(
2
,
field
.
offset
)));
emit
(
"#define "
..
prefix
..
"_SHIFT "
..
string.format
(
"%d"
,
field
.
offset
));
emit
(
"#define "
..
prefix
..
"_W(value) "
..
string.format
(
"(((value) & 0x%08x) << %d)"
,
math.pow
(
2
,
field
.
size
)
-
1
,
field
.
offset
));
if
(
field
.
type
==
SIGNED
)
then
emit
(
"#define "
..
prefix
..
"_R(reg) "
..
string.format
(
"( ((reg)&0x%08x ? 0x%08x : 0) | (((reg) >> %d) & 0x%08x))"
,
math.pow
(
2
,
field
.
offset
+
field
.
size
-
1
),
-- sign mask
(
math.pow
(
2
,
32
-
field
.
size
)
-
1
)
*
math.pow
(
2
,
field
.
size
),
-- sign extension mask
field
.
offset
,
math.pow
(
2
,
field
.
size
)
-
1
));
else
emit
(
"#define "
..
prefix
..
"_R(reg) "
..
string.format
(
"(((reg) >> %d) & 0x%08x)"
,
field
.
offset
,
math.pow
(
2
,
field
.
size
)
-
1
));
end
end
end
function
cgen_c_ramdefs
(
ram
)
local
prefix
=
string.upper
(
periph
.
c_prefix
)
..
"_"
..
string.upper
(
ram
.
c_prefix
);
emit
(
"/* definitions for RAM: "
..
ram
.
name
..
" *);
emit(string.format("
#
define
"..prefix.."
_BYTES
0x
%
08
x
%-
50
s
", ram.size * ram.width / 8, "
/*
size
in
bytes
*/
"));
emit(string.format("
#
define
"..prefix.."
_WORDS
0x
%
08
x
%-
50
s
", ram.size, "
/*
size
in
"..ram.width.."
-
bit
words
,
32
-
bit
aligned
*/
"));
end
function cgen_c_field_masks()
foreach_reg(function(reg)
if(reg.__type == TYPE_REG and reg.num_fields ~= nil and reg.num_fields > 0) then
emit("
/*
definitions
for
register
:
"..reg.name.."
*/
);
foreach_subfield
(
reg
,
function
(
field
,
reg
)
cgen_c_field_define
(
field
,
reg
)
end
);
elseif
(
reg
.
__type
==
TYPE_RAM
)
then
cgen_c_ramdefs
(
reg
);
end
end
);
end
function
cgen_c_headers_reg
(
reg
)
foreach_subfield
(
reg
,
function
(
field
,
reg
)
emit
()
end
);
end
function
cgen_c_headers_ram
()
end
function
cgen_c_fileheader
()
emit
(
"/*"
);
emit
(
" Register definitions for slave core: "
..
periph
.
name
);
emit
(
""
);
emit
(
" * File : "
..
options
.
output_c_header_file
);
emit
(
" * Author : auto-generated by wbgen2 from "
..
input_wb_file
);
emit
(
" * Created : "
..
os.date
());
emit
(
" * Standard : ANSI C"
);
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_c_struct
()
local
cur_offset
=
0
;
local
pad_id
=
0
;
function
pad_struct
(
base
)
if
(
cur_offset
<
base
)
then
emit
(
"/* padding to: "
..
base
..
" words */"
);
emit
(
"uint32_t __padding_"
..
pad_id
..
"["
..
(
base
-
cur_offset
)
..
"];"
);
pad_id
=
pad_id
+
1
;
cur_offset
=
base
;
end
end
emit
(
"PACKED struct "
..
string.upper
(
periph
.
c_prefix
)
..
"_WB {"
);
indent_right
();
-- emit struct entires for REGs
foreach_reg
(
function
(
reg
)
if
(
reg
.
__type
==
TYPE_REG
)
then
pad_struct
(
reg
.
base
);
emit
(
"/* "
..
reg
.
name
..
" */"
);
emit
(
"volatile uint32_t "
..
string.upper
(
reg
.
prefix
)
..
";"
);
cur_offset
=
cur_offset
+
1
;
end
end
);
-- .. and for RAMs
foreach_reg
(
function
(
ram
)
if
(
ram
.
__type
==
TYPE_RAM
)
then
local
base
=
math.pow
(
2
,
ram
.
select_bits
)
*
math.pow
(
2
,
address_bus_width
-
address_bus_select_bits
);
pad_struct
(
base
);
emiti
();
emitx
(
"/* RAM: "
..
ram
.
name
..
", "
..
ram
.
size
..
" "
..
ram
.
width
..
"-bit words, "
..
DATA_BUS_WIDTH
..
"-bit aligned, "
..
csel
(
ram
.
byte_select
,
"byte"
,
"word"
)
..
"-addressable"
);
if
(
ram
.
wrap_bits
>
0
)
then
emitx
(
", mirroring: "
..
math.pow
(
2
,
ram
.
wrap_bits
)
..
" times */\n"
);
else
emitx
(
" */\n"
);
end
if
(
ram
.
byte_select
)
then
emit
(
"volatile uint8_t "
..
string.upper
(
ram
.
prefix
)
..
" ["
..
(
ram
.
size
*
(
DATA_BUS_WIDTH
/
8
)
*
math.pow
(
2
,
ram
.
wrap_bits
))
..
"];"
);
else
emit
(
"volatile uint32_t "
..
string.upper
(
ram
.
prefix
)
..
" ["
..
(
ram
.
size
*
math.pow
(
2
,
ram
.
wrap_bits
))
..
"];"
);
end
end
end
);
indent_left
();
emit
(
"};"
);
end
function
cgen_generate_c_header_code
()
cgen_new_snippet
();
cgen_c_fileheader
();
emit
(
""
);
emit
(
"#ifndef __WBGEN2_REGDEFS_"
..
string.upper
(
string.gsub
(
input_wb_file
,
"%."
,
"_"
)))
emit
(
"#define __WBGEN2_REGDEFS_"
..
string.upper
(
string.gsub
(
input_wb_file
,
"%."
,
"_"
)))
emit
(
""
);
emit
(
"#include <inttypes.h>"
);
emit
(
""
);
emit
(
"#if defined( __GNUC__)"
);
emit
(
"#define PACKED __attribute__ ((packed))"
);
emit
(
"#else"
);
emit
(
"#error \"
Unsupported
compiler
?\
""
);
emit
(
"#endif"
);
emit
(
""
);
emit
(
"#ifndef __WBGEN2_MACROS_DEFINED__"
);
emit
(
"#define __WBGEN2_MACROS_DEFINED__"
);
emit
(
"#define WBGEN2_GENMASK(offset, size) (((1<<(size))-1) << (offset))"
);
emit
(
"#define WBGEN2_GENWRITE(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))"
);
emit
(
"#endif"
);
cgen_c_field_masks
();
emit
(
""
);
cgen_c_struct
();
emit
(
""
);
emit
(
"#endif"
);
cgen_write_current_snippet
();
end
trunk/software/wbgen2/cgen_common.lua
View file @
cc54a8c2
...
@@ -60,7 +60,7 @@ function vgm(to, from)
...
@@ -60,7 +60,7 @@ function vgm(to, from)
end
end
-- combinatorial process: process(sensitivity_list) begin {code} end process;
-- combinatorial process: process(sensitivity_list) begin {code} end process;
function
v
sync
process
(
slist
,
code
)
function
v
comb
process
(
slist
,
code
)
local
s
=
{};
local
s
=
{};
s
.
t
=
"combprocess"
;
s
.
t
=
"combprocess"
;
s
.
slist
=
slist
;
s
.
slist
=
slist
;
...
@@ -168,7 +168,18 @@ function vsub(a,b)
...
@@ -168,7 +168,18 @@ function vsub(a,b)
return
s
;
return
s
;
end
end
function
vothers
(
value
)
local
s
=
{}
s
.
t
=
"others"
;
s
.
val
=
value
;
return
s
;
end
function
vopenpin
()
local
s
=
{}
s
.
t
=
"openpin"
;
return
s
;
end
-- constructor for a HDL signal
-- constructor for a HDL signal
function
signal
(
type
,
nbits
,
name
,
comment
)
function
signal
(
type
,
nbits
,
name
,
comment
)
...
@@ -202,6 +213,7 @@ function add_global_ports(p)
...
@@ -202,6 +213,7 @@ function add_global_ports(p)
table_join
(
global_ports
,
p
);
table_join
(
global_ports
,
p
);
end
end
function
cgen_build_clock_list
()
function
cgen_build_clock_list
()
local
allclocks
=
tree_2_table
(
"clock"
);
local
allclocks
=
tree_2_table
(
"clock"
);
local
i
,
v
;
local
i
,
v
;
...
@@ -241,6 +253,9 @@ end
...
@@ -241,6 +253,9 @@ end
function
cgen_find_sigport
(
name
)
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_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
for
i
,
v
in
pairs
(
g_siglist
)
do
if
(
name
==
v
.
name
)
then
return
v
;
end
end
die
(
"cgen internal error: undefined signal '"
..
name
..
"'"
);
return
nil
;
return
nil
;
end
end
...
@@ -289,18 +304,18 @@ function cgen_get_snippet()
...
@@ -289,18 +304,18 @@ function cgen_get_snippet()
end
end
function
cgen_write_current_snippet
()
function
cgen_write_current_snippet
()
hdl_file
.
write
(
hdl
_file
,
emit_code
);
output_code_file
.
write
(
output_code
_file
,
emit_code
);
end
end
function
cgen_write_snippet
(
s
)
function
cgen_write_snippet
(
s
)
hdl_file
.
write
(
hdl
_file
,
s
);
output_code_file
.
write
(
output_code
_file
,
s
);
end
end
function
cgen_generate_
hdl_
init
(
filename
)
function
cgen_generate_init
(
filename
)
hdl
_file
=
io.open
(
filename
,
"w"
);
output_code
_file
=
io.open
(
filename
,
"w"
);
end
end
function
cgen_generate_
hdl_
done
()
function
cgen_generate_done
()
hdl_file
.
close
(
hdl
_file
);
output_code_file
.
close
(
output_code
_file
);
end
end
trunk/software/wbgen2/cgen_vhdl.lua
View file @
cc54a8c2
...
@@ -56,7 +56,7 @@ function cgen_vhdl_header()
...
@@ -56,7 +56,7 @@ function cgen_vhdl_header()
-- do we have RAMs or FIFOs? - if yes, include the wbgen2 components library.
-- do we have RAMs or FIFOs? - if yes, include the wbgen2 components library.
if
(
periph
.
ramcount
>
0
or
periph
.
fifocount
>
0
)
then
if
(
periph
.
ramcount
>
0
or
periph
.
fifocount
>
0
)
then
emit
(
"library wbgen2;"
);
emit
(
"library wbgen2;"
);
emit
(
"use wbgen2.all;"
);
emit
(
"use wbgen2.
wbgen2_pkg.
all;"
);
end
end
emit
(
""
);
emit
(
""
);
...
@@ -211,13 +211,40 @@ function cgen_generate_vhdl_code(tree)
...
@@ -211,13 +211,40 @@ function cgen_generate_vhdl_code(tree)
emit
(
""
);
emit
(
""
);
end
end
-- emits a VHDL combinatorial process
function
cgen_vhdl_combprocess
(
node
)
local
first_one
=
true
;
emiti
();
emitx
(
"process ("
);
for
i
,
v
in
pairs
(
node
.
slist
)
do
if
(
first_one
)
then
first_one
=
false
;
else
emitx
(
", "
);
end
emitx
(
v
);
end
emit
(
")"
);
emit
(
"begin"
);
indent_right
();
recurse
(
node
.
code
);
indent_left
();
emit
(
"end process;"
);
emit
(
""
);
emit
(
""
);
end
-- function takes a node and determines it's type, value and range
-- function takes a node and determines it's type, value and range
function
node_typesize
(
node
)
function
node_typesize
(
node
)
local
ts
=
{};
local
ts
=
{};
local
sig
;
local
sig
;
--
print(node);
--
if(node==nil) then print(""..node); end
-- if it's a direct signal or a numeric constant, it simply returns it.
-- if it's a direct signal or a numeric constant, it simply returns it.
...
@@ -235,7 +262,13 @@ function cgen_generate_vhdl_code(tree)
...
@@ -235,7 +262,13 @@ function cgen_generate_vhdl_code(tree)
ts
.
l
=
node
.
l
;
ts
.
l
=
node
.
l
;
ts
.
name
=
sig
.
name
;
ts
.
name
=
sig
.
name
;
ts
.
type
=
sig
.
type
;
ts
.
type
=
sig
.
type
;
ts
.
size
=
csel
(
ts
.
l
==
nil
,
1
,
ts
.
h
-
ts
.
l
+
1
);
if
(
ts
.
l
==
nil
)
then
ts
.
size
=
1
;
ts
.
type
=
BIT
;
else
ts
.
size
=
ts
.
h
-
ts
.
l
+
1
;
end
return
ts
;
return
ts
;
...
@@ -320,16 +353,17 @@ function cgen_generate_vhdl_code(tree)
...
@@ -320,16 +353,17 @@ function cgen_generate_vhdl_code(tree)
-- dest: slv <= src: signed/unsigned
-- dest: slv <= src: signed/unsigned
if
(
tsd
.
type
==
SLV
)
then
if
(
tsd
.
type
==
SLV
)
then
return
(
"std_logic_vector("
..
gen_subrange
(
tss
.
name
)
..
")"
);
return
(
"std_logic_vector("
..
gen_subrange
(
tss
)
..
")"
);
else
die
(
"unsupported assignment: "
..
tsd
.
name
..
" "
..
tss
.
name
);
end
else
die
(
"unsupported assignment: "
..
tsd
.
name
..
" "
..
tss
.
name
);
end
elseif
(
tss
.
type
==
SLV
)
then
elseif
(
tss
.
type
==
SLV
)
then
-- dest: signed/unsigned <= src: slv
-- dest: signed/unsigned <= src: slv
if
(
tsd
.
type
==
SIGNED
)
then
if
(
tsd
.
type
==
SIGNED
)
then
return
(
"signed("
..
gen_subrange
(
tss
.
name
)
..
")"
);
return
(
"signed("
..
gen_subrange
(
tss
)
..
")"
);
elseif
(
tsd
.
type
==
UNSIGNED
)
then
elseif
(
tsd
.
type
==
UNSIGNED
)
then
return
(
"unsigned("
..
gen_subrange
(
tss
.
name
)
..
")"
);
print
(
tss
);
return
(
"unsigned("
..
gen_subrange
(
tss
)
..
")"
);
else
die
(
"unsupported assignment: "
..
tsd
.
name
..
" "
..
tss
.
name
);
end
else
die
(
"unsupported assignment: "
..
tsd
.
name
..
" "
..
tss
.
name
);
end
else
die
(
"unsupported assignment: "
..
tsd
.
name
..
" "
..
tss
.
name
);
end
else
die
(
"unsupported assignment: "
..
tsd
.
name
..
" "
..
tss
.
name
);
end
...
@@ -344,11 +378,13 @@ function cgen_generate_vhdl_code(tree)
...
@@ -344,11 +378,13 @@ function cgen_generate_vhdl_code(tree)
-- source node is an expression? - recurse it
-- source node is an expression? - recurse it
if
(
tss
.
type
==
EXPRESSION
)
then
if
(
tss
.
type
==
EXPRESSION
)
then
emiti
();
emiti
();
-- print(gen_subrange(tsd));
emitx
(
gen_subrange
(
tsd
)
..
" <= "
);
emitx
(
gen_subrange
(
tsd
)
..
" <= "
);
recurse
({
tss
.
code
});
recurse
({
tss
.
code
});
emitx
(
";\n"
);
emitx
(
";\n"
);
else
else
-- not an expression? - assign the destination with proper type casting.
-- not an expression? - assign the destination with proper type casting.
-- print(gen_subrange(tsd));
emit
(
gen_subrange
(
tsd
)
..
" <= "
..
gen_vhdl_typecvt
(
tsd
,
tss
)
..
";"
);
emit
(
gen_subrange
(
tsd
)
..
" <= "
..
gen_vhdl_typecvt
(
tsd
,
tss
)
..
";"
);
end
end
end
end
...
@@ -393,10 +429,13 @@ function cgen_generate_vhdl_code(tree)
...
@@ -393,10 +429,13 @@ function cgen_generate_vhdl_code(tree)
-- function generates code for a VHDL binary expression.
-- function generates code for a VHDL binary expression.
function
cgen_vhdl_binary_op
(
node
)
function
cgen_vhdl_binary_op
(
node
)
local
tsa
=
node_typesize
(
node
.
a
);
local
tsa
=
node_typesize
(
node
.
a
);
local
tsb
=
node_typesize
(
node
.
b
);
local
tsb
=
node_typesize
(
node
.
b
);
local
op
=
node
.
t
;
local
op
=
node
.
t
;
-- emit the left-side operand
-- emit the left-side operand
if
(
tsa
.
type
==
EXPRESSION
)
then
if
(
tsa
.
type
==
EXPRESSION
)
then
emitx
(
"("
);
recurse
({
node
.
a
});
emitx
(
")"
);
emitx
(
"("
);
recurse
({
node
.
a
});
emitx
(
")"
);
...
@@ -422,6 +461,7 @@ function cgen_generate_vhdl_code(tree)
...
@@ -422,6 +461,7 @@ function cgen_generate_vhdl_code(tree)
--
--
function
cgen_vhdl_comment
(
node
)
function
cgen_vhdl_comment
(
node
)
-- print("COMMENT: "..node.str);
emitx
(
"-- "
..
node
.
str
..
"
\n
"
);
emitx
(
"-- "
..
node
.
str
..
"
\n
"
);
end
end
...
@@ -525,12 +565,23 @@ function cgen_generate_vhdl_code(tree)
...
@@ -525,12 +565,23 @@ function cgen_generate_vhdl_code(tree)
emit
(
""
);
emit
(
""
);
end
end
-- generates VHDL "others => value" construct
function
cgen_vhdl_others
(
node
)
emitx
(
"(others => '"
..
node
.
val
..
"')"
);
end
-- generates VHDL "pin => open" mapping
function
cgen_vhdl_openpin
(
node
)
emitx
(
"open"
);
end
-- the main recursive traversal function.
-- the main recursive traversal function.
function
recurse
(
node
)
function
recurse
(
node
)
local
generators
=
{
local
generators
=
{
[
"comment"
]
=
cgen_vhdl_comment
;
[
"comment"
]
=
cgen_vhdl_comment
;
[
"syncprocess"
]
=
cgen_vhdl_syncprocess
;
[
"syncprocess"
]
=
cgen_vhdl_syncprocess
;
[
"combprocess"
]
=
cgen_vhdl_combprocess
;
[
"assign"
]
=
cgen_vhdl_assign
;
[
"assign"
]
=
cgen_vhdl_assign
;
[
"if"
]
=
cgen_vhdl_if
;
[
"if"
]
=
cgen_vhdl_if
;
[
"eq"
]
=
cgen_vhdl_binary_op
;
[
"eq"
]
=
cgen_vhdl_binary_op
;
...
@@ -541,14 +592,20 @@ function cgen_generate_vhdl_code(tree)
...
@@ -541,14 +592,20 @@ function cgen_generate_vhdl_code(tree)
[
"not"
]
=
cgen_vhdl_not
;
[
"not"
]
=
cgen_vhdl_not
;
[
"switch"
]
=
cgen_vhdl_switch
;
[
"switch"
]
=
cgen_vhdl_switch
;
[
"instance"
]
=
cgen_vhdl_instance
;
[
"instance"
]
=
cgen_vhdl_instance
;
[
"others"
]
=
cgen_vhdl_others
;
[
"openpin"
]
=
cgen_vhdl_openpin
;
};
};
-- print(node);
for
i
,
v
in
pairs
(
node
)
do
for
i
,
v
in
pairs
(
node
)
do
-- no type? probably just a block of code. recurse it deeper.
-- no type? probably just a block of code. recurse it deeper.
if
(
v
.
t
==
nil
)
then
if
(
v
.
t
==
nil
)
then
recurse
(
v
);
recurse
(
v
);
else
else
local
func
=
generators
[
v
.
t
];
local
func
=
generators
[
v
.
t
];
-- print(v.t);
if
(
func
==
nil
)
then
if
(
func
==
nil
)
then
die
(
"Unimplemented generator: "
..
v
.
t
);
die
(
"Unimplemented generator: "
..
v
.
t
);
end
end
...
...
trunk/software/wbgen2/examples/gpio_port/gpio_port.vhdl
View file @
cc54a8c2
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
-- Author : T.W.
-- Author : T.W.
-- Company :
-- Company :
-- Created : 2010-02-22
-- Created : 2010-02-22
-- Last update: 2010-0
2-22
-- Last update: 2010-0
3-15
-- Platform :
-- Platform :
-- Standard : VHDL'87
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
...
@@ -33,7 +33,7 @@ entity gpio_port is
...
@@ -33,7 +33,7 @@ entity gpio_port is
wb_data_i
:
in
std_logic_vector
(
31
downto
0
);
wb_data_i
:
in
std_logic_vector
(
31
downto
0
);
wb_data_o
:
out
std_logic_vector
(
31
downto
0
);
wb_data_o
:
out
std_logic_vector
(
31
downto
0
);
wb_cyc_i
:
in
std_logic
;
wb_cyc_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic
_vector
(
3
downto
0
)
;
wb_stb_i
:
in
std_logic
;
wb_stb_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_ack_o
:
out
std_logic
;
wb_ack_o
:
out
std_logic
;
...
@@ -53,7 +53,7 @@ architecture syn of gpio_port is
...
@@ -53,7 +53,7 @@ architecture syn of gpio_port is
wb_data_i
:
in
std_logic_vector
(
31
downto
0
);
wb_data_i
:
in
std_logic_vector
(
31
downto
0
);
wb_data_o
:
out
std_logic_vector
(
31
downto
0
);
wb_data_o
:
out
std_logic_vector
(
31
downto
0
);
wb_cyc_i
:
in
std_logic
;
wb_cyc_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic
_vector
(
3
downto
0
)
;
wb_stb_i
:
in
std_logic
;
wb_stb_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_ack_o
:
out
std_logic
;
wb_ack_o
:
out
std_logic
;
...
...
trunk/software/wbgen2/examples/gpio_port/testbench.v
View file @
cc54a8c2
...
@@ -7,6 +7,8 @@
...
@@ -7,6 +7,8 @@
module
main
;
module
main
;
reg
clk
=
1
;
reg
clk
=
1
;
reg
rst
=
0
;
reg
rst
=
0
;
wire
[
3
:
0
]
ones
=
'b1111
;
always
#(
`wbclk_period
/
2
)
clk
<=
~
clk
;
always
#(
`wbclk_period
/
2
)
clk
<=
~
clk
;
...
@@ -26,10 +28,10 @@ module main;
...
@@ -26,10 +28,10 @@ module main;
.
wb_data_i
(
wb_data_o
)
,
.
wb_data_i
(
wb_data_o
)
,
.
wb_data_o
(
wb_data_i
)
,
.
wb_data_o
(
wb_data_i
)
,
.
wb_cyc_i
(
wb_cyc
)
,
.
wb_cyc_i
(
wb_cyc
)
,
.
wb_sel_i
(
wb_sel
)
,
.
wb_stb_i
(
wb_stb
)
,
.
wb_stb_i
(
wb_stb
)
,
.
wb_we_i
(
wb_we
)
,
.
wb_we_i
(
wb_we
)
,
.
wb_ack_o
(
wb_ack
)
,
.
wb_ack_o
(
wb_ack
)
,
.
wb_sel_i
(
ones
)
,
.
gpio_pins_b
(
gpio_pins_b
)
.
gpio_pins_b
(
gpio_pins_b
)
)
;
)
;
...
...
trunk/software/wbgen2/examples/gpio_port_async/gpio_port_async.vhdl
View file @
cc54a8c2
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
-- Author : T.W.
-- Author : T.W.
-- Company :
-- Company :
-- Created : 2010-02-22
-- Created : 2010-02-22
-- Last update: 2010-0
2-22
-- Last update: 2010-0
3-16
-- Platform :
-- Platform :
-- Standard : VHDL'87
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
...
@@ -33,7 +33,7 @@ entity gpio_port_async is
...
@@ -33,7 +33,7 @@ entity gpio_port_async is
wb_data_i
:
in
std_logic_vector
(
31
downto
0
);
wb_data_i
:
in
std_logic_vector
(
31
downto
0
);
wb_data_o
:
out
std_logic_vector
(
31
downto
0
);
wb_data_o
:
out
std_logic_vector
(
31
downto
0
);
wb_cyc_i
:
in
std_logic
;
wb_cyc_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic
_vector
(
3
downto
0
)
;
wb_stb_i
:
in
std_logic
;
wb_stb_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_ack_o
:
out
std_logic
;
wb_ack_o
:
out
std_logic
;
...
@@ -54,7 +54,7 @@ architecture syn of gpio_port_async is
...
@@ -54,7 +54,7 @@ architecture syn of gpio_port_async is
wb_data_i
:
in
std_logic_vector
(
31
downto
0
);
wb_data_i
:
in
std_logic_vector
(
31
downto
0
);
wb_data_o
:
out
std_logic_vector
(
31
downto
0
);
wb_data_o
:
out
std_logic_vector
(
31
downto
0
);
wb_cyc_i
:
in
std_logic
;
wb_cyc_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic
_vector
(
3
downto
0
)
;
wb_stb_i
:
in
std_logic
;
wb_stb_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_ack_o
:
out
std_logic
;
wb_ack_o
:
out
std_logic
;
...
...
trunk/software/wbgen2/examples/gpio_port_async/testbench.v
View file @
cc54a8c2
...
@@ -9,6 +9,9 @@ module main;
...
@@ -9,6 +9,9 @@ module main;
reg
clk
=
1
;
reg
clk
=
1
;
reg
clk_async
=
1
;
reg
clk_async
=
1
;
reg
rst
=
0
;
reg
rst
=
0
;
wire
[
3
:
0
]
ones
=
'b1111
;
always
#(
`wbclk_period
)
clk
<=~
clk
;
always
#(
`wbclk_period
)
clk
<=~
clk
;
always
#(
`clk_async_period
/
2
)
clk_async
<=
~
clk_async
;
always
#(
`clk_async_period
/
2
)
clk_async
<=
~
clk_async
;
...
@@ -28,10 +31,11 @@ module main;
...
@@ -28,10 +31,11 @@ module main;
.
wb_data_i
(
wb_data_o
)
,
.
wb_data_i
(
wb_data_o
)
,
.
wb_data_o
(
wb_data_i
)
,
.
wb_data_o
(
wb_data_i
)
,
.
wb_cyc_i
(
wb_cyc
)
,
.
wb_cyc_i
(
wb_cyc
)
,
.
wb_sel_i
(
wb_sel
)
,
.
wb_sel_i
(
ones
)
,
.
wb_stb_i
(
wb_stb
)
,
.
wb_stb_i
(
wb_stb
)
,
.
wb_we_i
(
wb_we
)
,
.
wb_we_i
(
wb_we
)
,
.
wb_ack_o
(
wb_ack
)
,
.
wb_ack_o
(
wb_ack
)
,
.
gpio_clk_i
(
clk_async
)
,
.
gpio_clk_i
(
clk_async
)
,
.
gpio_pins_b
(
gpio_pins_b
)
.
gpio_pins_b
(
gpio_pins_b
)
...
...
trunk/software/wbgen2/lib/wbgen2_pkg.vhd
View file @
cc54a8c2
...
@@ -6,30 +6,28 @@ library wbgen2;
...
@@ -6,30 +6,28 @@ library wbgen2;
package
wbgen2_pkg
is
package
wbgen2_pkg
is
component
wbgen2_dpssram
component
wbgen2_dpssram
generic
(
generic
(
g_data_width
:
natural
;
g_data_width
:
natural
;
g_size
:
natural
;
g_size
:
natural
;
g_addr_width
:
natural
;
g_addr_width
:
natural
;
g_dual_clock
:
boolean
;
g_dual_clock
:
boolean
;
g_use_bwsel
:
boolean
);
g_use_bwsel
:
boolean
);
port
(
port
(
clk_a_i
:
in
std_logic
;
clk_a_i
:
in
std_logic_vector
((
g_data_width
+
7
)
/
8
downto
0
);
clk_b_i
:
in
std_logic
;
clk_b_i
:
in
std_logic
;
addr_a_i
:
in
std_logic_vector
(
g_addr_width
-1
downto
0
);
addr_a_i
:
in
std_logic_vector
(
g_addr_width
-1
downto
0
);
addr_b_i
:
in
std_logic_vector
(
g_addr_width
-1
downto
0
);
addr_b_i
:
in
std_logic_vector
(
g_addr_width
-1
downto
0
);
data_a_i
:
in
std_logic_vector
(
g_data_width
-1
downto
0
);
data_a_i
:
in
std_logic_vector
(
g_data_width
-1
downto
0
);
data_b_i
:
in
std_logic_vector
(
g_data_width
-1
downto
0
);
data_b_i
:
in
std_logic_vector
(
g_data_width
-1
downto
0
);
data_a_o
:
out
std_logic_vector
(
g_data_width
-1
downto
0
);
data_a_o
:
in
std_logic_vector
(
g_data_width
-1
downto
0
);
data_b_o
:
out
std_logic_vector
(
g_data_width
-1
downto
0
);
data_b_o
:
in
std_logic_vector
(
g_data_width
-1
downto
0
);
bwsel_a_i
:
in
std_logic_vector
((
g_data_width
+
7
)
/
8
downto
0
);
bwsel_a_i
:
in
std_logic_vector
((
g_data_width
+
7
)
/
8
downto
0
);
bwsel_b_i
:
in
std_logic_vector
((
g_data_width
+
7
)
/
8
downto
0
);
bwsel_b_i
:
in
std_logic_vector
((
g_data_width
+
7
)
/
8
downto
0
);
rd_a_i
:
in
std_logic
;
rd_a_i
:
in
std_logic
;
rd_b_i
:
in
std_logic
;
rd_b_i
:
in
std_logic
;
wr_a_i
:
in
std_logic
;
wr_a_i
:
in
std_logic
;
wr_b_i
:
in
std_logic
);
wr_b_i
:
in
std_logic
);
end
component
;
end
component
;
end
wbgen2_pkg
;
end
wbgen2_pkg
;
trunk/software/wbgen2/maketest.sh
0 → 100755
View file @
cc54a8c2
#!/bin/bash
./wbgen2.lua regs_with_fields.wb
-vo
a.vhd
-co
a.h
#vlib work
#vlib wbgen2
#vcom -work wbgen2 lib/wbgen2_pkg.vhd
#vcom -work wbgen2 lib/wbgen2_dpssram.vhd
#vcom a.vhd
trunk/software/wbgen2/regs_with_fields.wb
0 → 100644
View file @
cc54a8c2
-- here comes our peripheral definition
peripheral {
-- short (human-readable) name for the peripheral.
name = "Test fields and regs";
-- a longer description, if you want
description = "";
-- name of the target VHDL entity to be generated
hdl_entity = "wb_slave_test_regs_fields";
-- prefix for all the generated ports belonging to our peripheral
prefix = "TESTRF";
-- Pin direction register. Readable and writable from the bus, readable from the device.
reg {
name = "Test register SLV/BITs";
description = "Test register SLV/BITs";
prefix = "TRSLV";
field {
name = "Bit field 1";
description = "";
prefix = "BIT1";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Bit field 2";
description = "";
prefix = "BIT2";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Reset bit";
description = "write 1 to reset something";
prefix = "RESET";
type = MONOSTABLE;
};
field {
name = "Counter";
description = "8-bit counter";
prefix = "CNTR";
type = SLV;
size = 8;
align = 8;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "16-bit value";
description = "16-bit SLV";
prefix = "SLV16";
type = SLV;
size = 16;
align = 16;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Test register signed";
prefix = "TSIGNED";
field {
name = "Signed with range";
prefix = "signedrange";
type = SIGNED;
range = {-100, 100};
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Signed 1";
prefix = "signed12bit";
type = SIGNED;
align = 16;
size = 12;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Test register UNsigned";
prefix = "TUNSIGNED";
align = 4;
field {
name = "UnSigned with range";
prefix = "unsignedrange";
type = UNSIGNED;
range = {-200, 250};
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "UNSigned 1";
prefix = "signed13bit";
type = UNSIGNED;
align = 16;
size = 13;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
ram {
name = "memory 1";
prefix = "mem1K";
size = 256;
width = 32;
byte_select = true;
clock = "clk1_i";
wrap_bits = 1;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
};
ram {
name = "memory 2";
prefix = "mem2K";
size = 1024;
width = 16;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
trunk/software/wbgen2/target_wishbone.lua
View file @
cc54a8c2
This diff is collapsed.
Click to expand it.
trunk/software/wbgen2/wbgen2.lua
View file @
cc54a8c2
...
@@ -15,6 +15,7 @@ dofile(wbgen2_libdir.."/wbgen_common.lua");
...
@@ -15,6 +15,7 @@ dofile(wbgen2_libdir.."/wbgen_common.lua");
dofile
(
wbgen2_libdir
..
"/cgen_common.lua"
);
dofile
(
wbgen2_libdir
..
"/cgen_common.lua"
);
dofile
(
wbgen2_libdir
..
"/cgen_vhdl.lua"
);
dofile
(
wbgen2_libdir
..
"/cgen_vhdl.lua"
);
dofile
(
wbgen2_libdir
..
"/cgen_verilog.lua"
);
dofile
(
wbgen2_libdir
..
"/cgen_verilog.lua"
);
dofile
(
wbgen2_libdir
..
"/cgen_c_headers.lua"
);
dofile
(
wbgen2_libdir
..
"/wbgen_regbank.lua"
);
dofile
(
wbgen2_libdir
..
"/wbgen_regbank.lua"
);
dofile
(
wbgen2_libdir
..
"/wbgen_rams.lua"
);
dofile
(
wbgen2_libdir
..
"/wbgen_rams.lua"
);
dofile
(
wbgen2_libdir
..
"/target_wishbone.lua"
);
dofile
(
wbgen2_libdir
..
"/target_wishbone.lua"
);
...
@@ -57,7 +58,7 @@ function parse_args(arg)
...
@@ -57,7 +58,7 @@ function parse_args(arg)
options
.
output_hdl_file
=
chk_nil
(
arg
[
n
+
1
],
"HDL output filename expected"
);
options
.
output_hdl_file
=
chk_nil
(
arg
[
n
+
1
],
"HDL output filename expected"
);
n
=
n
+
2
;
n
=
n
+
2
;
elseif
(
sw
==
"-co"
)
then
elseif
(
sw
==
"-co"
)
then
o
utput_c
_file
=
chk_nil
(
arg
[
n
+
1
],
"C header output filename expected"
);
o
ptions
.
output_c_header
_file
=
chk_nil
(
arg
[
n
+
1
],
"C header output filename expected"
);
n
=
n
+
2
;
n
=
n
+
2
;
elseif
(
sw
==
"--gen-reg-constants"
)
then
elseif
(
sw
==
"--gen-reg-constants"
)
then
vhdl_gen_reg_constants
=
true
;
vhdl_gen_reg_constants
=
true
;
...
@@ -94,17 +95,29 @@ foreach_reg( fix_prefix );
...
@@ -94,17 +95,29 @@ foreach_reg( fix_prefix );
periph
=
fix_prefix
(
periph
);
periph
=
fix_prefix
(
periph
);
wbgen_count_subblocks
();
foreach_field
(
calc_size
);
foreach_field
(
calc_size
);
foreach_reg
(
check_max_size
);
foreach_reg
(
check_max_size
);
foreach_field
(
calc_field_offsets
);
foreach_field
(
calc_field_offsets
);
foreach_reg
(
calc_address_sizes
);
foreach_reg
(
calc_address_sizes
);
assign_addresses
();
assign_addresses
();
tree
=
gen_bus_logic_wishbone
();
tree
=
gen_bus_logic_wishbone
();
cgen_build_signals_ports
();
cgen_build_signals_ports
();
cgen_generate_hdl_init
(
options
.
output_hdl_file
)
cgen_generate_vhdl_code
(
tree
);
if
(
options
.
output_hdl_file
~=
nil
)
then
cgen_generate_hdl_done
();
cgen_generate_init
(
options
.
output_hdl_file
)
cgen_generate_vhdl_code
(
tree
);
cgen_generate_done
();
end
if
(
options
.
output_c_header_file
~=
nil
)
then
cgen_generate_init
(
options
.
output_c_header_file
)
cgen_generate_c_header_code
();
cgen_generate_done
();
end
trunk/software/wbgen2/wbgen_common.lua
View file @
cc54a8c2
...
@@ -165,6 +165,9 @@ function calc_field_offsets(field, reg)
...
@@ -165,6 +165,9 @@ function calc_field_offsets(field, reg)
reg
.
current_offset
=
ofs
+
field
.
size
;
reg
.
current_offset
=
ofs
+
field
.
size
;
field
.
offset
=
ofs
;
field
.
offset
=
ofs
;
if
(
reg
.
num_fields
==
nil
)
then
reg
.
num_fields
=
0
;
end
reg
.
num_fields
=
reg
.
num_fields
+
1
;
if
(
reg
.
__type
==
TYPE_REG
and
reg
.
current_offset
>
DATA_BUS_WIDTH
)
then
if
(
reg
.
__type
==
TYPE_REG
and
reg
.
current_offset
>
DATA_BUS_WIDTH
)
then
die
(
"Total size of register '"
..
reg
.
name
..
"' ("
..
reg
.
current_offset
..
") exceeds data bus width ("
..
DATA_BUS_WIDTH
..
")"
);
die
(
"Total size of register '"
..
reg
.
name
..
"' ("
..
reg
.
current_offset
..
") exceeds data bus width ("
..
DATA_BUS_WIDTH
..
")"
);
...
@@ -322,7 +325,8 @@ function calc_address_sizes(reg)
...
@@ -322,7 +325,8 @@ function calc_address_sizes(reg)
die
(
"RAM '"
..
reg
.
name
..
"' data width exceeds WB data bus width"
);
die
(
"RAM '"
..
reg
.
name
..
"' data width exceeds WB data bus width"
);
end
end
reg
.
select_bits
=
num_rams
+
1
;
reg
.
select_bits
=
csel
(
periph
.
regcount
+
periph
.
fifocount
==
0
,
num_rams
,
num_rams
+
1
);
num_rams
=
num_rams
+
1
;
num_rams
=
num_rams
+
1
;
end
end
...
@@ -418,3 +422,28 @@ function remove_duplicates(t)
...
@@ -418,3 +422,28 @@ function remove_duplicates(t)
end
end
end
end
function
wbgen_count_subblocks
()
local
ramcount
=
0
;
local
fifocount
=
0
;
local
regcount
=
0
;
-- count the RAMs & FIFOs in the design
foreach_reg
(
function
(
reg
)
if
(
reg
.
__type
==
TYPE_RAM
)
then
ramcount
=
ramcount
+
1
;
end
if
(
reg
.
__type
==
TYPE_FIFO
)
then
fifocount
=
fifocount
+
1
;
end
if
(
reg
.
__type
==
TYPE_REG
)
then
regcount
=
regcount
+
1
;
end
end
);
periph
.
ramcount
=
ramcount
;
periph
.
fifocount
=
fifocount
;
periph
.
regcount
=
regcount
;
end
trunk/software/wbgen2/wbgen_rams.lua
View file @
cc54a8c2
#!/usr/bin/lua
#!/usr/bin/lua
function
gen_code_ram
(
ram
)
function
ram_wire_core_ports
(
ram
)
local
prefix
=
string.lower
(
periph
.
hdl_prefix
..
"_"
..
ram
.
hdl_prefix
);
local
prefix
=
ram
.
full_prefix
;
local
maps
=
{};
print
(
"GENRAMCODE!"
..
ram
.
name
);
-- generate the RAM-related ports
ram
.
full_prefix
=
prefix
;
ram
.
signals
=
{};
ram
.
ports
=
{
port
(
SLV
,
ram
.
addr_bits
-
ram
.
wrap_bits
,
"in"
,
prefix
..
"_addr_i"
,
"Ports for RAM: "
..
ram
.
name
)
};
ram
.
reset_code_main
=
{};
table_join
(
maps
,
{
vpm
(
"clk_a_i"
,
"bus_clock"
);
vpm
(
"clk_b_i"
,
csel
(
ram
.
clock
~=
nil
,
ram
.
clock
,
"bus_clock"
));
vpm
(
"addr_b_i"
,
prefix
..
"_addr_i"
);
});
if
(
match
(
ram
.
access_dev
,
{
READ_ONLY
,
READ_WRITE
}))
then
-- RAM is readable from the core - wire the data output and read strobe signals
if
(
match
(
ram
.
access_dev
,
{
READ_ONLY
,
READ_WRITE
}))
then
table_join
(
ram
.
ports
,
{
port
(
SLV
,
ram
.
width
,
"out"
,
prefix
..
"_data_o"
,
"Read data output"
),
table_join
(
ram
.
ports
,
{
port
(
SLV
,
ram
.
width
,
"out"
,
prefix
..
"_data_o"
,
"Read data output"
),
port
(
BIT
,
0
,
"in"
,
prefix
..
"_rd_i"
,
"Read strobe input (active high)"
)
});
port
(
BIT
,
0
,
"in"
,
prefix
..
"_rd_i"
,
"Read strobe input (active high)"
)
});
table_join
(
ram
.
maps
,
{
vpm
(
"data_b_o"
,
prefix
..
"_data_o"
);
table_join
(
maps
,
{
vpm
(
"data_b_o"
,
prefix
..
"_data_o"
);
vpm
(
"rd_b_i"
,
prefix
..
"_rd_i"
);
}
);
vpm
(
"rd_b_i"
,
prefix
..
"_rd_i"
);
}
);
else
-- ram is not readable - the read strobe low and leave the data output open
table_join
(
ram
.
maps
,
{
vpm
(
"data_b_o"
,
vopenpin
());
vpm
(
"rd_b_i"
,
vi
(
allzeros
,
0
))
});
end
end
if
(
match
(
ram
.
access_dev
,
{
WRITE_ONLY
,
READ_WRITE
}))
then
if
(
match
(
ram
.
access_dev
,
{
WRITE_ONLY
,
READ_WRITE
}))
then
table_join
(
ram
.
ports
,
{
port
(
SLV
,
ram
.
width
,
"in"
,
prefix
..
"_data_i"
,
"Write data input"
),
port
(
BIT
,
0
,
"in"
,
prefix
..
"_wr_i"
,
"Write strobe (active high)"
)
});
table_join
(
maps
,
{
vpm
(
"data_b_i"
,
prefix
..
"_data_i"
);
table_join
(
ram
.
ports
,
{
port
(
SLV
,
ram
.
width
,
"in"
,
prefix
..
"_data_i"
,
"Write data input"
),
vpm
(
"wr_b_i"
,
prefix
..
"_wr_i"
);
});
port
(
BIT
,
0
,
"in"
,
prefix
..
"_wr_i"
,
"Write strobe (active high)"
)
});
table_join
(
ram
.
maps
,
{
vpm
(
"data_b_i"
,
prefix
..
"_data_i"
);
vpm
(
"wr_b_i"
,
prefix
..
"_wr_i"
);
});
if
(
ram
.
byte_select
==
true
and
ram
.
width
>=
16
)
then
if
(
ram
.
byte_select
==
true
and
ram
.
width
>=
16
)
then
table_join
(
ram
.
ports
,
{
port
(
SLV
,
ram
.
width
/
8
,
"in"
,
prefix
..
"_bwsel_i"
,
"Byte select input (active high)"
)
}
);
table_join
(
ram
.
ports
,
{
port
(
SLV
,
ram
.
width
/
8
,
"in"
,
prefix
..
"_bwsel_i"
,
"Byte select input (active high)"
)
}
);
table_join
(
maps
,
{
vpm
(
"bwsel_b_i"
,
prefix
..
"_bwsel_i"
);
}
);
table_join
(
ram
.
maps
,
{
vpm
(
"bwsel_b_i"
,
prefix
..
"_bwsel_i"
);
}
);
end
else
table_join
(
ram
.
maps
,
{
vpm
(
"bwsel_b_i"
,
vi
(
"allones"
,
math.floor
(
ram
.
width
/
8
)
-
1
,
0
));
}
);
end
else
table_join
(
ram
.
maps
,
{
vpm
(
"bwsel_b_i"
,
vi
(
"allones"
,
math.floor
(
ram
.
width
/
8
)
-
1
,
0
));
vpm
(
"data_b_i"
,
vi
(
"allzeros"
,
ram
.
width
-
1
,
0
));
vpm
(
"wr_b_i"
,
vi
(
"allzeros"
,
0
))
});
end
end
end
function
ram_wire_bus_ports
(
ram
)
table_join
(
maps
,
{
vpm
(
"addr_a_i"
,
vi
(
"rwaddr_reg"
,
log2up
(
ram
.
size
)
-
1
,
0
))
});
local
prefix
=
ram
.
full_prefix
;
if
(
match
(
ram
.
access_bus
,
{
READ_ONLY
,
READ_WRITE
}))
then
-- RAM is readable from the bus?
if
(
match
(
ram
.
access_bus
,
{
READ_ONLY
,
READ_WRITE
}))
then
-- yes: wire rd strobe and data output
table_join
(
ram
.
signals
,
{
signal
(
SLV
,
ram
.
width
,
prefix
..
"_rddata_int"
),
table_join
(
ram
.
signals
,
{
signal
(
SLV
,
ram
.
width
,
prefix
..
"_rddata_int"
),
signal
(
BIT
,
0
,
prefix
..
"_rd_int"
)
}
);
signal
(
BIT
,
0
,
prefix
..
"_rd_int"
)
}
);
table_join
(
maps
,
{
vpm
(
"data_a_o"
,
vi
(
prefix
..
"_rddata_int"
,
ram
.
width
-
1
,
0
));
table_join
(
ram
.
maps
,
{
vpm
(
"data_a_o"
,
vi
(
prefix
..
"_rddata_int"
,
ram
.
width
-
1
,
0
));
vpm
(
"rd_a_i"
,
prefix
..
"_rd_int"
);
}
);
vpm
(
"rd_a_i"
,
prefix
..
"_rd_int"
);
}
);
table_join
(
ram
.
reset_code_main
,
{
va
(
prefix
..
"_rd_int"
,
0
);
});
else
-- not readable? - set read strobe to zero and leave the data output open
table_join
(
ram
.
maps
,
{
vpm
(
"rd_a_i"
,
vi
(
"allzeros"
,
0
)),
vpm
(
"data_a_o"
,
vopenpin
())
});
end
end
-- RAM is writable from the bus?
if
(
match
(
ram
.
access_bus
,
{
WRITE_ONLY
,
READ_WRITE
}))
then
if
(
match
(
ram
.
access_bus
,
{
WRITE_ONLY
,
READ_WRITE
}))
then
table_join
(
ram
.
signals
,
{
signal
(
BIT
,
0
,
prefix
..
"_wr_int"
)
}
);
table_join
(
ram
.
signals
,
{
signal
(
BIT
,
0
,
prefix
..
"_wr_int"
)
}
);
table_join
(
maps
,
{
vpm
(
"data_a_i"
,
vi
(
"wrdata_reg"
,
ram
.
width
-
1
,
0
));
table_join
(
ram
.
maps
,
{
vpm
(
"data_a_i"
,
vi
(
"wrdata_reg"
,
ram
.
width
-
1
,
0
));
vpm
(
"wr_a_i"
,
prefix
..
"_wr_int"
);
});
vpm
(
"wr_a_i"
,
prefix
..
"_wr_int"
);
});
table_join
(
ram
.
reset_code_main
,
{
va
(
prefix
..
"_wr_int"
,
0
);
});
if
(
ram
.
byte_select
==
true
and
ram
.
width
>=
16
)
then
if
(
ram
.
byte_select
==
true
and
ram
.
width
>=
16
)
then
table_join
(
maps
,
{
vpm
(
"bwsel_a_i"
,
vi
(
"bwsel_reg"
,
math.floor
(
ram
.
width
/
8
)
-
1
,
0
));
}
);
table_join
(
ram
.
maps
,
{
vpm
(
"bwsel_a_i"
,
vi
(
"bwsel_reg"
,
math.floor
(
ram
.
width
/
8
)
-
1
,
0
));
}
);
end
else
table_join
(
ram
.
maps
,
{
vpm
(
"bwsel_a_i"
,
vi
(
"allones"
,
math.floor
(
ram
.
width
/
8
)
-
1
,
0
));
}
);
end
else
table_join
(
ram
.
maps
,
{
vpm
(
"bwsel_a_i"
,
vi
(
"allones"
,
math.floor
(
ram
.
width
/
8
)
-
1
,
0
));
vpm
(
"data_a_i"
,
vi
(
"allzeros"
,
ram
.
width
-
1
,
0
));
vpm
(
"wr_a_i"
,
vi
(
"allzeros"
,
0
))
});
end
end
end
function
gen_code_ram
(
ram
)
local
prefix
=
string.lower
(
periph
.
hdl_prefix
..
"_"
..
ram
.
hdl_prefix
);
-- generate the RAM-related ports
ram
.
full_prefix
=
prefix
;
ram
.
signals
=
{};
ram
.
maps
=
{};
ram
.
ports
=
{
port
(
SLV
,
ram
.
addr_bits
-
ram
.
wrap_bits
,
"in"
,
prefix
..
"_addr_i"
,
"Ports for RAM: "
..
ram
.
name
)
};
ram
.
reset_code_main
=
{};
-- wire the obligartory signals - address busses and clocks
table_join
(
ram
.
maps
,
{
vpm
(
"clk_a_i"
,
"bus_clock_int"
);
vpm
(
"clk_b_i"
,
csel
(
ram
.
clock
~=
nil
,
ram
.
clock
,
"bus_clock_int"
));
vpm
(
"addr_b_i"
,
prefix
..
"_addr_i"
);
vpm
(
"addr_a_i"
,
vi
(
"rwaddr_reg"
,
log2up
(
ram
.
size
)
-
1
,
0
));
});
-- evaluate the access flags (from the core) and wire the core signals to appropriate ports
ram_wire_core_ports
(
ram
);
-- do the same for the bus signals
ram_wire_bus_ports
(
ram
);
-- fill in all the generic mappings
-- fill in all the generic mappings
table_join
(
maps
,
{
vgm
(
"g_data_width"
,
ram
.
width
);
table_join
(
ram
.
maps
,
{
vgm
(
"g_data_width"
,
ram
.
width
);
vgm
(
"g_size"
,
ram
.
size
);
vgm
(
"g_size"
,
ram
.
size
);
vgm
(
"g_addr_width"
,
log2up
(
ram
.
size
));
vgm
(
"g_addr_width"
,
log2up
(
ram
.
size
));
vgm
(
"g_dual_clock"
,
csel
(
ram
.
clock
~=
nil
,
"true"
,
"false"
));
vgm
(
"g_dual_clock"
,
csel
(
ram
.
clock
~=
nil
,
"true"
,
"false"
));
vgm
(
"g_use_bwsel"
,
csel
(
ram
.
byte_select
==
true
,
"true"
,
"false"
));
vgm
(
"g_use_bwsel"
,
csel
(
ram
.
byte_select
==
true
,
"true"
,
"false"
));
});
});
-- instantiate the RAM.
ram
.
extra_code
=
{
vcomment
(
"RAM block instantiation for memory: "
..
ram
.
name
);
ram
.
extra_code
=
{
vcomment
(
"RAM block instantiation for memory: "
..
ram
.
name
);
vinstance
(
prefix
..
"_raminst"
,
"wbgen2_dpssram"
,
maps
);
};
vinstance
(
prefix
..
"_raminst"
,
"wbgen2_dpssram"
,
ram
.
maps
);
};
end
end
trunk/software/wbgen2/wbgen_regbank.lua
View file @
cc54a8c2
...
@@ -45,7 +45,7 @@ function gen_hdl_code_monostable(field, reg)
...
@@ -45,7 +45,7 @@ function gen_hdl_code_monostable(field, reg)
field
.
ports
=
{
port
(
BIT
,
0
,
"out"
,
prefix
..
"_o"
,
"Port for MONOSTABLE field: '"
..
field
.
name
..
"' in reg: '"
..
reg
.
name
..
"'"
)
};
field
.
ports
=
{
port
(
BIT
,
0
,
"out"
,
prefix
..
"_o"
,
"Port for MONOSTABLE field: '"
..
field
.
name
..
"' in reg: '"
..
reg
.
name
..
"'"
)
};
field
.
acklen
=
3
;
field
.
acklen
=
3
;
field
.
extra_code
=
vsyncprocess
(
"
wb_clk_i
"
,
"rst_n_i"
,
{
field
.
extra_code
=
vsyncprocess
(
"
bus_clock_int
"
,
"rst_n_i"
,
{
vreset
(
0
,
{
vreset
(
0
,
{
va
(
prefix
..
"_dly0"
,
0
);
va
(
prefix
..
"_dly0"
,
0
);
va
(
prefix
..
"_o"
,
0
);
va
(
prefix
..
"_o"
,
0
);
...
@@ -176,7 +176,7 @@ function gen_hdl_code_bit(field, reg)
...
@@ -176,7 +176,7 @@ function gen_hdl_code_bit(field, reg)
field
.
reset_code_main
=
{
va
(
prefix
..
"_int"
,
0
)
};
field
.
reset_code_main
=
{
va
(
prefix
..
"_int"
,
0
)
};
field
.
extra_code
=
{
vcomment
(
"synchronizer chain for field : "
..
field
.
name
..
" (type RW/RO,
wb_clk_i
<-> "
..
field
.
clock
..
")"
);
field
.
extra_code
=
{
vcomment
(
"synchronizer chain for field : "
..
field
.
name
..
" (type RW/RO,
bus_clock_int
<-> "
..
field
.
clock
..
")"
);
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vreset
(
0
,
{
vreset
(
0
,
{
va
(
prefix
..
"_o"
,
0
);
va
(
prefix
..
"_o"
,
0
);
...
@@ -204,7 +204,7 @@ function gen_hdl_code_bit(field, reg)
...
@@ -204,7 +204,7 @@ function gen_hdl_code_bit(field, reg)
field
.
reset_code_main
=
{
};
field
.
reset_code_main
=
{
};
field
.
extra_code
=
{
vcomment
(
"synchronizer chain for field : "
..
field
.
name
..
" (type RO/WO, "
..
field
.
clock
..
" ->
wb_clk_i
)"
);
field
.
extra_code
=
{
vcomment
(
"synchronizer chain for field : "
..
field
.
name
..
" (type RO/WO, "
..
field
.
clock
..
" ->
bus_clock_int
)"
);
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vreset
(
0
,
{
vreset
(
0
,
{
va
(
prefix
..
"_sync0"
,
0
);
va
(
prefix
..
"_sync0"
,
0
);
...
@@ -266,14 +266,14 @@ function gen_hdl_code_bit(field, reg)
...
@@ -266,14 +266,14 @@ function gen_hdl_code_bit(field, reg)
field
.
ackgen_code_pre
=
{
va
(
prefix
..
"_lw"
,
prefix
..
"_lw_delay"
);
field
.
ackgen_code_pre
=
{
va
(
prefix
..
"_lw"
,
prefix
..
"_lw_delay"
);
va
(
prefix
..
"_lw_delay"
,
0
);
va
(
prefix
..
"_lw_delay"
,
0
);
vif
(
vand
(
vequal
(
"ack_cntr"
,
1
),
vequal
(
prefix
..
"_lw_read_in_progress"
,
1
)),
{
vif
(
vand
(
vequal
(
vi
(
"ack_sreg"
,
1
)
,
1
),
vequal
(
prefix
..
"_lw_read_in_progress"
,
1
)),
{
va
(
vi
(
"rddata_reg"
,
field
.
offset
),
prefix
..
"_int_read"
);
va
(
vi
(
"rddata_reg"
,
field
.
offset
),
prefix
..
"_int_read"
);
va
(
prefix
..
"_lw_read_in_progress"
,
0
);
va
(
prefix
..
"_lw_read_in_progress"
,
0
);
});
});
};
};
field
.
extra_code
=
{
vcomment
(
"asynchronous BIT register : "
..
field
.
name
..
" (type RW/WO, "
..
field
.
clock
..
" <->
wb_clk_i
)"
);
field
.
extra_code
=
{
vcomment
(
"asynchronous BIT register : "
..
field
.
name
..
" (type RW/WO, "
..
field
.
clock
..
" <->
bus_clock_int
)"
);
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vreset
(
0
,
{
vreset
(
0
,
{
va
(
prefix
..
"_lw_s0"
,
0
);
va
(
prefix
..
"_lw_s0"
,
0
);
...
@@ -399,7 +399,7 @@ function gen_hdl_code_slv(field, reg)
...
@@ -399,7 +399,7 @@ function gen_hdl_code_slv(field, reg)
va
(
prefix
..
"_swb_delay"
,
0
);
};
va
(
prefix
..
"_swb_delay"
,
0
);
};
field
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
field
.
type
]
..
" register : "
..
field
.
name
..
" (type RW/RO, "
..
field
.
clock
..
" <->
wb_clk_i
)"
);
field
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
field
.
type
]
..
" register : "
..
field
.
name
..
" (type RW/RO, "
..
field
.
clock
..
" <->
bus_clock_int
)"
);
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vreset
(
0
,
{
vreset
(
0
,
{
va
(
prefix
..
"_swb_s0"
,
0
);
va
(
prefix
..
"_swb_s0"
,
0
);
...
@@ -446,13 +446,13 @@ function gen_hdl_code_slv(field, reg)
...
@@ -446,13 +446,13 @@ function gen_hdl_code_slv(field, reg)
field
.
ackgen_code_pre
=
{
va
(
prefix
..
"_lwb"
,
prefix
..
"_lwb_delay"
);
field
.
ackgen_code_pre
=
{
va
(
prefix
..
"_lwb"
,
prefix
..
"_lwb_delay"
);
va
(
prefix
..
"_lwb_delay"
,
0
);
va
(
prefix
..
"_lwb_delay"
,
0
);
vif
(
vand
(
vequal
(
"ack_cntr"
,
1
),
vequal
(
prefix
..
"_lwb_in_progress"
,
1
)),
{
vif
(
vand
(
vequal
(
vi
(
"ack_sreg"
,
1
)
,
1
),
vequal
(
prefix
..
"_lwb_in_progress"
,
1
)),
{
va
(
vir
(
"rddata_reg"
,
field
),
prefix
..
"_int"
);
va
(
vir
(
"rddata_reg"
,
field
),
prefix
..
"_int"
);
va
(
prefix
..
"_lwb_in_progress"
,
0
);
va
(
prefix
..
"_lwb_in_progress"
,
0
);
});
});
};
};
field
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
field
.
type
]
..
" register : "
..
field
.
name
..
" (type RO/WO, "
..
field
.
clock
..
" <->
wb_clk_i
)"
),
field
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
field
.
type
]
..
" register : "
..
field
.
name
..
" (type RO/WO, "
..
field
.
clock
..
" <->
bus_clock_int
)"
),
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vreset
(
0
,
{
vreset
(
0
,
{
va
(
prefix
..
"_lwb_s0"
,
0
);
va
(
prefix
..
"_lwb_s0"
,
0
);
...
@@ -520,13 +520,13 @@ function gen_hdl_code_slv(field, reg)
...
@@ -520,13 +520,13 @@ function gen_hdl_code_slv(field, reg)
field
.
ackgen_code_pre
=
{
va
(
prefix
..
"_lw"
,
prefix
..
"_lw_delay"
);
field
.
ackgen_code_pre
=
{
va
(
prefix
..
"_lw"
,
prefix
..
"_lw_delay"
);
va
(
prefix
..
"_lw_delay"
,
0
);
va
(
prefix
..
"_lw_delay"
,
0
);
vif
(
vand
(
vequal
(
"ack_cntr"
,
1
),
vequal
(
prefix
..
"_lw_read_in_progress"
,
1
)),
{
vif
(
vand
(
vequal
(
vi
(
"ack_sreg"
,
1
)
,
1
),
vequal
(
prefix
..
"_lw_read_in_progress"
,
1
)),
{
va
(
vir
(
"rddata_reg"
,
field
),
prefix
..
"_int_read"
);
va
(
vir
(
"rddata_reg"
,
field
),
prefix
..
"_int_read"
);
});
});
va
(
prefix
..
"_lw_read_in_progress"
,
0
);
va
(
prefix
..
"_lw_read_in_progress"
,
0
);
};
};
field
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
field
.
type
]
..
" register : "
..
field
.
name
..
" (type RW/WO, "
..
field
.
clock
..
" <->
wb_clk_i
)"
);
field
.
extra_code
=
{
vcomment
(
"asynchronous "
..
fieldtype_2_vhdl
[
field
.
type
]
..
" register : "
..
field
.
name
..
" (type RW/WO, "
..
field
.
clock
..
" <->
bus_clock_int
)"
);
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vsyncprocess
(
field
.
clock
,
"rst_n_i"
,
{
vreset
(
0
,
{
vreset
(
0
,
{
va
(
prefix
..
"_lw_s0"
,
0
);
va
(
prefix
..
"_lw_s0"
,
0
);
...
...
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