`timescale 1 ns / 1 ps
modulemyip_v1_0_S00_AXI #
(
//Users to add parameters here
//User parameters ends
//Do not modify the parameters beyond this line
//Width of S_AXI data bus
parameterinteger C_S_AXI_DATA_WIDTH = 32,
//Width of S_AXI address bus
parameterinteger C_S_AXI_ADDR_WIDTH = 4
)
(
//Users to add ports here
//User ports ends
//Do not modify the ports beyond this line
//Global Clock Signal
inputwire S_AXI_ACLK,
//Global Reset Signal. This Signal is Active LOW
inputwire S_AXI_ARESETN, //复位,低有效
//Write address (issued by master, acceped by Slave)
inputwire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR, //写地址,给出一次写突发传输的写地址
//Write channel Protection type. This signal indicates the
// privilege and security level ofthe transaction, and whether
// the transaction is a data accessor an instruction access.
inputwire [2 : 0] S_AXI_AWPROT, //写通道保护类型。此信号表示事务的特权和安全级别,以及事务是数据访问还是指令访问。
//Write address valid. This signal indicates that the master signaling
// valid write address and controlinformation.
inputwire S_AXI_AWVALID, //写地址有效信号。此信号表示主信号有效的写入地址和控制信息
//Write address ready. This signal indicates that the slave is ready
// to accept an address and associatedcontrol signals.
outputwire S_AXI_AWREADY, //表明“从”可以接收地址和对应的控制信号
//Write data (issued by master, acceped by Slave)
inputwire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA, //写数据
//Write strobes. This signal indicates which byte lanes hold
// valid data. There is one writestrobe bit for each eight
// bits of the write data bus.
inputwire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB, //写选通信号。 此信号指示哪个字节(8个wire)线保存有效数据。写入数据总线的每个八位有一个写选通位。
//Write valid. This signal indicates that valid write
// data and strobes are available.
inputwire S_AXI_WVALID, //写有效,表明此次写有效
//Write ready. This signal indicates that the slave
// can accept the write data.
outputwire S_AXI_WREADY,//表明从机可以接收写数据
//Write response. This signal indicates the status
// of the write transaction.
outputwire [1 : 0] S_AXI_BRESP,//写响应,表明写传输的状态
//Write response valid. This signal indicates that the channel
// is signaling a valid writeresponse.
outputwire S_AXI_BVALID,//写响应有效
//Response ready. This signal indicates that the master
// can accept a write response.
inputwire S_AXI_BREADY,//表明主机能够接收写响应
//Read address (issued by master, acceped by Slave)
inputwire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR,// 读地址,给出一次写突发传输的读地址
//Protection type. This signal indicates the privilege
// and security level of thetransaction, and whether the
// transaction is a data access oran instruction access.
inputwire [2 : 0] S_AXI_ARPROT,//保护类型,表明一次传输的特权级及安全等级,以及事务是数据访问还是指令访问。
//Read address valid. This signal indicates that the channel
// is signaling valid read addressand control information.
inputwire S_AXI_ARVALID,//读地址有效信号,此信号通道的地址和控制信号有效。
//Read address ready. This signal indicates that the slave is
// ready to accept an address andassociated control signals.
outputwire S_AXI_ARREADY,//表明从机可以接受地址和控制信号
//Read data (issued by slave)
outputwire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA,//读数据
//Read response. This signal indicates the status of the
// read transfer.
outputwire [1 : 0] S_AXI_RRESP,//读响应,处于读传输状态
//Read valid. This signal indicates that the channel is
// signaling the required read data.
outputwire S_AXI_RVALID,//读有效,表明此次读有效
//Read ready. This signal indicates that the master can
// accept the read data and responseinformation.
inputwire S_AXI_RREADY //读主机可以接收到读数据和响应信息
);
//AXI4LITE signals
reg[C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr;//写地址
reg axi_awready;//写地址就绪信号
reg axi_wready;//写就绪信号
reg[1 : 0] axi_bresp;//写响应信号,处于写状态
reg axi_bvalid;//写响应有效信号
reg[C_S_AXI_ADDR_WIDTH-1 : 0] axi_araddr;//读地址
reg axi_arready;//读地址就绪信号
reg[C_S_AXI_DATA_WIDTH-1 : 0] axi_rdata;//读数据信号
reg[1 : 0] axi_rresp;//读响应信号,处于读状态
reg axi_rvalid;//读有效信号
//Example-specific design signals
//local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
//ADDR_LSB is used for addressing 32/64 bit registers/memories
//ADDR_LSB = 2 for 32 bits (n downto 2)
//ADDR_LSB = 3 for 64 bits (n downto 3)
localparaminteger ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1;
localparaminteger OPT_MEM_ADDR_BITS = 1;
//----------------------------------------------
//--Signals for user logic register space example
//------------------------------------------------
//--Number of Slave Registers 4
reg[C_S_AXI_DATA_WIDTH-1:0] slv_reg0;
reg[C_S_AXI_DATA_WIDTH-1:0] slv_reg1;
reg[C_S_AXI_DATA_WIDTH-1:0] slv_reg2;
reg[C_S_AXI_DATA_WIDTH-1:0] slv_reg3;
wire slv_reg_rden;
wire slv_reg_wren;
reg[C_S_AXI_DATA_WIDTH-1:0] reg_data_out;
integer byte_index;
reg aw_en;
//I/O Connections assignments
assignS_AXI_AWREADY = axi_awready;
assignS_AXI_WREADY = axi_wready;
assignS_AXI_BRESP = axi_bresp;
assignS_AXI_BVALID = axi_bvalid;
assignS_AXI_ARREADY = axi_arready;
assignS_AXI_RDATA = axi_rdata;
assignS_AXI_RRESP = axi_rresp;
assignS_AXI_RVALID = axi_rvalid;
//Implement axi_awready generation
//axi_awready is asserted for one S_AXI_ACLK clock cycle when both
//S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
//de-asserted when reset is low.
always@( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_awready <= 1'b0;
aw_en <= 1'b1;
end
else
begin
if (~axi_awready && S_AXI_AWVALID&& S_AXI_WVALID && aw_en) //写地址未完成,写地址有效,写数据有效,写使能为1
begin
// slave is ready to accept write addresswhen ‘
// there is a valid write address andwrite data
// on the write address and data bus.This design
// expects no outstandingtransactions.
axi_awready <= 1'b1;
aw_en <= 1'b0; //aw_en为1时表明还没有写数据可以写,即进入此条件,进入后改为0,表明正在写数据,外部不能再往里面写完数据了。
end
else if (S_AXI_BREADY &&axi_bvalid)//写响应完成,写响应有效,即写完了将写使能和写就绪信号恢复为初始状态
begin
aw_en <= 1'b1;
axi_awready <= 1'b0;
end
else
begin
axi_awready <= 1'b0;
end
end
end
//Implement axi_awaddr latching
//This process is used to latch the address when both
//S_AXI_AWVALID and S_AXI_WVALID are valid.
//当S_AXI_AWVALID和 S_AXI_WVALID 信号均有效时,将地址锁存。
always@( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_awaddr <= 0;
end
else
begin
if (~axi_awready && S_AXI_AWVALID&& S_AXI_WVALID && aw_en)//写地址未完成,写地址有效,写使能有效时将地址写入
begin
// Write Address latching
axi_awaddr <= S_AXI_AWADDR;
end
end
end
//Implement axi_wready generation
//axi_wready is asserted for one S_AXI_ACLK clock cycle when both
//S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
//de-asserted when reset is low.
always@( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_wready <= 1'b0;
end
else
begin
if (~axi_wready && S_AXI_WVALID&& S_AXI_AWVALID && aw_en )//写就未完成,写有效,写地址有效,写使能为1,将写完成状态改为完成
begin
// slave is ready to accept writedata when
// there is a valid write address andwrite data
// on the write address and data bus.This design
// expects no outstandingtransactions.
axi_wready <= 1'b1;
end
else
begin
axi_wready <= 1'b0;
end
end
end
//Implement memory mapped register select and write logic generation
//The write data is accepted and written to memory mapped registers when
//axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Writestrobes are used to
//select byte enables of slave registers while writing.
//These registers are cleared when reset (active low) is applied.
//Slave register write enable is asserted when valid address and data areavailable
//and the slave is ready to accept the write address and write data.
assignslv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready&& S_AXI_AWVALID;//写完成,写有效,写地址完成,写地址有效
always@( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
slv_reg0 <= 0;
slv_reg1 <= 0;
slv_reg2 <= 0;
slv_reg3 <= 0;
end
else begin
if (slv_reg_wren)
begin
case (axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )/*这段程序的作用是,当PS那边向AXI4-Lite总线写数据时,PS这边负责将数据接收到寄存器slv_reg。而slv_reg寄存器有0~3共4个。至于赋值给哪一个由
axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]决定,根据宏定义其实就是由axi_awaddr[3:2] (写地址中不仅包含地址,而且包含了控制位,这里的[3:2]就是控制位)决定赋值给哪个slv_reg。PS调用写函数时,如果不做地址偏移的话,axi_awaddr[3:2]的值默认是为0的,举个例子,如果我们自定义的IP的地址被映射为0x43C00000,那么我们Xil_Out32(0x43C00000,Value)写的就是slv_reg0的值。如果地址偏移4位,如
Xil_Out32(0x43C00000 + 4,Value) 写的就是slv_reg1的值,依次类推*/
2'h0:
for ( byte_index = 0; byte_index<= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
if ( S_AXI_WSTRB[byte_index] == 1) begin //S_AXI_WSTRB的每一位信号都对应一个字节数据,当该位有效则代表这个字节数据有效
// Respective byte enables areasserted as per write strobes
// Slave register 0
slv_reg0[(byte_index*8) +: 8]<= S_AXI_WDATA[(byte_index*8) +: 8];
end
2'h1:
for ( byte_index = 0; byte_index<= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
if ( S_AXI_WSTRB[byte_index] == 1) begin
// Respective byte enables areasserted as per write strobes
// Slave register 1
slv_reg1[(byte_index*8) +: 8]<= S_AXI_WDATA[(byte_index*8) +: 8];
end
2'h2:
for ( byte_index = 0; byte_index<= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
if ( S_AXI_WSTRB[byte_index] == 1) begin
// Respective byte enables areasserted as per write strobes
// Slave register 2
slv_reg2[(byte_index*8) +: 8]<= S_AXI_WDATA[(byte_index*8) +: 8];
end
2'h3:
for ( byte_index = 0; byte_index<= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
if ( S_AXI_WSTRB[byte_index] == 1) begin
// Respective byte enables areasserted as per write strobes
// Slave register 3
slv_reg3[(byte_index*8) +: 8]<= S_AXI_WDATA[(byte_index*8) +: 8];
end
default : begin
slv_reg0 <= slv_reg0;
slv_reg1 <= slv_reg1;
slv_reg2 <= slv_reg2;
slv_reg3 <= slv_reg3;
end
endcase
end
end
end
//Implement write response logic generation
//The write response and response valid signals are asserted by the slave
//when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
//This marks the acceptance of address and indicates the status of
//write transaction.
always@( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_bvalid <= 0;
axi_bresp <= 2'b0;
end
else
begin
if (axi_awready && S_AXI_AWVALID&& ~axi_bvalid && axi_wready && S_AXI_WVALID)//写地址有效,写数据有效,写地址完成,写完成,写响应无效,
begin //即,将数据已经成功写入,此时应将写响应改为有效,写传输状态置0
// indicates a valid write responseis available
axi_bvalid <= 1'b1;
axi_bresp <= 2'b0; // 'OKAY' response
end // work error responses infuture
else
begin
if (S_AXI_BREADY &&axi_bvalid) //主机传来写响应完成,自身处于写响应有效
//check if bready is asserted whilebvalid is high)
//(there is a possibility thatbready is always asserted high)
begin
axi_bvalid <= 1'b0;
end
end
end
end
//Implement axi_arready generation
//axi_arready is asserted for one S_AXI_ACLK clock cycle when
//S_AXI_ARVALID is asserted. axi_awready is
//de-asserted when reset (active low) is asserted.
//The read address is also latched when S_AXI_ARVALID is
//asserted. axi_araddr is reset to zero on reset assertion.
always@( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_arready <= 1'b0;
axi_araddr <= 32'b0;
end
else
begin
if (~axi_arready &&S_AXI_ARVALID)//读地址未完成,读地址有效
begin
// indicates that the slave hasacceped the valid read address
axi_arready <= 1'b1;
// Read address latching
axi_araddr <= S_AXI_ARADDR;
end
else
begin
axi_arready <= 1'b0;
end
end
end
//Implement axi_arvalid generation
//axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
//S_AXI_ARVALID and axi_arready are asserted. The slave registers
//data are available on the axi_rdata bus at this instance. The
//assertion of axi_rvalid marks the validity of read data on the
//bus and axi_rresp indicates the status of read transaction.axi_rvalid
//is deasserted on reset (active low). axi_rresp and axi_rdata are
//cleared to zero on reset (active low).
always@( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_rvalid <= 0;
axi_rresp <= 0;
end
else
begin
if (axi_arready && S_AXI_ARVALID&& ~axi_rvalid)//读地址完成,读地址有效,读未完成,此时将读改为有效,将读状态改为未处于读状态
begin
// Valid read data is available atthe read data bus
axi_rvalid <= 1'b1;
axi_rresp <= 2'b0; // 'OKAY' response
end
else if (axi_rvalid &&S_AXI_RREADY)//读有效,读完成,此时将读改为无效
begin
// Read data is accepted by themaster
axi_rvalid <= 1'b0;
end
end
end
//Implement memory mapped register select and read logic generation
//Slave register read enable is asserted when valid address is available
//and the slave is ready to accept the read address.
assignslv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;//读地址完成,读地址有效,读无效,即此时成功拿到主机给的地址但读数据还未完成
always@(*)
begin
// Address decoding for reading registers
case (axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
2'h0 : reg_data_out <= slv_reg0;
2'h1 : reg_data_out <= slv_reg1;
2'h2 : reg_data_out <= slv_reg2;
2'h3 : reg_data_out <= slv_reg3;
default : reg_data_out <= 0;
endcase
end
//Output register or memory read data
always@( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_rdata <= 0;
end
else
begin
// When there is a valid read address(S_AXI_ARVALID) with
// acceptance of read address by theslave (axi_arready),
// output the read dada
if (slv_reg_rden)//当需要读出数据时
begin
axi_rdata <= reg_data_out; // register read data
end
end
end
//Add user logic here
//User logic ends
endmodule
没有回复内容