AXI学习记录(7)------简易AXI Slave实现
文章目录
前言
许久未更新了,之前的文章中简单介绍了AXI4相关内容,下面将简单介绍AXI4 Slave如何实现的,当然也包括AXI4 Master module和简单的Testbench。
1 Master rsim module的功能
下面将介绍Master rsim module具体实现了哪些功能,这里没有做的很复杂,就是一个简单的module:
- 使用端口上的start_en信号开始;
- 先进行写操作,即写入AWLEN+1个数,数据从1依次增加4,增加16次;
- 写完后接着进行读操作,读取ARLEN+1个数。
下图是Master module的简易状态机:

Master状态机RTL:
assign w_idle_to_start = ~r_master_en_d1 & MASTER_EN; // MASTER_EN posedge
always @(*) begin
case(r_state_cur)
ST_IDLE : r_state_next = w_idle_to_start ? WR_ST_TRANS : ST_IDLE ;
WR_ST_TRANS : r_state_next = r_WLAST ? WR_ST_END : WR_ST_TRANS ;
WR_ST_END : r_state_next = RD_ST_TRANS ;
RD_ST_TRANS : r_state_next = RLAST ? RD_ST_END : RD_ST_TRANS ;
RD_ST_END : r_state_next = ST_IDLE ;
default : r_state_next = ST_IDLE ;
endcase
end
其余RTL见附件。
2 Slave的功能
2.1 写操作
- 接收到Master给的AWVALID信号后,将Slave的AWREADY信号拉高,AWREADY信号持续1个Cycle后拉低。
- 由于WDATA位宽为32bits,故AWSIZE的值只能是3’b000/001/010,这里固定为3’b010;
- 使用AWSIZE为3’b010,对于BURST为INCR的情况,内部r_axi_s_awddr每次递增4,什么时候地址递增?在WVALID & WREADY = 1且地址counter不大于AWLEN时递增;
- 当Slave接收到Master给的WVALID信号后,将WREADY信号拉高,该信号在WLAST=1时拉低。
- Slave中将Master写的数据保存到SRAM(使用寄存器组表示)中,什么时候写有效,即WVALID & WREADY = 1有效,
- 对于写回复,bresp信号则在WLAST是写0(OK)即可;而BVALID信号则在准备写入数据时拉高,收到BREADY时拉低。
写入SRAM RTL:
wire w_sram_wr_en = r_axi_s_wready & AXI_S_WVALID;
wire [ADDR_WIDTH-ADDR_LSB-1:0] w_sram_addr = r_axi_s_awv_arr_flag ? r_axi_s_araddr[ADDR_WIDTH-1:ADDR_LSB]:
(r_axi_s_awv_awr_flag ? r_axi_s_awaddr[ADDR_WIDTH-1:ADDR_LSB]:0);
integer i;
always @(posedge AXI_S_ACLK or negedge AXI_S_ARESETN) begin
if (~AXI_S_ARESETN) begin
for (i=0; i<SRAM_DEPTH; i=i+1)
r_sram[i] <= #udly {DATA_WIDTH{1'h0}};
end
else if (w_sram_wr_en) begin
if (AXI_S_WSTRB[0])
r_sram[w_sram_addr][ 7: 0] <= #udly AXI_S_WDATA[ 7: 0];
if (AXI_S_WSTRB[1])
r_sram[w_sram_addr][15: 8] <= #udly AXI_S_WDATA[15: 8];
if (AXI_S_WSTRB[2])
r_sram[w_sram_addr][23:16] <= #udly AXI_S_WDATA[23:16];
if (AXI_S_WSTRB[3])
r_sram[w_sram_addr][31:24] <= #udly AXI_S_WDATA[31:24];
end
end
2.2 读操作
- 接收到Master给的ARVALID信号后,将Slave的ARREADY信号拉高,ARREADY信号持续1个Cycle后拉低。
- 由于RDATA位宽为32bits,故ARSIZE的值只能是3’b000/001/010,这里固定为3’b010;
- 使用ARSIZE为3’b010,对于BURST为INCR的情况,内部r_axi_s_arddr每次递增4,什么时候地址递增?在RVALID & RREADY = 1且地址counter不大于ARLEN时递增;
- 当Slave接收到Master给的RREADY信号后,将RVALID信号拉高,该信号在RLAST=1时拉低。
- 读操作需要生成RLAST,怎么生成呢?对读取数据进行计数,记到ARLEN-1时将RLAST拉高,起个Cycle拉低。
- Master从Slave的SRAM中读取数据,什么时候读有效,即RVALID& RREADY = 1有效;
- 对于读回复,bresp信号则在接收到r_axi_s_awv_arr_flag时为0(OK)即可;
从SRAM读取数据RTL:
wire w_sram_rd_en = AXI_S_RREADY & r_axi_s_rvalid;
wire [DATA_WIDTH-1:0] w_sram_data_out = r_sram[w_sram_addr];
always @(posedge AXI_S_ACLK or negedge AXI_S_ARESETN) begin
if (~AXI_S_ARESETN)
r_axi_s_rdata <= #udly {DATA_WIDTH{1'h0}};
else if (w_sram_rd_en)
r_axi_s_rdata <= #udly w_sram_data_out;
end
3 结果分析
如下图所示,先写入AWLEN+1个起始为1依次递增4的数据,再读取出ARLEN+1个数据,可以看到r_axi_s_rdata和AXI_S_WDATA相同。基本功能OK。

3.1 参考RTL
参考RTL路径:AXI4 Simple all RTL
参考make vcs/verdi 命令:
#------------------------------------------------------------------------------------
# VCS
vcs : vcs -f file_list -timescale=1ns/1ns -full64 -R +vc +v2k -sverilog -debug_access+all |tee vcs.log
#------------------------------------------------------------------------------------
# verdi
verdi : verdi -sv -f file_list -ssf verilog.fsdb &
#------------------------------------------------------------------------------------
总结
本文简单介绍了AXI4 Master rsim module和AXI4 Slave的实现。后续研究一下outstanding功能,再看看能否将Slave在TSMC某个工艺上综合一下看看怎么个事。
964

被折叠的 条评论
为什么被折叠?



