Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
饶先宏
hdl4se
提交
f6da6054
H
hdl4se
项目概览
饶先宏
/
hdl4se
通知
12
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hdl4se
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
f6da6054
编写于
9月 10, 2021
作者:
饶先宏
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
https://codechina.csdn.net/m0_56903617/hdl4se
上级
10137b71
56b6929b
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
147 addition
and
804 deletion
+147
-804
examples/hdl4se_riscv/verilog/axi/riscv_core_with_axi_master.v
...les/hdl4se_riscv/verilog/axi/riscv_core_with_axi_master.v
+147
-0
examples/hdl4se_riscv/verilog/axi/riscv_cpu_axi_v1_0.v
examples/hdl4se_riscv/verilog/axi/riscv_cpu_axi_v1_0.v
+0
-90
examples/hdl4se_riscv/verilog/axi/riscv_cpu_axi_v1_0_M00_AXI.v
...les/hdl4se_riscv/verilog/axi/riscv_cpu_axi_v1_0_M00_AXI.v
+0
-714
未找到文件。
examples/hdl4se_riscv/verilog/axi/riscv_core_with_axi_master.v
0 → 100644
浏览文件 @
f6da6054
`timescale
1
ns
/
1
ps
module
riscv_core_with_axi_master
(
// clock and reset
input
wire
wClk
,
input
wire
nwReset
,
// Write Address
output
wire
wAWValid
,
output
wire
[
31
:
0
]
bAWAddr
,
output
wire
[
2
:
0
]
bAWProt
,
input
wire
wAWReady
,
// Write Data
output
wire
wWValid
,
output
wire
[
31
:
0
]
bWData
,
output
wire
[
3
:
0
]
bWStrb
,
input
wire
wWReady
,
// Write Response
output
wire
wBReady
,
input
wire
[
1
:
0
]
bBResp
,
input
wire
wBValid
,
// ReadAddr
output
wire
wARValid
,
output
wire
[
31
:
0
]
bARAddr
,
output
wire
[
2
:
0
]
bARProt
,
input
wire
wARReady
,
//ReadData
output
wire
wRReady
input
wire
wRValid
,
input
wire
[
31
:
0
]
bRData
,
input
wire
[
1
:
0
]
bRResp
);
reg
axi_awvalid
;
assign
wAWValid
=
axi_awvalid
;
reg
[
31
:
0
]
axi_awaddr
;
assign
bAWAddr
=
axi_awaddr
;
assign
bAWProt
=
3'b000
;
reg
axi_wvalid
;
assign
wWValid
=
axi_wvalid
;
reg
[
31
:
0
]
axi_wdata
;
assign
bWData
=
axi_wdata
;
reg
[
3
:
0
]
axi_wstrb
;
assign
bWStrb
=
axi_wstrb
;
assign
wBReady
=
1'b1
;
reg
axi_arvalid
;
assign
wARValid
=
axi_arvalid
;
reg
[
31
:
0
]
axi_araddr
;
assign
bARAddr
=
axi_araddr
;
assign
bARProt
=
3'b001
;
assign
wRReady
=
1'b1
;
wire
wWrite
,
wRead
,
wReadReady
,
wWriteReady
;
wire
[
31
:
0
]
bWriteAddr
,
bWriteData
,
bReadAddr
,
bReadData
,
bReadDataRam
,
bReadDataKey
;
wire
[
4
:
0
]
regno
;
wire
[
3
:
0
]
regena
;
wire
[
31
:
0
]
regwrdata
;
wire
regwren
;
wire
[
31
:
0
]
regrddata
;
wire
[
4
:
0
]
regno2
;
wire
[
3
:
0
]
regena2
;
wire
[
31
:
0
]
regwrdata2
;
wire
regwren2
;
wire
[
31
:
0
]
regrddata2
;
regfile
regs
(
regno
,
regena
,
wClk
,
regwrdata
,
regwren
,
regrddata
);
regfile
regs2
(
regno2
,
regena2
,
wClk
,
regwrdata2
,
regwren2
,
regrddata2
);
riscv_core
core
(
wClk
,
nwReset
,
wWrite
,
bWriteAddr
,
bWriteData
,
bWriteMask
,
wWriteReady
,
wRead
,
bReadAddr
,
bReadData
,
wReadReady
,
regno
,
regena
,
regwrdata
,
regwren
,
regrddata
,
regno2
,
regena2
,
regwrdata2
,
regwren2
,
regrddata2
);
//Write Address
reg
[
31
:
0
]
awaddr
;
reg
awvalid
;
always
@
(
posedge
wClk
)
if
(
~
nwReset
)
begin
awvalid
<=
1'b0
;
end
else
if
(
wWrite
)
begin
awaddr
<=
bWriteAddr
;
awvalid
<=
1'b1
;
end
else
if
(
wAWReady
)
begin
awvalid
<=
1'b0
;
end
assign
wWriteReady
=
(
wWrite
||
awvalid
)
&&
wAWReady
;
always
@
(
*
)
begin
axi_awvalid
=
wWrite
?
1'b1
:
awvalid
;
axi_awaddr
=
wWrite
?
bWriteAddr
:
awaddr
;
end
/* Write Data */
reg
[
31
:
0
]
wdata
;
reg
[
3
:
0
]
wstrb
;
reg
wvalid
;
always
@
(
wClk
)
begin
if
(
~
nwReset
)
begin
wvalid
<=
1'b0
;
end
if
(
wWrite
)
begin
wdata
<=
bWriteData
;
wstrb
<=
~
bWriteMask
;
wvalid
<=
1'b1
;
end
if
(
wWReady
)
begin
wvalid
<=
1'b0
;
end
end
always
@
(
*
)
begin
axi_wvalid
=
wWrite
?
1'b1
:
wvalid
;
axi_wdata
=
wWrite
?
bWriteData
:
wdata
;
axi_wstrb
=
wWrite
?
~
bWriteMask
:
wstrb
;
end
//Read Address
reg
[
31
:
0
]
araddr
;
reg
arvalid
;
always
@
(
posedge
wClk
)
if
(
~
nwReset
)
begin
arvalid
<=
1'b0
;
end
else
if
(
wRead
)
begin
araddr
<=
bReadAddr
;
arvalid
<=
1'b1
;
end
else
if
(
wARReady
)
begin
arvalid
<=
1'b0
;
end
assign
wReadyReady
=
(
wRead
||
arvalid
)
&&
wARReady
;
always
@
(
*
)
begin
axi_arvalid
=
wRead
?
1'b1
:
arvalid
;
axi_araddr
=
wRead
?
bReadAddr
:
araddr
;
end
assign
bReadData
=
bRData
;
endmodule
examples/hdl4se_riscv/verilog/axi/riscv_cpu_axi_v1_0.v
已删除
100644 → 0
浏览文件 @
10137b71
`timescale
1
ns
/
1
ps
module
riscv_cpu_axi_v1_0
#
(
// Users to add parameters here
// User parameters ends
// Do not modify the parameters beyond this line
// Parameters of Axi Master Bus Interface M00_AXI
parameter
C_M00_AXI_START_DATA_VALUE
=
32'hAA000000
,
parameter
C_M00_AXI_TARGET_SLAVE_BASE_ADDR
=
32'h40000000
,
parameter
integer
C_M00_AXI_ADDR_WIDTH
=
32
,
parameter
integer
C_M00_AXI_DATA_WIDTH
=
32
,
parameter
integer
C_M00_AXI_TRANSACTIONS_NUM
=
4
)
(
// Users to add ports here
// User ports ends
// Do not modify the ports beyond this line
// Ports of Axi Master Bus Interface M00_AXI
input
wire
m00_axi_init_axi_txn
,
output
wire
m00_axi_error
,
output
wire
m00_axi_txn_done
,
input
wire
m00_axi_aclk
,
input
wire
m00_axi_aresetn
,
output
wire
[
C_M00_AXI_ADDR_WIDTH
-
1
:
0
]
m00_axi_awaddr
,
output
wire
[
2
:
0
]
m00_axi_awprot
,
output
wire
m00_axi_awvalid
,
input
wire
m00_axi_awready
,
output
wire
[
C_M00_AXI_DATA_WIDTH
-
1
:
0
]
m00_axi_wdata
,
output
wire
[
C_M00_AXI_DATA_WIDTH
/
8
-
1
:
0
]
m00_axi_wstrb
,
output
wire
m00_axi_wvalid
,
input
wire
m00_axi_wready
,
input
wire
[
1
:
0
]
m00_axi_bresp
,
input
wire
m00_axi_bvalid
,
output
wire
m00_axi_bready
,
output
wire
[
C_M00_AXI_ADDR_WIDTH
-
1
:
0
]
m00_axi_araddr
,
output
wire
[
2
:
0
]
m00_axi_arprot
,
output
wire
m00_axi_arvalid
,
input
wire
m00_axi_arready
,
input
wire
[
C_M00_AXI_DATA_WIDTH
-
1
:
0
]
m00_axi_rdata
,
input
wire
[
1
:
0
]
m00_axi_rresp
,
input
wire
m00_axi_rvalid
,
output
wire
m00_axi_rready
);
// Instantiation of Axi Bus Interface M00_AXI
riscv_cpu_axi_v1_0_M00_AXI
#
(
.
C_M_START_DATA_VALUE
(
C_M00_AXI_START_DATA_VALUE
),
.
C_M_TARGET_SLAVE_BASE_ADDR
(
C_M00_AXI_TARGET_SLAVE_BASE_ADDR
),
.
C_M_AXI_ADDR_WIDTH
(
C_M00_AXI_ADDR_WIDTH
),
.
C_M_AXI_DATA_WIDTH
(
C_M00_AXI_DATA_WIDTH
),
.
C_M_TRANSACTIONS_NUM
(
C_M00_AXI_TRANSACTIONS_NUM
)
)
riscv_cpu_axi_v1_0_M00_AXI_inst
(
.
INIT_AXI_TXN
(
m00_axi_init_axi_txn
),
.
ERROR
(
m00_axi_error
),
.
TXN_DONE
(
m00_axi_txn_done
),
.
M_AXI_ACLK
(
m00_axi_aclk
),
.
M_AXI_ARESETN
(
m00_axi_aresetn
),
.
M_AXI_AWADDR
(
m00_axi_awaddr
),
.
M_AXI_AWPROT
(
m00_axi_awprot
),
.
M_AXI_AWVALID
(
m00_axi_awvalid
),
.
M_AXI_AWREADY
(
m00_axi_awready
),
.
M_AXI_WDATA
(
m00_axi_wdata
),
.
M_AXI_WSTRB
(
m00_axi_wstrb
),
.
M_AXI_WVALID
(
m00_axi_wvalid
),
.
M_AXI_WREADY
(
m00_axi_wready
),
.
M_AXI_BRESP
(
m00_axi_bresp
),
.
M_AXI_BVALID
(
m00_axi_bvalid
),
.
M_AXI_BREADY
(
m00_axi_bready
),
.
M_AXI_ARADDR
(
m00_axi_araddr
),
.
M_AXI_ARPROT
(
m00_axi_arprot
),
.
M_AXI_ARVALID
(
m00_axi_arvalid
),
.
M_AXI_ARREADY
(
m00_axi_arready
),
.
M_AXI_RDATA
(
m00_axi_rdata
),
.
M_AXI_RRESP
(
m00_axi_rresp
),
.
M_AXI_RVALID
(
m00_axi_rvalid
),
.
M_AXI_RREADY
(
m00_axi_rready
)
);
// Add user logic here
// User logic ends
endmodule
examples/hdl4se_riscv/verilog/axi/riscv_cpu_axi_v1_0_M00_AXI.v
已删除
100644 → 0
浏览文件 @
10137b71
`timescale
1
ns
/
1
ps
module
riscv_cpu_axi_v1_0_M00_AXI
#
(
// Users to add parameters here
// User parameters ends
// Do not modify the parameters beyond this line
// The master will start generating data from the C_M_START_DATA_VALUE value
parameter
C_M_START_DATA_VALUE
=
32'hAA000000
,
// The master requires a target slave base address.
// The master will initiate read and write transactions on the slave with base address specified here as a parameter.
parameter
C_M_TARGET_SLAVE_BASE_ADDR
=
32'h40000000
,
// Width of M_AXI address bus.
// The master generates the read and write addresses of width specified as C_M_AXI_ADDR_WIDTH.
parameter
integer
C_M_AXI_ADDR_WIDTH
=
32
,
// Width of M_AXI data bus.
// The master issues write data and accept read data where the width of the data bus is C_M_AXI_DATA_WIDTH
parameter
integer
C_M_AXI_DATA_WIDTH
=
32
,
// Transaction number is the number of write
// and read transactions the master will perform as a part of this example memory test.
parameter
integer
C_M_TRANSACTIONS_NUM
=
4
)
(
// Users to add ports here
// User ports ends
// Do not modify the ports beyond this line
// Initiate AXI transactions
input
wire
INIT_AXI_TXN
,
// Asserts when ERROR is detected
output
reg
ERROR
,
// Asserts when AXI transactions is complete
output
wire
TXN_DONE
,
// AXI clock signal
input
wire
M_AXI_ACLK
,
// AXI active low reset signal
input
wire
M_AXI_ARESETN
,
// Master Interface Write Address Channel ports. Write address (issued by master)
output
wire
[
C_M_AXI_ADDR_WIDTH
-
1
:
0
]
M_AXI_AWADDR
,
// Write channel Protection type.
// This signal indicates the privilege and security level of the transaction,
// and whether the transaction is a data access or an instruction access.
output
wire
[
2
:
0
]
M_AXI_AWPROT
,
// Write address valid.
// This signal indicates that the master signaling valid write address and control information.
output
wire
M_AXI_AWVALID
,
// Write address ready.
// This signal indicates that the slave is ready to accept an address and associated control signals.
input
wire
M_AXI_AWREADY
,
// Master Interface Write Data Channel ports. Write data (issued by master)
output
wire
[
C_M_AXI_DATA_WIDTH
-
1
:
0
]
M_AXI_WDATA
,
// Write strobes.
// This signal indicates which byte lanes hold valid data.
// There is one write strobe bit for each eight bits of the write data bus.
output
wire
[
C_M_AXI_DATA_WIDTH
/
8
-
1
:
0
]
M_AXI_WSTRB
,
// Write valid. This signal indicates that valid write data and strobes are available.
output
wire
M_AXI_WVALID
,
// Write ready. This signal indicates that the slave can accept the write data.
input
wire
M_AXI_WREADY
,
// Master Interface Write Response Channel ports.
// This signal indicates the status of the write transaction.
input
wire
[
1
:
0
]
M_AXI_BRESP
,
// Write response valid.
// This signal indicates that the channel is signaling a valid write response
input
wire
M_AXI_BVALID
,
// Response ready. This signal indicates that the master can accept a write response.
output
wire
M_AXI_BREADY
,
// Master Interface Read Address Channel ports. Read address (issued by master)
output
wire
[
C_M_AXI_ADDR_WIDTH
-
1
:
0
]
M_AXI_ARADDR
,
// Protection type.
// This signal indicates the privilege and security level of the transaction,
// and whether the transaction is a data access or an instruction access.
output
wire
[
2
:
0
]
M_AXI_ARPROT
,
// Read address valid.
// This signal indicates that the channel is signaling valid read address and control information.
output
wire
M_AXI_ARVALID
,
// Read address ready.
// This signal indicates that the slave is ready to accept an address and associated control signals.
input
wire
M_AXI_ARREADY
,
// Master Interface Read Data Channel ports. Read data (issued by slave)
input
wire
[
C_M_AXI_DATA_WIDTH
-
1
:
0
]
M_AXI_RDATA
,
// Read response. This signal indicates the status of the read transfer.
input
wire
[
1
:
0
]
M_AXI_RRESP
,
// Read valid. This signal indicates that the channel is signaling the required read data.
input
wire
M_AXI_RVALID
,
// Read ready. This signal indicates that the master can accept the read data and response information.
output
wire
M_AXI_RREADY
);
// function called clogb2 that returns an integer which has the
// value of the ceiling of the log base 2
function
integer
clogb2
(
input
integer
bit_depth
);
begin
for
(
clogb2
=
0
;
bit_depth
>
0
;
clogb2
=
clogb2
+
1
)
bit_depth
=
bit_depth
>>
1
;
end
endfunction
// TRANS_NUM_BITS is the width of the index counter for
// number of write or read transaction.
localparam
integer
TRANS_NUM_BITS
=
clogb2
(
C_M_TRANSACTIONS_NUM
-
1
);
// Example State machine to initialize counter, initialize write transactions,
// initialize read transactions and comparison of read data with the
// written data words.
parameter
[
1
:
0
]
IDLE
=
2'b00
,
// This state initiates AXI4Lite transaction
// after the state machine changes state to INIT_WRITE
// when there is 0 to 1 transition on INIT_AXI_TXN
INIT_WRITE
=
2'b01
,
// This state initializes write transaction,
// once writes are done, the state machine
// changes state to INIT_READ
INIT_READ
=
2'b10
,
// This state initializes read transaction
// once reads are done, the state machine
// changes state to INIT_COMPARE
INIT_COMPARE
=
2'b11
;
// This state issues the status of comparison
// of the written data with the read data
reg
[
1
:
0
]
mst_exec_state
;
// AXI4LITE signals
//write address valid
reg
axi_awvalid
;
//write data valid
reg
axi_wvalid
;
//read address valid
reg
axi_arvalid
;
//read data acceptance
reg
axi_rready
;
//write response acceptance
reg
axi_bready
;
//write address
reg
[
C_M_AXI_ADDR_WIDTH
-
1
:
0
]
axi_awaddr
;
//write data
reg
[
C_M_AXI_DATA_WIDTH
-
1
:
0
]
axi_wdata
;
//read addresss
reg
[
C_M_AXI_ADDR_WIDTH
-
1
:
0
]
axi_araddr
;
//Asserts when there is a write response error
wire
write_resp_error
;
//Asserts when there is a read response error
wire
read_resp_error
;
//A pulse to initiate a write transaction
reg
start_single_write
;
//A pulse to initiate a read transaction
reg
start_single_read
;
//Asserts when a single beat write transaction is issued and remains asserted till the completion of write trasaction.
reg
write_issued
;
//Asserts when a single beat read transaction is issued and remains asserted till the completion of read trasaction.
reg
read_issued
;
//flag that marks the completion of write trasactions. The number of write transaction is user selected by the parameter C_M_TRANSACTIONS_NUM.
reg
writes_done
;
//flag that marks the completion of read trasactions. The number of read transaction is user selected by the parameter C_M_TRANSACTIONS_NUM
reg
reads_done
;
//The error register is asserted when any of the write response error, read response error or the data mismatch flags are asserted.
reg
error_reg
;
//index counter to track the number of write transaction issued
reg
[
TRANS_NUM_BITS
:
0
]
write_index
;
//index counter to track the number of read transaction issued
reg
[
TRANS_NUM_BITS
:
0
]
read_index
;
//Expected read data used to compare with the read data.
reg
[
C_M_AXI_DATA_WIDTH
-
1
:
0
]
expected_rdata
;
//Flag marks the completion of comparison of the read data with the expected read data
reg
compare_done
;
//This flag is asserted when there is a mismatch of the read data with the expected read data.
reg
read_mismatch
;
//Flag is asserted when the write index reaches the last write transction number
reg
last_write
;
//Flag is asserted when the read index reaches the last read transction number
reg
last_read
;
reg
init_txn_ff
;
reg
init_txn_ff2
;
reg
init_txn_edge
;
wire
init_txn_pulse
;
// I/O Connections assignments
//Adding the offset address to the base addr of the slave
assign
M_AXI_AWADDR
=
C_M_TARGET_SLAVE_BASE_ADDR
+
axi_awaddr
;
//AXI 4 write data
assign
M_AXI_WDATA
=
axi_wdata
;
assign
M_AXI_AWPROT
=
3'b000
;
assign
M_AXI_AWVALID
=
axi_awvalid
;
//Write Data(W)
assign
M_AXI_WVALID
=
axi_wvalid
;
//Set all byte strobes in this example
assign
M_AXI_WSTRB
=
4'b1111
;
//Write Response (B)
assign
M_AXI_BREADY
=
axi_bready
;
//Read Address (AR)
assign
M_AXI_ARADDR
=
C_M_TARGET_SLAVE_BASE_ADDR
+
axi_araddr
;
assign
M_AXI_ARVALID
=
axi_arvalid
;
assign
M_AXI_ARPROT
=
3'b001
;
//Read and Read Response (R)
assign
M_AXI_RREADY
=
axi_rready
;
//Example design I/O
assign
TXN_DONE
=
compare_done
;
assign
init_txn_pulse
=
(
!
init_txn_ff2
)
&&
init_txn_ff
;
//Generate a pulse to initiate AXI transaction.
always
@
(
posedge
M_AXI_ACLK
)
begin
// Initiates AXI transaction delay
if
(
M_AXI_ARESETN
==
0
)
begin
init_txn_ff
<=
1'b0
;
init_txn_ff2
<=
1'b0
;
end
else
begin
init_txn_ff
<=
INIT_AXI_TXN
;
init_txn_ff2
<=
init_txn_ff
;
end
end
//--------------------
//Write Address Channel
//--------------------
// The purpose of the write address channel is to request the address and
// command information for the entire transaction. It is a single beat
// of information.
// Note for this example the axi_awvalid/axi_wvalid are asserted at the same
// time, and then each is deasserted independent from each other.
// This is a lower-performance, but simplier control scheme.
// AXI VALID signals must be held active until accepted by the partner.
// A data transfer is accepted by the slave when a master has
// VALID data and the slave acknoledges it is also READY. While the master
// is allowed to generated multiple, back-to-back requests by not
// deasserting VALID, this design will add rest cycle for
// simplicity.
// Since only one outstanding transaction is issued by the user design,
// there will not be a collision between a new request and an accepted
// request on the same clock cycle.
always
@
(
posedge
M_AXI_ACLK
)
begin
//Only VALID signals must be deasserted during reset per AXI spec
//Consider inverting then registering active-low reset for higher fmax
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
axi_awvalid
<=
1'b0
;
end
//Signal a new address/data command is available by user logic
else
begin
if
(
start_single_write
)
begin
axi_awvalid
<=
1'b1
;
end
//Address accepted by interconnect/slave (issue of M_AXI_AWREADY by slave)
else
if
(
M_AXI_AWREADY
&&
axi_awvalid
)
begin
axi_awvalid
<=
1'b0
;
end
end
end
// start_single_write triggers a new write
// transaction. write_index is a counter to
// keep track with number of write transaction
// issued/initiated
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
write_index
<=
0
;
end
// Signals a new write address/ write data is
// available by user logic
else
if
(
start_single_write
)
begin
write_index
<=
write_index
+
1
;
end
end
//--------------------
//Write Data Channel
//--------------------
//The write data channel is for transfering the actual data.
//The data generation is speific to the example design, and
//so only the WVALID/WREADY handshake is shown here
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
axi_wvalid
<=
1'b0
;
end
//Signal a new address/data command is available by user logic
else
if
(
start_single_write
)
begin
axi_wvalid
<=
1'b1
;
end
//Data accepted by interconnect/slave (issue of M_AXI_WREADY by slave)
else
if
(
M_AXI_WREADY
&&
axi_wvalid
)
begin
axi_wvalid
<=
1'b0
;
end
end
//----------------------------
//Write Response (B) Channel
//----------------------------
//The write response channel provides feedback that the write has committed
//to memory. BREADY will occur after both the data and the write address
//has arrived and been accepted by the slave, and can guarantee that no
//other accesses launched afterwards will be able to be reordered before it.
//The BRESP bit [1] is used indicate any errors from the interconnect or
//slave for the entire write burst. This example will capture the error.
//While not necessary per spec, it is advisable to reset READY signals in
//case of differing reset latencies between master/slave.
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
axi_bready
<=
1'b0
;
end
// accept/acknowledge bresp with axi_bready by the master
// when M_AXI_BVALID is asserted by slave
else
if
(
M_AXI_BVALID
&&
~
axi_bready
)
begin
axi_bready
<=
1'b1
;
end
// deassert after one clock cycle
else
if
(
axi_bready
)
begin
axi_bready
<=
1'b0
;
end
// retain the previous value
else
axi_bready
<=
axi_bready
;
end
//Flag write errors
assign
write_resp_error
=
(
axi_bready
&
M_AXI_BVALID
&
M_AXI_BRESP
[
1
]);
//----------------------------
//Read Address Channel
//----------------------------
//start_single_read triggers a new read transaction. read_index is a counter to
//keep track with number of read transaction issued/initiated
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
read_index
<=
0
;
end
// Signals a new read address is
// available by user logic
else
if
(
start_single_read
)
begin
read_index
<=
read_index
+
1
;
end
end
// A new axi_arvalid is asserted when there is a valid read address
// available by the master. start_single_read triggers a new read
// transaction
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
axi_arvalid
<=
1'b0
;
end
//Signal a new read address command is available by user logic
else
if
(
start_single_read
)
begin
axi_arvalid
<=
1'b1
;
end
//RAddress accepted by interconnect/slave (issue of M_AXI_ARREADY by slave)
else
if
(
M_AXI_ARREADY
&&
axi_arvalid
)
begin
axi_arvalid
<=
1'b0
;
end
// retain the previous value
end
//--------------------------------
//Read Data (and Response) Channel
//--------------------------------
//The Read Data channel returns the results of the read request
//The master will accept the read data by asserting axi_rready
//when there is a valid read data available.
//While not necessary per spec, it is advisable to reset READY signals in
//case of differing reset latencies between master/slave.
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
axi_rready
<=
1'b0
;
end
// accept/acknowledge rdata/rresp with axi_rready by the master
// when M_AXI_RVALID is asserted by slave
else
if
(
M_AXI_RVALID
&&
~
axi_rready
)
begin
axi_rready
<=
1'b1
;
end
// deassert after one clock cycle
else
if
(
axi_rready
)
begin
axi_rready
<=
1'b0
;
end
// retain the previous value
end
//Flag write errors
assign
read_resp_error
=
(
axi_rready
&
M_AXI_RVALID
&
M_AXI_RRESP
[
1
]);
//--------------------------------
//User Logic
//--------------------------------
//Address/Data Stimulus
//Address/data pairs for this example. The read and write values should
//match.
//Modify these as desired for different address patterns.
//Write Addresses
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
axi_awaddr
<=
0
;
end
// Signals a new write address/ write data is
// available by user logic
else
if
(
M_AXI_AWREADY
&&
axi_awvalid
)
begin
axi_awaddr
<=
axi_awaddr
+
32'h00000004
;
end
end
// Write data generation
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
axi_wdata
<=
C_M_START_DATA_VALUE
;
end
// Signals a new write address/ write data is
// available by user logic
else
if
(
M_AXI_WREADY
&&
axi_wvalid
)
begin
axi_wdata
<=
C_M_START_DATA_VALUE
+
write_index
;
end
end
//Read Addresses
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
axi_araddr
<=
0
;
end
// Signals a new write address/ write data is
// available by user logic
else
if
(
M_AXI_ARREADY
&&
axi_arvalid
)
begin
axi_araddr
<=
axi_araddr
+
32'h00000004
;
end
end
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
begin
expected_rdata
<=
C_M_START_DATA_VALUE
;
end
// Signals a new write address/ write data is
// available by user logic
else
if
(
M_AXI_RVALID
&&
axi_rready
)
begin
expected_rdata
<=
C_M_START_DATA_VALUE
+
read_index
;
end
end
//implement master command interface state machine
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
1'b0
)
begin
// reset condition
// All the signals are assigned default values under reset condition
mst_exec_state
<=
IDLE
;
start_single_write
<=
1'b0
;
write_issued
<=
1'b0
;
start_single_read
<=
1'b0
;
read_issued
<=
1'b0
;
compare_done
<=
1'b0
;
ERROR
<=
1'b0
;
end
else
begin
// state transition
case
(
mst_exec_state
)
IDLE:
// This state is responsible to initiate
// AXI transaction when init_txn_pulse is asserted
if
(
init_txn_pulse
==
1'b1
)
begin
mst_exec_state
<=
INIT_WRITE
;
ERROR
<=
1'b0
;
compare_done
<=
1'b0
;
end
else
begin
mst_exec_state
<=
IDLE
;
end
INIT_WRITE:
// This state is responsible to issue start_single_write pulse to
// initiate a write transaction. Write transactions will be
// issued until last_write signal is asserted.
// write controller
if
(
writes_done
)
begin
mst_exec_state
<=
INIT_READ
;
//
end
else
begin
mst_exec_state
<=
INIT_WRITE
;
if
(
~
axi_awvalid
&&
~
axi_wvalid
&&
~
M_AXI_BVALID
&&
~
last_write
&&
~
start_single_write
&&
~
write_issued
)
begin
start_single_write
<=
1'b1
;
write_issued
<=
1'b1
;
end
else
if
(
axi_bready
)
begin
write_issued
<=
1'b0
;
end
else
begin
start_single_write
<=
1'b0
;
//Negate to generate a pulse
end
end
INIT_READ:
// This state is responsible to issue start_single_read pulse to
// initiate a read transaction. Read transactions will be
// issued until last_read signal is asserted.
// read controller
if
(
reads_done
)
begin
mst_exec_state
<=
INIT_COMPARE
;
end
else
begin
mst_exec_state
<=
INIT_READ
;
if
(
~
axi_arvalid
&&
~
M_AXI_RVALID
&&
~
last_read
&&
~
start_single_read
&&
~
read_issued
)
begin
start_single_read
<=
1'b1
;
read_issued
<=
1'b1
;
end
else
if
(
axi_rready
)
begin
read_issued
<=
1'b0
;
end
else
begin
start_single_read
<=
1'b0
;
//Negate to generate a pulse
end
end
INIT_COMPARE:
begin
// This state is responsible to issue the state of comparison
// of written data with the read data. If no error flags are set,
// compare_done signal will be asseted to indicate success.
ERROR
<=
error_reg
;
mst_exec_state
<=
IDLE
;
compare_done
<=
1'b1
;
end
default
:
begin
mst_exec_state
<=
IDLE
;
end
endcase
end
end
//MASTER_EXECUTION_PROC
//Terminal write count
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
last_write
<=
1'b0
;
//The last write should be associated with a write address ready response
else
if
((
write_index
==
C_M_TRANSACTIONS_NUM
)
&&
M_AXI_AWREADY
)
last_write
<=
1'b1
;
else
last_write
<=
last_write
;
end
//Check for last write completion.
//This logic is to qualify the last write count with the final write
//response. This demonstrates how to confirm that a write has been
//committed.
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
writes_done
<=
1'b0
;
//The writes_done should be associated with a bready response
else
if
(
last_write
&&
M_AXI_BVALID
&&
axi_bready
)
writes_done
<=
1'b1
;
else
writes_done
<=
writes_done
;
end
//------------------
//Read example
//------------------
//Terminal Read Count
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
last_read
<=
1'b0
;
//The last read should be associated with a read address ready response
else
if
((
read_index
==
C_M_TRANSACTIONS_NUM
)
&&
(
M_AXI_ARREADY
)
)
last_read
<=
1'b1
;
else
last_read
<=
last_read
;
end
/*
Check for last read completion.
This logic is to qualify the last read count with the final read
response/data.
*/
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
reads_done
<=
1'b0
;
//The reads_done should be associated with a read ready response
else
if
(
last_read
&&
M_AXI_RVALID
&&
axi_rready
)
reads_done
<=
1'b1
;
else
reads_done
<=
reads_done
;
end
//-----------------------------
//Example design error register
//-----------------------------
//Data Comparison
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
read_mismatch
<=
1'b0
;
//The read data when available (on axi_rready) is compared with the expected data
else
if
((
M_AXI_RVALID
&&
axi_rready
)
&&
(
M_AXI_RDATA
!=
expected_rdata
))
read_mismatch
<=
1'b1
;
else
read_mismatch
<=
read_mismatch
;
end
// Register and hold any data mismatches, or read/write interface errors
always
@
(
posedge
M_AXI_ACLK
)
begin
if
(
M_AXI_ARESETN
==
0
||
init_txn_pulse
==
1'b1
)
error_reg
<=
1'b0
;
//Capture any error types
else
if
(
read_mismatch
||
write_resp_error
||
read_resp_error
)
error_reg
<=
1'b1
;
else
error_reg
<=
error_reg
;
end
// Add user logic here
// User logic ends
endmodule
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录