Pushing the bulk of UHD-3.7.0 code.
Original-commit: ff1546f8137f7f92bb250f685561b0c34cc0e053
This commit is contained in:
@@ -0,0 +1,538 @@
|
||||
|
||||
`include "axi_defs.v"
|
||||
|
||||
`define DEBUG if (1)
|
||||
|
||||
module axi_dma_master
|
||||
(
|
||||
input aclk, // Global AXI clock
|
||||
input areset, // Global AXI reset
|
||||
//
|
||||
// AXI Write address channel
|
||||
//
|
||||
output [0 : 0] m_axi_awid, // Write address ID. This signal is the identification tag for the write address signals
|
||||
output reg [31 : 0] m_axi_awaddr, // Write address. The write address gives the address of the first transfer in a write burst
|
||||
output reg [7 : 0] m_axi_awlen, // Burst length. The burst length gives the exact number of transfers in a burst.
|
||||
output [2 : 0] m_axi_awsize, // Burst size. This signal indicates the size of each transfer in the burst.
|
||||
output [1 : 0] m_axi_awburst, // Burst type. The burst type and the size information, determine how the address is calculated
|
||||
output [0 : 0] m_axi_awlock, // Lock type. Provides additional information about the atomic characteristics of the transfer.
|
||||
output [3 : 0] m_axi_awcache, // Memory type. This signal indicates how transactions are required to progress
|
||||
output [2 : 0] m_axi_awprot, // Protection type. This signal indicates the privilege and security level of the transaction
|
||||
output [3 : 0] m_axi_awqos, // Quality of Service, QoS. The QoS identifier sent for each write transaction
|
||||
output [3 : 0] m_axi_awregion, // Region identifier. Permits a single physical interface on a slave to be re-used.
|
||||
output [0 : 0] m_axi_awuser, // User signal. Optional User-defined signal in the write address channel.
|
||||
output reg m_axi_awvalid, // Write address valid. This signal indicates that the channel is signaling valid write addr
|
||||
input m_axi_awready, // Write address ready. This signal indicates that the slave is ready to accept an address
|
||||
//
|
||||
// AXI Write data channel.
|
||||
//
|
||||
output [63 : 0] m_axi_wdata, // Write data
|
||||
output [7 : 0] m_axi_wstrb, // Write strobes. This signal indicates which byte lanes hold valid data.
|
||||
output reg m_axi_wlast, // Write last. This signal indicates the last transfer in a write burst
|
||||
output [0 : 0] m_axi_wuser, // User signal. Optional User-defined signal in the write data channel.
|
||||
output m_axi_wvalid, // Write valid. This signal indicates that valid write data and strobes are available.
|
||||
input m_axi_wready, // Write ready. This signal indicates that the slave can accept the write data.
|
||||
//
|
||||
// AXI Write response channel signals
|
||||
//
|
||||
input [0 : 0] m_axi_bid, // Response ID tag. This signal is the ID tag of the write response.
|
||||
input [1 : 0] m_axi_bresp, // Write response. This signal indicates the status of the write transaction.
|
||||
input [0 : 0] m_axi_buser, // User signal. Optional User-defined signal in the write response channel.
|
||||
input m_axi_bvalid, // Write response valid. This signal indicates that the channel is signaling a valid response
|
||||
output reg m_axi_bready, // Response ready. This signal indicates that the master can accept a write response
|
||||
//
|
||||
// AXI Read address channel
|
||||
//
|
||||
output [0 : 0] m_axi_arid, // Read address ID. This signal is the identification tag for the read address group of signals
|
||||
output reg [31 : 0] m_axi_araddr, // Read address. The read address gives the address of the first transfer in a read burst
|
||||
output reg [7 : 0] m_axi_arlen, // Burst length. This signal indicates the exact number of transfers in a burst.
|
||||
output [2 : 0] m_axi_arsize, // Burst size. This signal indicates the size of each transfer in the burst.
|
||||
output [1 : 0] m_axi_arburst, // Burst type. The burst type and the size information determine how the address for each transfer
|
||||
output [0 : 0] m_axi_arlock, // Lock type. This signal provides additional information about the atomic characteristics
|
||||
output [3 : 0] m_axi_arcache, // Memory type. This signal indicates how transactions are required to progress
|
||||
output [2 : 0] m_axi_arprot, // Protection type. This signal indicates the privilege and security level of the transaction
|
||||
output [3 : 0] m_axi_arqos, // Quality of Service, QoS. QoS identifier sent for each read transaction.
|
||||
output [3 : 0] m_axi_arregion, // Region identifier. Permits a single physical interface on a slave to be re-used
|
||||
output [0 : 0] m_axi_aruser, // User signal. Optional User-defined signal in the read address channel.
|
||||
output reg m_axi_arvalid, // Read address valid. This signal indicates that the channel is signaling valid read addr
|
||||
input m_axi_arready, // Read address ready. This signal indicates that the slave is ready to accept an address
|
||||
//
|
||||
// AXI Read data channel
|
||||
//
|
||||
input [0 : 0] m_axi_rid, // Read ID tag. This signal is the identification tag for the read data group of signals
|
||||
input [63 : 0] m_axi_rdata, // Read data.
|
||||
input [1 : 0] m_axi_rresp, // Read response. This signal indicates the status of the read transfer
|
||||
input m_axi_rlast, // Read last. This signal indicates the last transfer in a read burst.
|
||||
input [0 : 0] m_axi_ruser, // User signal. Optional User-defined signal in the read data channel.
|
||||
input m_axi_rvalid, // Read valid. This signal indicates that the channel is signaling the required read data.
|
||||
output m_axi_rready, // Read ready. This signal indicates that the master can accept the read data and response
|
||||
//
|
||||
// DMA interface for Write transaction
|
||||
//
|
||||
input [31:0] write_addr, // Byte address for start of write transaction (should be 64bit alligned)
|
||||
input [7:0] write_count, // Count of 64bit words to write. (minus one)
|
||||
input write_ctrl_valid,
|
||||
output reg write_ctrl_ready,
|
||||
input [63:0] write_data,
|
||||
input write_data_valid,
|
||||
output write_data_ready,
|
||||
//
|
||||
// DMA interface for Read
|
||||
//
|
||||
input [31:0] read_addr, // Byte address for start of read transaction (should be 64bit alligned)
|
||||
input [7:0] read_count, // Count of 64bit words to read.
|
||||
input read_ctrl_valid,
|
||||
output reg read_ctrl_ready,
|
||||
output [63:0] read_data,
|
||||
output read_data_valid,
|
||||
input read_data_ready,
|
||||
//
|
||||
// Debug Bus
|
||||
//
|
||||
output [31:0] debug
|
||||
|
||||
);
|
||||
|
||||
|
||||
localparam AW_IDLE = 0;
|
||||
localparam WAIT_AWREADY = 1;
|
||||
localparam WAIT_BVALID = 2;
|
||||
localparam AW_ERROR = 3;
|
||||
|
||||
reg [1:0] write_addr_state;
|
||||
reg [7:0] write_data_count; // Count write transfers.
|
||||
reg enable_data_write;
|
||||
|
||||
localparam DW_IDLE = 0;
|
||||
localparam DW_RUN = 1;
|
||||
localparam DW_LAST = 2;
|
||||
|
||||
reg [1:0] write_data_state;
|
||||
|
||||
localparam AR_IDLE = 0;
|
||||
localparam WAIT_ARREADY = 1;
|
||||
localparam WAIT_READ_DONE = 2;
|
||||
localparam AR_ERROR = 3;
|
||||
|
||||
reg [1:0] read_addr_state;
|
||||
|
||||
localparam DR_IDLE = 0;
|
||||
localparam DR_RUN = 1;
|
||||
localparam DR_WAIT_ERROR = 2;
|
||||
localparam DR_ERROR = 3;
|
||||
|
||||
reg [1:0] read_data_state;
|
||||
reg [7:0] read_data_count;
|
||||
reg enable_data_read;
|
||||
|
||||
///////////////////////////
|
||||
// DEBUG
|
||||
///////////////////////////
|
||||
assign debug= {24'h0,write_addr_state[1:0],write_data_state[1:0],read_addr_state[1:0],read_data_state[1:0]};
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AXI Write address channel
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
assign m_axi_awid = 1'b0;
|
||||
assign m_axi_awsize = 3'h3; // 8 bytes.
|
||||
assign m_axi_awburst = `AXI4_BURST_INCR;
|
||||
assign m_axi_awlock = `AXI4_LOCK_NORMAL;
|
||||
assign m_axi_awcache = `AXI4_CACHE_ALLOCATE | `AXI4_CACHE_OTHER_ALLOCATE | `AXI4_CACHE_MODIFIABLE | `AXI4_CACHE_BUFFERABLE;
|
||||
assign m_axi_awprot = `AXI4_PROT_NON_SECURE;
|
||||
assign m_axi_awqos = 4'h0;
|
||||
assign m_axi_awregion = 4'h0;
|
||||
assign m_axi_awuser = 1'b0;
|
||||
|
||||
|
||||
//
|
||||
// AXI Write address state machine
|
||||
//
|
||||
always @(posedge aclk)
|
||||
if (areset) begin
|
||||
write_ctrl_ready <= 1'b0;
|
||||
write_addr_state <= AW_IDLE;
|
||||
m_axi_awaddr[31:0] <= 32'h0;
|
||||
m_axi_awlen[7:0] <= 8'h0;
|
||||
m_axi_awvalid <= 1'b0;
|
||||
m_axi_bready <= 1'b0;
|
||||
end else
|
||||
case (write_addr_state)
|
||||
//
|
||||
// AW_IDLE
|
||||
// We are ready to accept a new write transaction.
|
||||
//
|
||||
AW_IDLE: begin
|
||||
// Premptively accept new write transaction since we are idle.
|
||||
write_ctrl_ready <= 1'b1;
|
||||
// No need to be waiting for a response while idle.
|
||||
m_axi_bready <= 1'b0;
|
||||
// If we are offered a new transaction then.....
|
||||
if (write_ctrl_valid) begin
|
||||
// Drive all the relevent AXI4 write address channel signals next cycle.
|
||||
m_axi_awaddr[31:0] <= write_addr[31:0];
|
||||
m_axi_awlen[7:0] <= {write_count};
|
||||
m_axi_awvalid <= 1'b1;
|
||||
// If the AXI4 write channel is pre-emptively accepting the transaction...
|
||||
if (m_axi_awready == 1'b1) begin
|
||||
// ...go straight to looking for a transaction response...
|
||||
`DEBUG $display("WRITE TRANSACTION: ADDR: %x LEN: %x @ time %d",write_addr[31:0],write_count,$time);
|
||||
write_addr_state <= WAIT_BVALID;
|
||||
m_axi_bready <= 1'b1;
|
||||
end else begin
|
||||
// ...otherwise wait to get the transaction accepted.
|
||||
write_addr_state <= WAIT_AWREADY;
|
||||
end
|
||||
end
|
||||
end
|
||||
//
|
||||
// WAIT_AWREADY
|
||||
// Waiting for AXI4 slave to accept new write transaction.
|
||||
//
|
||||
WAIT_AWREADY: begin
|
||||
write_ctrl_ready <= 1'b0;
|
||||
// If the AXI4 write channel is accepting the transaction...
|
||||
if (m_axi_awready == 1'b1) begin
|
||||
// ...go to looking for a transaction response...
|
||||
write_addr_state <= WAIT_BVALID;
|
||||
m_axi_bready <= 1'b1;
|
||||
`DEBUG $display("WRITE TRANSACTION: ADDR: %x LEN: %x @ time %d",m_axi_awaddr[31:0],m_axi_awlen[7:0],$time);
|
||||
end else begin
|
||||
// ...otherwise wait to get the trasaction accepted.
|
||||
write_addr_state <= WAIT_AWREADY;
|
||||
end
|
||||
end // case: WAIT_AWREADY
|
||||
//
|
||||
// WAIT_BVALID
|
||||
// Write transaction has been accepted, now waiting for a response to signal it's sucsesful.
|
||||
// Ignoring ID tag for the moment
|
||||
//
|
||||
WAIT_BVALID: begin
|
||||
write_ctrl_ready <= 1'b0;
|
||||
m_axi_awvalid <= 1'b0;
|
||||
// Wait for response channel to signal how write transaction went down....
|
||||
if (m_axi_bvalid == 1'b1) begin
|
||||
if ((m_axi_bresp == `AXI4_RESP_OKAY) || (m_axi_bresp == `AXI4_RESP_EXOKAY)) begin
|
||||
// ....it went well, we are ready to start something new.
|
||||
write_addr_state <= AW_IDLE;
|
||||
m_axi_bready <= 1'b0;
|
||||
write_ctrl_ready <= 1'b1; // Ready to run again as soon as we hit idle.
|
||||
end else if ((m_axi_bresp == `AXI4_RESP_SLVERR) || (m_axi_bresp == `AXI4_RESP_DECERR)) begin
|
||||
// ....things got ugly, retreat to an error stat and wait for intervention.
|
||||
write_addr_state <= AW_ERROR;
|
||||
m_axi_bready <= 1'b0;
|
||||
end
|
||||
end else begin
|
||||
write_addr_state <= WAIT_BVALID;
|
||||
m_axi_bready <= 1'b1;
|
||||
end
|
||||
end // case: WAIT_BVALID
|
||||
//
|
||||
// AW_ERROR
|
||||
// Something bad happened, going to need external intervention to restore a safe state.
|
||||
//
|
||||
AW_ERROR: begin
|
||||
write_ctrl_ready <= 1'b0;
|
||||
write_addr_state <= AW_ERROR;
|
||||
m_axi_awaddr[31:0] <= 32'h0;
|
||||
m_axi_awlen[7:0] <= 8'h0;
|
||||
m_axi_awvalid <= 1'b0;
|
||||
m_axi_bready <= 1'b0;
|
||||
end
|
||||
endcase // case(write_addr_state)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AXI Write data channel
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
assign m_axi_wstrb = 8'hff;
|
||||
assign m_axi_wuser = 1'b0;
|
||||
|
||||
//
|
||||
// AXI Write data state machine
|
||||
//
|
||||
always @(posedge aclk)
|
||||
if (areset) begin
|
||||
write_data_state <= AW_IDLE;
|
||||
write_data_count <= 1;
|
||||
enable_data_write <= 1'b0;
|
||||
m_axi_wlast <= 1'b0;
|
||||
|
||||
end else
|
||||
case (write_data_state)
|
||||
//
|
||||
// DW_IDLE
|
||||
// Sit in this state until presented with the control details of a new write transaction.
|
||||
//
|
||||
DW_IDLE: begin
|
||||
write_data_count <= 1;
|
||||
m_axi_wlast <= 1'b0;
|
||||
|
||||
if (write_ctrl_valid && write_ctrl_ready) begin
|
||||
enable_data_write <= 1'b1;
|
||||
if (write_count[7:0] == 8'h0) begin
|
||||
// Single transfer transaction
|
||||
write_data_state <= DW_LAST;
|
||||
m_axi_wlast <= 1'b1;
|
||||
end else begin
|
||||
write_data_state <= DW_RUN;
|
||||
end
|
||||
end else begin
|
||||
write_data_state <= DW_IDLE;
|
||||
end
|
||||
end
|
||||
//
|
||||
// DW_RUN
|
||||
//
|
||||
DW_RUN : begin
|
||||
enable_data_write <= 1'b1;
|
||||
m_axi_wlast <= 1'b0;
|
||||
|
||||
if (write_data_valid && m_axi_wready) begin
|
||||
// Single write transfer
|
||||
write_data_count <= write_data_count + 1;
|
||||
|
||||
if (write_data_count == m_axi_awlen[7:0]) begin
|
||||
write_data_state <= DW_LAST;
|
||||
m_axi_wlast <= 1'b1;
|
||||
end else begin
|
||||
write_data_state <= DW_RUN;
|
||||
end
|
||||
end else begin
|
||||
write_data_state <= DW_RUN;
|
||||
end
|
||||
end
|
||||
//
|
||||
// DW_LAST
|
||||
//
|
||||
DW_LAST: begin
|
||||
if (write_data_valid && m_axi_wready) begin
|
||||
enable_data_write <= 1'b0;
|
||||
write_data_state <= DW_IDLE;
|
||||
m_axi_wlast <= 1'b0;
|
||||
end else begin
|
||||
enable_data_write <= 1'b1;
|
||||
write_data_state <= DW_LAST;
|
||||
m_axi_wlast <= 1'b1;
|
||||
end
|
||||
end // case: DW_LAST
|
||||
//
|
||||
default:
|
||||
write_data_state <= DW_IDLE;
|
||||
|
||||
endcase // case(write_data_state)
|
||||
|
||||
|
||||
assign m_axi_wdata = write_data;
|
||||
assign m_axi_wvalid = enable_data_write && write_data_valid;
|
||||
assign write_data_ready = enable_data_write && m_axi_wready;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AXI Read address channel
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
assign m_axi_arid = 1'b0;
|
||||
assign m_axi_arsize = 3'h3; // 8 bytes
|
||||
assign m_axi_arburst = `AXI4_BURST_INCR;
|
||||
assign m_axi_arlock = `AXI4_LOCK_NORMAL;
|
||||
assign m_axi_arcache = `AXI4_CACHE_ALLOCATE | `AXI4_CACHE_OTHER_ALLOCATE | `AXI4_CACHE_MODIFIABLE | `AXI4_CACHE_BUFFERABLE;
|
||||
assign m_axi_arprot = `AXI4_PROT_NON_SECURE;
|
||||
assign m_axi_arqos = 4'h0;
|
||||
assign m_axi_arregion = 4'h0;
|
||||
assign m_axi_aruser = 1'b0;
|
||||
|
||||
|
||||
//
|
||||
// AXI Read address state machine
|
||||
//
|
||||
always @(posedge aclk)
|
||||
if (areset) begin
|
||||
read_ctrl_ready <= 1'b0;
|
||||
read_addr_state <= AR_IDLE;
|
||||
m_axi_araddr[31:0] <= 32'h0;
|
||||
m_axi_arlen[7:0] <= 8'h0;
|
||||
m_axi_arvalid <= 1'b0;
|
||||
end else
|
||||
case (read_addr_state)
|
||||
//
|
||||
// AR_IDLE
|
||||
// We are ready to accept a new read transaction.
|
||||
//
|
||||
AR_IDLE: begin
|
||||
// Premptively accept new read transaction since we are idle.
|
||||
read_ctrl_ready <= 1'b1;
|
||||
// If we are offered a new transaction then.....
|
||||
if (read_ctrl_valid) begin
|
||||
// Drive all the relevent AXI4 read address channel signals next cycle.
|
||||
m_axi_araddr[31:0] <= read_addr[31:0];
|
||||
m_axi_arlen[7:0] <= {read_count};
|
||||
m_axi_arvalid <= 1'b1;
|
||||
// If the AXI4 read channel is pre-emptively accepting the transaction...
|
||||
if (m_axi_arready == 1'b1) begin
|
||||
// ...go straight to looking for the transaction to complete
|
||||
`DEBUG $display("READ TRANSACTION: ADDR: %x LEN: %x @ time %d",read_addr[31:0],read_count,$time);
|
||||
read_addr_state <= WAIT_READ_DONE;
|
||||
end else begin
|
||||
// ...otherwise wait to get the transaction accepted.
|
||||
read_addr_state <= WAIT_ARREADY;
|
||||
end
|
||||
end
|
||||
end
|
||||
//
|
||||
// WAIT_ARREADY
|
||||
// Waiting for AXI4 slave to accept new read transaction.
|
||||
//
|
||||
WAIT_ARREADY: begin
|
||||
read_ctrl_ready <= 1'b0;
|
||||
// If the AXI4 read channel is accepting the transaction...
|
||||
if (m_axi_arready == 1'b1) begin
|
||||
// ...go to looking for the transaction to complete...
|
||||
read_addr_state <= WAIT_READ_DONE;
|
||||
`DEBUG $display("READ TRANSACTION: ADDR: %x LEN: %x @ time %d",m_axi_araddr[31:0],m_axi_arlen[7:0],$time);
|
||||
end else begin
|
||||
// ...otherwise wait to get the trasaction accepted.
|
||||
read_addr_state <= WAIT_ARREADY;
|
||||
end
|
||||
end // case: WAIT_ARREADY
|
||||
//
|
||||
// WAIT_READ_DONE
|
||||
// Read transaction has been accepted, now waiting for the data transfer to complete
|
||||
// Ignoring ID tag for the moment
|
||||
//
|
||||
WAIT_READ_DONE: begin
|
||||
read_ctrl_ready <= 1'b0;
|
||||
m_axi_arvalid <= 1'b0;
|
||||
// Wait for read transaction to complete
|
||||
if (read_data_state == DR_IDLE) begin
|
||||
// ....it went well, we are ready to start something new.
|
||||
read_addr_state <= AR_IDLE;
|
||||
read_ctrl_ready <= 1'b1; // Ready to run again as soon as we hit idle.
|
||||
end else if (read_data_state == DR_ERROR) begin
|
||||
// ....things got ugly, retreat to an error stat and wait for intervention.
|
||||
read_addr_state <= AR_ERROR;
|
||||
end else begin
|
||||
read_addr_state <= WAIT_READ_DONE;
|
||||
end
|
||||
end // case: WAIT_BVALID
|
||||
//
|
||||
// AR_ERROR
|
||||
// Something bad happened, going to need external intervention to restore a safe state.
|
||||
//
|
||||
AR_ERROR: begin
|
||||
read_ctrl_ready <= 1'b0;
|
||||
read_addr_state <= AR_ERROR;
|
||||
m_axi_araddr[31:0] <= 32'h0;
|
||||
m_axi_arlen[7:0] <= 8'h0;
|
||||
m_axi_arvalid <= 1'b0;
|
||||
end
|
||||
endcase // case(read_addr_state)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AXI Read data channel
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//
|
||||
// AXI Read data state machine
|
||||
//
|
||||
always @(posedge aclk)
|
||||
if (areset) begin
|
||||
read_data_state <= AR_IDLE;
|
||||
read_data_count <= 0;
|
||||
enable_data_read <= 1'b0;
|
||||
|
||||
end else
|
||||
case (read_data_state)
|
||||
//
|
||||
// DR_IDLE
|
||||
// Sit in this state until presented with the control details of a new read transaction.
|
||||
//
|
||||
DR_IDLE: begin
|
||||
read_data_count <= 0;
|
||||
|
||||
if (read_ctrl_valid && read_ctrl_ready) begin
|
||||
enable_data_read <= 1'b1;
|
||||
read_data_state <= DR_RUN;
|
||||
end else begin
|
||||
read_data_state <= DR_IDLE;
|
||||
end
|
||||
end
|
||||
//
|
||||
// DR_RUN
|
||||
// Sit here counting read transfers. If any have error's shift to error state.
|
||||
//
|
||||
DR_RUN : begin
|
||||
enable_data_read <= 1'b1;
|
||||
|
||||
if (read_data_ready && m_axi_rvalid) begin
|
||||
// Single read transfer
|
||||
read_data_count <= read_data_count + 1;
|
||||
if ((m_axi_rresp == `AXI4_RESP_SLVERR) || (m_axi_rresp == `AXI4_RESP_DECERR)) begin
|
||||
if (m_axi_rlast) begin
|
||||
read_data_state <= DR_ERROR;
|
||||
end else begin
|
||||
read_data_state <= DR_WAIT_ERROR;
|
||||
end
|
||||
end else if (m_axi_rlast) begin // Implicitly good response signalled this transfer.
|
||||
if (read_data_count == m_axi_arlen[7:0]) begin
|
||||
read_data_state <= DR_IDLE;
|
||||
end else begin
|
||||
read_data_state <= DR_ERROR;
|
||||
end
|
||||
end else begin
|
||||
read_data_state <= DR_RUN;
|
||||
end
|
||||
end else begin
|
||||
read_data_state <= DR_RUN;
|
||||
end
|
||||
end
|
||||
//
|
||||
// DR_WAIT_ERROR
|
||||
// Something bad happened, wait for last signalled in this burst
|
||||
//
|
||||
DR_WAIT_ERROR: begin
|
||||
if (read_data_ready && m_axi_rvalid && m_axi_rlast) begin
|
||||
enable_data_read <= 1'b0;
|
||||
read_data_state <= DR_ERROR;
|
||||
end else begin
|
||||
enable_data_read <= 1'b1;
|
||||
read_data_state <= DR_WAIT_ERROR;
|
||||
end
|
||||
end // case: DR_WAIT_ERROR
|
||||
//
|
||||
// DR_ERROR
|
||||
// Something bad happened, going to need external intervention to restore a safe state.
|
||||
//
|
||||
DR_ERROR: begin
|
||||
enable_data_read <= 1'b0;
|
||||
read_data_state <= DR_ERROR;
|
||||
end // case: DR_ERROR
|
||||
|
||||
|
||||
endcase // case(read_data_state)
|
||||
|
||||
|
||||
assign read_data = m_axi_rdata;
|
||||
assign m_axi_rready = enable_data_read && read_data_ready;
|
||||
assign read_data_valid = enable_data_read && m_axi_rvalid;
|
||||
|
||||
endmodule // axi_dma_master
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user