Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tapasco
tapasco
Commits
8d7821f5
Commit
8d7821f5
authored
Aug 23, 2017
by
Jens Korinth
Browse files
Port to Chisel 3
parent
48cb64c9
Changes
24
Hide whitespace changes
Inline
Side-by-side
build.sbt
View file @
8d7821f5
...
...
@@ -21,8 +21,9 @@ libraryDependencies ++= (Seq("chisel3","chisel-iotesters").map {
dep
:
String
=>
"edu.berkeley.cs"
%%
dep
%
sys
.
props
.
getOrElse
(
dep
+
"Version"
,
defaultVersions
(
dep
))
})
libraryDependencies
++=
Seq
(
"com.novocode"
%
"junit-interface"
%
"0.11"
%
"test"
,
"org.scalatest"
%%
"scalatest"
%
"2.2.6"
%
"test"
,
"com.typesafe.play"
%%
"play-json"
%
"2.4.8"
"com.typesafe.play"
%%
"play-json"
%
"2.4.8"
)
// no parallel testing
...
...
@@ -31,6 +32,7 @@ parallelExecution in Test := false
testForkedParallel
in
Test
:=
false
scalacOptions
++=
Seq
(
"-language:implicitConversions"
,
"-language:reflectiveCalls"
,
"-deprecation"
,
"-feature"
)
// project structure
...
...
src/main/scala/AXIDefs.scala
deleted
100644 → 0
View file @
48cb64c9
package
AXIDefs
{
import
Chisel._
import
Literal._
import
Node._
// Part I: Definitions for the actual data carried over AXI channels
// in part II we will provide definitions for the actual AXI interfaces
// by wrapping the part I types in Decoupled (ready/valid) bundles
// AXI channel data definitions
class
AXIAddress
(
addrWidthBits
:
Int
,
idBits
:
Int
)
extends
Bundle
{
// address for the transaction, should be burst aligned if bursts are used
val
addr
=
UInt
(
width
=
addrWidthBits
)
// size of data beat in bytes
// set to UInt(log2Up((dataBits/8)-1)) for full-width bursts
val
size
=
UInt
(
width
=
3
)
// number of data beats -1 in burst: max 255 for incrementing, 15 for wrapping
val
len
=
UInt
(
width
=
8
)
// burst mode: 0 for fixed, 1 for incrementing, 2 for wrapping
val
burst
=
UInt
(
width
=
2
)
// transaction ID for multiple outstanding requests
val
id
=
UInt
(
width
=
idBits
)
// set to 1 for exclusive access
val
lock
=
Bool
()
// cachability, set to 0010 or 0011
val
cache
=
UInt
(
width
=
4
)
// generally ignored, set to to all zeroes
val
prot
=
UInt
(
width
=
3
)
// not implemented, set to zeroes
val
qos
=
UInt
(
width
=
4
)
override
def
clone
=
{
new
AXIAddress
(
addrWidthBits
,
idBits
).
asInstanceOf
[
this.
type
]
}
}
class
AXIWriteData
(
dataWidthBits
:
Int
)
extends
Bundle
{
val
data
=
UInt
(
width
=
dataWidthBits
)
val
strb
=
UInt
(
width
=
dataWidthBits
/
8
)
val
last
=
Bool
()
override
def
clone
=
{
new
AXIWriteData
(
dataWidthBits
).
asInstanceOf
[
this.
type
]
}
}
class
AXIWriteResponse
(
idBits
:
Int
)
extends
Bundle
{
val
id
=
UInt
(
width
=
idBits
)
val
resp
=
UInt
(
width
=
2
)
override
def
clone
=
{
new
AXIWriteResponse
(
idBits
).
asInstanceOf
[
this.
type
]
}
}
class
AXIReadData
(
dataWidthBits
:
Int
,
idBits
:
Int
)
extends
Bundle
{
val
data
=
UInt
(
width
=
dataWidthBits
)
val
id
=
UInt
(
width
=
idBits
)
val
last
=
Bool
()
val
resp
=
UInt
(
width
=
2
)
override
def
clone
=
{
new
AXIReadData
(
dataWidthBits
,
idBits
).
asInstanceOf
[
this.
type
]
}
}
// Part II: Definitions for the actual AXI interfaces
// TODO add full slave interface definition
class
AXIMasterIF
(
addrWidthBits
:
Int
,
dataWidthBits
:
Int
,
idBits
:
Int
)
extends
Bundle
{
// write address channel
val
writeAddr
=
Decoupled
(
new
AXIAddress
(
addrWidthBits
,
idBits
))
// write data channel
val
writeData
=
Decoupled
(
new
AXIWriteData
(
dataWidthBits
))
// write response channel (for memory consistency)
val
writeResp
=
Decoupled
(
new
AXIWriteResponse
(
idBits
)).
flip
// read address channel
val
readAddr
=
Decoupled
(
new
AXIAddress
(
addrWidthBits
,
idBits
))
// read data channel
val
readData
=
Decoupled
(
new
AXIReadData
(
dataWidthBits
,
idBits
)).
flip
// rename signals to be compatible with those in the Xilinx template
def
renameSignals
(
prefix
:
Option
[
String
],
suffix
:
Option
[
String
])
=
{
// write address channel
writeAddr
.
bits
.
addr
.
setName
(
"%sM_AXI_AWADDR%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeAddr
.
bits
.
prot
.
setName
(
"%sM_AXI_AWPROT%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeAddr
.
bits
.
size
.
setName
(
"%sM_AXI_AWSIZE%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeAddr
.
bits
.
len
.
setName
(
"%sM_AXI_AWLEN%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeAddr
.
bits
.
burst
.
setName
(
"%sM_AXI_AWBURST%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeAddr
.
bits
.
lock
.
setName
(
"%sM_AXI_AWLOCK%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeAddr
.
bits
.
cache
.
setName
(
"%sM_AXI_AWCACHE%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeAddr
.
bits
.
qos
.
setName
(
"%sM_AXI_AWQOS%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeAddr
.
bits
.
id
.
setName
(
"%sM_AXI_AWID%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeAddr
.
valid
.
setName
(
"%sM_AXI_AWVALID%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeAddr
.
ready
.
setName
(
"%sM_AXI_AWREADY%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
// write data channel
writeData
.
bits
.
data
.
setName
(
"%sM_AXI_WDATA%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeData
.
bits
.
strb
.
setName
(
"%sM_AXI_WSTRB%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeData
.
bits
.
last
.
setName
(
"%sM_AXI_WLAST%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeData
.
valid
.
setName
(
"%sM_AXI_WVALID%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeData
.
ready
.
setName
(
"%sM_AXI_WREADY%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
// write response channel
writeResp
.
bits
.
resp
.
setName
(
"%sM_AXI_BRESP%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeResp
.
bits
.
id
.
setName
(
"%sM_AXI_BID%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeResp
.
valid
.
setName
(
"%sM_AXI_BVALID%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
writeResp
.
ready
.
setName
(
"%sM_AXI_BREADY%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
// read address channel
readAddr
.
bits
.
addr
.
setName
(
"%sM_AXI_ARADDR%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readAddr
.
bits
.
prot
.
setName
(
"%sM_AXI_ARPROT%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readAddr
.
bits
.
size
.
setName
(
"%sM_AXI_ARSIZE%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readAddr
.
bits
.
len
.
setName
(
"%sM_AXI_ARLEN%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readAddr
.
bits
.
burst
.
setName
(
"%sM_AXI_ARBURST%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readAddr
.
bits
.
lock
.
setName
(
"%sM_AXI_ARLOCK%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readAddr
.
bits
.
cache
.
setName
(
"%sM_AXI_ARCACHE%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readAddr
.
bits
.
qos
.
setName
(
"%sM_AXI_ARQOS%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readAddr
.
bits
.
id
.
setName
(
"%sM_AXI_ARID%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readAddr
.
valid
.
setName
(
"%sM_AXI_ARVALID%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readAddr
.
ready
.
setName
(
"%sM_AXI_ARREADY%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
// read data channel
readData
.
bits
.
id
.
setName
(
"%sM_AXI_RID%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readData
.
bits
.
data
.
setName
(
"%sM_AXI_RDATA%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readData
.
bits
.
resp
.
setName
(
"%sM_AXI_RRESP%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readData
.
bits
.
last
.
setName
(
"%sM_AXI_RLAST%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readData
.
valid
.
setName
(
"%sM_AXI_RVALID%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
readData
.
ready
.
setName
(
"%sM_AXI_RREADY%s"
.
format
(
prefix
.
getOrElse
(
""
),
suffix
.
getOrElse
(
""
)))
}
override
def
clone
=
{
new
AXIMasterIF
(
addrWidthBits
,
dataWidthBits
,
idBits
).
asInstanceOf
[
this.
type
]
}
}
}
src/main/scala/AXILiteDefs.scala
deleted
100644 → 0
View file @
48cb64c9
package
AXILiteDefs
{
import
Chisel._
import
Literal._
import
Node._
// Part I: Definitions for the actual data carried over AXI channels
// in part II we will provide definitions for the actual AXI interfaces
// by wrapping the part I types in Decoupled (ready/valid) bundles
// AXI Lite channel data definitions
class
AXILiteAddress
(
addrWidthBits
:
Int
)
extends
Bundle
{
val
addr
=
UInt
(
width
=
addrWidthBits
)
val
prot
=
UInt
(
width
=
3
)
override
def
clone
=
{
new
AXILiteAddress
(
addrWidthBits
).
asInstanceOf
[
this.
type
]
}
}
class
AXILiteWriteData
(
dataWidthBits
:
Int
)
extends
Bundle
{
val
data
=
UInt
(
width
=
dataWidthBits
)
val
strb
=
UInt
(
width
=
dataWidthBits
/
8
)
override
def
clone
=
{
new
AXILiteWriteData
(
dataWidthBits
).
asInstanceOf
[
this.
type
]
}
}
class
AXILiteReadData
(
dataWidthBits
:
Int
)
extends
Bundle
{
val
data
=
UInt
(
width
=
dataWidthBits
)
val
resp
=
UInt
(
width
=
2
)
override
def
clone
=
{
new
AXILiteReadData
(
dataWidthBits
).
asInstanceOf
[
this.
type
]
}
}
// Part II: Definitions for the actual AXI interfaces
class
AXILiteSlaveIF
(
addrWidthBits
:
Int
,
dataWidthBits
:
Int
)
extends
Bundle
{
// write address channel
val
writeAddr
=
Decoupled
(
new
AXILiteAddress
(
addrWidthBits
)).
flip
// write data channel
val
writeData
=
Decoupled
(
new
AXILiteWriteData
(
dataWidthBits
)).
flip
// write response channel (for memory consistency)
val
writeResp
=
Decoupled
(
UInt
(
width
=
2
))
// read address channel
val
readAddr
=
Decoupled
(
new
AXILiteAddress
(
addrWidthBits
)).
flip
// read data channel
val
readData
=
Decoupled
(
new
AXILiteReadData
(
dataWidthBits
))
// rename signals to be compatible with those in the Xilinx template
def
renameSignals
()
{
writeAddr
.
bits
.
addr
.
setName
(
"S_AXI_AWADDR"
)
writeAddr
.
bits
.
prot
.
setName
(
"S_AXI_AWPROT"
)
writeAddr
.
valid
.
setName
(
"S_AXI_AWVALID"
)
writeAddr
.
ready
.
setName
(
"S_AXI_AWREADY"
)
writeData
.
bits
.
data
.
setName
(
"S_AXI_WDATA"
)
writeData
.
bits
.
strb
.
setName
(
"S_AXI_WSTRB"
)
writeData
.
valid
.
setName
(
"S_AXI_WVALID"
)
writeData
.
ready
.
setName
(
"S_AXI_WREADY"
)
writeResp
.
bits
.
setName
(
"S_AXI_BRESP"
)
writeResp
.
valid
.
setName
(
"S_AXI_BVALID"
)
writeResp
.
ready
.
setName
(
"S_AXI_BREADY"
)
readAddr
.
bits
.
addr
.
setName
(
"S_AXI_ARADDR"
)
readAddr
.
bits
.
prot
.
setName
(
"S_AXI_ARPROT"
)
readAddr
.
valid
.
setName
(
"S_AXI_ARVALID"
)
readAddr
.
ready
.
setName
(
"S_AXI_ARREADY"
)
readData
.
bits
.
data
.
setName
(
"S_AXI_RDATA"
)
readData
.
bits
.
resp
.
setName
(
"S_AXI_RRESP"
)
readData
.
valid
.
setName
(
"S_AXI_RVALID"
)
readData
.
ready
.
setName
(
"S_AXI_RREADY"
)
}
override
def
clone
=
{
new
AXILiteSlaveIF
(
addrWidthBits
,
dataWidthBits
).
asInstanceOf
[
this.
type
]
}
}
class
AXILiteMasterIF
(
addrWidthBits
:
Int
,
dataWidthBits
:
Int
)
extends
Bundle
{
// write address channel
val
writeAddr
=
Decoupled
(
new
AXILiteAddress
(
addrWidthBits
))
// write data channel
val
writeData
=
Decoupled
(
new
AXILiteWriteData
(
dataWidthBits
))
// write response channel (for memory consistency)
val
writeResp
=
Decoupled
(
UInt
(
width
=
2
)).
flip
// read address channel
val
readAddr
=
Decoupled
(
new
AXILiteAddress
(
addrWidthBits
))
// read data channel
val
readData
=
Decoupled
(
new
AXILiteReadData
(
dataWidthBits
)).
flip
// rename signals to be compatible with those in the Xilinx template
def
renameSignals
()
{
writeAddr
.
bits
.
addr
.
setName
(
"M_AXI_AWADDR"
)
writeAddr
.
bits
.
prot
.
setName
(
"M_AXI_AWPROT"
)
writeAddr
.
valid
.
setName
(
"M_AXI_AWVALID"
)
writeAddr
.
ready
.
setName
(
"M_AXI_AWREADY"
)
writeData
.
bits
.
data
.
setName
(
"M_AXI_WDATA"
)
writeData
.
bits
.
strb
.
setName
(
"M_AXI_WSTRB"
)
writeData
.
valid
.
setName
(
"M_AXI_WVALID"
)
writeData
.
ready
.
setName
(
"M_AXI_WREADY"
)
writeResp
.
bits
.
setName
(
"M_AXI_BRESP"
)
writeResp
.
valid
.
setName
(
"M_AXI_BVALID"
)
writeResp
.
ready
.
setName
(
"M_AXI_BREADY"
)
readAddr
.
bits
.
addr
.
setName
(
"M_AXI_ARADDR"
)
readAddr
.
bits
.
prot
.
setName
(
"M_AXI_ARPROT"
)
readAddr
.
valid
.
setName
(
"M_AXI_ARVALID"
)
readAddr
.
ready
.
setName
(
"M_AXI_ARREADY"
)
readData
.
bits
.
data
.
setName
(
"M_AXI_RDATA"
)
readData
.
bits
.
resp
.
setName
(
"M_AXI_RRESP"
)
readData
.
valid
.
setName
(
"M_AXI_RVALID"
)
readData
.
ready
.
setName
(
"M_AXI_RREADY"
)
}
override
def
clone
=
{
new
AXILiteMasterIF
(
addrWidthBits
,
dataWidthBits
).
asInstanceOf
[
this.
type
]
}
}
}
src/main/scala/AxiFifoAdapter.scala
View file @
8d7821f5
package
chisel.axiutils
import
Chisel._
import
AXIDefs._
import
chisel3._
import
chisel3.util._
import
chisel.axi._
/**
* Configuration parameters for AxiFifoAdapter.
...
...
@@ -9,20 +10,18 @@ import AXIDefs._
* @param burstSize Number of beats per burst (optional).
* @param size Address wrap-around after size elements (optional).
**/
sealed
case
class
AxiFifoAdapterConfiguration
(
axi
:
AxiConfiguration
,
fifoDepth
:
Int
,
burstSize
:
Option
[
Int
]
=
None
,
size
:
Option
[
Int
]
=
None
)
sealed
case
class
AxiFifoAdapterConfiguration
(
fifoDepth
:
Int
,
burstSize
:
Option
[
Int
]
=
None
,
size
:
Option
[
Int
]
=
None
)
/**
* I/O bundle for AxiFifoAdapter.
**/
class
AxiFifoAdapterIO
(
cfg
:
AxiFifoAdapterConfiguration
)
extends
Bundle
{
val
maxi
=
new
AXIMasterIF
(
cfg
.
axi
.
addrWidth
,
cfg
.
axi
.
dataWidth
,
cfg
.
axi
.
idWidth
)
val
deq
=
Decoupled
(
UInt
(
width
=
cfg
.
axi
.
dataWidth
))
val
base
=
UInt
(
INPUT
,
width
=
cfg
.
axi
.
addrWidth
)
class
AxiFifoAdapterIO
(
cfg
:
AxiFifoAdapterConfiguration
)
(
implicit
axi
:
Axi4.Configuration
)
extends
Bundle
{
val
maxi
=
Axi4
.
Master
(
axi
)
val
deq
=
Decoupled
(
UInt
(
axi
.
dataWidth
))
val
base
=
Input
(
UInt
(
axi
.
addrWidth
))
}
/**
...
...
@@ -31,12 +30,13 @@ class AxiFifoAdapterIO(cfg: AxiFifoAdapterConfiguration) extends Bundle {
* interface; the FIFO itself uses handshakes for consumption.
* @param cfg Configuration parameters.
**/
class
AxiFifoAdapter
(
cfg
:
AxiFifoAdapterConfiguration
)
extends
Module
{
class
AxiFifoAdapter
(
cfg
:
AxiFifoAdapterConfiguration
)
(
implicit
axi
:
Axi4.Configuration
)
extends
Module
{
val
bsz
=
cfg
.
burstSize
.
getOrElse
(
cfg
.
fifoDepth
)
require
(
cfg
.
size
.
map
(
s
=>
log2
Up
(
s
)
<=
cfg
.
axi
.
addrWidth
).
getOrElse
(
true
),
"addrWidth (%d) must be large enough to address all %d element, at least %d bits"
.
format
(
cfg
.
axi
.
addrWidth
,
cfg
.
size
.
get
,
log2
Up
(
cfg
.
size
.
get
)))
require
(
cfg
.
size
.
map
(
s
=>
log2
Ceil
(
s
)
<=
axi
.
addrWidth
).
getOrElse
(
true
),
"addrWidth (%d) must be large enough to address all %d element
s
, at least %d bits"
.
format
(
axi
.
addrWidth
:
Int
,
cfg
.
size
.
get
,
log2
Ceil
(
cfg
.
size
.
get
)))
require
(
cfg
.
size
.
isEmpty
,
"size parameter is not implemented"
)
require
(
bsz
>
0
&&
bsz
<=
cfg
.
fifoDepth
&&
bsz
<=
256
,
...
...
@@ -44,67 +44,68 @@ class AxiFifoAdapter(cfg: AxiFifoAdapterConfiguration) extends Module {
.
format
(
bsz
,
cfg
.
fifoDepth
))
println
(
"AxiFifoAdapter: fifoDepth = %d, address bits = %d, data bits = %d, id bits = %d%s%s"
.
format
(
cfg
.
fifoDepth
,
cfg
.
axi
.
addrWidth
,
cfg
.
axi
.
dataWidth
,
cfg
.
axi
.
idWidth
,
.
format
(
cfg
.
fifoDepth
,
axi
.
addrWidth
:
Int
,
axi
.
dataWidth
:
Int
,
axi
.
idWidth
:
Int
,
cfg
.
burstSize
.
map
(
", burst size = %d"
.
format
(
_
)).
getOrElse
(
""
),
cfg
.
size
.
map
(
", size = %d"
.
format
(
_
)).
getOrElse
(
""
)))
val
io
=
new
AxiFifoAdapterIO
(
cfg
)
val
io
=
IO
(
new
AxiFifoAdapterIO
(
cfg
)
)
val
fifo
=
Module
(
new
Queue
(
UInt
(
width
=
cfg
.
axi
.
dataWidth
),
cfg
.
fifoDepth
))
val
axi_read
::
axi_wait
::
Nil
=
Enum
(
UInt
(),
2
)
val
state
=
Reg
(
init
=
axi_wait
)
val
len
=
Reg
(
UInt
(
width
=
log2Up
(
bsz
)))
val
axi_read
::
axi_wait
::
Nil
=
Enum
(
2
)
val
fifo
=
Module
(
new
Queue
(
UInt
(
axi
.
dataWidth
),
cfg
.
fifoDepth
))
val
state
=
RegInit
(
axi_wait
)
val
len
=
Reg
(
UInt
(
log2Ceil
(
bsz
).
W
))
val
ra_hs
=
Reg
(
Bool
())
val
maxi_rlast
=
io
.
maxi
.
readData
.
bits
.
last
val
maxi_raddr
=
Reg
(
i
nit
=
io
.
base
)
val
maxi_rlast
=
io
.
maxi
.
readData
.
bits
.
last
val
maxi_raddr
=
Reg
I
nit
(
io
.
base
)
val
maxi_ravalid
=
!
reset
&&
state
===
axi_read
&&
!
ra_hs
val
maxi_raready
=
io
.
maxi
.
readAddr
.
ready
val
maxi_rready
=
!
reset
&&
state
===
axi_read
&&
fifo
.
io
.
enq
.
ready
val
maxi_rvalid
=
state
===
axi_read
&&
io
.
maxi
.
readData
.
valid
val
maxi_rready
=
!
reset
&&
state
===
axi_read
&&
fifo
.
io
.
enq
.
ready
val
maxi_rvalid
=
state
===
axi_read
&&
io
.
maxi
.
readData
.
valid
io
.
deq
<>
fifo
.
io
.
deq
fifo
.
io
.
enq
.
bits
:=
io
.
maxi
.
readData
.
bits
.
data
io
.
maxi
.
readData
.
ready
:=
maxi_rready
io
.
maxi
.
readAddr
.
valid
:=
maxi_ravalid
fifo
.
io
.
enq
.
valid
:=
io
.
maxi
.
readData
.
valid
io
.
deq
<>
fifo
.
io
.
deq
fifo
.
io
.
enq
.
bits
:=
io
.
maxi
.
readData
.
bits
.
data
io
.
maxi
.
readData
.
ready
:=
maxi_rready
io
.
maxi
.
readAddr
.
valid
:=
maxi_ravalid
fifo
.
io
.
enq
.
valid
:=
io
.
maxi
.
readData
.
valid
// AXI boilerplate
io
.
maxi
.
readAddr
.
bits
.
addr
:=
maxi_raddr
io
.
maxi
.
readAddr
.
bits
.
size
:=
UInt
(
if
(
cfg
.
axi
.
dataWidth
>
8
)
log2
Up
(
cfg
.
axi
.
dataWidth
/
8
)
else
0
)
io
.
maxi
.
readAddr
.
bits
.
len
:=
UInt
(
bsz
-
1
)
io
.
maxi
.
readAddr
.
bits
.
burst
:=
UInt
(
"b01"
)
// INCR
io
.
maxi
.
readAddr
.
bits
.
id
:=
UInt
(
0
)
io
.
maxi
.
readAddr
.
bits
.
lock
:=
UInt
(
0
)
io
.
maxi
.
readAddr
.
bits
.
cache
:=
UInt
(
"b1111"
)
// bufferable, write-back RW allocate
io
.
maxi
.
readAddr
.
bits
.
prot
:=
UInt
(
0
)
io
.
maxi
.
readAddr
.
bits
.
qos
:=
UInt
(
0
)
io
.
maxi
.
readAddr
.
bits
.
addr
:=
maxi_raddr
io
.
maxi
.
readAddr
.
bits
.
burst
.
size
:=
(
if
(
axi
.
dataWidth
>
8
)
log2
Ceil
(
axi
.
dataWidth
/
8
)
else
0
)
.
U
io
.
maxi
.
readAddr
.
bits
.
burst
.
len
:=
(
bsz
-
1
)
.
U
io
.
maxi
.
readAddr
.
bits
.
burst
.
burst
:=
Axi4
.
Burst
.
Type
.
incr
io
.
maxi
.
readAddr
.
bits
.
id
:=
0.
U
io
.
maxi
.
readAddr
.
bits
.
lock
.
lock
:=
0.
U
io
.
maxi
.
readAddr
.
bits
.
cache
.
cache
:=
Axi4
.
Cache
.
Read
.
WRITE_BACK_RW_ALLOCATE
io
.
maxi
.
readAddr
.
bits
.
prot
.
prot
:=
0.
U
io
.
maxi
.
readAddr
.
bits
.
qos
:=
0.
U
// write channel tie-offs
io
.
maxi
.
writeAddr
.
valid
:=
Bool
(
false
)
io
.
maxi
.
writeData
.
valid
:=
Bool
(
false
)
io
.
maxi
.
writeResp
.
ready
:=
Bool
(
false
)
io
.
maxi
.
writeAddr
.
valid
:=
false
.
B
io
.
maxi
.
writeData
.
valid
:=
false
.
B
io
.
maxi
.
writeResp
.
ready
:=
false
.
B
when
(
reset
)
{
state
:=
axi_wait
len
:=
UInt
(
bsz
-
1
)
len
:=
(
bsz
-
1
)
.
U
maxi_raddr
:=
io
.
base
ra_hs
:=
Bool
(
false
)
ra_hs
:=
false
.
B
}
.
otherwise
{
when
(
state
===
axi_wait
&&
fifo
.
io
.
count
<=
UInt
(
cfg
.
fifoDepth
-
bsz
))
{
state
:=
axi_read
}
when
(
state
===
axi_wait
&&
fifo
.
io
.
count
<=
(
cfg
.
fifoDepth
-
bsz
)
.
U
)
{
state
:=
axi_read
}
when
(
state
===
axi_read
)
{
when
(
maxi_ravalid
&&
maxi_raready
)
{
maxi_raddr
:=
maxi_raddr
+
UInt
(
bsz
*
(
cfg
.
axi
.
dataWidth
/
8
))
ra_hs
:=
Bool
(
true
)
maxi_raddr
:=
maxi_raddr
+
(
bsz
*
(
axi
.
dataWidth
/
8
))
.
U
ra_hs
:=
true
.
B
}
when
(
maxi_rready
&&
maxi_rvalid
)
{
when
(
maxi_rlast
)
{
state
:=
Mux
(
fifo
.
io
.
count
<=
UInt
(
cfg
.
fifoDepth
-
bsz
),
state
,
axi_wait
)
len
:=
UInt
(
bsz
-
1
)
ra_hs
:=
Bool
(
false
)
state
:=
Mux
(
fifo
.
io
.
count
<=
(
cfg
.
fifoDepth
-
bsz
)
.
U
,
state
,
axi_wait
)
len
:=
(
bsz
-
1
)
.
U
ra_hs
:=
false
.
B
}
.
otherwise
{
len
:=
len
-
UInt
(
1
)
}
.
otherwise
{
len
:=
len
-
1.
U
}
}
}
}
...
...
@@ -117,27 +118,18 @@ object AxiFifoAdapter {
* @param cfg Configuration.
* @return AxiFifoAdapter instance.
**/
def
apply
(
cfg
:
AxiFifoAdapterConfiguration
)
:
AxiFifoAdapter
=
new
AxiFifoAdapter
(
cfg
)
def
apply
(
cfg
:
AxiFifoAdapterConfiguration
)
(
implicit
axi
:
Axi4.Configuration
)
:
AxiFifoAdapter
=
new
AxiFifoAdapter
(
cfg
)
/**
* Build an AxiFifoAdapter.
* @param fifoDepth Depth of the backing FIFO (each element data width wide).
* @param addrWidth Width of AXI address line in bits.
* @param dataWidth Width of AXI data line in bits.
* @param idWidth Width of AXI id line in bits.
* @param burstSize Number of beats per burst (optional).
* @param size Address wrap-around after size elements (optional).
* @return AxiFifoAdapter instance.
**/
def
apply
(
fifoDepth
:
Int
,
addrWidth
:
Int
,
dataWidth
:
Int
,
idWidth
:
Int
=
1
,
burstSize
:
Option
[
Int
]
=
None
,
size
:
Option
[
Int
]
=
None
)
:
AxiFifoAdapter
=
new
AxiFifoAdapter
(
AxiFifoAdapterConfiguration
(
axi
=
AxiConfiguration
(
addrWidth
,
dataWidth
,
idWidth
),
fifoDepth
=
fifoDepth
,
burstSize
=
burstSize
,
size
=
size
))
size
:
Option
[
Int
]
=
None
)
(
implicit
axi
:
Axi4.Configuration
)
:
AxiFifoAdapter
=
new
AxiFifoAdapter
(
AxiFifoAdapterConfiguration
(
fifoDepth
=
fifoDepth
,
burstSize
=
burstSize
,
size
=
size
))
}
src/main/scala/AxiModuleBuilder.scala
View file @
8d7821f5
package
chisel.axiutils
import
chisel.axiutils.registers._
import
chisel.packaging.
{
CoreDefinition
,
ModuleBuilder
}
import
chisel.packaging.CoreDefinition.root
import
chisel.miscutils.DecoupledDataSource
import
scala.sys.process._
import
java.nio.file.Paths
import
C
hisel._
import
AXIDefs
._
import
chisel.axiutils.registers._
import
chisel.packaging.
{
CoreDefinition
,
ModuleBuilder
}
import
chisel.packaging.CoreDefinition.root
import
chisel.miscutils.DecoupledDataSource
import
scala.sys.process._
import
java.nio.file.Paths
import
c
hisel
3
._
import
chisel.axi
._
class
FifoAxiAdapterTest1
(
dataWidth
:
Int
,
size
:
Int
)
extends
Module
{
class
FifoAxiAdapterTest1
(
dataWidth
:
Int
,
size
:
Int
)
extends
Module
{
val
addrWidth
=
32
val
io
=
new
Bundle
{
val
maxi
=
new
AXIMasterIF
(
addrWidth
,
dataWidth
,
1
)
val
base
=
UInt
(
INPUT
,
width
=
addrWidth
)
}
implicit
val
axi
=
Axi4
.
Configuration
(
AddrWidth
(
addrWidth
),
DataWidth
(
dataWidth
),
IdWidth
(
1
))
val
io
=
IO
(
new
Bundle
{
val
maxi
=
Axi4
.
Master
(
axi
)
val
base
=
Input
(
UInt
(
AddrWidth
(
addrWidth
)))
})
val
datasrc
=
Module
(
new
DecoupledDataSource
(
UInt
(
width
=
dataWidth
),
size
=
256
,
n
=>
UInt
(
n
),
false
))
val
fad
=
Module
(
new
FifoAxiAdapter
(
fifoDepth
=
size
,
addrWidth
=
addrWidth
,
dataWidth
=
dataWidth
,
burstSize
=
Some
(
16
)))
val
datasrc
=
Module
(
new
DecoupledDataSource
(
dataWidth
.
U
,
size
=
256
,
n
=>
n
.
U
,
false
))
val
fad
=
Module
(
new
FifoAxiAdapter
(
fifoDepth
=
size
,
burstSize
=
Some
(
16
)))
io
.
maxi
.
renameSignals
(
None
,
None
)
io
.
base
.
s
e
tName
(
"base"
)
//
io.maxi.renameSignals(None, None)
io
.
base
.
s
ugges
tName
(
"base"
)
fad
.
io
.
base
:=
io
.
base
fad
.
io
.
enq
<>
datasrc
.
io
.
out
...
...
@@ -31,11 +31,15 @@ class FifoAxiAdapterTest1(dataWidth : Int, size: Int) extends Module {
}
object
AxiModuleBuilder
extends
ModuleBuilder
{
implicit
val
axi
=
AxiConfiguration
(
addrWidth
=
32
,
dataWidth
=
64
,
idWidth
=
1
)
implicit
val
axi
=
Axi4
.
Configuration
(
AddrWidth
(
32
),
DataWidth
(
64
),
IdWidth
(
1
))
implicit
val
axilite
=
Axi4Lite
.
Configuration
(
Axi4Lite
.
AddrWidth
(
32
),
Axi4Lite
.
Width64
)
val
modules
:
List
[(()
=>
Module
,
CoreDefinition
)]
=
List
(
(
// test module with fixed data
()
=>
Module
(
new
FifoAxiAdapterTest1
(
dataWidth
=
32
,
256
)
)
,
()
=>
new
FifoAxiAdapterTest1
(
dataWidth
=
32
,
256
),
CoreDefinition
(
name
=
"FifoAxiAdapterTest1"
,
vendor
=
"esa.cs.tu-darmstadt.de"
,
...
...
@@ -45,9 +49,7 @@ object AxiModuleBuilder extends ModuleBuilder {
)
),
(
// generic adapter module FIFO -> AXI
()
=>
Module
(
new
FifoAxiAdapter
(
fifoDepth
=
8
,
addrWidth
=
32
,
dataWidth
=
64
)),
()
=>
new
FifoAxiAdapter
(
fifoDepth
=
8
),
CoreDefinition
(
name
=
"FifoAxiAdapter"
,
vendor
=
"esa.cs.tu-darmstadt.de"
,
...
...
@@ -57,9 +59,10 @@ object AxiModuleBuilder extends ModuleBuilder {
)
),
(
// generic adapter module AXI -> FIFO
()
=>
Module
(
AxiFifoAdapter
(
fifoDepth
=
4
,
addrWidth
=
32
,
dataWidth
=
32
)),
()
=>
AxiFifoAdapter
(
fifoDepth
=
4
)
(
Axi4
.
Configuration
(
addrWidth
=
AddrWidth
(
32
),
dataWidth
=
DataWidth
(
32
),
idWidth
=
IdWidth
(
1
))),
CoreDefinition
(
name
=
"AxiFifoAdapter"
,
vendor
=
"esa.cs.tu-darmstadt.de"
,
...
...
@@ -69,16 +72,15 @@ object AxiModuleBuilder extends ModuleBuilder {
)
),
(
// AXI-based sliding window
()
=>
Module
(
new
AxiSlidingWindow
(
AxiSlidingWindowConfiguration
(
gen
=
UInt
(
width
=
8
),
()
=>
{
implicit
val
axi
=
Axi4
.
Configuration
(
AddrWidth
(
32
),
DataWidth
(
64
),
IdWidth
(
1
))
new
AxiSlidingWindow
(
AxiSlidingWindowConfiguration
(
gen
=
UInt
(
8.
W
),
width
=
8
,
depth
=
3
,
afa
=
AxiFifoAdapterConfiguration
(
axi
=
AxiConfiguration
(
addrWidth
=
32
,
dataWidth
=
64
,
idWidth
=
1
),
fifoDepth
=
32
,
burstSize
=
Some
(
16
)
)
))),
afa
=
AxiFifoAdapterConfiguration
(
fifoDepth
=
32
,
burstSize
=
Some
(
16
))
))
},
CoreDefinition
(
name
=
"AxiSlidingWindow3x8"
,
vendor
=
"esa.cs.tu-darmstadt.de"
,
...
...
@@ -88,7 +90,7 @@ object AxiModuleBuilder extends ModuleBuilder {
)
),
(